11package runner
22
33import (
4+ "context"
45 "embed"
56 "encoding/json"
67 "fmt"
@@ -15,12 +16,15 @@ import (
1516type TestRunner struct {
1617 handler * Handler
1718 handlerConfig * HandlerConfig
19+ timeout time.Duration
1820}
1921
2022// NewTestRunner creates a new test runner for executing test suites against a handler binary.
2123// The handlerTimeout parameter specifies the maximum duration to wait for the handler to
2224// respond to each test case. If zero, defaults to 10 seconds.
23- func NewTestRunner (handlerPath string , handlerTimeout time.Duration ) (* TestRunner , error ) {
25+ // The timeout parameter specifies the total duration allowed for running all tests
26+ // across all test suites. If zero, defaults to 30 seconds.
27+ func NewTestRunner (handlerPath string , handlerTimeout time.Duration , timeout time.Duration ) (* TestRunner , error ) {
2428 if _ , err := os .Stat (handlerPath ); os .IsNotExist (err ) {
2529 return nil , fmt .Errorf ("handler binary not found: %s" , handlerPath )
2630 }
@@ -33,12 +37,17 @@ func NewTestRunner(handlerPath string, handlerTimeout time.Duration) (*TestRunne
3337 return nil , err
3438 }
3539
40+ if timeout == 0 {
41+ timeout = 30 * time .Second
42+ }
43+
3644 return & TestRunner {
3745 handler : handler ,
3846 handlerConfig : & HandlerConfig {
3947 Path : handlerPath ,
4048 Timeout : handlerTimeout ,
4149 },
50+ timeout : timeout ,
4251 }, nil
4352}
4453
@@ -89,15 +98,16 @@ func (tr *TestRunner) CloseHandler() {
8998 tr .handler = nil
9099}
91100
92- // RunTestSuite executes a test suite
93- func (tr * TestRunner ) RunTestSuite (suite TestSuite ) TestResult {
101+ // RunTestSuite executes a test suite. The context can be used to enforce a total
102+ // execution timeout across all test suites.
103+ func (tr * TestRunner ) RunTestSuite (ctx context.Context , suite TestSuite ) TestResult {
94104 result := TestResult {
95105 SuiteName : suite .Name ,
96106 TotalTests : len (suite .Tests ),
97107 }
98108
99109 for _ , test := range suite .Tests {
100- testResult := tr .runTest (test )
110+ testResult := tr .runTest (ctx , test )
101111 result .TestResults = append (result .TestResults , testResult )
102112 if testResult .Passed {
103113 result .PassedTests ++
@@ -111,7 +121,18 @@ func (tr *TestRunner) RunTestSuite(suite TestSuite) TestResult {
111121
112122// runTest executes a single test case by sending a request, reading the response,
113123// and validating the result matches expected output
114- func (tr * TestRunner ) runTest (test TestCase ) SingleTestResult {
124+ func (tr * TestRunner ) runTest (ctx context.Context , test TestCase ) SingleTestResult {
125+ // Check if context is already cancelled
126+ select {
127+ case <- ctx .Done ():
128+ return SingleTestResult {
129+ TestID : test .ID ,
130+ Passed : false ,
131+ Message : fmt .Sprintf ("Total execution timeout exceeded (%v)" , tr .timeout ),
132+ }
133+ default :
134+ }
135+
115136 req := Request {
116137 ID : test .ID ,
117138 Method : test .Method ,
0 commit comments