@@ -2,6 +2,7 @@ import assert from "node:assert";
2
2
import diagnostics_channel from "node:diagnostics_channel" ;
3
3
import { FaultInjectorClient } from "./fault-injector-client" ;
4
4
import {
5
+ createTestClient ,
5
6
getDatabaseConfig ,
6
7
getDatabaseConfigFromEnv ,
7
8
getEnvConfig ,
@@ -12,14 +13,21 @@ import { DiagnosticsEvent } from "../../client/enterprise-maintenance-manager";
12
13
import { before } from "mocha" ;
13
14
14
15
describe ( "Push Notifications" , ( ) => {
15
- const diagnosticsLog : DiagnosticsEvent [ ] = [ ] ;
16
-
17
- const onMessageHandler = ( message : unknown ) => {
18
- diagnosticsLog . push ( message as DiagnosticsEvent ) ;
16
+ const createNotificationMessageHandler = (
17
+ result : Record < DiagnosticsEvent [ "type" ] , number > ,
18
+ notifications : Array < DiagnosticsEvent [ "type" ] >
19
+ ) => {
20
+ return ( message : unknown ) => {
21
+ if ( notifications . includes ( ( message as DiagnosticsEvent ) . type ) ) {
22
+ const event = message as DiagnosticsEvent ;
23
+ result [ event . type ] = ( result [ event . type ] ?? 0 ) + 1 ;
24
+ }
25
+ } ;
19
26
} ;
20
27
28
+ let onMessageHandler : ReturnType < typeof createNotificationMessageHandler > ;
21
29
let clientConfig : RedisConnectionConfig ;
22
- let client : ReturnType < typeof createClient < any , any , any , 3 > > ;
30
+ let client : ReturnType < typeof createClient < any , any , any , any > > ;
23
31
let faultInjectorClient : FaultInjectorClient ;
24
32
25
33
before ( ( ) => {
@@ -33,62 +41,97 @@ describe("Push Notifications", () => {
33
41
} ) ;
34
42
35
43
beforeEach ( async ( ) => {
36
- diagnosticsLog . length = 0 ;
37
- diagnostics_channel . subscribe ( "redis.maintenance" , onMessageHandler ) ;
44
+ client = await createTestClient ( clientConfig ) ;
38
45
39
- client = createClient ( {
40
- socket : {
41
- host : clientConfig . host ,
42
- port : clientConfig . port ,
43
- ...( clientConfig . tls === true ? { tls : true } : { } ) ,
44
- } ,
45
- password : clientConfig . password ,
46
- username : clientConfig . username ,
47
- RESP : 3 ,
48
- maintPushNotifications : "auto" ,
49
- maintMovingEndpointType : "external-ip" ,
50
- maintRelaxedCommandTimeout : 10000 ,
51
- maintRelaxedSocketTimeout : 10000 ,
52
- } ) ;
53
-
54
- client . on ( "error" , ( err : Error ) => {
55
- throw new Error ( `Client error: ${ err . message } ` ) ;
56
- } ) ;
57
-
58
- await client . connect ( ) ;
46
+ await client . flushAll ( ) ;
59
47
} ) ;
60
48
61
49
afterEach ( ( ) => {
62
- diagnostics_channel . unsubscribe ( "redis.maintenance" , onMessageHandler ) ;
63
- client . destroy ( ) ;
50
+ if ( onMessageHandler ! ) {
51
+ diagnostics_channel . unsubscribe ( "redis.maintenance" , onMessageHandler ) ;
52
+ }
53
+
54
+ if ( client && client . isOpen ) {
55
+ client . destroy ( ) ;
56
+ }
64
57
} ) ;
65
58
66
59
it ( "should receive MOVING, MIGRATING, and MIGRATED push notifications" , async ( ) => {
67
- const { action_id : migrateActionId } =
68
- await faultInjectorClient . triggerAction < { action_id : string } > ( {
69
- type : "migrate" ,
70
- parameters : {
71
- cluster_index : "0" ,
72
- } ,
60
+ const notifications : Array < DiagnosticsEvent [ "type" ] > = [
61
+ "MOVING" ,
62
+ "MIGRATING" ,
63
+ "MIGRATED" ,
64
+ ] ;
65
+
66
+ const diagnosticsMap : Record < DiagnosticsEvent [ "type" ] , number > = { } ;
67
+
68
+ onMessageHandler = createNotificationMessageHandler (
69
+ diagnosticsMap ,
70
+ notifications
71
+ ) ;
72
+
73
+ diagnostics_channel . subscribe ( "redis.maintenance" , onMessageHandler ) ;
74
+
75
+ const { action_id : bindAndMigrateActionId } =
76
+ await faultInjectorClient . migrateAndBindAction ( {
77
+ bdbId : clientConfig . bdbId ,
78
+ clusterIndex : 0 ,
73
79
} ) ;
74
80
75
- await faultInjectorClient . waitForAction ( migrateActionId ) ;
81
+ await faultInjectorClient . waitForAction ( bindAndMigrateActionId ) ;
76
82
77
- const { action_id : bindActionId } =
78
- await faultInjectorClient . triggerAction < { action_id : string } > ( {
79
- type : "bind" ,
83
+ assert . strictEqual (
84
+ diagnosticsMap . MOVING ,
85
+ 1 ,
86
+ "Should have received exactly one MOVING notification"
87
+ ) ;
88
+ assert . strictEqual (
89
+ diagnosticsMap . MIGRATING ,
90
+ 1 ,
91
+ "Should have received exactly one MIGRATING notification"
92
+ ) ;
93
+ assert . strictEqual (
94
+ diagnosticsMap . MIGRATED ,
95
+ 1 ,
96
+ "Should have received exactly one MIGRATED notification"
97
+ ) ;
98
+ } ) ;
99
+
100
+ it ( "should receive FAILING_OVER and FAILED_OVER push notifications" , async ( ) => {
101
+ const notifications : Array < DiagnosticsEvent [ "type" ] > = [
102
+ "FAILING_OVER" ,
103
+ "FAILED_OVER" ,
104
+ ] ;
105
+
106
+ const diagnosticsMap : Record < DiagnosticsEvent [ "type" ] , number > = { } ;
107
+
108
+ onMessageHandler = createNotificationMessageHandler (
109
+ diagnosticsMap ,
110
+ notifications
111
+ ) ;
112
+
113
+ diagnostics_channel . subscribe ( "redis.maintenance" , onMessageHandler ) ;
114
+
115
+ const { action_id : failoverActionId } =
116
+ await faultInjectorClient . triggerAction ( {
117
+ type : "failover" ,
80
118
parameters : {
81
- cluster_index : "0" ,
82
- bdb_id : ` ${ clientConfig . bdbId } ` ,
119
+ bdb_id : clientConfig . bdbId . toString ( ) ,
120
+ cluster_index : 0 ,
83
121
} ,
84
122
} ) ;
85
123
86
- await faultInjectorClient . waitForAction ( bindActionId ) ;
124
+ await faultInjectorClient . waitForAction ( failoverActionId ) ;
87
125
88
- const pushNotificationLogs = diagnosticsLog . filter ( ( log ) => {
89
- return [ "MOVING" , "MIGRATING" , "MIGRATED" ] . includes ( log ?. type ) ;
90
- } ) ;
91
-
92
- assert . strictEqual ( pushNotificationLogs . length , 3 ) ;
126
+ assert . strictEqual (
127
+ diagnosticsMap . FAILING_OVER ,
128
+ 1 ,
129
+ "Should have received exactly one FAILING_OVER notification"
130
+ ) ;
131
+ assert . strictEqual (
132
+ diagnosticsMap . FAILED_OVER ,
133
+ 1 ,
134
+ "Should have received exactly one FAILED_OVER notification"
135
+ ) ;
93
136
} ) ;
94
137
} ) ;
0 commit comments