Skip to content

Commit d361d40

Browse files
shaileshpadaveShailesh Jagannath Padave
andauthored
Update ServiceRegistry test (#74)
* Update ServiceRegistry test * Update ServiceRegistry test * Made few changes in test * Fix test * waitForWorflowCompletion --------- Co-authored-by: Shailesh Jagannath Padave <shaileshpadave@192.168.1.3>
1 parent d976fe1 commit d361d40

4 files changed

Lines changed: 146 additions & 89 deletions

File tree

src/core/__test__/ServiceRegistryClient.test.ts

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {beforeAll, describe, expect, jest, test} from "@jest/globals";
1+
import {beforeAll, afterEach, describe, expect, jest, test} from "@jest/globals";
22
import {ServiceRegistryClient} from "../serviceRegistryClient";
33
import {orkesConductorClient} from "../../orkes";
44
import {ServiceType} from "../../common/open-api/models/ServiceRegistryModels";
@@ -8,20 +8,34 @@ import * as path from 'path';
88
describe("ServiceRegistryClient", () => {
99
const clientPromise = orkesConductorClient({useEnvVars: true});
1010
let serviceRegistryClient: ServiceRegistryClient;
11+
const testServicesToCleanup: string[] = [];
1112

1213
beforeAll(async () => {
1314
const client = await clientPromise;
1415
serviceRegistryClient = new ServiceRegistryClient(client);
1516
});
1617

18+
afterEach(async () => {
19+
// Clean up any services created during tests
20+
for (const serviceName of testServicesToCleanup) {
21+
try {
22+
await serviceRegistryClient.removeService(serviceName);
23+
} catch (e) {
24+
// Ignore cleanup errors - service might already be deleted or not exist
25+
console.debug(`Failed to cleanup service ${serviceName}:`, e);
26+
}
27+
}
28+
testServicesToCleanup.length = 0;
29+
});
30+
1731
jest.setTimeout(15000);
1832

1933
test("Should add and retrieve a service registry", async () => {
2034
// Create a test service registry
2135
const testServiceRegistry = {
2236
name: "test_service_registry",
2337
type: ServiceType.HTTP,
24-
serviceURI: "http://localhost:8081/api-docs",
38+
serviceURI: "http://httpbin:8081/api-docs",
2539
config: {
2640
circuitBreakerConfig: {
2741
failureRateThreshold: 50.0,
@@ -37,6 +51,9 @@ describe("ServiceRegistryClient", () => {
3751
}
3852
};
3953

54+
// Add service to cleanup list
55+
testServicesToCleanup.push(testServiceRegistry.name);
56+
4057
// Register the service registry
4158
await expect(
4259
serviceRegistryClient.addOrUpdateService(testServiceRegistry)
@@ -72,9 +89,12 @@ describe("ServiceRegistryClient", () => {
7289
const testServiceRegistry = {
7390
name: "test_service_registry_to_remove",
7491
type: ServiceType.HTTP,
75-
serviceURI: "http://localhost:8081"
92+
serviceURI: "http://httpbin:8081/api-docs"
7693
};
7794

95+
// Add service to cleanup list
96+
testServicesToCleanup.push(testServiceRegistry.name);
97+
7898
// Register the service registry
7999
await expect(
80100
serviceRegistryClient.addOrUpdateService(testServiceRegistry)
@@ -101,9 +121,12 @@ describe("ServiceRegistryClient", () => {
101121
const testServiceRegistry = {
102122
name: "test_service_registry_with_method",
103123
type: ServiceType.HTTP,
104-
serviceURI: "http://localhost:8082"
124+
serviceURI: "http://httpbin:8081/api-docs"
105125
};
106126

127+
// Add service to cleanup list
128+
testServicesToCleanup.push(testServiceRegistry.name);
129+
107130
// Register the service registry
108131
await expect(
109132
serviceRegistryClient.addOrUpdateService(testServiceRegistry)
@@ -145,102 +168,73 @@ describe("ServiceRegistryClient", () => {
145168
expect(foundMethod?.methodType).toEqual(testServiceMethod.methodType);
146169
expect(foundMethod?.inputType).toEqual(testServiceMethod.inputType);
147170
expect(foundMethod?.outputType).toEqual(testServiceMethod.outputType);
148-
149-
// Clean up
150-
await serviceRegistryClient.removeService(testServiceRegistry.name);
151171
});
152172

153173
test("Should discover methods from a http service", async () => {
154174
// Create a test service registry for discovery
155-
// Note: This should point to a real service that supports discovery
156-
// For HTTP services, it should point to a service with a Swagger/OpenAPI doc
157-
// For gRPC services, it should point to a running gRPC service with reflection
158175
const testServiceRegistry = {
159176
name: "test_service_registry_discovery",
160177
type: ServiceType.HTTP,
161-
serviceURI: "http://localhost:8081/api-docs"
178+
serviceURI: "http://httpbin:8081/api-docs"
162179
};
163180

181+
// Add service to cleanup list
182+
testServicesToCleanup.push(testServiceRegistry.name);
183+
164184
// Register the service registry
165-
await expect(
166-
serviceRegistryClient.addOrUpdateService(testServiceRegistry)
167-
).resolves.not.toThrowError();
185+
await serviceRegistryClient.addOrUpdateService(testServiceRegistry);
168186

169-
try {
170-
// Attempt to discover methods without creating them
171-
const discoveredMethods = await serviceRegistryClient.discover(
172-
testServiceRegistry.name,
173-
true
174-
);
175-
176-
// Verify that we discovered at least one method
177-
expect(discoveredMethods).toBeDefined();
178-
expect(Array.isArray(discoveredMethods)).toBe(true);
179-
180-
// Check that we got at least one method
181-
// If the service URI is valid, this should pass
182-
expect(discoveredMethods.length).toBeGreaterThan(0);
183-
184-
if (discoveredMethods.length > 0) {
185-
// Check that the discovered methods have the expected properties
186-
const firstMethod = discoveredMethods[0];
187-
expect(firstMethod.methodName).toBeDefined();
188-
expect(firstMethod.methodType).toBeDefined();
189-
}
190-
} catch (error) {
191-
// If the discovery endpoint fails (e.g., if the petstore API is down),
192-
// we'll log the error but not fail the test
193-
console.warn("Discovery test failed, possibly due to external service unavailability:", error);
194-
} finally {
195-
// Clean up
196-
await serviceRegistryClient.removeService(testServiceRegistry.name);
187+
// Attempt to discover methods - this will fail the test if discovery fails
188+
const discoveredMethods = await serviceRegistryClient.discover(
189+
testServiceRegistry.name,
190+
true
191+
);
192+
193+
// Verify that we discovered methods
194+
expect(discoveredMethods).toBeDefined();
195+
expect(Array.isArray(discoveredMethods)).toBe(true);
196+
expect(discoveredMethods.length).toBeGreaterThan(0);
197+
198+
if (discoveredMethods.length > 0) {
199+
// Check that the discovered methods have the expected properties
200+
const firstMethod = discoveredMethods[0];
201+
expect(firstMethod.methodName).toBeDefined();
202+
expect(firstMethod.methodType).toBeDefined();
197203
}
198204
});
199205

200206
test("Should discover methods from a gRPC service", async () => {
201207
// Create a test service registry for discovery
202-
// Note: This should point to a real service that supports discovery
203-
// For HTTP services, it should point to a service with a Swagger/OpenAPI doc
204-
// For gRPC services, it should point to a running gRPC service with reflection
205208
const testServiceRegistry = {
206209
name: "test_gRPC_service_registry_discovery",
207210
type: ServiceType.gRPC,
208-
serviceURI: "localhost:50051"
211+
serviceURI: "grpcbin:50051"
209212
};
210213

214+
// Add service to cleanup list
215+
testServicesToCleanup.push(testServiceRegistry.name);
216+
211217
// Register the service registry
212-
await expect(
213-
serviceRegistryClient.addOrUpdateService(testServiceRegistry)
214-
).resolves.not.toThrowError();
218+
await serviceRegistryClient.addOrUpdateService(testServiceRegistry);
215219

216220
const filePath = path.join(__dirname, 'metadata', 'compiled.bin');
217221
const fileBuffer = fs.readFileSync(filePath);
218222
const blob = new Blob([fileBuffer], {type: 'application/octet-stream'});
219223

220-
// Register the service registry
221-
await expect(
222-
serviceRegistryClient.setProtoData(testServiceRegistry.name, 'compiled.bin', blob)
223-
).resolves.not.toThrowError();
224+
// Set proto data
225+
await serviceRegistryClient.setProtoData(testServiceRegistry.name, 'compiled.bin', blob);
224226

225-
try {
226-
const serviceMethods = await serviceRegistryClient.getService(testServiceRegistry.name).then();
227-
const methods = serviceMethods.methods;
228-
expect(serviceMethods).toBeDefined();
229-
expect(methods?.length).toBeGreaterThan(0);
230-
expect(Array.isArray(methods)).toBe(true);
231-
232-
if (methods) {
233-
const firstMethod = methods[0];
234-
expect(firstMethod.methodName).toBeDefined();
235-
expect(firstMethod.methodType).toBeDefined();
236-
}
237-
} catch (error) {
238-
// If the discovery endpoint fails (e.g., if the petstore API is down),
239-
// we'll log the error but not fail the test
240-
console.warn("Discovery test failed, possibly due to external service unavailability:", error);
241-
} finally {
242-
// Clean up
243-
await serviceRegistryClient.removeService(testServiceRegistry.name);
227+
const serviceMethods = await serviceRegistryClient.getService(testServiceRegistry.name);
228+
const methods = serviceMethods.methods;
229+
230+
expect(serviceMethods).toBeDefined();
231+
expect(methods?.length).toBeGreaterThan(0);
232+
expect(Array.isArray(methods)).toBe(true);
233+
234+
if (methods) {
235+
const firstMethod = methods[0];
236+
expect(firstMethod.methodName).toBeDefined();
237+
expect(firstMethod.methodType).toBeDefined();
244238
}
245239
});
246240
});

src/core/__test__/executor.test.ts

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import {expect, describe, test, jest, beforeAll} from "@jest/globals";
1+
import {expect, describe, test, jest, beforeAll, afterEach, afterAll} from "@jest/globals";
22
import {Consistency, ReturnStrategy, SetVariableTaskDef, TaskType, WorkflowDef} from "../../common";
33
import { orkesConductorClient } from "../../orkes";
44
import { WorkflowExecutor } from "../executor";
55
import { v4 as uuidv4 } from "uuid";
66
import {MetadataClient} from "../metadataClient";
77
import {TestUtil} from "./utils/test-util";
8-
import {after} from "node:test";
98
import {TaskResultStatusEnum} from "../../common/open-api/models/TaskResultStatusEnum";
109
import {SignalResponse} from "../../common/open-api/models/SignalResponse";
1110

@@ -114,7 +113,6 @@ describe("Executor", () => {
114113
});
115114
});
116115

117-
118116
describe("Execute with Return Strategy and Consistency", () => {
119117
// Constants specific to this test suite
120118
const WORKFLOW_NAMES = {
@@ -130,6 +128,8 @@ describe("Execute with Return Strategy and Consistency", () => {
130128
let client: any;
131129
let executor: WorkflowExecutor;
132130
let metadataClient: MetadataClient;
131+
const workflowsToCleanup: {name: string, version: number}[] = [];
132+
const executionsToCleanup: string[] = [];
133133

134134
beforeAll(async () => {
135135
client = await clientPromise;
@@ -139,9 +139,28 @@ describe("Execute with Return Strategy and Consistency", () => {
139139

140140
// Register all test workflows
141141
await registerAllWorkflows();
142-
})
142+
});
143+
144+
afterEach(async () => {
145+
// Clean up executions first
146+
for (const executionId of executionsToCleanup) {
147+
try {
148+
const workflowStatus = await executor.getWorkflowStatus(executionId, false, false);
149+
150+
if (workflowStatus.status && !['COMPLETED', 'FAILED', 'TERMINATED', 'TIMED_OUT'].includes(workflowStatus.status)) {
151+
await executor.terminate(executionId, "Test cleanup");
152+
console.debug(`Terminated running workflow: ${executionId}`);
153+
} else {
154+
console.debug(`Skipping cleanup for ${workflowStatus.status} workflow: ${executionId}`);
155+
}
156+
} catch (e) {
157+
console.debug(`Failed to cleanup execution ${executionId}:`, e);
158+
}
159+
}
160+
executionsToCleanup.length = 0;
161+
});
143162

144-
after(async () => {
163+
afterAll(async () => {
145164
// Cleanup all workflows
146165
await cleanupAllWorkflows();
147166
});
@@ -154,24 +173,27 @@ describe("Execute with Return Strategy and Consistency", () => {
154173
TestUtil.registerWorkflow(WORKFLOW_NAMES.SUB_WF_2),
155174
TestUtil.registerWorkflow(WORKFLOW_NAMES.WAIT_SIGNAL_TEST)
156175
]);
176+
177+
// Add to cleanup list
178+
Object.values(WORKFLOW_NAMES).forEach(name => {
179+
workflowsToCleanup.push({name, version: 1});
180+
});
181+
157182
console.log('✓ All workflows registered successfully');
158183
} catch (error) {
159184
throw new Error(`Failed to register workflows: ${error}`);
160185
}
161186
}
162187

163188
async function cleanupAllWorkflows(): Promise<void> {
164-
const cleanupPromises = [
165-
TestUtil.unregisterWorkflow(WORKFLOW_NAMES.COMPLEX_WF, 1),
166-
TestUtil.unregisterWorkflow(WORKFLOW_NAMES.SUB_WF_1, 1),
167-
TestUtil.unregisterWorkflow(WORKFLOW_NAMES.SUB_WF_2, 1),
168-
TestUtil.unregisterWorkflow(WORKFLOW_NAMES.WAIT_SIGNAL_TEST, 1)
169-
];
189+
const cleanupPromises = workflowsToCleanup.map(({name, version}) =>
190+
TestUtil.unregisterWorkflow(name, version)
191+
);
170192

171193
const results = await Promise.allSettled(cleanupPromises);
172194
results.forEach((result, index) => {
173195
if (result.status === 'rejected') {
174-
console.warn(`Failed to cleanup workflow ${Object.values(WORKFLOW_NAMES)[index]}: ${result.reason}`);
196+
console.warn(`Failed to cleanup workflow ${workflowsToCleanup[index].name}: ${result.reason}`);
175197
}
176198
});
177199
console.log('✓ Cleanup completed');
@@ -241,7 +263,6 @@ describe("Execute with Return Strategy and Consistency", () => {
241263
}
242264
];
243265

244-
// Let's write one comprehensive test first, then replicate
245266
test("Should execute complex workflow with SYNC + TARGET_WORKFLOW and validate all aspects", async () => {
246267
const testCase = testCombinations[0]; // SYNC + TARGET_WORKFLOW
247268

@@ -262,6 +283,11 @@ describe("Execute with Return Strategy and Consistency", () => {
262283
// Convert to SignalResponse instance
263284
const result = Object.assign(new SignalResponse(), rawResult);
264285

286+
// Add to cleanup list
287+
if (result.workflowId) {
288+
executionsToCleanup.push(result.workflowId);
289+
}
290+
265291
console.log(`Started workflow with ID: ${result.workflowId} for strategy: ${testCase.name}`);
266292

267293
// ========== BASIC VALIDATIONS ==========
@@ -285,7 +311,6 @@ describe("Execute with Return Strategy and Consistency", () => {
285311
expect(result.status).toBeDefined();
286312
expect(result.createTime).toBeGreaterThan(0);
287313
expect(result.updateTime).toBeGreaterThan(0);
288-
//expect(result.updateTime).toBeGreaterThanOrEqual(result.createTime);
289314
expect(result.tasks).toBeDefined();
290315
expect(Array.isArray(result.tasks)).toBe(true);
291316
expect(result.tasks!.length).toBeGreaterThan(0);
@@ -317,7 +342,6 @@ describe("Execute with Return Strategy and Consistency", () => {
317342
expect(workflowFromResp.status).toEqual(result.status);
318343
expect(workflowFromResp.createTime).toEqual(result.createTime);
319344
expect(workflowFromResp.updateTime).toEqual(result.updateTime);
320-
//expect(workflowFromResp.tasks.length).toEqual(result.tasks!.length);
321345

322346
// Test that task helper methods throw errors
323347
expect(() => result.getBlockingTask()).toThrow('does not contain task details');
@@ -405,6 +429,11 @@ describe("Execute with Return Strategy and Consistency", () => {
405429
// Convert to SignalResponse instance
406430
const result = Object.assign(new SignalResponse(), rawResult);
407431

432+
// Add to cleanup list
433+
if (result.workflowId) {
434+
executionsToCleanup.push(result.workflowId);
435+
}
436+
408437
// Basic validations
409438
expect(result.responseType).toEqual(testCase.returnStrategy);
410439
expect(result.workflowId).toBeDefined();
@@ -451,5 +480,4 @@ describe("Execute with Return Strategy and Consistency", () => {
451480
});
452481
});
453482
});
454-
455483
});

0 commit comments

Comments
 (0)