diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index 11b51e6..4ac89ee 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -1,7 +1,7 @@ [package] org = "ballerinax" name = "aws.redshift" -version = "1.0.0" +version = "1.0.1" authors = ["Ballerina"] keywords = ["Data Warehouse", "Columnar Storage", "Cost/Paid", "vendor/aws"] repository = "https://github.com/ballerina-platform/module-ballerinax-aws.redshift" @@ -15,8 +15,8 @@ graalvmCompatible = true [[platform.java11.dependency]] groupId = "io.ballerina.stdlib" artifactId = "aws.redshift-native" -version = "1.0.0" -path = "../native/build/libs/aws.redshift-native-1.0.0.jar" +version = "1.0.1-SNAPSHOT" +path = "../native/build/libs/aws.redshift-native-1.0.1-SNAPSHOT.jar" [[platform.java11.dependency]] groupId = "io.ballerina.stdlib" diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index d18114f..6492469 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -24,6 +24,15 @@ modules = [ {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} ] +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + [[package]] org = "ballerina" name = "lang.object" @@ -37,6 +46,30 @@ dependencies = [ {org = "ballerina", name = "jballerina.java"} ] +[[package]] +org = "ballerina" +name = "log" +version = "2.9.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"}, + {org = "ballerina", name = "observe"} +] +modules = [ + {org = "ballerina", packageName = "log", moduleName = "log"} +] + +[[package]] +org = "ballerina" +name = "observe" +version = "1.2.2" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + [[package]] org = "ballerina" name = "sql" @@ -51,6 +84,19 @@ modules = [ {org = "ballerina", packageName = "sql", moduleName = "sql"} ] +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + [[package]] org = "ballerina" name = "time" @@ -62,12 +108,24 @@ dependencies = [ [[package]] org = "ballerinax" name = "aws.redshift" -version = "1.0.0" +version = "1.0.1" dependencies = [ {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "sql"} + {org = "ballerina", name = "log"}, + {org = "ballerina", name = "sql"}, + {org = "ballerina", name = "test"}, + {org = "ballerinax", name = "postgresql.driver"} ] modules = [ {org = "ballerinax", packageName = "aws.redshift", moduleName = "aws.redshift"} ] +[[package]] +org = "ballerinax" +name = "postgresql.driver" +version = "1.5.0" +scope = "testOnly" +modules = [ + {org = "ballerinax", packageName = "postgresql.driver", moduleName = "postgresql.driver"} +] + diff --git a/ballerina/build.gradle b/ballerina/build.gradle index 299ed34..9c1f401 100644 --- a/ballerina/build.gradle +++ b/ballerina/build.gradle @@ -47,7 +47,7 @@ def stripBallerinaExtensionVersion(String extVersion) { ballerina { packageOrganization = packageOrg module = packageName - testCoverageParam = "--code-coverage --coverage-format=xml" + testCoverageParam = "--code-coverage --coverage-format=xml --includes=*" isConnector = true platform = "java17" } @@ -86,6 +86,55 @@ clean { delete 'build' } +task startDatabaseServer() { + doLast { + if (!Os.isFamily(Os.FAMILY_WINDOWS)) { + def stdOut = new ByteArrayOutputStream() + exec { + commandLine 'sh', '-c', "docker ps --filter name=server-redshift-1" + standardOutput = stdOut + } + if (!stdOut.toString().contains("server-redshift-1")) { + println "Starting Redshift server." + exec { + commandLine 'sh', '-c', "docker-compose -f tests/server/docker-compose.yaml up -d" + standardOutput = stdOut + } + println stdOut.toString() + sleep(10 * 1000) + } else { + println "Redshift server is already started." + } + } + } +} + +task stopDatabaseServer() { + doLast { + if (!Os.isFamily(Os.FAMILY_WINDOWS)) { + def stdOut = new ByteArrayOutputStream() + exec { + commandLine 'sh', '-c', "docker ps --filter name=server-redshift-1" + standardOutput = stdOut + } + if (stdOut.toString().contains("server-redshift-1")) { + println "Stopping RabbitMQ server." + exec { + commandLine 'sh', '-c', "docker-compose -f tests/server/docker-compose.yaml rm -svf" + standardOutput = stdOut + } + println stdOut.toString() + sleep(5 * 1000) + } else { + println "Redshift server is not started." + } + } + } +} + build.dependsOn copyToLib build.dependsOn ":${packageName}-native:build" +test.dependsOn ":${packageName}-native:build" +test.dependsOn startDatabaseServer +build.finalizedBy stopDatabaseServer publish.dependsOn build diff --git a/ballerina/tests/README.md b/ballerina/tests/README.md new file mode 100644 index 0000000..dd75c56 --- /dev/null +++ b/ballerina/tests/README.md @@ -0,0 +1,28 @@ +# Ballerina AWS Redshift Connector Test Module + +This test module is written to test the functionality of the Ballerina AWS Redshift Connector. + +## Docker Image + +For testing purposes, this [docker-pgredshift](https://github.com/HearthSim/docker-pgredshift/pkgs/container/docker-pgredshift) Docker image is used. It emulates AWS Redshift but with limited features, and it does not support SSL. + +## Emulated AWS Redshift Features + +The docker-pgredshift image provides a simulated environment resembling AWS Redshift. However, it is essential to be aware of the limited features and the absence of SSL support in this emulation. + +## Connection Details + +To establish a connection with the emulated AWS Redshift, the Ballerina AWS Redshift Connector uses the [Ballerina PostgreSQL Driver](https://github.com/ballerina-platform/module-ballerinax-postgresql.driver/) as the docker-pgredshift image is based on PostgreSQL and does not connect with the Redshift driver. + +## Usage + +Follow these steps to manually run the test module: + +1. Pull the docker-pgredshift image from [here](https://github.com/HearthSim/docker-pgredshift/pkgs/container/docker-pgredshift). +2. Set up the docker-pgredshift container to emulate AWS Redshift. +3. Use the Ballerina AWS Redshift Connector in your Ballerina programs to interact with the emulated AWS Redshift instance. + +## Reference Links + +- [docker-pgredshift Image](https://github.com/HearthSim/docker-pgredshift/pkgs/container/docker-pgredshift) +- [Ballerina PostgreSQL Driver](https://github.com/ballerina-platform/module-ballerinax-postgresql.driver/) diff --git a/ballerina/tests/batch-execute-test.bal b/ballerina/tests/batch-execute-test.bal new file mode 100644 index 0000000..b44b444 --- /dev/null +++ b/ballerina/tests/batch-execute-test.bal @@ -0,0 +1,118 @@ +// Copyright (c) 2024 WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/sql; +import ballerina/test; + +@test:Config { + groups: ["batch-execute"] +} +function batchInsertIntoDataTable() returns error? { + var data = [ + {row_id: 12, longValue: 9223372036854774807, doubleValue: 123.34}, + {row_id: 13, longValue: 9223372036854774807, doubleValue: 123.34}, + {row_id: 14, longValue: 9223372036854774807, doubleValue: 123.34} + ]; + sql:ParameterizedQuery[] sqlQueries = + from var row in data + select `INSERT INTO NumericTypes (int_type, bigint_type, double_type) VALUES (${row.row_id}, ${row.longValue}, ${row.doubleValue})`; + validateBatchExecutionResult(check batchExecuteRedshiftClient(sqlQueries), [1, 1, 1] + ); +} + +@test:Config { + groups: ["batch-execute"], + dependsOn: [batchInsertIntoDataTable] +} +function batchInsertIntoDataTable2() returns error? { + int rowId = 15; + int intValue = 5; + sql:ParameterizedQuery sqlQuery = `INSERT INTO NumericTypes (row_id, int_type) VALUES(${rowId}, ${intValue})`; + sql:ParameterizedQuery[] sqlQueries = [sqlQuery]; + validateBatchExecutionResult(check batchExecuteRedshiftClient(sqlQueries), [1]); +} + +@test:Config { + groups: ["batch-execute"], + dependsOn: [batchInsertIntoDataTable2] +} +function batchInsertIntoDataTableFailure() returns error? { + var data = [ + {row_id: 16, longValue: 9223372036854774807, doubleValue: 123.34}, + {row_id: 17, longValue: 9223372036854774807, doubleValue: 123.34}, + {row_id: 1, longValue: 9223372036854774807, doubleValue: 123.34}, + {row_id: 18, longValue: 9223372036854774807, doubleValue: 123.34} + ]; + sql:ParameterizedQuery[] sqlQueries = + from var row in data + select `INSERT INTO NumericTypes (row_id, bigint_type, double_type) VALUES (${row.row_id}, ${row.longValue}, ${row.doubleValue})`; + sql:ExecutionResult[]|error result = batchExecuteRedshiftClient(sqlQueries); + test:assertTrue(result is error); + if result is sql:BatchExecuteError { + sql:BatchExecuteErrorDetail errorDetails = result.detail(); + test:assertEquals(errorDetails.executionResults.length(), 4); + test:assertEquals(errorDetails.executionResults[0].affectedRowCount, -3); + test:assertEquals(errorDetails.executionResults[1].affectedRowCount, -3); + test:assertEquals(errorDetails.executionResults[2].affectedRowCount, -3); + test:assertEquals(errorDetails.executionResults[3].affectedRowCount, -3); + } else { + test:assertFail("Database Error expected."); + } +} + +@test:Config { + groups: ["batch-execute"], + dependsOn: [batchInsertIntoDataTableFailure] +} +function batchInsertIntoCharacterTable() returns error? { + var data = [ + {row_id: 14, charValue: "This is char2", varcharValue: "This is varchar2"}, + {row_id: 15, charValue: "This is char3", varcharValue: "This is varchar3"}, + {row_id: 16, charValue: "This is char4", varcharValue: "This is varchar4"} + ]; + sql:ParameterizedQuery[] sqlQueries = + from var row in data + select `INSERT INTO CharacterTypes (row_id, char_type, varchar_type) VALUES (${row.row_id}, ${row.charValue}, ${row.varcharValue})`; + validateBatchExecutionResult(check batchExecuteRedshiftClient(sqlQueries), [1, 1, 1]); +} + +@test:Config { + groups: ["batch-execute"], + dependsOn: [batchInsertIntoCharacterTable] +} +function batchUpdateCharacterTable() returns error? { + var data = [ + {row_id: 14, varcharValue: "Updated varchar2"}, + {row_id: 15, varcharValue: "Updated varchar3"}, + {row_id: 16, varcharValue: "Updated varchar4"} + ]; + sql:ParameterizedQuery[] sqlQueries = + from var row in data + select `UPDATE CharacterTypes SET varchar_type = ${row.varcharValue} + WHERE row_id = ${row.row_id}`; + validateBatchExecutionResult(check batchExecuteRedshiftClient(sqlQueries), [1, 1, 1]); +} + +isolated function validateBatchExecutionResult(sql:ExecutionResult[] results, int[] rowCount) { + test:assertEquals(results.length(), rowCount.length()); +} + +function batchExecuteRedshiftClient(sql:ParameterizedQuery[] sqlQueries) returns sql:ExecutionResult[]|error { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult[] result = check dbClient->batchExecute(sqlQueries); + check dbClient.close(); + return result; +} diff --git a/ballerina/tests/call-procedure-tests.bal b/ballerina/tests/call-procedure-tests.bal new file mode 100644 index 0000000..4d2f51d --- /dev/null +++ b/ballerina/tests/call-procedure-tests.bal @@ -0,0 +1,73 @@ +// Copyright (c) 2024 WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/sql; +import ballerina/test; + +@test:Config { + groups: ["procedures"] +} +function testNumericProcedureCall() returns error? { + int rowId = 35; + sql:IntegerValue intType = new (1); + int bigintType = 123456; + float double_type = 123.456; + + sql:ParameterizedCallQuery sqlQuery = + ` + SELECT NumericProcedure(${rowId}, ${intType}, ${bigintType}, ${double_type}); + `; + _ = check callProcedure(sqlQuery, [NumericProcedureRecord]); + + sql:ParameterizedQuery query = `SELECT row_id, int_type, bigint_type, double_type + FROM NumericTypes WHERE row_id = ${rowId}`; + + NumericProcedureRecord expectedDataRow = { + row_id: rowId, + int_type: 1, + bigint_type: 123456, + double_type: 123.456 + }; + test:assertEquals(check queryProcedureClient(query, NumericProcedureRecord), expectedDataRow, "Numeric Call procedure insert and query did not match."); +} + +function callProcedure(sql:ParameterizedCallQuery sqlQuery, typedesc[] rowTypes = []) returns sql:ProcedureCallResult|error { + Client dbClient = check new (jdbcUrl, user, password); + sql:ProcedureCallResult result = check dbClient->call(sqlQuery, rowTypes); + check dbClient.close(); + return result; +} + +function queryProcedureClient(sql:ParameterizedQuery sqlQuery, typedesc? resultType = ()) +returns record {}|error { + Client dbClient = check new (jdbcUrl, user, password); + stream streamData; + if resultType is () { + streamData = dbClient->query(sqlQuery); + } else { + streamData = dbClient->query(sqlQuery, resultType); + } + record {|record {} value;|}? data = check streamData.next(); + check streamData.close(); + record {}? value = data?.value; + check dbClient.close(); + if value is () { + return {}; + } else { + return value; + } +} + diff --git a/ballerina/tests/connection-tests.bal b/ballerina/tests/connection-tests.bal new file mode 100644 index 0000000..96b47a2 --- /dev/null +++ b/ballerina/tests/connection-tests.bal @@ -0,0 +1,54 @@ +// Copyright (c) 2024 WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/sql; +import ballerina/test; +import ballerinax/postgresql.driver as _; + +@test:Config { + groups: ["connection"] +} +isolated function testConnectionInit() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + error? closeResult = dbClient.close(); + test:assertExactEquals(closeResult, (), "Initialising connection with url, user and password fields fails."); +} + +@test:Config { + groups: ["connection"] +} +function testWithNamedArgs() returns error? { + Client dbClient = check new (password = password, user = user, url = jdbcUrl); + error? closeResult = dbClient.close(); + test:assertExactEquals(closeResult, (), "Initialising connection with named args fails."); +} + +@test:Config { + groups: ["connection"] +} +function testWithConnectionParams1() returns error? { + sql:ConnectionPool connectionPool = { + maxOpenConnections: 25, + maxConnectionLifeTime: 30, + minIdleConnections: 15 + }; + Options options = { + properties: {"ConnectionTimeout": "300"} + }; + Client dbClient = check new (password = password, user = user, url = jdbcUrl, options = options, connectionPool = connectionPool); + error? closeResult = dbClient.close(); + test:assertExactEquals(closeResult, (), "Initialising connection with connection params fails."); +} diff --git a/ballerina/tests/constants.bal b/ballerina/tests/constants.bal new file mode 100644 index 0000000..10ca4ad --- /dev/null +++ b/ballerina/tests/constants.bal @@ -0,0 +1,26 @@ +// Copyright (c) 2024 WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +final string & readonly jdbcUrl = "jdbc:postgresql://localhost:5432/postgres?ssl=false"; +final string & readonly user = "postgres"; +final string & readonly password = "password"; + +public type NumericProcedureRecord record { + int row_id; + int int_type; + int bigint_type; + float double_type; +}; diff --git a/ballerina/tests/execute-basic-test.bal b/ballerina/tests/execute-basic-test.bal new file mode 100644 index 0000000..cae6739 --- /dev/null +++ b/ballerina/tests/execute-basic-test.bal @@ -0,0 +1,154 @@ +// Copyright (c) 2024 WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/sql; +import ballerina/test; +import ballerinax/postgresql.driver as _; + +@test:Config { + groups: ["execute"] +} +function testCreateTable() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult result = check dbClient->execute(` + CREATE TABLE Student(student_id int, LastName varchar(255)) + `); + check dbClient.close(); + test:assertExactEquals(result.affectedRowCount, 0, "Affected row count is different."); + test:assertExactEquals(result.lastInsertId, (), "Last Insert Id is not nil."); +} + +@test:Config { + groups: ["execute"], + dependsOn: [testCreateTable] +} +function testInsertTable() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult result = check dbClient->execute(`Insert into Student (student_id) values (20)`); + check dbClient.close(); + + test:assertExactEquals(result.affectedRowCount, 1, "Affected row count is different."); + int|string? insertId = result.lastInsertId; + if insertId is int { + test:assertTrue(insertId > 1, "Last Insert Id is nil."); + } else { + test:assertFail("Insert Id should be an integer."); + } +} + +@test:Config { + groups: ["execute"] +} +function testCreateTableWithDataTypes() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult result = check dbClient->execute(` + CREATE TABLE DataTypesTest ( + smallint_col SMALLINT, + int_col INTEGER NOT NULL, + bigint_col BIGINT, + decimal_col DECIMAL(10, 2), + real_col REAL, + double_col DOUBLE PRECISION, + boolean_col BOOLEAN, + char_col CHAR(10), + varchar_col VARCHAR(255), + date_col DATE, + timestamp_col TIMESTAMP, + timestamptz_col TIMESTAMPTZ, + time_col TIME, + timetz_col TIMETZ + ) + `); + check dbClient.close(); + test:assertExactEquals(result.affectedRowCount, 0, "Affected row count is different."); + test:assertExactEquals(result.lastInsertId, (), "Last Insert Id is not nil."); +} + +@test:Config { + groups: ["execute"], + dependsOn: [testCreateTableWithDataTypes] +} +function testInsertDataWithDifferentTypes() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult result = check dbClient->execute(` + INSERT INTO DataTypesTest VALUES + (1, 123, 1234567890, 123.45, 3.14, 6.28, true, 'TestChar', 'TestVarchar', + '2024-02-07', '2024-02-07 12:00:00', '2024-02-07 12:00:00+00:00', + '12:00:00', '12:00:00+00:00') + `); + check dbClient.close(); + test:assertExactEquals(result.affectedRowCount, 1, "Affected row count is different."); + test:assertExactEquals(getInsertedNumericValue(), 123.45, "Numeric value mismatch."); +} + +type DecimalColumn record {| + decimal decimal_col; +|}; + +function getInsertedNumericValue() returns decimal|error { + Client dbClient = check new (jdbcUrl, user, password); + stream decimalStream = dbClient->query(`SELECT decimal_col FROM DataTypesTest`); + check from DecimalColumn column in decimalStream + do { + return column.decimal_col; + }; + return 0.0; +} + +@test:Config { + groups: ["execute"], + dependsOn: [testCreateTableWithDataTypes] +} +function testInsertStringIntoIntegerColumn() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult|sql:Error result = dbClient->execute(` + INSERT INTO DataTypesTest (int_col) VALUES ('InvalidString') + `); + check dbClient.close(); + if result is sql:ExecutionResult { + test:assertFail("Expected a type mismatch error, but the query executed successfully."); + } +} + +@test:Config { + groups: ["execute"], + dependsOn: [testCreateTableWithDataTypes] +} +function testInsertNullIntoNotNullColumn() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult|sql:Error result = dbClient->execute(` + INSERT INTO DataTypesTest (int_col) VALUES (NULL) + `); + check dbClient.close(); + if result is sql:ExecutionResult { + test:assertFail("Expected a NOT NULL constraint violation error, but the query executed successfully."); + } +} + +@test:Config { + groups: ["execute"] +} +function testInvalidSqlQuery() returns error? { + Client dbClient = check new (jdbcUrl, user, password); + sql:ExecutionResult|sql:Error result = dbClient->execute(` + INVALID SQL QUERY + `); + check dbClient.close(); + if result is sql:ExecutionResult { + test:assertFail("Expected an SQL syntax error, but the query executed successfully."); + } +} + diff --git a/ballerina/tests/server/docker-compose.yaml b/ballerina/tests/server/docker-compose.yaml new file mode 100644 index 0000000..97798fb --- /dev/null +++ b/ballerina/tests/server/docker-compose.yaml @@ -0,0 +1,9 @@ +version: '3' + +services: + redshift: + image: ghcr.io/hearthsim/docker-pgredshift:latest + environment: + POSTGRES_PASSWORD: password + ports: + - "5432:5432" diff --git a/ballerina/tests/setup-tests.bal b/ballerina/tests/setup-tests.bal new file mode 100644 index 0000000..4571202 --- /dev/null +++ b/ballerina/tests/setup-tests.bal @@ -0,0 +1,58 @@ +// Copyright (c) 2024 WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/log; +import ballerina/test; + +@test:BeforeSuite +function beforeFunction() returns error? { + log:printInfo("Setting up tables"); + Client dbClient = check new (jdbcUrl, user, password); + _ = check dbClient->execute(` + CREATE TABLE IF NOT EXISTS NumericTypes ( + row_id SERIAL PRIMARY KEY, + int_type INTEGER, + bigint_type BIGINT, + double_type DOUBLE PRECISION + ) + `); + _ = check dbClient->execute(` + CREATE TABLE IF NOT EXISTS CharacterTypes ( + row_id SERIAL PRIMARY KEY, + char_type CHAR(15), + varchar_type VARCHAR(20) + ) + `); + _ = check dbClient->execute(` + CREATE OR REPLACE FUNCTION NumericProcedure( + row_id_in BIGINT, + int_type_in INTEGER, + bigint_type_in BIGINT, + double_type_in DOUBLE PRECISION + ) + RETURNS VOID LANGUAGE plpgsql AS $$ + BEGIN + INSERT INTO NumericTypes ( + row_id, int_type, bigint_type, double_type + ) + VALUES ( + row_id_in, int_type_in, bigint_type_in, double_type_in + ); + END; + $$; + `); + check dbClient.close(); +} diff --git a/changelog.md b/changelog.md index 8a30606..7824dfa 100644 --- a/changelog.md +++ b/changelog.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Improve documentation](https://github.com/ballerina-platform/ballerina-library/issues/5997) +### Changed + +- [Add test coverage](https://github.com/ballerina-platform/ballerina-library/issues/6025) + ## [1.0.0] - 2024-01-26 ### Added