@@ -56,12 +56,7 @@ func TestAdminServer(t *testing.T) {
5656 AppName : "test-app" ,
5757 AdminServer : true ,
5858 })
59-
6059 require .NoError (t , err )
61- testWorkflow := func (dbosCtx DBOSContext , input string ) (string , error ) {
62- return "result-" + input , nil
63- }
64- RegisterWorkflow (ctx , testWorkflow )
6560
6661 err = ctx .Launch ()
6762 require .NoError (t , err )
@@ -149,17 +144,6 @@ func TestAdminServer(t *testing.T) {
149144 assert .True (t , foundInternalQueue , "Expected to find internal queue in metadata" )
150145 },
151146 },
152- {
153- name : "Workflows endpoint accepts valid request and tests time filters" ,
154- method : "POST" ,
155- endpoint : fmt .Sprintf ("http://localhost:3001/%s" , strings .TrimPrefix (_WORKFLOWS_PATTERN , "POST /" )),
156- body : nil , // Will be set during test execution
157- contentType : "application/json" ,
158- expectedStatus : http .StatusOK ,
159- validateResp : func (t * testing.T , resp * http.Response ) {
160- // This will be overridden in the test
161- },
162- },
163147 {
164148 name : "Workflows endpoint accepts all filters without error" ,
165149 method : "POST" ,
@@ -195,183 +179,210 @@ func TestAdminServer(t *testing.T) {
195179
196180 for _ , tt := range tests {
197181 t .Run (tt .name , func (t * testing.T ) {
198- // Special handling for workflows time filter test
199- if tt .name == "List endpoints time filtering" {
200- // Create first workflow
201- handle1 , err := RunAsWorkflow (ctx , testWorkflow , "workflow1" )
202- require .NoError (t , err , "Failed to create first workflow" )
203- result1 , err := handle1 .GetResult ()
204- require .NoError (t , err , "Failed to get first workflow result" )
205- assert .Equal (t , "result-workflow1" , result1 )
206- workflowID1 := handle1 .GetWorkflowID ()
207-
208- // Record time between workflows
209- timeBetween := time .Now ()
210-
211- // Wait 1 second
212- time .Sleep (1 * time .Second )
213-
214- // Create second workflow
215- handle2 , err := RunAsWorkflow (ctx , testWorkflow , "workflow2" )
216- require .NoError (t , err , "Failed to create second workflow" )
217- result2 , err := handle2 .GetResult ()
218- require .NoError (t , err , "Failed to get second workflow result" )
219- assert .Equal (t , "result-workflow2" , result2 )
220- workflowID2 := handle2 .GetWorkflowID ()
221-
222- // Test 1: Query with start_time before timeBetween (should get both workflows)
223- reqBody1 := map [string ]any {
224- "start_time" : timeBetween .Add (- 2 * time .Second ).Format (time .RFC3339 ),
225- "limit" : 10 ,
226- }
227- req1 , err := http .NewRequest (tt .method , tt .endpoint , bytes .NewBuffer (mustMarshal (reqBody1 )))
228- require .NoError (t , err , "Failed to create request 1" )
229- req1 .Header .Set ("Content-Type" , tt .contentType )
230-
231- resp1 , err := client .Do (req1 )
232- require .NoError (t , err , "Failed to make request 1" )
233- defer resp1 .Body .Close ()
234-
235- assert .Equal (t , tt .expectedStatus , resp1 .StatusCode )
236-
237- var workflows1 []map [string ]any
238- err = json .NewDecoder (resp1 .Body ).Decode (& workflows1 )
239- require .NoError (t , err , "Failed to decode workflows response 1" )
182+ var req * http.Request
183+ var err error
240184
241- // Should have exactly 2 workflows that we just created
242- assert .Equal (t , 2 , len (workflows1 ), "Expected exactly 2 workflows with start_time before timeBetween" )
185+ if tt .body != nil {
186+ req , err = http .NewRequest (tt .method , tt .endpoint , tt .body )
187+ } else {
188+ req , err = http .NewRequest (tt .method , tt .endpoint , nil )
189+ }
190+ require .NoError (t , err , "Failed to create request" )
243191
244- // Verify timestamps are epoch milliseconds
245- timeBetweenMillis := timeBetween .UnixMilli ()
246- for _ , wf := range workflows1 {
247- _ , ok := wf ["CreatedAt" ].(float64 )
248- require .True (t , ok , "CreatedAt should be a number" )
249- }
250- // Verify the timestamp is around timeBetween (within 2 seconds before or after)
251- assert .Less (t , int64 (workflows1 [0 ]["CreatedAt" ].(float64 )), timeBetweenMillis , "first workflow CreatedAt should be before timeBetween" )
252- assert .Greater (t , int64 (workflows1 [1 ]["CreatedAt" ].(float64 )), timeBetweenMillis , "second workflow CreatedAt should be before timeBetween" )
253-
254- // Verify both workflow IDs are present
255- foundIDs1 := make (map [string ]bool )
256- for _ , wf := range workflows1 {
257- id , ok := wf ["WorkflowUUID" ].(string )
258- require .True (t , ok , "WorkflowUUID should be a string" )
259- foundIDs1 [id ] = true
260- }
261- assert .True (t , foundIDs1 [workflowID1 ], "Expected to find first workflow ID in results" )
262- assert .True (t , foundIDs1 [workflowID2 ], "Expected to find second workflow ID in results" )
192+ if tt .contentType != "" {
193+ req .Header .Set ("Content-Type" , tt .contentType )
194+ }
263195
264- // Test 2: Query with start_time after timeBetween (should get only second workflow)
265- reqBody2 := map [string ]any {
266- "start_time" : timeBetween .Format (time .RFC3339 ),
267- "limit" : 10 ,
268- }
269- req2 , err := http .NewRequest (tt .method , tt .endpoint , bytes .NewBuffer (mustMarshal (reqBody2 )))
270- require .NoError (t , err , "Failed to create request 2" )
271- req2 .Header .Set ("Content-Type" , tt .contentType )
196+ resp , err := client .Do (req )
197+ require .NoError (t , err , "Failed to make request" )
198+ defer resp .Body .Close ()
272199
273- resp2 , err := client .Do (req2 )
274- require .NoError (t , err , "Failed to make request 2" )
275- defer resp2 .Body .Close ()
200+ assert .Equal (t , tt .expectedStatus , resp .StatusCode )
276201
277- assert .Equal (t , tt .expectedStatus , resp2 .StatusCode )
202+ if tt .validateResp != nil {
203+ tt .validateResp (t , resp )
204+ }
205+ })
206+ }
207+ })
278208
279- var workflows2 []map [string ]any
280- err = json .NewDecoder (resp2 .Body ).Decode (& workflows2 )
281- require .NoError (t , err , "Failed to decode workflows response 2" )
209+ t .Run ("List endpoints time filtering" , func (t * testing.T ) {
210+ ctx , err := NewDBOSContext (Config {
211+ DatabaseURL : databaseURL ,
212+ AppName : "test-app" ,
213+ AdminServer : true ,
214+ })
215+ require .NoError (t , err )
282216
283- // Should have exactly 1 workflow (the second one)
284- assert .Equal (t , 1 , len (workflows2 ), "Expected exactly 1 workflow with start_time after timeBetween" )
217+ testWorkflow := func (dbosCtx DBOSContext , input string ) (string , error ) {
218+ return "result-" + input , nil
219+ }
220+ RegisterWorkflow (ctx , testWorkflow )
285221
286- // Verify it's the second workflow
287- id2 , ok := workflows2 [0 ]["WorkflowUUID" ].(string )
288- require .True (t , ok , "WorkflowUUID should be a string" )
289- assert .Equal (t , workflowID2 , id2 , "Expected second workflow ID in results" )
222+ err = ctx .Launch ()
223+ require .NoError (t , err )
290224
291- // Also test end_time filter
292- reqBody3 := map [string ]any {
293- "end_time" : timeBetween .Format (time .RFC3339 ),
294- "limit" : 10 ,
295- }
296- req3 , err := http .NewRequest (tt .method , tt .endpoint , bytes .NewBuffer (mustMarshal (reqBody3 )))
297- require .NoError (t , err , "Failed to create request 3" )
298- req3 .Header .Set ("Content-Type" , tt .contentType )
225+ // Ensure cleanup
226+ defer func () {
227+ if ctx != nil {
228+ ctx .Cancel ()
229+ }
230+ }()
299231
300- resp3 , err := client .Do (req3 )
301- require .NoError (t , err , "Failed to make request 3" )
302- defer resp3 .Body .Close ()
232+ client := & http.Client {Timeout : 5 * time .Second }
233+ endpoint := fmt .Sprintf ("http://localhost:3001/%s" , strings .TrimPrefix (_WORKFLOWS_PATTERN , "POST /" ))
234+
235+ // Create first workflow
236+ handle1 , err := RunAsWorkflow (ctx , testWorkflow , "workflow1" )
237+ require .NoError (t , err , "Failed to create first workflow" )
238+ workflowID1 := handle1 .GetWorkflowID ()
239+
240+ // Wait for first workflow to complete
241+ result1 , err := handle1 .GetResult ()
242+ require .NoError (t , err , "Failed to get first workflow result" )
243+ assert .Equal (t , "result-workflow1" , result1 )
244+
245+ // Record time between workflows
246+ time .Sleep (500 * time .Millisecond )
247+ timeBetween := time .Now ()
248+ time .Sleep (500 * time .Millisecond )
249+
250+ // Create second workflow
251+ handle2 , err := RunAsWorkflow (ctx , testWorkflow , "workflow2" )
252+ require .NoError (t , err , "Failed to create second workflow" )
253+ result2 , err := handle2 .GetResult ()
254+ require .NoError (t , err , "Failed to get second workflow result" )
255+ assert .Equal (t , "result-workflow2" , result2 )
256+ workflowID2 := handle2 .GetWorkflowID ()
257+
258+ // Test 1: Query with start_time before timeBetween (should get both workflows)
259+ reqBody1 := map [string ]any {
260+ "start_time" : timeBetween .Add (- 2 * time .Second ).Format (time .RFC3339 ),
261+ "limit" : 10 ,
262+ }
263+ req1 , err := http .NewRequest (http .MethodPost , endpoint , bytes .NewBuffer (mustMarshal (reqBody1 )))
264+ require .NoError (t , err , "Failed to create request 1" )
265+ req1 .Header .Set ("Content-Type" , "application/json" )
303266
304- assert .Equal (t , tt .expectedStatus , resp3 .StatusCode )
267+ resp1 , err := client .Do (req1 )
268+ require .NoError (t , err , "Failed to make request 1" )
269+ defer resp1 .Body .Close ()
305270
306- var workflows3 []map [string ]any
307- err = json .NewDecoder (resp3 .Body ).Decode (& workflows3 )
308- require .NoError (t , err , "Failed to decode workflows response 3" )
271+ assert .Equal (t , http .StatusOK , resp1 .StatusCode )
309272
310- // Should have exactly 1 workflow (the first one)
311- assert .Equal (t , 1 , len (workflows3 ), "Expected exactly 1 workflow with end_time before timeBetween" )
273+ var workflows1 []map [string ]any
274+ err = json .NewDecoder (resp1 .Body ).Decode (& workflows1 )
275+ require .NoError (t , err , "Failed to decode workflows response 1" )
312276
313- // Verify it's the first workflow
314- id3 , ok := workflows3 [0 ]["WorkflowUUID" ].(string )
315- require .True (t , ok , "WorkflowUUID should be a string" )
316- assert .Equal (t , workflowID1 , id3 , "Expected first workflow ID in results" )
277+ // Should have exactly 2 workflows that we just created
278+ assert .Equal (t , 2 , len (workflows1 ), "Expected exactly 2 workflows with start_time before timeBetween" )
317279
318- // Test 4: Query with empty body (should return all workflows)
319- req4 , err := http .NewRequest (tt .method , tt .endpoint , nil )
320- require .NoError (t , err , "Failed to create request 4" )
280+ // Verify timestamps are epoch milliseconds
281+ timeBetweenMillis := timeBetween .UnixMilli ()
282+ for _ , wf := range workflows1 {
283+ _ , ok := wf ["CreatedAt" ].(float64 )
284+ require .True (t , ok , "CreatedAt should be a number" )
285+ }
286+ // Verify the timestamp is around timeBetween (within 2 seconds before or after)
287+ assert .Less (t , int64 (workflows1 [0 ]["CreatedAt" ].(float64 )), timeBetweenMillis , "first workflow CreatedAt should be before timeBetween" )
288+ assert .Greater (t , int64 (workflows1 [1 ]["CreatedAt" ].(float64 )), timeBetweenMillis , "second workflow CreatedAt should be before timeBetween" )
289+
290+ // Verify both workflow IDs are present
291+ foundIDs1 := make (map [string ]bool )
292+ for _ , wf := range workflows1 {
293+ id , ok := wf ["WorkflowUUID" ].(string )
294+ require .True (t , ok , "WorkflowUUID should be a string" )
295+ foundIDs1 [id ] = true
296+ }
297+ assert .True (t , foundIDs1 [workflowID1 ], "Expected to find first workflow ID in results" )
298+ assert .True (t , foundIDs1 [workflowID2 ], "Expected to find second workflow ID in results" )
321299
322- resp4 , err := client .Do (req4 )
323- require .NoError (t , err , "Failed to make request 4" )
324- defer resp4 .Body .Close ()
300+ // Test 2: Query with start_time after timeBetween (should get only second workflow)
301+ reqBody2 := map [string ]any {
302+ "start_time" : timeBetween .Format (time .RFC3339 ),
303+ "limit" : 10 ,
304+ }
305+ fmt .Println ("Request body 2:" , reqBody2 , "timebetween" , timeBetween .UnixMilli ())
306+ req2 , err := http .NewRequest (http .MethodPost , endpoint , bytes .NewBuffer (mustMarshal (reqBody2 )))
307+ require .NoError (t , err , "Failed to create request 2" )
308+ req2 .Header .Set ("Content-Type" , "application/json" )
309+
310+ resp2 , err := client .Do (req2 )
311+ require .NoError (t , err , "Failed to make request 2" )
312+ defer resp2 .Body .Close ()
313+
314+ assert .Equal (t , http .StatusOK , resp2 .StatusCode )
315+
316+ var workflows2 []map [string ]any
317+ err = json .NewDecoder (resp2 .Body ).Decode (& workflows2 )
318+ require .NoError (t , err , "Failed to decode workflows response 2" )
319+ fmt .Println (workflows2 )
320+
321+ // Should have exactly 1 workflow (the second one)
322+ assert .Equal (t , 1 , len (workflows2 ), "Expected exactly 1 workflow with start_time after timeBetween" )
323+
324+ // Verify it's the second workflow
325+ id2 , ok := workflows2 [0 ]["WorkflowUUID" ].(string )
326+ require .True (t , ok , "WorkflowUUID should be a string" )
327+ assert .Equal (t , workflowID2 , id2 , "Expected second workflow ID in results" )
328+
329+ // Also test end_time filter
330+ reqBody3 := map [string ]any {
331+ "end_time" : timeBetween .Format (time .RFC3339 ),
332+ "limit" : 10 ,
333+ }
334+ req3 , err := http .NewRequest (http .MethodPost , endpoint , bytes .NewBuffer (mustMarshal (reqBody3 )))
335+ require .NoError (t , err , "Failed to create request 3" )
336+ req3 .Header .Set ("Content-Type" , "application/json" )
325337
326- assert .Equal (t , tt .expectedStatus , resp4 .StatusCode )
338+ resp3 , err := client .Do (req3 )
339+ require .NoError (t , err , "Failed to make request 3" )
340+ defer resp3 .Body .Close ()
327341
328- var workflows4 []map [string ]any
329- err = json .NewDecoder (resp4 .Body ).Decode (& workflows4 )
330- require .NoError (t , err , "Failed to decode workflows response 4" )
342+ assert .Equal (t , http .StatusOK , resp3 .StatusCode )
331343
332- // Should have exactly 2 workflows (both that we created)
333- assert .Equal (t , 2 , len (workflows4 ), "Expected exactly 2 workflows with empty body" )
344+ var workflows3 []map [string ]any
345+ err = json .NewDecoder (resp3 .Body ).Decode (& workflows3 )
346+ require .NoError (t , err , "Failed to decode workflows response 3" )
334347
335- // Verify both workflow IDs are present
336- foundIDs4 := make (map [string ]bool )
337- for _ , wf := range workflows4 {
338- id , ok := wf ["WorkflowUUID" ].(string )
339- require .True (t , ok , "WorkflowUUID should be a string" )
340- foundIDs4 [id ] = true
341- }
342- assert .True (t , foundIDs4 [workflowID1 ], "Expected to find first workflow ID in empty body results" )
343- assert .True (t , foundIDs4 [workflowID2 ], "Expected to find second workflow ID in empty body results" )
348+ // Should have exactly 1 workflow (the first one)
349+ assert .Equal (t , 1 , len (workflows3 ), "Expected exactly 1 workflow with end_time before timeBetween" )
344350
345- return // Skip the normal test flow
346- }
351+ // Verify it's the first workflow
352+ id3 , ok := workflows3 [0 ]["WorkflowUUID" ].(string )
353+ require .True (t , ok , "WorkflowUUID should be a string" )
354+ assert .Equal (t , workflowID1 , id3 , "Expected first workflow ID in results" )
347355
348- // Normal test flow for other tests
349- var req * http.Request
350- var err error
356+ // Test 4: Query with empty body (should return all workflows)
357+ req4 , err := http .NewRequest ( http . MethodPost , endpoint , nil )
358+ require . NoError ( t , err , "Failed to create request 4" )
351359
352- if tt .body != nil {
353- req , err = http .NewRequest (tt .method , tt .endpoint , tt .body )
354- } else {
355- req , err = http .NewRequest (tt .method , tt .endpoint , nil )
356- }
357- require .NoError (t , err , "Failed to create request" )
360+ resp4 , err := client .Do (req4 )
361+ require .NoError (t , err , "Failed to make request 4" )
362+ defer resp4 .Body .Close ()
358363
359- if tt .contentType != "" {
360- req .Header .Set ("Content-Type" , tt .contentType )
361- }
364+ assert .Equal (t , http .StatusOK , resp4 .StatusCode )
362365
363- resp , err := client . Do ( req )
364- require . NoError ( t , err , "Failed to make request" )
365- defer resp . Body . Close ( )
366+ var workflows4 [] map [ string ] any
367+ err = json . NewDecoder ( resp4 . Body ). Decode ( & workflows4 )
368+ require . NoError ( t , err , "Failed to decode workflows response 4" )
366369
367- assert .Equal (t , tt .expectedStatus , resp .StatusCode )
370+ // Should have exactly 2 workflows (both that we created)
371+ assert .Equal (t , 2 , len (workflows4 ), "Expected exactly 2 workflows with empty body" )
368372
369- if tt .validateResp != nil {
370- tt .validateResp (t , resp )
371- }
372- })
373+ // Verify both workflow IDs are present
374+ foundIDs4 := make (map [string ]bool )
375+ for _ , wf := range workflows4 {
376+ id , ok := wf ["WorkflowUUID" ].(string )
377+ require .True (t , ok , "WorkflowUUID should be a string" )
378+ foundIDs4 [id ] = true
373379 }
380+ assert .True (t , foundIDs4 [workflowID1 ], "Expected to find first workflow ID in empty body results" )
381+ assert .True (t , foundIDs4 [workflowID2 ], "Expected to find second workflow ID in empty body results" )
382+
383+ return // Skip the normal test flow
374384 })
385+
375386}
376387
377388func mustMarshal (v any ) []byte {
0 commit comments