Skip to content

Commit 6539eb6

Browse files
authored
Add Opensearch module (#1072)
1 parent d3d33d6 commit 6539eb6

File tree

11 files changed

+368
-0
lines changed

11 files changed

+368
-0
lines changed

.github/dependabot.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ updates:
3939
- "/packages/modules/nats"
4040
- "/packages/modules/neo4j"
4141
- "/packages/modules/ollama"
42+
- "/packages/modules/opensearch"
4243
- "/packages/modules/postgresql"
4344
- "/packages/modules/qdrant"
4445
- "/packages/modules/rabbitmq"

docs/modules/opensearch.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenSearch Module
2+
3+
[OpenSearch](https://opensearch.org/) is a community-driven, open source search and analytics suite derived from Elasticsearch. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.
4+
5+
## Install
6+
7+
```bash
8+
npm install @testcontainers/opensearch --save-dev
9+
```
10+
11+
## Examples
12+
13+
<!--codeinclude-->
14+
[Create an index:](../../packages/modules/opensearch/src/opensearch-container.test.ts) inside_block:createIndex
15+
<!--/codeinclude-->
16+
17+
<!--codeinclude-->
18+
[Index a document:](../../packages/modules/opensearch/src/opensearch-container.test.ts) inside_block:indexDocument
19+
<!--/codeinclude-->
20+
21+
<!--codeinclude-->
22+
[Set a custom password:](../../packages/modules/opensearch/src/opensearch-container.test.ts) inside_block:customPassword
23+
<!--/codeinclude-->

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ nav:
7474
- Nats: modules/nats.md
7575
- Neo4J: modules/neo4j.md
7676
- Ollama: modules/ollama.md
77+
- OpenSearch: modules/opensearch.md
7778
- PostgreSQL: modules/postgresql.md
7879
- Qdrant: modules/qdrant.md
7980
- RabbitMQ: modules/rabbitmq.md

package-lock.json

Lines changed: 73 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FROM opensearchproject/opensearch:3.1.0
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "@testcontainers/opensearch",
3+
"version": "11.2.1",
4+
"license": "MIT",
5+
"keywords": [
6+
"opensearch",
7+
"testing",
8+
"docker",
9+
"testcontainers"
10+
],
11+
"description": "OpenSearch module for Testcontainers",
12+
"homepage": "https://github.com/testcontainers/testcontainers-node#readme",
13+
"repository": {
14+
"type": "git",
15+
"url": "git+https://github.com/testcontainers/testcontainers-node.git"
16+
},
17+
"bugs": {
18+
"url": "https://github.com/testcontainers/testcontainers-node/issues"
19+
},
20+
"main": "build/index.js",
21+
"files": [
22+
"build"
23+
],
24+
"publishConfig": {
25+
"access": "public"
26+
},
27+
"scripts": {
28+
"prepack": "shx cp ../../../README.md . && shx cp ../../../LICENSE .",
29+
"build": "tsc --project tsconfig.build.json"
30+
},
31+
"devDependencies": {
32+
"@opensearch-project/opensearch": "^3.5.1",
33+
"@types/zxcvbn": "^4.4.5"
34+
},
35+
"dependencies": {
36+
"testcontainers": "^11.2.1",
37+
"zxcvbn": "^4.4.2"
38+
}
39+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { OpenSearchContainer, StartedOpenSearchContainer } from "./opensearch-container";
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { Client } from "@opensearch-project/opensearch";
2+
import { getImage } from "../../../testcontainers/src/utils/test-helper";
3+
import { OpenSearchContainer } from "./opensearch-container";
4+
5+
const IMAGE = getImage(__dirname);
6+
const images = ["opensearchproject/opensearch:2.19.2", IMAGE];
7+
8+
describe("OpenSearchContainer", { timeout: 180_000 }, () => {
9+
// createIndex {
10+
it.each(images)("should create an index with %s", async (image) => {
11+
const container = await new OpenSearchContainer(image).start();
12+
const client = new Client({
13+
node: container.getHttpUrl(),
14+
auth: {
15+
username: container.getUsername(),
16+
password: container.getPassword(),
17+
},
18+
ssl: {
19+
// trust the self-signed cert
20+
rejectUnauthorized: false,
21+
},
22+
});
23+
24+
await client.indices.create({ index: "people" });
25+
const existsResponse = await client.indices.exists({ index: "people" });
26+
expect(existsResponse.body).toBe(true);
27+
await container.stop();
28+
});
29+
// }
30+
31+
// indexDocument {
32+
it("should index a document", async () => {
33+
const container = await new OpenSearchContainer(IMAGE).start();
34+
const client = new Client({
35+
node: container.getHttpUrl(),
36+
auth: {
37+
username: container.getUsername(),
38+
password: container.getPassword(),
39+
},
40+
ssl: {
41+
rejectUnauthorized: false,
42+
},
43+
});
44+
45+
const document = { id: "1", name: "John Doe" };
46+
47+
await client.index({
48+
index: "people",
49+
id: document.id,
50+
body: document,
51+
});
52+
53+
const getResponse = await client.get({ index: "people", id: document.id });
54+
expect(getResponse.body._source).toStrictEqual(document);
55+
await container.stop();
56+
});
57+
// }
58+
59+
it("should work with restarted container", async () => {
60+
const container = await new OpenSearchContainer(IMAGE).start();
61+
await container.restart();
62+
63+
const client = new Client({
64+
node: container.getHttpUrl(),
65+
auth: {
66+
username: container.getUsername(),
67+
password: container.getPassword(),
68+
},
69+
ssl: {
70+
rejectUnauthorized: false,
71+
},
72+
});
73+
74+
await client.indices.create({ index: "people" });
75+
const existsResponse = await client.indices.exists({ index: "people" });
76+
expect(existsResponse.body).toBe(true);
77+
await container.stop();
78+
});
79+
80+
it("should throw when given an invalid password", () => {
81+
expect(() => new OpenSearchContainer(IMAGE).withPassword("weakpwd")).toThrowError(/Password "weakpwd" is too weak/);
82+
});
83+
84+
// customPassword {
85+
it("should set custom password", async () => {
86+
const container = await new OpenSearchContainer(IMAGE).withPassword("Str0ng!Passw0rd2025").start();
87+
88+
const client = new Client({
89+
node: container.getHttpUrl(),
90+
auth: {
91+
username: container.getUsername(),
92+
password: container.getPassword(),
93+
},
94+
ssl: {
95+
rejectUnauthorized: false,
96+
},
97+
});
98+
99+
await client.indices.create({ index: "people" });
100+
const existsResponse = await client.indices.exists({ index: "people" });
101+
expect(existsResponse.body).toBe(true);
102+
await container.stop();
103+
});
104+
// }
105+
});

0 commit comments

Comments
 (0)