diff --git a/packages/client/lib/tests/test-scenario/connection-handoff.e2e.ts b/packages/client/lib/tests/test-scenario/connection-handoff.e2e.ts index 3c71dff7ec..3fbf5e38d4 100644 --- a/packages/client/lib/tests/test-scenario/connection-handoff.e2e.ts +++ b/packages/client/lib/tests/test-scenario/connection-handoff.e2e.ts @@ -110,7 +110,7 @@ describe("Connection Handoff", () => { ]; for (const { name, clientOptions } of cases) { - it.only(`should establish new connection and resume traffic afterwards - ${name}`, async () => { + it(`should establish new connection and resume traffic afterwards - ${name}`, async () => { client = await createTestClient(clientConfig, clientOptions); const spyObject = spyOnTemporaryClientInstanceMethod(client, "connect"); diff --git a/packages/client/lib/tests/test-scenario/fault-injector-client.ts b/packages/client/lib/tests/test-scenario/fault-injector-client.ts index 22f6721182..13c81412b1 100644 --- a/packages/client/lib/tests/test-scenario/fault-injector-client.ts +++ b/packages/client/lib/tests/test-scenario/fault-injector-client.ts @@ -9,7 +9,8 @@ export type ActionType = | "execute_rlutil_command" | "execute_rladmin_command" | "migrate" - | "bind"; + | "bind" + | "update_cluster_config"; export interface ActionRequest { type: ActionType; @@ -47,7 +48,9 @@ export class FaultInjectorClient { * @param action The action request to trigger * @throws {Error} When the HTTP request fails or response cannot be parsed as JSON */ - public triggerAction(action: ActionRequest): Promise { + public triggerAction( + action: ActionRequest + ): Promise { return this.#request("POST", "/action", action); } diff --git a/packages/client/lib/tests/test-scenario/push-notification.e2e.ts b/packages/client/lib/tests/test-scenario/push-notification.e2e.ts index cfe714dbd2..9962d0a02d 100644 --- a/packages/client/lib/tests/test-scenario/push-notification.e2e.ts +++ b/packages/client/lib/tests/test-scenario/push-notification.e2e.ts @@ -40,12 +40,6 @@ describe("Push Notifications", () => { clientConfig = getDatabaseConfig(redisConfig); }); - beforeEach(async () => { - client = await createTestClient(clientConfig); - - await client.flushAll(); - }); - afterEach(() => { if (onMessageHandler!) { diagnostics_channel.unsubscribe("redis.maintenance", onMessageHandler); @@ -56,82 +50,300 @@ describe("Push Notifications", () => { } }); - it("should receive MOVING, MIGRATING, and MIGRATED push notifications", async () => { - const notifications: Array = [ - "MOVING", - "MIGRATING", - "MIGRATED", - ]; + describe("Push Notifications Enabled", () => { + beforeEach(async () => { + client = await createTestClient(clientConfig); - const diagnosticsMap: Record = {}; + await client.flushAll(); + }); - onMessageHandler = createNotificationMessageHandler( - diagnosticsMap, - notifications - ); + it("should receive MOVING, MIGRATING, and MIGRATED push notifications", async () => { + const notifications: Array = [ + "MOVING", + "MIGRATING", + "MIGRATED", + ]; - diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); + const diagnosticsMap: Record = {}; - const { action_id: bindAndMigrateActionId } = - await faultInjectorClient.migrateAndBindAction({ - bdbId: clientConfig.bdbId, - clusterIndex: 0, - }); + onMessageHandler = createNotificationMessageHandler( + diagnosticsMap, + notifications + ); - await faultInjectorClient.waitForAction(bindAndMigrateActionId); + diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); - assert.strictEqual( - diagnosticsMap.MOVING, - 1, - "Should have received exactly one MOVING notification" - ); - assert.strictEqual( - diagnosticsMap.MIGRATING, - 1, - "Should have received exactly one MIGRATING notification" - ); - assert.strictEqual( - diagnosticsMap.MIGRATED, - 1, - "Should have received exactly one MIGRATED notification" - ); + const { action_id: bindAndMigrateActionId } = + await faultInjectorClient.migrateAndBindAction({ + bdbId: clientConfig.bdbId, + clusterIndex: 0, + }); + + await faultInjectorClient.waitForAction(bindAndMigrateActionId); + + assert.strictEqual( + diagnosticsMap.MOVING, + 1, + "Should have received exactly one MOVING notification" + ); + assert.strictEqual( + diagnosticsMap.MIGRATING, + 1, + "Should have received exactly one MIGRATING notification" + ); + assert.strictEqual( + diagnosticsMap.MIGRATED, + 1, + "Should have received exactly one MIGRATED notification" + ); + }); + + it("should receive FAILING_OVER and FAILED_OVER push notifications", async () => { + const notifications: Array = [ + "FAILING_OVER", + "FAILED_OVER", + ]; + + const diagnosticsMap: Record = {}; + + onMessageHandler = createNotificationMessageHandler( + diagnosticsMap, + notifications + ); + + diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); + + const { action_id: failoverActionId } = + await faultInjectorClient.triggerAction({ + type: "failover", + parameters: { + bdb_id: clientConfig.bdbId.toString(), + cluster_index: 0, + }, + }); + + await faultInjectorClient.waitForAction(failoverActionId); + + assert.strictEqual( + diagnosticsMap.FAILING_OVER, + 1, + "Should have received exactly one FAILING_OVER notification" + ); + assert.strictEqual( + diagnosticsMap.FAILED_OVER, + 1, + "Should have received exactly one FAILED_OVER notification" + ); + }); }); - it("should receive FAILING_OVER and FAILED_OVER push notifications", async () => { - const notifications: Array = [ - "FAILING_OVER", - "FAILED_OVER", - ]; + describe("Push Notifications Disabled - Client", () => { + beforeEach(async () => { + client = await createTestClient(clientConfig, { + maintPushNotifications: "disabled", + }); - const diagnosticsMap: Record = {}; + client.on("error", (_err) => { + // Expect the socket to be closed + // Ignore errors + }); - onMessageHandler = createNotificationMessageHandler( - diagnosticsMap, - notifications - ); + await client.flushAll(); + }); + + it("should NOT receive MOVING, MIGRATING, and MIGRATED push notifications", async () => { + const notifications: Array = [ + "MOVING", + "MIGRATING", + "MIGRATED", + ]; + + const diagnosticsMap: Record = {}; + + onMessageHandler = createNotificationMessageHandler( + diagnosticsMap, + notifications + ); + + diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); + + const { action_id: bindAndMigrateActionId } = + await faultInjectorClient.migrateAndBindAction({ + bdbId: clientConfig.bdbId, + clusterIndex: 0, + }); + + await faultInjectorClient.waitForAction(bindAndMigrateActionId); + + assert.strictEqual( + diagnosticsMap.MOVING, + undefined, + "Should NOT have received exactly one MOVING notification" + ); + assert.strictEqual( + diagnosticsMap.MIGRATING, + undefined, + "Should NOT have received exactly one MIGRATING notification" + ); + assert.strictEqual( + diagnosticsMap.MIGRATED, + undefined, + "Should NOT have received exactly one MIGRATED notification" + ); + }); - diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); + it("should NOT receive FAILING_OVER and FAILED_OVER push notifications", async () => { + const notifications: Array = [ + "FAILING_OVER", + "FAILED_OVER", + ]; - const { action_id: failoverActionId } = - await faultInjectorClient.triggerAction({ - type: "failover", - parameters: { - bdb_id: clientConfig.bdbId.toString(), - cluster_index: 0, - }, + const diagnosticsMap: Record = {}; + + onMessageHandler = createNotificationMessageHandler( + diagnosticsMap, + notifications + ); + + diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); + + const { action_id: failoverActionId } = + await faultInjectorClient.triggerAction({ + type: "failover", + parameters: { + bdb_id: clientConfig.bdbId.toString(), + cluster_index: 0, + }, + }); + + await faultInjectorClient.waitForAction(failoverActionId); + + assert.strictEqual( + diagnosticsMap.FAILING_OVER, + undefined, + "Should have received exactly one FAILING_OVER notification" + ); + assert.strictEqual( + diagnosticsMap.FAILED_OVER, + undefined, + "Should have received exactly one FAILED_OVER notification" + ); + }); + }); + + describe("Push Notifications Disabled - Server", () => { + beforeEach(async () => { + client = await createTestClient(clientConfig); + + client.on("error", (_err) => { + // Expect the socket to be closed + // Ignore errors }); - await faultInjectorClient.waitForAction(failoverActionId); + await client.flushAll(); + }); - assert.strictEqual( - diagnosticsMap.FAILING_OVER, - 1, - "Should have received exactly one FAILING_OVER notification" - ); - assert.strictEqual( - diagnosticsMap.FAILED_OVER, - 1, - "Should have received exactly one FAILED_OVER notification" - ); + before(async () => { + const { action_id: disablePushNotificationsActionId } = + await faultInjectorClient.triggerAction({ + type: "update_cluster_config", + parameters: { + config: { client_maint_notifications: false }, + }, + }); + + await faultInjectorClient.waitForAction(disablePushNotificationsActionId); + }); + + after(async () => { + const { action_id: enablePushNotificationsActionId } = + await faultInjectorClient.triggerAction({ + type: "update_cluster_config", + parameters: { + config: { client_maint_notifications: true }, + }, + }); + + await faultInjectorClient.waitForAction(enablePushNotificationsActionId); + }); + + it("should NOT receive MOVING, MIGRATING, and MIGRATED push notifications", async () => { + const notifications: Array = [ + "MOVING", + "MIGRATING", + "MIGRATED", + ]; + + const diagnosticsMap: Record = {}; + + onMessageHandler = createNotificationMessageHandler( + diagnosticsMap, + notifications + ); + + diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); + + const { action_id: bindAndMigrateActionId } = + await faultInjectorClient.migrateAndBindAction({ + bdbId: clientConfig.bdbId, + clusterIndex: 0, + }); + + await faultInjectorClient.waitForAction(bindAndMigrateActionId); + + assert.strictEqual( + diagnosticsMap.MOVING, + undefined, + "Should NOT have received exactly one MOVING notification" + ); + assert.strictEqual( + diagnosticsMap.MIGRATING, + undefined, + "Should NOT have received exactly one MIGRATING notification" + ); + assert.strictEqual( + diagnosticsMap.MIGRATED, + undefined, + "Should NOT have received exactly one MIGRATED notification" + ); + }); + + it("should NOT receive FAILING_OVER and FAILED_OVER push notifications", async () => { + const notifications: Array = [ + "FAILING_OVER", + "FAILED_OVER", + ]; + + const diagnosticsMap: Record = {}; + + onMessageHandler = createNotificationMessageHandler( + diagnosticsMap, + notifications + ); + + diagnostics_channel.subscribe("redis.maintenance", onMessageHandler); + + const { action_id: failoverActionId } = + await faultInjectorClient.triggerAction({ + type: "failover", + parameters: { + bdb_id: clientConfig.bdbId.toString(), + cluster_index: 0, + }, + }); + + await faultInjectorClient.waitForAction(failoverActionId); + + assert.strictEqual( + diagnosticsMap.FAILING_OVER, + undefined, + "Should have received exactly one FAILING_OVER notification" + ); + assert.strictEqual( + diagnosticsMap.FAILED_OVER, + undefined, + "Should have received exactly one FAILED_OVER notification" + ); + }); }); }); diff --git a/packages/client/lib/tests/test-scenario/test-scenario.util.ts b/packages/client/lib/tests/test-scenario/test-scenario.util.ts index 9a8ef7c6e4..c98ba90fe1 100644 --- a/packages/client/lib/tests/test-scenario/test-scenario.util.ts +++ b/packages/client/lib/tests/test-scenario/test-scenario.util.ts @@ -168,10 +168,6 @@ export async function createTestClient( ...options, }); - client.on("error", (err: Error) => { - throw new Error(`Client error: ${err.message}`); - }); - await client.connect(); return client;