@onlineapps/conn-orch-validator 2.0.32 → 2.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/DESIGN.md +64 -118
- package/package.json +2 -2
- package/src/CookbookTestRunner.js +16 -4
- package/src/ServiceReadinessValidator.js +40 -54
- package/src/ValidationOrchestrator.js +9 -5
- package/src/config.js +1 -1
- package/src/helpers/createServiceReadinessTests.js +1 -1
- package/src/index.js +13 -19
- package/examples/service-wrapper-usage.js +0 -250
- package/examples/three-tier-testing.js +0 -144
- package/src/ServiceTestHarness.js +0 -256
- package/src/ServiceValidator.js +0 -399
- package/src/TestOrchestrator.js +0 -730
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Example: How service-wrapper uses connector-testing
|
|
5
|
-
* Shows the integration between service-wrapper and testing framework
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const { ServiceReadinessValidator, TestOrchestrator } = require('../src');
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Enhanced ServiceWrapper with integrated testing
|
|
12
|
-
*/
|
|
13
|
-
class ServiceWrapperWithTesting {
|
|
14
|
-
constructor(options) {
|
|
15
|
-
this.service = options.service;
|
|
16
|
-
this.serviceName = options.serviceName;
|
|
17
|
-
this.openApiSpec = options.openApiSpec;
|
|
18
|
-
this.config = options.config;
|
|
19
|
-
|
|
20
|
-
// Testing configuration
|
|
21
|
-
this.testingEnabled = options.testingEnabled !== false;
|
|
22
|
-
this.testLevel = options.testLevel || 'component'; // unit, component, or integration
|
|
23
|
-
this.validator = new ServiceReadinessValidator();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Start service with validation
|
|
28
|
-
*/
|
|
29
|
-
async start() {
|
|
30
|
-
console.log(`Starting ${this.serviceName}...`);
|
|
31
|
-
|
|
32
|
-
// Step 1: Pre-start validation
|
|
33
|
-
if (this.testingEnabled) {
|
|
34
|
-
const validation = await this.validateBeforeStart();
|
|
35
|
-
|
|
36
|
-
if (!validation.ready) {
|
|
37
|
-
throw new Error(`Service validation failed: ${validation.recommendation}`);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
console.log(`Validation passed with score: ${validation.score}/100`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Step 2: Start the actual service
|
|
44
|
-
await this.startService();
|
|
45
|
-
|
|
46
|
-
// Step 3: Post-start verification
|
|
47
|
-
if (this.testingEnabled) {
|
|
48
|
-
await this.verifyAfterStart();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
console.log(`${this.serviceName} started successfully`);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Validate service before starting
|
|
56
|
-
*/
|
|
57
|
-
async validateBeforeStart() {
|
|
58
|
-
console.log('Running pre-start validation...');
|
|
59
|
-
|
|
60
|
-
// Use TestOrchestrator for comprehensive testing
|
|
61
|
-
const orchestrator = new TestOrchestrator({
|
|
62
|
-
service: this.service,
|
|
63
|
-
serviceName: this.serviceName,
|
|
64
|
-
openApiSpec: this.openApiSpec
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Run tests based on configured level
|
|
68
|
-
let testResults;
|
|
69
|
-
switch (this.testLevel) {
|
|
70
|
-
case 'unit':
|
|
71
|
-
testResults = await orchestrator.runUnitTests();
|
|
72
|
-
break;
|
|
73
|
-
case 'component':
|
|
74
|
-
testResults = await orchestrator.runComponentTests();
|
|
75
|
-
break;
|
|
76
|
-
case 'integration':
|
|
77
|
-
testResults = await orchestrator.runIntegrationTests();
|
|
78
|
-
break;
|
|
79
|
-
default:
|
|
80
|
-
testResults = await orchestrator.runComponentTests();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Convert test results to readiness format
|
|
84
|
-
return {
|
|
85
|
-
ready: testResults.passed,
|
|
86
|
-
score: testResults.coverage || 0,
|
|
87
|
-
recommendation: testResults.passed
|
|
88
|
-
? 'Service passed validation'
|
|
89
|
-
: 'Service failed validation tests',
|
|
90
|
-
details: testResults
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Start the actual service
|
|
96
|
-
*/
|
|
97
|
-
async startService() {
|
|
98
|
-
// This would contain the actual service startup logic
|
|
99
|
-
// - Start Express server
|
|
100
|
-
// - Connect to MQ
|
|
101
|
-
// - Register with registry
|
|
102
|
-
// - etc.
|
|
103
|
-
|
|
104
|
-
return new Promise((resolve) => {
|
|
105
|
-
const PORT = this.config.port || 3000;
|
|
106
|
-
this.server = this.service.listen(PORT, () => {
|
|
107
|
-
console.log(`Service listening on port ${PORT}`);
|
|
108
|
-
resolve();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Verify service after start
|
|
115
|
-
*/
|
|
116
|
-
async verifyAfterStart() {
|
|
117
|
-
console.log('Running post-start verification...');
|
|
118
|
-
|
|
119
|
-
const serviceUrl = `http://localhost:${this.config.port || 3000}`;
|
|
120
|
-
|
|
121
|
-
// Quick readiness check
|
|
122
|
-
const readiness = await this.validator.validateReadiness({
|
|
123
|
-
name: this.serviceName,
|
|
124
|
-
url: serviceUrl,
|
|
125
|
-
openApiSpec: this.openApiSpec,
|
|
126
|
-
healthEndpoint: '/health'
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
if (!readiness.ready) {
|
|
130
|
-
console.warn('Post-start verification found issues:', readiness.errors);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return readiness;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Stop service
|
|
138
|
-
*/
|
|
139
|
-
async stop() {
|
|
140
|
-
if (this.server) {
|
|
141
|
-
await new Promise((resolve) => {
|
|
142
|
-
this.server.close(resolve);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// === Example Usage ===
|
|
149
|
-
|
|
150
|
-
async function demonstrateUsage() {
|
|
151
|
-
const express = require('express');
|
|
152
|
-
|
|
153
|
-
// Create a simple service
|
|
154
|
-
const app = express();
|
|
155
|
-
app.use(express.json());
|
|
156
|
-
|
|
157
|
-
app.get('/health', (req, res) => {
|
|
158
|
-
res.json({ status: 'healthy' });
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
app.post('/api/process', (req, res) => {
|
|
162
|
-
res.json({ processed: true, data: req.body });
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
// OpenAPI spec
|
|
166
|
-
const openApiSpec = {
|
|
167
|
-
openapi: '3.0.0',
|
|
168
|
-
info: { title: 'Demo Service', version: '1.0.0' },
|
|
169
|
-
paths: {
|
|
170
|
-
'/health': {
|
|
171
|
-
get: {
|
|
172
|
-
operationId: 'healthCheck',
|
|
173
|
-
responses: {
|
|
174
|
-
'200': {
|
|
175
|
-
content: {
|
|
176
|
-
'application/json': {
|
|
177
|
-
schema: {
|
|
178
|
-
type: 'object',
|
|
179
|
-
properties: {
|
|
180
|
-
status: { type: 'string' }
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
'/api/process': {
|
|
190
|
-
post: {
|
|
191
|
-
operationId: 'processData',
|
|
192
|
-
requestBody: {
|
|
193
|
-
content: {
|
|
194
|
-
'application/json': {
|
|
195
|
-
schema: { type: 'object' }
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
responses: {
|
|
200
|
-
'200': {
|
|
201
|
-
content: {
|
|
202
|
-
'application/json': {
|
|
203
|
-
schema: { type: 'object' }
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
// Create wrapper with testing
|
|
214
|
-
const wrapper = new ServiceWrapperWithTesting({
|
|
215
|
-
service: app,
|
|
216
|
-
serviceName: 'demo-service',
|
|
217
|
-
openApiSpec,
|
|
218
|
-
config: {
|
|
219
|
-
port: 3333
|
|
220
|
-
},
|
|
221
|
-
testingEnabled: true,
|
|
222
|
-
testLevel: 'unit' // Start with unit tests for speed
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
try {
|
|
226
|
-
// Start service (will run validation first)
|
|
227
|
-
await wrapper.start();
|
|
228
|
-
|
|
229
|
-
console.log('\nService is running with validation!');
|
|
230
|
-
console.log('Try: curl http://localhost:3333/health');
|
|
231
|
-
|
|
232
|
-
// Keep running for demo
|
|
233
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
234
|
-
|
|
235
|
-
// Stop service
|
|
236
|
-
await wrapper.stop();
|
|
237
|
-
console.log('\nService stopped');
|
|
238
|
-
|
|
239
|
-
} catch (error) {
|
|
240
|
-
console.error('Failed to start service:', error.message);
|
|
241
|
-
process.exit(1);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Run demonstration
|
|
246
|
-
if (require.main === module) {
|
|
247
|
-
demonstrateUsage().catch(console.error);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
module.exports = { ServiceWrapperWithTesting };
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Example: Three-tier testing strategy
|
|
5
|
-
* Shows how to use connector-testing for comprehensive service validation
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const { TestOrchestrator } = require('../src');
|
|
9
|
-
const express = require('express');
|
|
10
|
-
|
|
11
|
-
// Example service
|
|
12
|
-
const app = express();
|
|
13
|
-
app.use(express.json());
|
|
14
|
-
|
|
15
|
-
app.get('/health', (req, res) => {
|
|
16
|
-
res.json({ status: 'healthy', service: 'example-service' });
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
app.post('/process', (req, res) => {
|
|
20
|
-
res.json({
|
|
21
|
-
processed: true,
|
|
22
|
-
input: req.body,
|
|
23
|
-
timestamp: Date.now()
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
app.get('/status', (req, res) => {
|
|
28
|
-
res.json({
|
|
29
|
-
running: true,
|
|
30
|
-
uptime: process.uptime()
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// OpenAPI specification
|
|
35
|
-
const openApiSpec = {
|
|
36
|
-
openapi: '3.0.0',
|
|
37
|
-
info: {
|
|
38
|
-
title: 'Example Service',
|
|
39
|
-
version: '1.0.0'
|
|
40
|
-
},
|
|
41
|
-
paths: {
|
|
42
|
-
'/health': {
|
|
43
|
-
get: {
|
|
44
|
-
operationId: 'healthCheck',
|
|
45
|
-
responses: {
|
|
46
|
-
'200': {
|
|
47
|
-
content: {
|
|
48
|
-
'application/json': {
|
|
49
|
-
schema: {
|
|
50
|
-
type: 'object',
|
|
51
|
-
properties: {
|
|
52
|
-
status: { type: 'string' },
|
|
53
|
-
service: { type: 'string' }
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
'/process': {
|
|
63
|
-
post: {
|
|
64
|
-
operationId: 'processData',
|
|
65
|
-
requestBody: {
|
|
66
|
-
content: {
|
|
67
|
-
'application/json': {
|
|
68
|
-
schema: { type: 'object' }
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
responses: {
|
|
73
|
-
'200': {
|
|
74
|
-
content: {
|
|
75
|
-
'application/json': {
|
|
76
|
-
schema: {
|
|
77
|
-
type: 'object',
|
|
78
|
-
properties: {
|
|
79
|
-
processed: { type: 'boolean' },
|
|
80
|
-
input: { type: 'object' },
|
|
81
|
-
timestamp: { type: 'number' }
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
'/status': {
|
|
91
|
-
get: {
|
|
92
|
-
operationId: 'getStatus',
|
|
93
|
-
responses: {
|
|
94
|
-
'200': {
|
|
95
|
-
content: {
|
|
96
|
-
'application/json': {
|
|
97
|
-
schema: {
|
|
98
|
-
type: 'object',
|
|
99
|
-
properties: {
|
|
100
|
-
running: { type: 'boolean' },
|
|
101
|
-
uptime: { type: 'number' }
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
async function runExample() {
|
|
114
|
-
console.log('=== Three-Tier Testing Example ===\n');
|
|
115
|
-
|
|
116
|
-
// Create test orchestrator
|
|
117
|
-
const orchestrator = new TestOrchestrator({
|
|
118
|
-
service: app,
|
|
119
|
-
serviceName: 'example-service',
|
|
120
|
-
openApiSpec,
|
|
121
|
-
logger: console
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// Run all three levels of testing
|
|
125
|
-
console.log('Starting comprehensive test suite...\n');
|
|
126
|
-
const results = await orchestrator.runAllTests();
|
|
127
|
-
|
|
128
|
-
// Generate and display report
|
|
129
|
-
const report = orchestrator.generateReport(results);
|
|
130
|
-
console.log('\n' + report);
|
|
131
|
-
|
|
132
|
-
// Return exit code based on results
|
|
133
|
-
process.exit(results.passed ? 0 : 1);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Run if executed directly
|
|
137
|
-
if (require.main === module) {
|
|
138
|
-
runExample().catch(error => {
|
|
139
|
-
console.error('Test failed:', error);
|
|
140
|
-
process.exit(1);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
module.exports = { app, openApiSpec, runExample };
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const MockMQClient = require('./mocks/MockMQClient');
|
|
4
|
-
const MockRegistry = require('./mocks/MockRegistry');
|
|
5
|
-
const MockStorage = require('./mocks/MockStorage');
|
|
6
|
-
const axios = require('axios');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* ServiceTestHarness - Complete test environment for services
|
|
10
|
-
*/
|
|
11
|
-
class ServiceTestHarness {
|
|
12
|
-
constructor(options = {}) {
|
|
13
|
-
this.service = options.service; // Express app
|
|
14
|
-
this.serviceName = options.serviceName || 'test-service';
|
|
15
|
-
this.openApiSpec = options.openApiSpec || {};
|
|
16
|
-
this.mockInfrastructure = options.mockInfrastructure !== false;
|
|
17
|
-
|
|
18
|
-
// Initialize mocks if requested
|
|
19
|
-
if (this.mockInfrastructure) {
|
|
20
|
-
this.mqClient = new MockMQClient();
|
|
21
|
-
this.registry = new MockRegistry();
|
|
22
|
-
this.storage = new MockStorage();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Test state
|
|
26
|
-
this.server = null;
|
|
27
|
-
this.port = options.port || 0; // 0 = random port
|
|
28
|
-
this.baseUrl = null;
|
|
29
|
-
this.isRunning = false;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Start test harness
|
|
34
|
-
*/
|
|
35
|
-
async start() {
|
|
36
|
-
if (this.isRunning) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Start Express server if provided
|
|
41
|
-
if (this.service) {
|
|
42
|
-
await this.startServer();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Connect mocks
|
|
46
|
-
if (this.mockInfrastructure) {
|
|
47
|
-
await this.mqClient.connect();
|
|
48
|
-
await this.registry.register({
|
|
49
|
-
name: this.serviceName,
|
|
50
|
-
url: this.baseUrl,
|
|
51
|
-
openapi: this.openApiSpec
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
this.isRunning = true;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Stop test harness
|
|
60
|
-
*/
|
|
61
|
-
async stop() {
|
|
62
|
-
if (!this.isRunning) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Stop server
|
|
67
|
-
if (this.server) {
|
|
68
|
-
await new Promise(resolve => {
|
|
69
|
-
this.server.close(resolve);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Disconnect mocks
|
|
74
|
-
if (this.mockInfrastructure) {
|
|
75
|
-
await this.mqClient.disconnect();
|
|
76
|
-
await this.registry.unregister(this.serviceName);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
this.isRunning = false;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Start Express server
|
|
84
|
-
* @private
|
|
85
|
-
*/
|
|
86
|
-
async startServer() {
|
|
87
|
-
return new Promise((resolve) => {
|
|
88
|
-
this.server = this.service.listen(this.port, () => {
|
|
89
|
-
const actualPort = this.server.address().port;
|
|
90
|
-
this.baseUrl = `http://127.0.0.1:${actualPort}`;
|
|
91
|
-
resolve();
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Call API endpoint
|
|
98
|
-
*/
|
|
99
|
-
async callApi(method, path, data = null, headers = {}) {
|
|
100
|
-
if (!this.baseUrl) {
|
|
101
|
-
throw new Error('Service not started');
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const config = {
|
|
105
|
-
method,
|
|
106
|
-
url: `${this.baseUrl}${path}`,
|
|
107
|
-
headers,
|
|
108
|
-
timeout: 5000
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
if (data) {
|
|
112
|
-
if (method === 'GET') {
|
|
113
|
-
config.params = data;
|
|
114
|
-
} else {
|
|
115
|
-
config.data = data;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const response = await axios(config);
|
|
120
|
-
return response.data;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Simulate workflow execution
|
|
125
|
-
*/
|
|
126
|
-
async simulateWorkflow(workflow) {
|
|
127
|
-
const results = [];
|
|
128
|
-
|
|
129
|
-
for (const step of workflow.steps) {
|
|
130
|
-
if (step.type === 'task' && step.service === this.serviceName) {
|
|
131
|
-
// Execute task step
|
|
132
|
-
const result = await this.executeStep(step);
|
|
133
|
-
results.push(result);
|
|
134
|
-
|
|
135
|
-
// Simulate publishing result to queue
|
|
136
|
-
if (this.mockInfrastructure) {
|
|
137
|
-
await this.mqClient.publish('workflow.completed', {
|
|
138
|
-
step: step.id,
|
|
139
|
-
result
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
workflow: workflow,
|
|
147
|
-
results,
|
|
148
|
-
completed: true
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Execute a single workflow step
|
|
154
|
-
* @private
|
|
155
|
-
*/
|
|
156
|
-
async executeStep(step) {
|
|
157
|
-
// Map step to API call based on operation
|
|
158
|
-
const operation = step.operation || step.id;
|
|
159
|
-
const endpoint = this.findEndpoint(operation);
|
|
160
|
-
|
|
161
|
-
if (!endpoint) {
|
|
162
|
-
throw new Error(`No endpoint found for operation: ${operation}`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Call the API
|
|
166
|
-
const response = await this.callApi(
|
|
167
|
-
endpoint.method,
|
|
168
|
-
endpoint.path,
|
|
169
|
-
step.input
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
return {
|
|
173
|
-
stepId: step.id,
|
|
174
|
-
operation,
|
|
175
|
-
response
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Find endpoint in OpenAPI spec
|
|
181
|
-
* @private
|
|
182
|
-
*/
|
|
183
|
-
findEndpoint(operationId) {
|
|
184
|
-
if (!this.openApiSpec.paths) {
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
for (const [path, pathItem] of Object.entries(this.openApiSpec.paths)) {
|
|
189
|
-
for (const [method, operation] of Object.entries(pathItem)) {
|
|
190
|
-
if (operation.operationId === operationId) {
|
|
191
|
-
return { method: method.toUpperCase(), path };
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Get published messages from mock MQ
|
|
201
|
-
*/
|
|
202
|
-
getPublishedMessages(queue = null) {
|
|
203
|
-
if (!this.mockInfrastructure) {
|
|
204
|
-
throw new Error('Mock infrastructure not enabled');
|
|
205
|
-
}
|
|
206
|
-
return this.mqClient.getPublishedMessages(queue);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Get service registration from mock registry
|
|
211
|
-
*/
|
|
212
|
-
getServiceRegistration() {
|
|
213
|
-
if (!this.mockInfrastructure) {
|
|
214
|
-
throw new Error('Mock infrastructure not enabled');
|
|
215
|
-
}
|
|
216
|
-
return this.registry.getService(this.serviceName);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Get storage contents from mock storage
|
|
221
|
-
*/
|
|
222
|
-
async getStorageObject(bucket, key) {
|
|
223
|
-
if (!this.mockInfrastructure) {
|
|
224
|
-
throw new Error('Mock infrastructure not enabled');
|
|
225
|
-
}
|
|
226
|
-
return await this.storage.get(bucket, key);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Clear all test data
|
|
231
|
-
*/
|
|
232
|
-
clear() {
|
|
233
|
-
if (this.mockInfrastructure) {
|
|
234
|
-
this.mqClient.clear();
|
|
235
|
-
this.registry.clear();
|
|
236
|
-
this.storage.clear();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Get test statistics
|
|
242
|
-
*/
|
|
243
|
-
getStats() {
|
|
244
|
-
if (!this.mockInfrastructure) {
|
|
245
|
-
return { mocks: 'disabled' };
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return {
|
|
249
|
-
mq: this.mqClient.getStats(),
|
|
250
|
-
registry: this.registry.getStats(),
|
|
251
|
-
storage: this.storage.getStats()
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
module.exports = ServiceTestHarness;
|