Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for AWS Redshift connector #14

Merged
merged 10 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
Expand Down
62 changes: 60 additions & 2 deletions ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -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"}
]

51 changes: 50 additions & 1 deletion ballerina/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down Expand Up @@ -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
28 changes: 28 additions & 0 deletions ballerina/tests/README.md
Original file line number Diff line number Diff line change
@@ -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/)
118 changes: 118 additions & 0 deletions ballerina/tests/batch-execute-test.bal
Original file line number Diff line number Diff line change
@@ -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;
}
Loading
Loading