diff --git a/.github/workflows/build-master.yml b/.github/workflows/build-master.yml index 440fdd10..94eed1e3 100644 --- a/.github/workflows/build-master.yml +++ b/.github/workflows/build-master.yml @@ -26,6 +26,13 @@ jobs: packagePAT: ${{ secrets.BALLERINA_BOT_TOKEN }} run: | ./gradlew publish + - name: Archive Error log + uses: actions/upload-artifact@v2 + if: failure() + with: + name: Ballerina Internal Log + path: sql-ballerina/ballerina-internal.log + if-no-files-found: ignore - name: Dispatch Dependent Module Builds if: github.event.action != 'stdlib-publish-snapshot' run: | diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 145d9cae..23447a96 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -18,6 +18,13 @@ jobs: packageUser: ${{ github.actor }} packagePAT: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew build + - name: Archive Error log + uses: actions/upload-artifact@v2 + if: failure() + with: + name: Ballerina Internal Log Linux + path: sql-ballerina/ballerina-internal.log + if-no-files-found: ignore windows-build: @@ -35,3 +42,10 @@ jobs: packagePAT: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew.bat build -x test # Due to no docker available in gitaction windows + - name: Archive Error log + uses: actions/upload-artifact@v2 + if: failure() + with: + name: Ballerina Internal Log Windows + path: sql-ballerina/ballerina-internal.log + if-no-files-found: ignore diff --git a/sql-ballerina/tests/local-transaction-test.bal b/sql-ballerina/tests/local-transaction-test.bal index 7b1493ce..9a3b2c8f 100644 --- a/sql-ballerina/tests/local-transaction-test.bal +++ b/sql-ballerina/tests/local-transaction-test.bal @@ -14,449 +14,464 @@ // specific language governing permissions and limitations // under the License. - import ballerina/lang.'transaction as transactions; - import ballerina/io; - import ballerina/test; - - string localTransactionDB = urlPrefix + "9004/transaction"; - - type TransactionResultCount record { - int COUNTVAL; - }; - - @test:BeforeGroups { - value: ["transaction"] - } - function initTransactionContainer() { - initializeDockerContainer("sql-transaction", "transaction", "9004", "transaction", "local-transaction-test-data.sql"); - } - - @test:AfterGroups { - value: ["transaction"] - } - function cleanTransactionContainer() { - cleanDockerContainer("sql-transaction"); - } - - @test:Config { - groups: ["transaction"] - } - function testLocalTransaction() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - int retryVal = -1; - boolean committedBlockExecuted = false; - transactions:Info transInfo; - retry(1) transaction { - var res = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 200, 5000.75, 'USA')"); - res = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 200, 5000.75, 'USA')"); - transInfo = transactions:info(); - var commitResult = commit; - if(commitResult is ()){ - committedBlockExecuted = true; - } - } - retryVal = transInfo.retryNumber; - //check whether update action is performed - int count = getCount(dbClient, "200"); - checkpanic dbClient.close(); - - test:assertEquals(retryVal, 0); - test:assertEquals(count, 2); - test:assertEquals(committedBlockExecuted, true); - } - - boolean stmtAfterFailureExecutedRWC = false; - int retryValRWC = -1; - @test:Config { - groups: ["transaction"], - dependsOn: ["testLocalTransaction"] - } - function testTransactionRollbackWithCheck() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - var result = testTransactionRollbackWithCheckHelper(dbClient); - int count = getCount(dbClient, "210"); - checkpanic dbClient.close(); - - test:assertEquals(retryValRWC, 1); - test:assertEquals(count, 0); - test:assertEquals(stmtAfterFailureExecutedRWC, false); - } - - function testTransactionRollbackWithCheckHelper(MockClient dbClient) returns error?{ - transactions:Info transInfo; - retry(1) transaction { - transInfo = transactions:info(); - retryValRWC = transInfo.retryNumber; - var e1 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID," + - "creditLimit,country) values ('James', 'Clerk', 210, 5000.75, 'USA')"); - var e2 = check dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID," + - "creditLimit,country) values ('James', 'Clerk', 210, 5000.75, 'USA')"); - stmtAfterFailureExecutedRWC = true; - check commit; - } - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testTransactionRollbackWithCheck"] - } - function testTransactionRollbackWithRollback() { +import ballerina/lang.'transaction as transactions; +import ballerina/io; +import ballerina/test; + +string localTransactionDB = urlPrefix + "9004/transaction"; + +type TransactionResultCount record { + int COUNTVAL; +}; + +public class SQLDefaultRetryManager { + private int count; + public function init(int count = 2) { + self.count = count; + } + public function shouldRetry(error? e) returns boolean { + if e is error && self.count > 0 { + self.count -= 1; + return true; + } else { + return false; + } + } +} + +@test:BeforeGroups { + value: ["transaction"] +} +function initTransactionContainer() { + initializeDockerContainer("sql-transaction", "transaction", "9004", "transaction", "local-transaction-test-data.sql"); +} + +@test:AfterGroups { + value: ["transaction"] +} +function cleanTransactionContainer() { + cleanDockerContainer("sql-transaction"); +} + +@test:Config { + groups: ["transaction"] +} +function testLocalTransaction() { MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - int retryVal = -1; - boolean stmtAfterFailureExecuted = false; - transactions:Info transInfo; - retry(1) transaction { - transInfo = transactions:info(); - var e1 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID," + - "creditLimit,country) values ('James', 'Clerk', 211, 5000.75, 'USA')"); - if (e1 is error){ - rollback; - } else { - var e2 = dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID," + - "creditLimit,country) values ('James', 'Clerk', 211, 5000.75, 'USA')"); - if (e2 is error){ - rollback; - stmtAfterFailureExecuted = true; - } else { - checkpanic commit; - } - } - } - retryVal = transInfo.retryNumber; - int count = getCount(dbClient, "211"); - checkpanic dbClient.close(); - - test:assertEquals(retryVal, 0); - test:assertEquals(count, 0); - test:assertEquals(stmtAfterFailureExecuted, true); - - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testTransactionRollbackWithRollback"] - } - function testLocalTransactionUpdateWithGeneratedKeys() { + int retryVal = -1; + boolean committedBlockExecuted = false; + transactions:Info transInfo; + retry(1) transaction { + var res = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('James', 'Clerk', 200, 5000.75, 'USA')"); + res = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('James', 'Clerk', 200, 5000.75, 'USA')"); + transInfo = transactions:info(); + var commitResult = commit; + if(commitResult is ()){ + committedBlockExecuted = true; + } + } + retryVal = transInfo.retryNumber; + //check whether update action is performed + int count = getCount(dbClient, "200"); + checkpanic dbClient.close(); + + test:assertEquals(retryVal, 0); + test:assertEquals(count, 2); + test:assertEquals(committedBlockExecuted, true); +} + +boolean stmtAfterFailureExecutedRWC = false; +int retryValRWC = -1; +@test:Config { + groups: ["transaction"], + dependsOn: ["testLocalTransaction"] +} +function testTransactionRollbackWithCheck() { MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - int returnVal = 0; - transactions:Info transInfo; - retry (1) transaction { - transInfo = transactions:info(); - var e1 = checkpanic dbClient->execute("Insert into Customers " + - "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 615, 5000.75, 'USA')"); - var e2 = checkpanic dbClient->execute("Insert into Customers " + - "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 615, 5000.75, 'USA')"); - checkpanic commit; - } - returnVal = transInfo.retryNumber; - //Check whether the update action is performed. - int count = getCount(dbClient, "615"); - checkpanic dbClient.close(); - - test:assertEquals(returnVal, 0); - test:assertEquals(count, 2); - } - - int returnValRGK = 0; - @test:Config { - groups: ["transaction"], - dependsOn: ["testLocalTransactionUpdateWithGeneratedKeys"] - } - function testLocalTransactionRollbackWithGeneratedKeys() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - var result = testLocalTransactionRollbackWithGeneratedKeysHelper(dbClient); - //check whether update action is performed - int count = getCount(dbClient, "615"); - checkpanic dbClient.close(); - test:assertEquals(returnValRGK, 1); - test:assertEquals(count, 2); - } - - function testLocalTransactionRollbackWithGeneratedKeysHelper(MockClient dbClient) returns error? { - transactions:Info transInfo; - retry(1) transaction { - transInfo = transactions:info(); - returnValRGK = transInfo.retryNumber; - var e1 = check dbClient->execute("Insert into Customers " + - "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 615, 5000.75, 'USA')"); - var e2 = check dbClient->execute("Insert into Customers2 " + + var result = testTransactionRollbackWithCheckHelper(dbClient); + int count = getCount(dbClient, "210"); + checkpanic dbClient.close(); + + test:assertEquals(retryValRWC, 1); + test:assertEquals(count, 0); + test:assertEquals(stmtAfterFailureExecutedRWC, false); +} + +function testTransactionRollbackWithCheckHelper(MockClient dbClient) returns error?{ + transactions:Info transInfo; + retry(1) transaction { + transInfo = transactions:info(); + retryValRWC = transInfo.retryNumber; + var e1 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID," + + "creditLimit,country) values ('James', 'Clerk', 210, 5000.75, 'USA')"); + var e2 = check dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID," + + "creditLimit,country) values ('James', 'Clerk', 210, 5000.75, 'USA')"); + stmtAfterFailureExecutedRWC = true; + check commit; + } +} + +@test:Config { + groups: ["transaction"], + dependsOn: ["testTransactionRollbackWithCheck"] +} +function testTransactionRollbackWithRollback() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + int retryVal = -1; + boolean stmtAfterFailureExecuted = false; + transactions:Info transInfo; + retry(1) transaction { + transInfo = transactions:info(); + var e1 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID," + + "creditLimit,country) values ('James', 'Clerk', 211, 5000.75, 'USA')"); + if (e1 is error){ + rollback; + } else { + var e2 = dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID," + + "creditLimit,country) values ('James', 'Clerk', 211, 5000.75, 'USA')"); + if (e2 is error){ + rollback; + stmtAfterFailureExecuted = true; + } else { + checkpanic commit; + } + } + } + retryVal = transInfo.retryNumber; + int count = getCount(dbClient, "211"); + checkpanic dbClient.close(); + + test:assertEquals(retryVal, 0); + test:assertEquals(count, 0); + test:assertEquals(stmtAfterFailureExecuted, true); + +} + +@test:Config { + groups: ["transaction"], + dependsOn: ["testTransactionRollbackWithRollback"] +} +function testLocalTransactionUpdateWithGeneratedKeys() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + int returnVal = 0; + transactions:Info transInfo; + retry(1) transaction { + transInfo = transactions:info(); + var e1 = checkpanic dbClient->execute("Insert into Customers " + "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 615, 5000.75, 'USA')"); - check commit; - } - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testLocalTransactionRollbackWithGeneratedKeys"] - } - function testTransactionAbort() { + var e2 = checkpanic dbClient->execute("Insert into Customers " + + "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 615, 5000.75, 'USA')"); + checkpanic commit; + } + returnVal = transInfo.retryNumber; + //Check whether the update action is performed. + int count = getCount(dbClient, "615"); + checkpanic dbClient.close(); + + test:assertEquals(returnVal, 0); + test:assertEquals(count, 2); +} + +int returnValRGK = 0; +@test:Config { + groups: ["transaction"], + dependsOn: ["testLocalTransactionUpdateWithGeneratedKeys"] +} +function testLocalTransactionRollbackWithGeneratedKeys() { MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - transactions:Info transInfo; - - int abortVal = 0; - var abortFunc = function(transactions:Info? info, error? cause, boolean willTry) { - abortVal = -1; - }; - - retry(1) transaction { - transInfo = transactions:info(); - transactions:onRollback(abortFunc); - var e1 = dbClient->execute("Insert into Customers " + - "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 220, 5000.75, 'USA')"); - var e2 = dbClient->execute("Insert into Customers " + + var result = testLocalTransactionRollbackWithGeneratedKeysHelper(dbClient); + //check whether update action is performed + int count = getCount(dbClient, "615"); + checkpanic dbClient.close(); + test:assertEquals(returnValRGK, 1); + test:assertEquals(count, 2); +} + +function testLocalTransactionRollbackWithGeneratedKeysHelper(MockClient dbClient) returns error? { + transactions:Info transInfo; + retry(1) transaction { + transInfo = transactions:info(); + returnValRGK = transInfo.retryNumber; + var e1 = check dbClient->execute("Insert into Customers " + + "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 615, 5000.75, 'USA')"); + var e2 = check dbClient->execute("Insert into Customers2 " + + "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 615, 5000.75, 'USA')"); + check commit; + } +} + +@test:Config { + groups: ["transaction"], + dependsOn: ["testLocalTransactionRollbackWithGeneratedKeys"] +} +function testTransactionAbort() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + transactions:Info transInfo; + + int abortVal = 0; + var abortFunc = function(transactions:Info? info, error? cause, boolean willTry) { + abortVal = -1; + }; + + retry(1) transaction { + transInfo = transactions:info(); + transactions:onRollback(abortFunc); + var e1 = dbClient->execute("Insert into Customers " + "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 220, 5000.75, 'USA')"); - int i = 0; - if (i == 0) { - rollback; - } else { - checkpanic commit; - } - } - int returnVal = transInfo.retryNumber; - //Check whether the update action is performed. - int count = getCount(dbClient, "220"); - checkpanic dbClient.close(); - - test:assertEquals(returnVal, 0); - test:assertEquals(abortVal, -1); - test:assertEquals(count, 0); - } - - int testTransactionErrorPanicRetVal = 0; - @test:Config { - enable: false, - groups: ["transaction"] - } - function testTransactionErrorPanic() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - int returnVal = 0; - int catchValue = 0; - var ret = trap testTransactionErrorPanicHelper(dbClient); - io:println(ret); - if (ret is error) { - catchValue = -1; - } - //Check whether the update action is performed. - int count = getCount(dbClient, "260"); - checkpanic dbClient.close(); - test:assertEquals(testTransactionErrorPanicRetVal, 1); - test:assertEquals(catchValue, -1); - test:assertEquals(count, 0); - } - - function testTransactionErrorPanicHelper(MockClient dbClient) { - int returnVal = 0; - transactions:Info transInfo; - retry(1) transaction { - transInfo = transactions:info(); - var e1 = dbClient->execute("Insert into Customers (firstName,lastName," + - "registrationID,creditLimit,country) values ('James', 'Clerk', 260, 5000.75, 'USA')"); - int i = 0; - if (i == 0) { - error e = error("error"); - panic e; - } else { - var r = commit; - } - } - io:println("exec"); - testTransactionErrorPanicRetVal = transInfo.retryNumber; - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testTransactionAbort"] - } - function testTransactionErrorPanicAndTrap() { + var e2 = dbClient->execute("Insert into Customers " + + "(firstName,lastName,registrationID,creditLimit,country) values ('James', 'Clerk', 220, 5000.75, 'USA')"); + int i = 0; + if (i == 0) { + rollback; + } else { + checkpanic commit; + } + } + int returnVal = transInfo.retryNumber; + //Check whether the update action is performed. + int count = getCount(dbClient, "220"); + checkpanic dbClient.close(); + + test:assertEquals(returnVal, 0); + test:assertEquals(abortVal, -1); + test:assertEquals(count, 0); +} + +int testTransactionErrorPanicRetVal = 0; +@test:Config { + enable: false, + groups: ["transaction"] +} +function testTransactionErrorPanic() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + int returnVal = 0; + int catchValue = 0; + var ret = trap testTransactionErrorPanicHelper(dbClient); + io:println(ret); + if (ret is error) { + catchValue = -1; + } + //Check whether the update action is performed. + int count = getCount(dbClient, "260"); + checkpanic dbClient.close(); + test:assertEquals(testTransactionErrorPanicRetVal, 1); + test:assertEquals(catchValue, -1); + test:assertEquals(count, 0); +} + +function testTransactionErrorPanicHelper(MockClient dbClient) { + int returnVal = 0; + transactions:Info transInfo; + retry(1) transaction { + transInfo = transactions:info(); + var e1 = dbClient->execute("Insert into Customers (firstName,lastName," + + "registrationID,creditLimit,country) values ('James', 'Clerk', 260, 5000.75, 'USA')"); + int i = 0; + if (i == 0) { + error e = error("error"); + panic e; + } else { + var r = commit; + } + } + io:println("exec"); + testTransactionErrorPanicRetVal = transInfo.retryNumber; +} + +@test:Config { + groups: ["transaction"], + dependsOn: ["testTransactionAbort"] +} +function testTransactionErrorPanicAndTrap() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + + int catchValue = 0; + transactions:Info transInfo; + retry(1) transaction { + transInfo = transactions:info(); + var e1 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID," + + "creditLimit,country) values ('James', 'Clerk', 250, 5000.75, 'USA')"); + var ret = trap testTransactionErrorPanicAndTrapHelper(0); + if (ret is error) { + catchValue = -1; + } + checkpanic commit; + } + int returnVal = transInfo.retryNumber; + //Check whether the update action is performed. + int count = getCount(dbClient, "250"); + checkpanic dbClient.close(); + test:assertEquals(returnVal, 0); + test:assertEquals(catchValue, -1); + test:assertEquals(count, 1); +} + +isolated function testTransactionErrorPanicAndTrapHelper(int i) { + if (i == 0) { + error err = error("error"); + panic err; + } +} + +@test:Config { + groups: ["transaction"], + dependsOn: ["testTransactionErrorPanicAndTrap"] +} +function testTwoTransactions() { MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - int catchValue = 0; - transactions:Info transInfo; - retry (1) transaction { - transInfo = transactions:info(); - var e1 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID," + - "creditLimit,country) values ('James', 'Clerk', 250, 5000.75, 'USA')"); - var ret = trap testTransactionErrorPanicAndTrapHelper(0); - if (ret is error) { - catchValue = -1; - } - checkpanic commit; - } - int returnVal = transInfo.retryNumber; - //Check whether the update action is performed. - int count = getCount(dbClient, "250"); - checkpanic dbClient.close(); - test:assertEquals(returnVal, 0); - test:assertEquals(catchValue, -1); - test:assertEquals(count, 1); - } - - isolated function testTransactionErrorPanicAndTrapHelper(int i) { - if (i == 0) { - error err = error("error"); - panic err; - } - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testTransactionErrorPanicAndTrap"] - } - function testTwoTransactions() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - - transactions:Info transInfo1; - transactions:Info transInfo2; - retry (1) transaction { - transInfo1 = transactions:info(); - var e1 = checkpanic dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 400, 5000.75, 'USA')"); - var e2 = checkpanic dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 400, 5000.75, 'USA')"); - checkpanic commit; - } - int returnVal1 = transInfo1.retryNumber; - - retry(1) transaction { - transInfo2 = transactions:info(); - var e1 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 400, 5000.75, 'USA')"); - var e2 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 400, 5000.75, 'USA')"); - checkpanic commit; - } - int returnVal2 = transInfo2.retryNumber; - - //Check whether the update action is performed. - int count = getCount(dbClient, "400"); - checkpanic dbClient.close(); - test:assertEquals(returnVal1, 0); - test:assertEquals(returnVal2, 0); - test:assertEquals(count, 4); - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testTwoTransactions"] - } - function testTransactionWithoutHandlers() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - transaction { + transactions:Info transInfo1; + transactions:Info transInfo2; + retry(1) transaction { + transInfo1 = transactions:info(); var e1 = checkpanic dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 350, 5000.75, 'USA')"); + "values ('James', 'Clerk', 400, 5000.75, 'USA')"); var e2 = checkpanic dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 350, 5000.75, 'USA')"); + "values ('James', 'Clerk', 400, 5000.75, 'USA')"); checkpanic commit; } - //Check whether the update action is performed. - int count = getCount(dbClient, "350"); - checkpanic dbClient.close(); - test:assertEquals(count, 2); - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testTransactionWithoutHandlers"] - } - function testLocalTransactionFailed() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - - string a = "beforetx"; - - var ret = trap testLocalTransactionFailedHelper(a, dbClient); - if (ret is string) { - a = ret; - } else { - a = ret.message() + " trapped"; - } - a = a + " afterTrx"; - int count = getCount(dbClient, "111"); - checkpanic dbClient.close(); - test:assertEquals(a, "beforetx inTrx trxAborted inTrx trxAborted inTrx trapped afterTrx"); - test:assertEquals(count, 0); - } - - function testLocalTransactionFailedHelper(string status,MockClient dbClient) returns string|error { - string a = status; - transactions:Info transInfo; - int i = 0; - - var onRollbackFunc = function(transactions:Info? info, error? cause, boolean willTry) { - a = a + " trxAborted"; - }; - - retry(2) transaction { - a = a + " inTrx"; - transInfo = transactions:info(); - transactions:onRollback(onRollbackFunc); - var e1 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('James', 'Clerk', 111, 5000.75, 'USA')"); - var e2 = dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID,creditLimit,country) " + - "values ('Anne', 'Clerk', 111, 5000.75, 'USA')"); - if(e2 is error){ - check getError(a); - } - check commit; + int returnVal1 = transInfo1.retryNumber; + + retry(1) transaction { + transInfo2 = transactions:info(); + var e1 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('James', 'Clerk', 400, 5000.75, 'USA')"); + var e2 = dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('James', 'Clerk', 400, 5000.75, 'USA')"); + checkpanic commit; } - return a; - } + int returnVal2 = transInfo2.retryNumber; - isolated function getError(string message) returns error? { - return error(message); - } - - @test:Config { - groups: ["transaction"], - dependsOn: ["testLocalTransactionFailed"] - } - function testLocalTransactionSuccessWithFailed() { - MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); - - string a = "beforetx"; - string | error ret = trap testLocalTransactionSuccessWithFailedHelper(a, dbClient); - if (ret is string) { - a = ret; - } else { - a = a + "trapped"; - } - a = a + " afterTrx"; - int count = getCount(dbClient, "222"); + //Check whether the update action is performed. + int count = getCount(dbClient, "400"); checkpanic dbClient.close(); - test:assertEquals(a, "beforetx inTrx inTrx inTrx committed afterTrx"); - test:assertEquals(count, 2); - } - - function testLocalTransactionSuccessWithFailedHelper(string status,MockClient dbClient) returns string|error { - int i = 0; - string a = status; - retry (3) transaction { - i = i + 1; - a = a + " inTrx"; - var e1 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country)" + - " values ('James', 'Clerk', 222, 5000.75, 'USA')"); - if (i == 3) { - var e2 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + - "values ('Anne', 'Clerk', 222, 5000.75, 'USA')"); - } else { - var e3 = check dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID,creditLimit,country) " + - "values ('Anne', 'Clerk', 222, 5000.75, 'USA')"); - } - check commit; - a = a + " committed"; - } - return a; - } - - function getCount(MockClient dbClient, string id) returns @tainted int { - stream streamData = > dbClient->query("Select COUNT(*) as " + - "countval from Customers where registrationID = "+ id, TransactionResultCount); - record {|TransactionResultCount value;|}? data = checkpanic streamData.next(); - checkpanic streamData.close(); - TransactionResultCount? value = data?.value; - if(value is TransactionResultCount){ - return value["COUNTVAL"]; - } - return 0; - } + test:assertEquals(returnVal1, 0); + test:assertEquals(returnVal2, 0); + test:assertEquals(count, 4); + } + +@test:Config { + groups: ["transaction"], + dependsOn: ["testTwoTransactions"] +} +function testTransactionWithoutHandlers() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + transaction { + var e1 = checkpanic dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('James', 'Clerk', 350, 5000.75, 'USA')"); + var e2 = checkpanic dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('James', 'Clerk', 350, 5000.75, 'USA')"); + checkpanic commit; + } + //Check whether the update action is performed. + int count = getCount(dbClient, "350"); + checkpanic dbClient.close(); + test:assertEquals(count, 2); +} + +@test:Config { + groups: ["transaction"], + dependsOn: ["testTransactionWithoutHandlers"] +} +function testLocalTransactionFailed() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + + string a = "beforetx"; + + var ret = trap testLocalTransactionFailedHelper(a, dbClient); + if (ret is string) { + a = ret; + } else { + a = ret.message() + " trapped"; + } + a = a + " afterTrx"; + int count = getCount(dbClient, "111"); + checkpanic dbClient.close(); + test:assertEquals(a, "beforetx inTrx trxAborted inTrx trxAborted inTrx trapped afterTrx"); + test:assertEquals(count, 0); +} + +function testLocalTransactionFailedHelper(string status,MockClient dbClient) returns string|error { + string a = status; + transactions:Info transInfo; + int i = 0; + + var onRollbackFunc = function(transactions:Info? info, error? cause, boolean willTry) { + a = a + " trxAborted"; + }; + + retry(2) transaction { + a = a + " inTrx"; + transInfo = transactions:info(); + transactions:onRollback(onRollbackFunc); + var e1 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('James', 'Clerk', 111, 5000.75, 'USA')"); + var e2 = dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID,creditLimit,country) " + + "values ('Anne', 'Clerk', 111, 5000.75, 'USA')"); + if(e2 is error){ + check getError(a); + } + check commit; + } + return a; +} + +isolated function getError(string message) returns error? { + return error(message); +} + +@test:Config { + groups: ["transaction"], + dependsOn: ["testLocalTransactionFailed"] +} +function testLocalTransactionSuccessWithFailed() { + MockClient dbClient = checkpanic new (url = localTransactionDB, user = user, password = password); + + string a = "beforetx"; + string | error ret = trap testLocalTransactionSuccessWithFailedHelper(a, dbClient); + if (ret is string) { + a = ret; + } else { + a = a + "trapped"; + } + a = a + " afterTrx"; + int count = getCount(dbClient, "222"); + checkpanic dbClient.close(); + test:assertEquals(a, "beforetx inTrx inTrx inTrx committed afterTrx"); + test:assertEquals(count, 2); +} + +function testLocalTransactionSuccessWithFailedHelper(string status,MockClient dbClient) returns string|error { + int i = 0; + string a = status; + retry(3) transaction { + i = i + 1; + a = a + " inTrx"; + var e1 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country)" + + " values ('James', 'Clerk', 222, 5000.75, 'USA')"); + if (i == 3) { + var e2 = check dbClient->execute("Insert into Customers (firstName,lastName,registrationID,creditLimit,country) " + + "values ('Anne', 'Clerk', 222, 5000.75, 'USA')"); + } else { + var e3 = check dbClient->execute("Insert into Customers2 (firstName,lastName,registrationID,creditLimit,country) " + + "values ('Anne', 'Clerk', 222, 5000.75, 'USA')"); + } + check commit; + a = a + " committed"; + } + return a; +} + +function getCount(MockClient dbClient, string id) returns @tainted int { + stream streamData = > dbClient->query("Select COUNT(*) as " + + "countval from Customers where registrationID = "+ id, TransactionResultCount); + record {|TransactionResultCount value;|}? data = checkpanic streamData.next(); + checkpanic streamData.close(); + TransactionResultCount? value = data?.value; + if(value is TransactionResultCount){ + return value["COUNTVAL"]; + } + return 0; +}