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 ScyllaDB module #861

Merged
merged 1 commit into from
Nov 12, 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
21 changes: 21 additions & 0 deletions docs/modules/scylladb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ScyllaDB Module

[ScyllaDB](https://www.scylladb.com/) is a distributed NoSQL wide-column database for data-intensive apps that require high performance and low latency. It was designed to be compatible with Apache Cassandra while achieving significantly higher throughputs and lower latencies.



## Install

```bash
npm install @testcontainers/scylladb --save-dev
```

## Examples

<!--codeinclude-->
[Connect:](../../packages/modules/scylladb/src/scylladb-container.test.ts) inside_block:connectWithDefaultCredentials
<!--/codeinclude-->

<!--codeinclude-->
[Insert & fetch data:](../../packages/modules/scylladb/src/scylladb-container.test.ts) inside_block:createAndFetchData
<!--/codeinclude-->
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ nav:
- RabbitMQ: modules/rabbitmq.md
- Redis: modules/redis.md
- Redpanda: modules/redpanda.md
- ScyllaDB: modules/scylladb.md
- Selenium: modules/selenium.md
- Weaviate: modules/weaviate.md
- Configuration: configuration.md
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions packages/modules/scylladb/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Config } from "jest";
import * as path from "path";

const config: Config = {
preset: "ts-jest",
moduleNameMapper: {
"^testcontainers$": path.resolve(__dirname, "../../testcontainers/src"),
},
};

export default config;
37 changes: 37 additions & 0 deletions packages/modules/scylladb/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@testcontainers/scylladb",
"version": "10.14.0",
"license": "MIT",
"keywords": [
"scylladb",
"testing",
"docker",
"testcontainers"
],
"description": "ScyllaDB module for Testcontainers",
"homepage": "https://github.com/testcontainers/testcontainers-node#readme",
"repository": {
"type": "git",
"url": "https://github.com/testcontainers/testcontainers-node"
},
"bugs": {
"url": "https://github.com/testcontainers/testcontainers-node/issues"
},
"main": "build/index.js",
"files": [
"build"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"prepack": "shx cp ../../../README.md . && shx cp ../../../LICENSE .",
"build": "tsc --project tsconfig.build.json"
},
"dependencies": {
"testcontainers": "^10.14.0"
},
"devDependencies": {
"cassandra-driver": "^4.7.2"
}
}
1 change: 1 addition & 0 deletions packages/modules/scylladb/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ScyllaContainer, StartedScyllaContainer } from "./scylladb-container";
67 changes: 67 additions & 0 deletions packages/modules/scylladb/src/scylladb-container.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Client } from "cassandra-driver"; // Scylla uses Cassandra's driver in Node.js
import { ScyllaContainer } from "./scylladb-container";

describe("ScyllaDB", () => {
jest.setTimeout(240_000);

// connectWithDefaultCredentials {
it("should connect and execute a query", async () => {
const container = await new ScyllaContainer("scylladb/scylla:6.2.0").start();

const client = new Client({
contactPoints: [container.getContactPoint()],
localDataCenter: container.getDatacenter(),
keyspace: "system",
});

await client.connect();

const result = await client.execute("SELECT cql_version FROM system.local");
expect(result.rows[0].cql_version).toBe("3.3.1");

await client.shutdown();
await container.stop();
});
// }

// createAndFetchData {
it("should create keyspace, a table, insert data, and retrieve it", async () => {
const container = await new ScyllaContainer().start();

const client = new Client({
contactPoints: [container.getContactPoint()],
localDataCenter: container.getDatacenter(),
});

await client.connect();

// Create the keyspace
await client.execute(`
CREATE KEYSPACE IF NOT EXISTS test_keyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}
`);

await client.execute("USE test_keyspace");

// Create the table.
await client.execute(`
CREATE TABLE IF NOT EXISTS test_keyspace.users (
id UUID PRIMARY KEY,
name text
)
`);

// Insert a record
const id = "d002cd08-401a-47d6-92d7-bb4204d092f8"; // Fixed UUID for testing
const username = "Test McTestinson";
await client.execute("INSERT INTO test_keyspace.users (id, name) VALUES (?, ?)", [id, username]);

// Fetch and verify the record
const result = await client.execute("SELECT * FROM test_keyspace.users WHERE id = ?", [id], { prepare: true });
expect(result.rows[0].name).toEqual(username);

await client.shutdown();
await container.stop();
});
// }
});
42 changes: 42 additions & 0 deletions packages/modules/scylladb/src/scylladb-container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { AbstractStartedContainer, GenericContainer, type StartedTestContainer } from "testcontainers";

const SCYLLA_PORT = 9042;

export class ScyllaContainer extends GenericContainer {
constructor(image = "scylladb/scylla:6.2.0") {
super(image);
this.withExposedPorts(SCYLLA_PORT);
this.withCommand(["--skip-wait-for-gossip-to-settle=0"]);
}

public override async start(): Promise<StartedScyllaContainer> {
this.withEnvironment({
SCYLLA_LISTEN_ADDRESS: "0.0.0.0",
SCYLLA_BROADCAST_ADDRESS: "0.0.0.0",
SCYLLA_RPC_ADDRESS: "0.0.0.0",
});
const startedContainer = await super.start();
return new StartedScyllaContainer(startedContainer);
}
}

export class StartedScyllaContainer extends AbstractStartedContainer {
private readonly port: number;

constructor(startedTestContainer: StartedTestContainer) {
super(startedTestContainer);
this.port = startedTestContainer.getMappedPort(SCYLLA_PORT);
}

public getPort(): number {
return this.port;
}

public getDatacenter(): string {
return "datacenter1"; // Forced in docker.
}

public getContactPoint(): string {
return `${this.getHost()}:${this.getPort()}`;
}
}
13 changes: 13 additions & 0 deletions packages/modules/scylladb/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "./tsconfig.json",
"exclude": [
"build",
"jest.config.ts",
"src/**/*.test.ts"
],
"references": [
{
"path": "../../testcontainers"
}
]
}
21 changes: 21 additions & 0 deletions packages/modules/scylladb/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "build",
"paths": {
"testcontainers": [
"../../testcontainers/src"
]
}
},
"exclude": [
"build",
"jest.config.ts"
],
"references": [
{
"path": "../../testcontainers"
}
]
}
Loading