11package main
22
33import (
4- "bytes"
54 "context"
65 "database/sql"
76 _ "embed"
@@ -14,6 +13,7 @@ import (
1413 "os/exec"
1514 "path/filepath"
1615 "runtime"
16+ "syscall"
1717 "testing"
1818 "time"
1919
@@ -96,21 +96,28 @@ func TestCLIWorkflow(t *testing.T) {
9696 testProjectInitialization (t , cliPath )
9797 })
9898
99- t .Run ("ApplicationLifecycle" , func (t * testing.T ) {
100- cmd := testApplicationLifecycle (t , cliPath )
101- t .Cleanup (func () {
102- if cmd .Process != nil {
103- /*
104- fmt.Println(cmd.Stderr)
105- fmt.Println(cmd.Stdout)
106- */
107- err := cmd .Process .Signal (os .Interrupt )
108- require .NoError (t , err , "Failed to send interrupt signal to application process" )
109- time .Sleep (1 * time .Second ) // Give it a moment to shut down gracefully
110- err = cmd .Process .Kill ()
111- require .NoError (t , err , "Failed to kill application process" )
112- }
113- })
99+ // Start a test application using dbos start
100+ cmd := exec .CommandContext (context .Background (), cliPath , "start" )
101+ cmd .Env = append (os .Environ (), "DBOS_SYSTEM_DATABASE_URL=" + getDatabaseURL ())
102+ err = cmd .Start ()
103+ require .NoError (t , err , "Failed to start application" )
104+ // Wait for server to be ready
105+ require .Eventually (t , func () bool {
106+ resp , err := http .Get ("http://localhost:" + testServerPort )
107+ if err != nil {
108+ return false
109+ }
110+ resp .Body .Close ()
111+ return resp .StatusCode == http .StatusOK
112+ }, 10 * time .Second , 500 * time .Millisecond , "Server should start within 10 seconds" )
113+
114+ t .Cleanup (func () {
115+ fmt .Printf ("Cleaning up application process %d\n " , cmd .Process .Pid )
116+ // fmt.Println(cmd.Stderr)
117+ // fmt.Println(cmd.Stdout)
118+ err := syscall .Kill (cmd .Process .Pid , syscall .SIGTERM )
119+ require .NoError (t , err , "Failed to send interrupt signal to application process" )
120+ _ = cmd .Wait ()
114121 })
115122
116123 t .Run ("WorkflowCommands" , func (t * testing.T ) {
@@ -124,7 +131,6 @@ func TestCLIWorkflow(t *testing.T) {
124131
125132// testProjectInitialization verifies project initialization
126133func testProjectInitialization (t * testing.T , cliPath string ) {
127-
128134 // Initialize project
129135 cmd := exec .Command (cliPath , "init" , testProjectName )
130136 output , err := cmd .CombinedOutput ()
@@ -168,71 +174,6 @@ func testProjectInitialization(t *testing.T, cliPath string) {
168174 require .NoError (t , err , "go mod tidy failed: %s" , string (modOutput ))
169175}
170176
171- // testApplicationLifecycle starts the application and triggers workflows
172- func testApplicationLifecycle (t * testing.T , cliPath string ) * exec.Cmd {
173- // Should already be in project directory from previous test
174-
175- // Start the application in background
176- ctx , cancel := context .WithTimeout (context .Background (), testTimeout )
177- defer cancel ()
178-
179- cmd := exec .CommandContext (ctx , cliPath , "start" )
180- cmd .Env = append (os .Environ (), "DBOS_SYSTEM_DATABASE_URL=" + getDatabaseURL ())
181-
182- // Capture output for debugging
183- var stdout , stderr bytes.Buffer
184- cmd .Stdout = & stdout
185- cmd .Stderr = & stderr
186-
187- err := cmd .Start ()
188- require .NoError (t , err , "Failed to start application" )
189-
190- // Wait for server to be ready
191- require .Eventually (t , func () bool {
192- resp , err := http .Get ("http://localhost:" + testServerPort )
193- if err != nil {
194- return false
195- }
196- resp .Body .Close ()
197- return resp .StatusCode == http .StatusOK
198- }, 10 * time .Second , 500 * time .Millisecond , "Server should start within 10 seconds" )
199-
200- // Trigger workflows via HTTP endpoints
201- t .Run ("TriggerExampleWorkflow" , func (t * testing.T ) {
202- resp , err := http .Get ("http://localhost:" + testServerPort + "/workflow" )
203- require .NoError (t , err , "Failed to trigger workflow" )
204- defer resp .Body .Close ()
205-
206- body , err := io .ReadAll (resp .Body )
207- require .NoError (t , err )
208-
209- assert .Equal (t , http .StatusOK , resp .StatusCode , "Workflow endpoint should return 200" )
210- assert .Contains (t , string (body ), "Workflow result" , "Should contain workflow result" )
211- })
212-
213- t .Run ("TriggerQueueWorkflow" , func (t * testing.T ) {
214- resp , err := http .Get ("http://localhost:" + testServerPort + "/queue" )
215- require .NoError (t , err , "Failed to trigger queue workflow" )
216- defer resp .Body .Close ()
217-
218- body , err := io .ReadAll (resp .Body )
219- require .NoError (t , err )
220-
221- assert .Equal (t , http .StatusOK , resp .StatusCode , "Queue endpoint should return 200" )
222-
223- // Parse JSON response to get workflow ID
224- var response map [string ]string
225- err = json .Unmarshal (body , & response )
226- require .NoError (t , err , "Should be valid JSON response" )
227-
228- workflowID , exists := response ["workflow_id" ]
229- assert .True (t , exists , "Response should contain workflow_id" )
230- assert .NotEmpty (t , workflowID , "Workflow ID should not be empty" )
231- })
232-
233- return cmd
234- }
235-
236177// testWorkflowCommands comprehensively tests all workflow CLI commands
237178func testWorkflowCommands (t * testing.T , cliPath string ) {
238179
@@ -260,8 +201,29 @@ func testWorkflowCommands(t *testing.T, cliPath string) {
260201// testListWorkflows tests various workflow listing scenarios
261202func testListWorkflows (t * testing.T , cliPath string ) {
262203 // Create some test workflows first to ensure we have data to filter
263- // The previous test functions have already created workflows that we can query
204+ resp , err := http .Get ("http://localhost:" + testServerPort + "/workflow" )
205+ require .NoError (t , err , "Failed to trigger workflow" )
206+ defer resp .Body .Close ()
207+ body , err := io .ReadAll (resp .Body )
208+ require .NoError (t , err )
209+ assert .Equal (t , http .StatusOK , resp .StatusCode , "Workflow endpoint should return 200" )
210+ assert .Contains (t , string (body ), "Workflow result" , "Should contain workflow result" )
211+
212+ resp , err = http .Get ("http://localhost:" + testServerPort + "/queue" )
213+ require .NoError (t , err , "Failed to trigger queue workflow" )
214+ defer resp .Body .Close ()
215+ body , err = io .ReadAll (resp .Body )
216+ require .NoError (t , err )
217+ assert .Equal (t , http .StatusOK , resp .StatusCode , "Queue endpoint should return 200" )
218+
219+ // Parse JSON response to get workflow ID
220+ var response map [string ]string
221+ err = json .Unmarshal (body , & response )
222+ require .NoError (t , err , "Should be valid JSON response" )
264223
224+ workflowID , exists := response ["workflow_id" ]
225+ assert .True (t , exists , "Response should contain workflow_id" )
226+ assert .NotEmpty (t , workflowID , "Workflow ID should not be empty" )
265227 // Get the current time for time-based filtering
266228 currentTime := time .Now ()
267229
@@ -728,14 +690,14 @@ func buildCLI(t *testing.T) string {
728690 // Build output path in the cmd directory
729691 cliPath := filepath .Join (cmdDir , "dbos-cli-test" )
730692
731- // Check if already built
732- if _ , err := os .Stat (cliPath ); os . IsNotExist ( err ) {
733- // Build the CLI from the cmd directory
734- buildCmd := exec . Command ( "go" , "build" , "-o" , "dbos-cli-test" , "." )
735- buildCmd . Dir = cmdDir
736- buildOutput , buildErr := buildCmd . CombinedOutput ()
737- require . NoError ( t , buildErr , "Failed to build CLI: %s" , string ( buildOutput ) )
738- }
693+ // Delete any existing binary before building
694+ os .Remove (cliPath )
695+
696+ // Build the CLI from the cmd directory
697+ buildCmd := exec . Command ( "go" , "build" , "-o" , "dbos-cli-test" , "." )
698+ buildCmd . Dir = cmdDir
699+ buildOutput , buildErr := buildCmd . CombinedOutput ( )
700+ require . NoError ( t , buildErr , "Failed to build CLI: %s" , string ( buildOutput ))
739701
740702 // Return absolute path
741703 absPath , err := filepath .Abs (cliPath )
0 commit comments