You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2021/05/24 03:22:01 UTC
[skywalking-nodejs] branch master updated: Add ioredis plugin (#53)
This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-nodejs.git
The following commit(s) were added to refs/heads/master by this push:
new 163a70d Add ioredis plugin (#53)
163a70d is described below
commit 163a70d4b8b863d063b7d96cacb5641730eb48b7
Author: keke <yo...@gmail.com>
AuthorDate: Mon May 24 11:21:55 2021 +0800
Add ioredis plugin (#53)
---
README.md | 2 +
package-lock.json | 95 +++++++++++++++
package.json | 2 +
src/plugins/IORedisPlugin.ts | 62 ++++++++++
src/trace/Component.ts | 3 +-
.../plugins/ioredis/client.ts | 33 +++---
tests/plugins/ioredis/docker-compose.yml | 84 +++++++++++++
tests/plugins/ioredis/expected.data.yaml | 131 +++++++++++++++++++++
.../plugins/ioredis/server.ts | 45 ++++---
tests/plugins/ioredis/test.ts | 57 +++++++++
10 files changed, 483 insertions(+), 31 deletions(-)
diff --git a/README.md b/README.md
index 7457ab6..a3395f3 100644
--- a/README.md
+++ b/README.md
@@ -79,11 +79,13 @@ Library | Plugin Name
| [`Express`](https://expressjs.com) | `express` |
| [`Axios`](https://github.com/axios/axios) | `axios` |
| [`MySQL`](https://github.com/mysqljs/mysql) | `mysql` |
+| [`MySQL`](https://github.com/sidorares/node-mysql2) | `mysql2` |
| [`PostgreSQL`](https://github.com/brianc/node-postgres) | `pg` |
| [`pg-cursor`](https://github.com/brianc/node-postgres) | `pg-cursor` |
| [`MongoDB`](https://github.com/mongodb/node-mongodb-native) | `mongodb` |
| [`Mongoose`](https://github.com/Automattic/mongoose) | `mongoose` |
| [`RabbitMQ`](https://github.com/squaremo/amqp.node) | `amqplib` |
+| [`Redis`](https://github.com/luin/ioredis) | `ioredis` |
### Compatible Libraries
diff --git a/package-lock.json b/package-lock.json
index 844dadd..add91e0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -953,6 +953,15 @@
"@types/node": "*"
}
},
+ "@types/ioredis": {
+ "version": "4.26.4",
+ "resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.26.4.tgz",
+ "integrity": "sha512-QFbjNq7EnOGw6d1gZZt2h26OFXjx7z+eqEnbCHSrDI1OOLEgOHMKdtIajJbuCr9uO+X9kQQRe7Lz6uxqxl5XKg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -2138,6 +2147,12 @@
"wrap-ansi": "^2.0.0"
}
},
+ "cluster-key-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
+ "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==",
+ "dev": true
+ },
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -3846,6 +3861,41 @@
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
},
+ "ioredis": {
+ "version": "4.27.2",
+ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.27.2.tgz",
+ "integrity": "sha512-7OpYymIthonkC2Jne5uGWXswdhlua1S1rWGAERaotn0hGJWTSURvxdHA9G6wNbT/qKCloCja/FHsfKXW8lpTmg==",
+ "dev": true,
+ "requires": {
+ "cluster-key-slot": "^1.1.0",
+ "debug": "^4.3.1",
+ "denque": "^1.1.0",
+ "lodash.defaults": "^4.2.0",
+ "lodash.flatten": "^4.4.0",
+ "p-map": "^2.1.0",
+ "redis-commands": "1.7.0",
+ "redis-errors": "^1.2.0",
+ "redis-parser": "^3.0.0",
+ "standard-as-callback": "^2.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -5234,6 +5284,18 @@
"resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz",
"integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y="
},
+ "lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=",
+ "dev": true
+ },
+ "lodash.flatten": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
+ "dev": true
+ },
"lodash.template": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
@@ -6202,6 +6264,12 @@
"p-limit": "^2.2.0"
}
},
+ "p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true
+ },
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -6585,6 +6653,27 @@
"util-deprecate": "~1.0.1"
}
},
+ "redis-commands": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
+ "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==",
+ "dev": true
+ },
+ "redis-errors": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
+ "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=",
+ "dev": true
+ },
+ "redis-parser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
+ "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
+ "dev": true,
+ "requires": {
+ "redis-errors": "^1.0.0"
+ }
+ },
"regex-not": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -7392,6 +7481,12 @@
}
}
},
+ "standard-as-callback": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
+ "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==",
+ "dev": true
+ },
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
diff --git a/package.json b/package.json
index a05e96f..fa343d0 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
"devDependencies": {
"@types/express": "^4.17.9",
"@types/google-protobuf": "^3.7.2",
+ "@types/ioredis": "^4.26.4",
"@types/jest": "^26.0.15",
"@types/node": "^14.0.11",
"@types/semver": "^7.2.0",
@@ -49,6 +50,7 @@
"express": "^4.17.1",
"grpc-tools": "^1.10.0",
"grpc_tools_node_protoc_ts": "^4.0.0",
+ "ioredis": "^4.27.2",
"jest": "^26.6.3",
"mongodb": "^3.6.4",
"mongoose": "^5.12.2",
diff --git a/src/plugins/IORedisPlugin.ts b/src/plugins/IORedisPlugin.ts
new file mode 100644
index 0000000..adbd930
--- /dev/null
+++ b/src/plugins/IORedisPlugin.ts
@@ -0,0 +1,62 @@
+/*!
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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 PluginInstaller from '../core/PluginInstaller';
+import SwPlugin, { wrapPromise } from '../core/SwPlugin';
+import { SpanLayer } from '../proto/language-agent/Tracing_pb';
+import Tag from '../Tag';
+import { Component } from '../trace/Component';
+import ContextManager from '../trace/context/ContextManager';
+
+class IORedisPlugin implements SwPlugin {
+ readonly module = 'ioredis';
+ readonly versions = '*';
+
+ install(installer: PluginInstaller): void {
+ const Redis = installer.require('ioredis');
+
+ this.interceptOperation(Redis, 'sendCommand');
+ }
+
+ interceptOperation(Cls: any, operation: string): void {
+ const _original = Cls.prototype[operation];
+
+ if (!_original)
+ return;
+
+ Cls.prototype[operation] = function (...args: any[]) {
+ const command = args[0];
+ const host = `${this.options.host}:${this.options.port}`;
+ const span = ContextManager.current.newExitSpan(`redis/${command?.name}`, Component.REDIS);
+
+ span.start();
+ span.component = Component.REDIS;
+ span.layer = SpanLayer.CACHE;
+ span.peer = host;
+ span.tag(Tag.dbType('Redis'));
+ span.tag(Tag.dbInstance(`${this.condition.select}`));
+
+ const ret = wrapPromise(span, _original.apply(this, args));
+ span.async();
+ return ret;
+ }
+ }
+}
+
+export default new IORedisPlugin();
\ No newline at end of file
diff --git a/src/trace/Component.ts b/src/trace/Component.ts
index f45bf0d..a4bd44f 100644
--- a/src/trace/Component.ts
+++ b/src/trace/Component.ts
@@ -21,6 +21,7 @@ export class Component {
static readonly UNKNOWN = new Component(0);
static readonly HTTP = new Component(2);
static readonly MYSQL = new Component(5);
+ static readonly REDIS = new Component(7);
static readonly MONGODB = new Component(9);
static readonly POSTGRESQL = new Component(22);
static readonly HTTP_SERVER = new Component(49);
@@ -31,5 +32,5 @@ export class Component {
static readonly AXIOS = new Component(4005);
static readonly MONGOOSE = new Component(4006);
- constructor(public readonly id: number) {}
+ constructor(public readonly id: number) { }
}
diff --git a/src/trace/Component.ts b/tests/plugins/ioredis/client.ts
similarity index 54%
copy from src/trace/Component.ts
copy to tests/plugins/ioredis/client.ts
index f45bf0d..2f33af1 100644
--- a/src/trace/Component.ts
+++ b/tests/plugins/ioredis/client.ts
@@ -17,19 +17,22 @@
*
*/
-export class Component {
- static readonly UNKNOWN = new Component(0);
- static readonly HTTP = new Component(2);
- static readonly MYSQL = new Component(5);
- static readonly MONGODB = new Component(9);
- static readonly POSTGRESQL = new Component(22);
- static readonly HTTP_SERVER = new Component(49);
- static readonly RABBITMQ_PRODUCER = new Component(52);
- static readonly RABBITMQ_CONSUMER = new Component(53);
- static readonly AZURE_HTTPTRIGGER = new Component(111);
- static readonly EXPRESS = new Component(4002);
- static readonly AXIOS = new Component(4005);
- static readonly MONGOOSE = new Component(4006);
+import * as http from 'http';
+import agent from '../../../src';
- constructor(public readonly id: number) {}
-}
+agent.start({
+ serviceName: 'client',
+ maxBufferSize: 1000,
+})
+
+const server = http.createServer((req, res) => {
+ http
+ .request(`http://${process.env.SERVER || 'localhost:5000'}${req.url}`, (r) => {
+ let data = '';
+ r.on('data', (chunk) => (data += chunk));
+ r.on('end', () => res.end(data));
+ })
+ .end();
+});
+
+server.listen(5001, () => console.info('Listening on port 5001...'));
diff --git a/tests/plugins/ioredis/docker-compose.yml b/tests/plugins/ioredis/docker-compose.yml
new file mode 100644
index 0000000..f66fb04
--- /dev/null
+++ b/tests/plugins/ioredis/docker-compose.yml
@@ -0,0 +1,84 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF 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.
+#
+
+version: "2.1"
+
+services:
+ collector:
+ extends:
+ file: ../common/base-compose.yml
+ service: collector
+ networks:
+ - traveling-light
+
+ redis:
+ container_name: redis
+ ports:
+ - 6379:6379
+ healthcheck:
+ test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/6379"]
+ interval: 5s
+ timeout: 60s
+ retries: 120
+ image: "redis:latest"
+ networks:
+ - traveling-light
+
+ server:
+ extends:
+ file: ../common/base-compose.yml
+ service: agent
+ ports:
+ - 5000:5000
+ environment:
+ REDIS_HOST: redis
+ volumes:
+ - .:/app/tests/plugins/ioredis
+ healthcheck:
+ test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/5000"]
+ interval: 5s
+ timeout: 60s
+ retries: 120
+ entrypoint:
+ ["bash", "-c", "npx ts-node /app/tests/plugins/ioredis/server.ts"]
+ depends_on:
+ collector:
+ condition: service_healthy
+ redis:
+ condition: service_healthy
+
+ client:
+ extends:
+ file: ../common/base-compose.yml
+ service: agent
+ ports:
+ - 5001:5001
+ environment:
+ SERVER: server:5000
+ healthcheck:
+ test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/5001"]
+ interval: 5s
+ timeout: 60s
+ retries: 120
+ entrypoint:
+ ["bash", "-c", "npx ts-node /app/tests/plugins/ioredis/client.ts"]
+ depends_on:
+ server:
+ condition: service_healthy
+
+networks:
+ traveling-light:
diff --git a/tests/plugins/ioredis/expected.data.yaml b/tests/plugins/ioredis/expected.data.yaml
new file mode 100644
index 0000000..d527352
--- /dev/null
+++ b/tests/plugins/ioredis/expected.data.yaml
@@ -0,0 +1,131 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF 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.
+#
+
+segmentItems:
+ - serviceName: server
+ segmentSize: 2
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: redis/info
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Cache
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 7
+ spanType: Exit
+ peer: redis:6379
+ skipAnalysis: false
+ tags:
+ - { key: coldStart, value: "true" }
+ - { key: db.type, value: Redis }
+ - { key: db.instance, value: "0" }
+ - segmentId: not null
+ spans:
+ - operationName: redis/set
+ operationId: 0
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: Cache
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 7
+ spanType: Exit
+ peer: redis:6379
+ skipAnalysis: false
+ tags:
+ - { key: db.type, value: Redis }
+ - { key: db.instance, value: "0" }
+ - operationName: redis/get
+ operationId: 0
+ parentSpanId: 0
+ spanId: 2
+ spanLayer: Cache
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 7
+ spanType: Exit
+ peer: redis:6379
+ skipAnalysis: false
+ tags:
+ - { key: db.type, value: Redis }
+ - { key: db.instance, value: "0" }
+ - operationName: /ioredis
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 49
+ spanType: Entry
+ peer: not null
+ skipAnalysis: false
+ tags:
+ - { key: http.url, value: "http://server:5000/ioredis" }
+ - { key: http.method, value: GET }
+ - { key: http.status.code, value: "200" }
+ - { key: http.status.msg, value: OK }
+ refs:
+ - parentEndpoint: ""
+ networkAddress: server:5000
+ refType: CrossProcess
+ parentSpanId: 1
+ parentTraceSegmentId: not null
+ parentServiceInstance: not null
+ parentService: client
+ traceId: not null
+ - serviceName: client
+ segmentSize: 1
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: /ioredis
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 49
+ spanType: Entry
+ peer: not null
+ skipAnalysis: false
+ tags:
+ - { key: coldStart, value: "true" }
+ - { key: http.url, value: "http://localhost:5001/ioredis" }
+ - { key: http.method, value: GET }
+ - { key: http.status.code, value: "200" }
+ - { key: http.status.msg, value: OK }
+ - operationName: /ioredis
+ operationId: 0
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: Http
+ startTime: gt 0
+ endTime: gt 0
+ componentId: 2
+ spanType: Exit
+ peer: server:5000
+ skipAnalysis: false
+ tags:
+ - { key: http.url, value: "http://server:5000/ioredis" }
+ - { key: http.method, value: GET }
+ - { key: http.status.code, value: "200" }
+ - { key: http.status.msg, value: OK }
diff --git a/src/trace/Component.ts b/tests/plugins/ioredis/server.ts
similarity index 53%
copy from src/trace/Component.ts
copy to tests/plugins/ioredis/server.ts
index f45bf0d..cf56507 100644
--- a/src/trace/Component.ts
+++ b/tests/plugins/ioredis/server.ts
@@ -17,19 +17,34 @@
*
*/
-export class Component {
- static readonly UNKNOWN = new Component(0);
- static readonly HTTP = new Component(2);
- static readonly MYSQL = new Component(5);
- static readonly MONGODB = new Component(9);
- static readonly POSTGRESQL = new Component(22);
- static readonly HTTP_SERVER = new Component(49);
- static readonly RABBITMQ_PRODUCER = new Component(52);
- static readonly RABBITMQ_CONSUMER = new Component(53);
- static readonly AZURE_HTTPTRIGGER = new Component(111);
- static readonly EXPRESS = new Component(4002);
- static readonly AXIOS = new Component(4005);
- static readonly MONGOOSE = new Component(4006);
+import * as http from 'http';
+import Redis from 'ioredis';
+import agent from '../../../src';
+import assert from 'assert';
- constructor(public readonly id: number) {}
-}
+agent.start({
+ serviceName: 'server',
+ maxBufferSize: 1000,
+});
+
+const client = new Redis({
+ host: process.env.REDIS_HOST || 'redis',
+});
+
+const server = http.createServer((req, res) => {
+ (async () => {
+ const cacheKey = 'now';
+ const now = '' + Date.now();
+
+ await client.set(cacheKey, now);
+ const _now = await client.get(cacheKey);
+ assert.strictEqual(now, _now);
+
+ res.end(_now);
+ })().catch((err: Error) => {
+ res.statusCode = 500;
+ res.end(err.message);
+ });
+})
+
+server.listen(5000, () => console.info('Listening on port 5000...'));
diff --git a/tests/plugins/ioredis/test.ts b/tests/plugins/ioredis/test.ts
new file mode 100644
index 0000000..8a8b423
--- /dev/null
+++ b/tests/plugins/ioredis/test.ts
@@ -0,0 +1,57 @@
+/*!
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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 * as path from 'path';
+import { DockerComposeEnvironment, StartedDockerComposeEnvironment, Wait } from 'testcontainers';
+import axios from 'axios';
+import waitForExpect from 'wait-for-expect';
+import { promises as fs } from 'fs';
+
+const rootDir = path.resolve(__dirname);
+
+describe('plugin tests', () => {
+ let compose: StartedDockerComposeEnvironment;
+
+ beforeAll(async () => {
+ compose = await new DockerComposeEnvironment(rootDir, 'docker-compose.yml')
+ .withWaitStrategy('client', Wait.forHealthCheck())
+ .withWaitStrategy('redis', Wait.forHealthCheck())
+ .up();
+ });
+
+ afterAll(async () => {
+ await compose.down();
+ });
+
+ it(__filename, async () => {
+ await waitForExpect(async () => expect((await axios.get('http://localhost:5001/ioredis')).status).toBe(200));
+
+ const expectedData = await fs.readFile(path.join(rootDir, 'expected.data.yaml'), 'utf8');
+
+ try {
+ await waitForExpect(async () =>
+ expect((await axios.post('http://localhost:12800/dataValidate', expectedData)).status).toBe(200),
+ );
+ } catch (e) {
+ const actualData = (await axios.get('http://localhost:12800/receiveData')).data;
+ console.info({ actualData });
+ throw e;
+ }
+ });
+});