11import  platform 
2+ import  queue 
23import  select 
34import  subprocess 
5+ import  threading 
46import  time 
57from  typing  import  List 
68
9+ # You might want to change the path of the executable based on your build directory 
10+ executable_windows_path  =  "build\\ Debug\\ cortex-cpp.exe" 
11+ executable_unix_path  =  "build/cortex-cpp" 
712
8- def  run (name : str , arguments : List [str ]):
13+ # Timeout 
14+ timeout  =  5   # secs 
15+ start_server_success_message  =  "Server started" 
16+ 
17+ 
18+ # Get the executable path based on the platform 
19+ def  getExecutablePath () ->  str :
920    if  platform .system () ==  "Windows" :
10-         executable   =   "build \\ cortex-cpp.exe" 
21+         return   executable_windows_path 
1122    else :
12-         executable  =  "build/cortex-cpp" 
13-     print ("Command name" , name )
14-     print ("Running command: " , [executable ] +  arguments )
15-     if  len (arguments ) ==  0 :
16-         result  =  subprocess .run (executable , capture_output = True , text = True , timeout = 5 )
17-     else :
18-         result  =  subprocess .run (
19-             [executable ] +  arguments , capture_output = True , text = True , timeout = 5 
20-         )
23+         return  executable_unix_path 
24+ 
25+ 
26+ # Execute a command 
27+ def  run (test_name : str , arguments : List [str ]):
28+     executable_path  =  getExecutablePath ()
29+     print ("Running:" , test_name )
30+     print ("Command:" , [executable_path ] +  arguments )
31+ 
32+     result  =  subprocess .run (
33+         [executable_path ] +  arguments , capture_output = True , text = True , timeout = timeout 
34+     )
2135    return  result .returncode , result .stdout , result .stderr 
2236
2337
24- def  start_server (timeout = 5 ):
38+ # Start the API server 
39+ # Wait for `Server started` message or failed 
40+ def  start_server () ->  bool :
2541    if  platform .system () ==  "Windows" :
26-         executable   =   "build \\ cortex-cpp.exe" 
42+         return   start_server_windows () 
2743    else :
28-         executable  =  "build/cortex-cpp" 
44+         return  start_server_nix ()
45+ 
46+ 
47+ def  start_server_nix () ->  bool :
48+     executable  =  getExecutablePath ()
2949    process  =  subprocess .Popen (
3050        executable , stdout = subprocess .PIPE , stderr = subprocess .PIPE , text = True 
3151    )
3252
33-     success_message  =  "Server started" 
3453    start_time  =  time .time ()
3554    while  time .time () -  start_time  <  timeout :
3655        # Use select to check if there's data to read from stdout or stderr 
@@ -39,18 +58,79 @@ def start_server(timeout=5):
3958        for  stream  in  readable :
4059            line  =  stream .readline ()
4160            if  line :
42-                 print (line .strip ())  # Print output for debugging 
43-                 if  success_message  in  line :
61+                 if  start_server_success_message  in  line :
4462                    # have to wait a bit for server to really up and accept connection 
4563                    time .sleep (0.3 )
46-                     return  True ,  process    # Success condition met 
64+                     return  True 
4765
4866        # Check if the process has ended 
4967        if  process .poll () is  not None :
50-             return  False , process   # Process ended without success message 
68+             return  False 
69+ 
70+     return  False 
71+ 
72+ 
73+ def  start_server_windows () ->  bool :
74+     executable  =  getExecutablePath ()
75+     process  =  subprocess .Popen (
76+         executable ,
77+         stdout = subprocess .PIPE ,
78+         stderr = subprocess .PIPE ,
79+         text = True ,
80+         bufsize = 1 ,
81+         universal_newlines = True ,
82+     )
83+ 
84+     q_out  =  queue .Queue ()
85+     q_err  =  queue .Queue ()
86+ 
87+     def  enqueue_output (out , queue ):
88+         for  line  in  iter (out .readline , b"" ):
89+             queue .put (line )
90+         out .close ()
91+ 
92+     # Start threads to read stdout and stderr 
93+     t_out  =  threading .Thread (target = enqueue_output , args = (process .stdout , q_out ))
94+     t_err  =  threading .Thread (target = enqueue_output , args = (process .stderr , q_err ))
95+     t_out .daemon  =  True 
96+     t_err .daemon  =  True 
97+     t_out .start ()
98+     t_err .start ()
99+ 
100+     # only wait for defined timeout 
101+     start_time  =  time .time ()
102+     while  time .time () -  start_time  <  timeout :
103+         # Check stdout 
104+         try :
105+             line  =  q_out .get_nowait ()
106+         except  queue .Empty :
107+             pass 
108+         else :
109+             print (f"STDOUT: { line .strip ()}  )
110+             if  start_server_success_message  in  line :
111+                 return  True 
112+ 
113+         # Check stderr 
114+         try :
115+             line  =  q_err .get_nowait ()
116+         except  queue .Empty :
117+             pass 
118+         else :
119+             print (f"STDERR: { line .strip ()}  )
120+             if  start_server_success_message  in  line :
121+                 # found the message. let's wait for some time for the server successfully started 
122+                 time .sleep (0.3 )
123+                 return  True , process 
124+ 
125+         # Check if the process has ended 
126+         if  process .poll () is  not None :
127+             return  False 
128+ 
129+         time .sleep (0.1 )
51130
52-     return  False ,  process    # Timeout reached 
131+     return  False 
53132
54133
134+ # Stop the API server 
55135def  stop_server ():
56136    run ("Stop server" , ["stop" ])
0 commit comments