Skip to content

Commit

Permalink
Merge pull request #45 from alanenriqueo/releases/v1
Browse files Browse the repository at this point in the history
Release v1.2.0
  • Loading branch information
DaeunYim committed Aug 5, 2022
2 parents 093f3af + d4f12a3 commit d27d971
Show file tree
Hide file tree
Showing 1,657 changed files with 331,299 additions and 256,380 deletions.
218 changes: 218 additions & 0 deletions __tests__/AzureMySqlResourceManager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import * as core from '@actions/core';
import { IAuthorizer } from 'azure-actions-webclient/Authorizer/IAuthorizer';
import { WebRequest, WebResponse } from 'azure-actions-webclient/WebClient';
import { ServiceClient as AzureRestClient, ToError, AzureError } from 'azure-actions-webclient/AzureRestClient';

import AzureMySqlResourceManager, { FirewallRule } from '../src/AzureMySqlResourceManager';
import FirewallManager from '../src/FirewallManager';

jest.mock('azure-actions-webclient/AzureRestClient');

describe('AzureMySqlResourceManager tests', () => {
it('initializes resource manager correctly for single server', async () => {
let getRequestUrlSpy = jest.spyOn(AzureRestClient.prototype, 'getRequestUri').mockReturnValue('https://randomUrl/');
let beginRequestSpy = jest.spyOn(AzureRestClient.prototype, 'beginRequest').mockResolvedValue({
statusCode: 200,
body: {
value: [
{
name: 'testServer',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer'
},
{
name: 'testServer2',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer2'
}
]
},
statusMessage: 'OK',
headers: []
});

let resourceManager = await AzureMySqlResourceManager.getResourceManager('testServer', {} as IAuthorizer);
let server = resourceManager.getMySqlServer();

expect(server!.name).toEqual('testServer');
expect(server!.id).toEqual('/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer');
expect(getRequestUrlSpy).toHaveBeenCalledTimes(1);
expect(beginRequestSpy).toHaveBeenCalledTimes(1);
});

it('initializes resource manager correctly for flexible server', async () => {
let getRequestUrlSpy = jest.spyOn(AzureRestClient.prototype, 'getRequestUri').mockReturnValue('https://randomUrl/');
let beginRequestSpy = jest.spyOn(AzureRestClient.prototype, 'beginRequest').mockResolvedValueOnce({
statusCode: 200,
body: {
value: [
{
name: 'testServer',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer'
},
{
name: 'testServer2',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer2'
}
]
},
statusMessage: 'OK',
headers: []
}).mockResolvedValueOnce({
statusCode: 200,
body: {
value: [
{
name: 'testServer3',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer3'
},
{
name: 'testServer4',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer4'
}
]
},
statusMessage: 'OK',
headers: []
});

let resourceManager = await AzureMySqlResourceManager.getResourceManager('testServer3', {} as IAuthorizer);
let server = resourceManager.getMySqlServer();

expect(server!.name).toEqual('testServer3');
expect(server!.id).toEqual('/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer3');
expect(getRequestUrlSpy).toHaveBeenCalledTimes(2);
expect(beginRequestSpy).toHaveBeenCalledTimes(2);
})

it('throws if resource manager fails to initialize', async () => {
let getRequestUrlSpy = jest.spyOn(AzureRestClient.prototype, 'getRequestUri').mockReturnValue('https://randomUrl/');
let beginRequestSpy = jest.spyOn(AzureRestClient.prototype, 'beginRequest').mockResolvedValueOnce({
statusCode: 200,
body: {
value: [
{
name: 'testServer1',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer1'
},
{
name: 'testServer2',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer2'
}
]
},
statusMessage: 'OK',
headers: []
}).mockResolvedValueOnce({
statusCode: 200,
body: {
value: [
{
name: 'testServer3',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/flexibleServers/testServer3'
},
{
name: 'testServer4',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/flexibleServers/testServer4'
}
]
},
statusMessage: 'OK',
headers: []
});

let expectedError = `Unable to get details of MySQL server testServer. MySQL server 'testServer' was not found in the subscription.`;
try {
await AzureMySqlResourceManager.getResourceManager('testServer', {} as IAuthorizer);
} catch(error) {
expect(error.message).toEqual(expectedError);
}
expect(getRequestUrlSpy).toHaveBeenCalledTimes(2);
expect(beginRequestSpy).toHaveBeenCalledTimes(2);
});

it('adds firewall rule successfully', async () => {
let getRequestUrlSpy = jest.spyOn(AzureRestClient.prototype, 'getRequestUri').mockReturnValue('https://randomUrl/');
let beginRequestSpy = jest.spyOn(AzureRestClient.prototype, 'beginRequest').mockResolvedValueOnce({
statusCode: 200,
body: {
value: [
{
name: 'testServer',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer'
},
{
name: 'testServer2',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer2'
}
]
},
statusMessage: 'OK',
headers: []
}).mockResolvedValueOnce({
statusCode: 202,
body: {},
statusMessage: 'OK',
headers: {
'azure-asyncoperation': 'http://asyncRedirectionURI'
}
}).mockResolvedValueOnce({
statusCode: 200,
body: {
'status': 'Succeeded'
},
statusMessage: 'OK',
headers: {}
});;

let getFirewallRuleSpy = jest.spyOn(AzureMySqlResourceManager.prototype, 'getFirewallRule').mockResolvedValue({
name: 'FirewallRule'
} as FirewallRule);

let resourceManager = await AzureMySqlResourceManager.getResourceManager('testServer', {} as IAuthorizer);
await resourceManager.addFirewallRule('0.0.0.0', '1.1.1.1');

expect(getRequestUrlSpy).toHaveBeenCalledTimes(2);
expect(beginRequestSpy).toHaveBeenCalledTimes(3);
expect(getFirewallRuleSpy).toHaveBeenCalledTimes(1);
});

it('removes firewall rule successfully', async () => {
let getRequestUrlSpy = jest.spyOn(AzureRestClient.prototype, 'getRequestUri').mockReturnValue('https://randomUrl/');
let beginRequestSpy = jest.spyOn(AzureRestClient.prototype, 'beginRequest').mockResolvedValueOnce({
statusCode: 200,
body: {
value: [
{
name: 'testServer',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer'
},
{
name: 'testServer2',
id: '/subscriptions/SubscriptionId/resourceGroups/testrg/providers/Microsoft.DBforMySQL/servers/testServer2'
}
]
},
statusMessage: 'OK',
headers: []
}).mockResolvedValueOnce({
statusCode: 202,
body: {},
statusMessage: 'OK',
headers: {
'azure-asyncoperation': 'http://asyncRedirectionURI'
}
}).mockResolvedValueOnce({
statusCode: 200,
body: {
'status': 'Succeeded'
},
statusMessage: 'OK',
headers: {}
});

let resourceManager = await AzureMySqlResourceManager.getResourceManager('testServer', {} as IAuthorizer);
await resourceManager.removeFirewallRule({ name: 'FirewallRule' } as FirewallRule);

expect(getRequestUrlSpy).toHaveBeenCalledTimes(2);
expect(beginRequestSpy).toHaveBeenCalledTimes(3);
});
})
49 changes: 49 additions & 0 deletions __tests__/MysqlUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as exec from '@actions/exec';
import MySqlUtils from "../src/MySqlUtils";
import AzureMySqlActionHelper from "../src/AzureMySqlActionHelper";
import { HttpClient } from '@actions/http-client';

jest.mock('@actions/http-client');

describe('MySqlUtils tests', () => {
afterEach(() => {
jest.resetAllMocks();
});

it('detectIPAddress should return ip address', async () => {
let getMySqlClientPathSpy = jest.spyOn(AzureMySqlActionHelper, 'getMySqlClientPath').mockResolvedValue('mysql.exe');

let execSpy = jest.spyOn(exec, 'exec').mockImplementation((_commandLine, _args, options) => {
let mysqlClientError = `Client with IP address '1.2.3.4' is not allowed to access the server.`;
options!.listeners!.stderr!(Buffer.from(mysqlClientError));
return Promise.reject(1);
});

let httpSpy = jest.spyOn(HttpClient.prototype, 'getJson').mockResolvedValue({
statusCode: 200,
result: {
ip: '1.2.3.4',
},
headers: {},
});

let ipAddress = await MySqlUtils.detectIPAddress('serverName', 'connString');

expect(getMySqlClientPathSpy).toHaveBeenCalledTimes(1);
expect(execSpy).toHaveBeenCalledTimes(1);
expect(httpSpy).toHaveBeenCalledTimes(1);
expect(ipAddress).toBe('1.2.3.4');
});

it('detectIPAddress should return empty string', async () => {
let getMySqlClientPathSpy = jest.spyOn(AzureMySqlActionHelper, 'getMySqlClientPath').mockResolvedValue('mysql.exe');

let execSpy = jest.spyOn(exec, 'exec').mockResolvedValue(0);

let ipAddress = await MySqlUtils.detectIPAddress('serverName', 'connString');

expect(getMySqlClientPathSpy).toHaveBeenCalledTimes(1);
expect(execSpy).toHaveBeenCalledTimes(1);
expect(ipAddress).toBe('');
});
});
1 change: 1 addition & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ inputs:
required: true
arguments:
description: 'Additional options supported by mysql simple SQL shell. These options will be applied when executing the given file on the Azure DB for Mysql.'
required: false
runs:
using: 'node12'
main: 'lib/main.js'
29 changes: 21 additions & 8 deletions lib/AzureMySqlAction.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Expand Down
29 changes: 21 additions & 8 deletions lib/AzureMySqlActionHelper.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Expand Down
Loading

0 comments on commit d27d971

Please sign in to comment.