@@ -12,20 +12,24 @@ import {
12
12
createServiceHandler ,
13
13
} from "@cocalc/conat/service/typed" ;
14
14
import { once } from "@cocalc/util/async-utils" ;
15
- import { before , after } from "@cocalc/backend/conat/test/setup" ;
15
+ import { before , after , connect } from "@cocalc/backend/conat/test/setup" ;
16
16
import { wait } from "@cocalc/backend/conat/test/util" ;
17
17
import { is_date as isDate } from "@cocalc/util/misc" ;
18
18
import { delay } from "awaiting" ;
19
+ import { initConatServer } from "@cocalc/backend/conat/test/setup" ;
20
+ import { getPort } from "@cocalc/backend/conat/test/util" ;
19
21
20
22
beforeAll ( before ) ;
21
23
22
24
describe ( "create a service and test it out" , ( ) => {
23
25
let s ;
26
+ let subject ;
24
27
it ( "creates a service" , async ( ) => {
25
28
s = createConatService ( {
26
29
service : "echo" ,
27
30
handler : ( mesg ) => mesg . repeat ( 2 ) ,
28
31
} ) ;
32
+ subject = s . subject ;
29
33
await once ( s , "running" ) ;
30
34
expect ( await callConatService ( { service : "echo" , mesg : "hello" } ) ) . toBe (
31
35
"hellohello" ,
@@ -35,9 +39,19 @@ describe("create a service and test it out", () => {
35
39
it ( "closes the services and observes it doesn't work anymore" , async ( ) => {
36
40
s . close ( ) ;
37
41
await expect ( async ( ) => {
38
- await callConatService ( { service : "echo" , mesg : "hi" , timeout : 1000 } ) ;
42
+ await callConatService ( { service : "echo" , mesg : "hi" , timeout : 250 } ) ;
39
43
} ) . rejects . toThrowError ( "timeout" ) ;
40
44
} ) ;
45
+
46
+ // [ ] TODO: broken!
47
+ it . skip ( "creates a listener on the same subject and try to call to verify timeout works" , async ( ) => {
48
+ const client = connect ( ) ;
49
+ const sub = await client . subscribe ( subject ) ;
50
+ await expect ( async ( ) => {
51
+ await callConatService ( { service : "echo" , mesg : "hi" , timeout : 250 } ) ;
52
+ } ) . rejects . toThrowError ( "timeout" ) ;
53
+ sub . close ( ) ;
54
+ } ) ;
41
55
} ) ;
42
56
43
57
describe ( "verify that you can create a service AFTER calling it and things to still work fine" , ( ) => {
@@ -118,4 +132,103 @@ describe("create and test a more complicated service", () => {
118
132
} ) ;
119
133
} ) ;
120
134
135
+ describe ( "create a service with specified client, stop and start the server, and see service still works" , ( ) => {
136
+ let server ;
137
+ let client ;
138
+ let client2 ;
139
+ let port ;
140
+ it ( "create a conat server and client" , async ( ) => {
141
+ port = await getPort ( ) ;
142
+ server = await initConatServer ( { port } ) ;
143
+ client = server . client ( { reconnectionDelay : 50 } ) ;
144
+ client2 = server . client ( { reconnectionDelay : 50 } ) ;
145
+ } ) ;
146
+
147
+ let service ;
148
+ it ( "create a service using specific client and call it using both clients" , async ( ) => {
149
+ service = createConatService ( {
150
+ client,
151
+ service : "double" ,
152
+ handler : ( mesg ) => mesg . repeat ( 2 ) ,
153
+ } ) ;
154
+
155
+ expect (
156
+ await callConatService ( { client, service : "double" , mesg : "hello" } ) ,
157
+ ) . toBe ( "hellohello" ) ;
158
+
159
+ expect (
160
+ await callConatService ( {
161
+ client : client2 ,
162
+ service : "double" ,
163
+ mesg : "hello" ,
164
+ } ) ,
165
+ ) . toBe ( "hellohello" ) ;
166
+ } ) ;
167
+
168
+ it ( "disconnect client and check service still works on reconnect" , async ( ) => {
169
+ // cause a disconnect -- client will connect again in 50ms soon
170
+ // and handle the request below:
171
+ client . conn . io . engine . close ( ) ;
172
+ expect (
173
+ await callConatService ( {
174
+ client : client2 ,
175
+ service : "double" ,
176
+ mesg : "hello" ,
177
+ } ) ,
178
+ ) . toBe ( "hellohello" ) ;
179
+ } ) ;
180
+
181
+ it ( "disconnect client2 and check service still works on reconnect" , async ( ) => {
182
+ // cause a disconnect -- client will connect again in 50ms soon
183
+ // and handle the request below:
184
+ client2 . conn . io . engine . close ( ) ;
185
+ expect (
186
+ await callConatService ( {
187
+ client : client2 ,
188
+ service : "double" ,
189
+ mesg : "hello" ,
190
+ } ) ,
191
+ ) . toBe ( "hellohello" ) ;
192
+ } ) ;
193
+
194
+ it ( "disconnect both clients and check service still works on reconnect" , async ( ) => {
195
+ // cause a disconnect -- client will connect again in 50ms soon
196
+ // and handle the request below:
197
+ client . conn . io . engine . close ( ) ;
198
+ client2 . conn . io . engine . close ( ) ;
199
+ expect (
200
+ await callConatService ( {
201
+ client : client2 ,
202
+ service : "double" ,
203
+ mesg : "hello" ,
204
+ } ) ,
205
+ ) . toBe ( "hellohello" ) ;
206
+ } ) ;
207
+
208
+ it ( "kills the server, then makes another one serving on the same port" , async ( ) => {
209
+ await server . close ( ) ;
210
+ server = await initConatServer ( { port } ) ;
211
+ // Killing the server is not at all a normal thing to expect, and causes loss of
212
+ // its state. The clients have to sync realize subscriptions are missing. This
213
+ // takes a fraction of a second and the call below won't immediately work without
214
+ // a short delay, unfortunately. TODO: should we handle this better?
215
+ await delay ( 100 ) ;
216
+ expect (
217
+ await callConatService ( {
218
+ client : client2 ,
219
+ service : "double" ,
220
+ mesg : "hello" ,
221
+ noRetry : true ,
222
+ } ) ,
223
+ ) . toBe ( "hellohello" ) ;
224
+ } ) ;
225
+
226
+ it ( "cleans up" , ( ) => {
227
+ service . close ( ) ;
228
+ client . close ( ) ;
229
+ client2 . close ( ) ;
230
+ server . close ( ) ;
231
+ } ) ;
232
+ } ) ;
233
+
121
234
afterAll ( after ) ;
0 commit comments