Skip to content

Commit

Permalink
adds port to sqlcmd calls, plus tests (#193)
Browse files Browse the repository at this point in the history
* adds port to sqlcmd calls, plus tests

* improve test cases
  • Loading branch information
dzsquared authored Dec 6, 2023
1 parent 4a56ed1 commit 1ad5218
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 14 deletions.
31 changes: 27 additions & 4 deletions __tests__/AzureSqlAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('AzureSqlAction tests', () => {
describe('validate sqlpackage calls for DacpacAction', () => {
const inputs = [
['Publish', '/TargetTimeout:20'],
['Publish', '/p:DropObjectsNotInSource=true /p:BlockOnPossibleDataLoss=false /v:RELEASEVERSION="1.0.0"'],
['Script', '/DeployScriptPath:script.sql'],
['DriftReport', '/OutputPath:report.xml'],
['DeployReport', '/OutputPath:report.xml']
Expand Down Expand Up @@ -56,10 +57,10 @@ describe('AzureSqlAction tests', () => {
describe('sql script action tests for different auth types', () => {
// Format: [test case description, connection string, expected sqlcmd arguments]
const testCases = [
['SQL login', 'Server=testServer.database.windows.net;Database=testDB;User Id=testUser;Password=placeholder', '-S testServer.database.windows.net -d testDB -U "testUser" -i "./TestFile.sql" -t 20'],
['AAD password', 'Server=testServer.database.windows.net;Database=testDB;Authentication=Active Directory Password;User Id=testAADUser;Password=placeholder', '-S testServer.database.windows.net -d testDB --authentication-method=ActiveDirectoryPassword -U "testAADUser" -i "./TestFile.sql" -t 20'],
['AAD service principal', 'Server=testServer.database.windows.net;Database=testDB;Authentication=Active Directory Service Principal;User Id=appId;Password=placeholder', '-S testServer.database.windows.net -d testDB --authentication-method=ActiveDirectoryServicePrincipal -U "appId" -i "./TestFile.sql" -t 20'],
['AAD default', 'Server=testServer.database.windows.net;Database=testDB;Authentication=Active Directory Default;', '-S testServer.database.windows.net -d testDB --authentication-method=ActiveDirectoryDefault -i "./TestFile.sql" -t 20']
['SQL login', 'Server=testServer.database.windows.net;Database=testDB;User Id=testUser;Password=placeholder', '-S testServer.database.windows.net,1433 -d testDB -U "testUser" -i "./TestFile.sql" -t 20'],
['AAD password', 'Server=testServer.database.windows.net;Database=testDB;Authentication=Active Directory Password;User Id=testAADUser;Password=placeholder', '-S testServer.database.windows.net,1433 -d testDB --authentication-method=ActiveDirectoryPassword -U "testAADUser" -i "./TestFile.sql" -t 20'],
['AAD service principal', 'Server=testServer.database.windows.net;Database=testDB;Authentication=Active Directory Service Principal;User Id=appId;Password=placeholder', '-S testServer.database.windows.net,1433 -d testDB --authentication-method=ActiveDirectoryServicePrincipal -U "appId" -i "./TestFile.sql" -t 20'],
['AAD default', 'Server=testServer.database.windows.net;Database=testDB;Authentication=Active Directory Default;', '-S testServer.database.windows.net,1433 -d testDB --authentication-method=ActiveDirectoryDefault -i "./TestFile.sql" -t 20']
];

it.each(testCases)('%s', async (testCase, connectionString, expectedSqlCmdCall) => {
Expand All @@ -86,6 +87,28 @@ describe('AzureSqlAction tests', () => {
})
});

describe('sql script action tests for different port numbers', () => {
// Format: [test case description, connection string, expected sqlcmd arguments]
const testCases = [
['Default port', 'Server=testServer.database.windows.net;Database=testDB;User Id=testUser;Password=placeholder', '-S testServer.database.windows.net,1433 -d testDB -U "testUser" -i "./TestFile.sql" -t 20'],
['Custom port', 'Server=testServer.database.windows.net,1234;Database=testDB;User Id=testUser;Password=placeholder', '-S testServer.database.windows.net,1234 -d testDB -U "testUser" -i "./TestFile.sql" -t 20']
];

it.each(testCases)('%s', async (testCase, connectionString, expectedSqlCmdCall) => {
const inputs = getInputs(ActionType.SqlAction, connectionString) as IActionInputs;
const action = new AzureSqlAction(inputs);
const sqlcmdExe = process.platform === 'win32' ? 'sqlcmd.exe' : 'sqlcmd';

const execSpy = jest.spyOn(exec, 'exec').mockResolvedValue(0);
const exportVariableSpy = jest.spyOn(core, 'exportVariable').mockReturnValue();

await action.execute();

expect(execSpy).toHaveBeenCalledTimes(1);
expect(execSpy).toHaveBeenCalledWith(`"${sqlcmdExe}" ${expectedSqlCmdCall}`);
})
});

it('throws if SqlCmd.exe fails to execute sql', async () => {
let inputs = getInputs(ActionType.SqlAction) as IActionInputs;
let action = new AzureSqlAction(inputs);
Expand Down
14 changes: 8 additions & 6 deletions __tests__/SqlConnectionConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,20 @@ describe('SqlConnectionConfig tests', () => {
});

describe('parse server name in connection strings', () => {
// all server names will be 'test1.database.windows.net'
// servernames are optionally combined with tcp prefix, port number, and servername formats
const connectionStrings = [
[`Server=test1.database.windows.net;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test1.database.windows.net', 'Validates server name without prefix'],
[`Server=tcp:test1.database.windows.net;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test1.database.windows.net', 'Validates server name with tcp prefix'],
[`Server=tcp:test1.database.windows.net,1433;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test1.database.windows.net', 'Validates server name with tcp prefix and port'],
[`Server=test1.database.windows.net,1433;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test1.database.windows.net', 'Validates server name with no prefix and port'],
[`Server=test1.database.windows.net;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test1.database.windows.net', '', 'Validates server name without prefix'],
[`Server=tcp:test1.database.windows.net;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test1.database.windows.net', '', 'Validates server name with tcp prefix'],
[`Server=tcp:test1.database.windows.net,1433;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test1.database.windows.net', '1433', 'Validates server name with tcp prefix and port'],
[`Server=database.windows.net,1433;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'database.windows.net', '1433', 'Validates server name with no prefix and port'],
[`Server=test2.20ee0ae768cc.database.windows.net,3342;Database=testdb;User Id=user;Password=placeholder;Authentication=SQLPassword`, 'test2.20ee0ae768cc.database.windows.net', '3342', 'Validates server name with no prefix and port'],
];

it.each(connectionStrings)('should parse server name successfully', (connectionStringInput, expectedServerName) => {
it.each(connectionStrings)('should parse server name successfully', (connectionStringInput, expectedServerName, expectedPortNumber) => {
const config = new SqlConnectionConfig(connectionStringInput);

expect(config.Config.server).toMatch(expectedServerName);
expect(config.Config.port?.toString()).toMatch(expectedPortNumber);
expect(config.Config.database).toMatch('testdb');
expect(config.ConnectionString).toMatch(connectionStringInput);
});
Expand Down
2 changes: 1 addition & 1 deletion lib/main.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/SqlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ export default class SqlUtils {
};
}
catch (error) {
core.debug(`${error.message}`);
core.debug(`SqlCmd stderr: ${sqlCmdError}`);
console.log(`${error.message}`);
console.log(`SqlCmd stderr: ${sqlCmdError}`);
return {
success: false,
errorMessage: sqlCmdError,
Expand Down Expand Up @@ -123,7 +123,7 @@ export default class SqlUtils {
throw new Error(`Platform ${process.platform} is not supported.`);
}

let sqlcmdCall = `"${sqlCmdPath}" -S ${connectionConfig.server} -d ${connectionConfig.database}`;
let sqlcmdCall = `"${sqlCmdPath}" -S ${connectionConfig.server},${connectionConfig.port ?? 1433} -d ${connectionConfig.database}`;

// Determine the correct sqlcmd arguments based on the auth type in connectionConfig
const authentication = connectionConfig['authentication'];
Expand Down

0 comments on commit 1ad5218

Please sign in to comment.