github.com/kubeshop/testkube@v1.17.23/pkg/triggers/scraper.go (about) 1 package triggers 2 3 import ( 4 "context" 5 "time" 6 7 "go.mongodb.org/mongo-driver/mongo" 8 9 "github.com/kubeshop/testkube/pkg/api/v1/testkube" 10 "github.com/kubeshop/testkube/pkg/event/bus" 11 ) 12 13 func (s *Service) runExecutionScraper(ctx context.Context) { 14 ticker := time.NewTicker(s.scraperInterval) 15 s.logger.Debugf("trigger service: starting execution scraper") 16 17 for { 18 select { 19 case <-ctx.Done(): 20 s.logger.Infof("trigger service: stopping scraper component") 21 return 22 case <-ticker.C: 23 s.logger.Debugf("trigger service: execution scraper component: starting new ticker iteration") 24 for triggerName, status := range s.triggerStatus { 25 if status.hasActiveTests() { 26 s.checkForRunningTestExecutions(ctx, status) 27 s.checkForRunningTestSuiteExecutions(ctx, status) 28 if !status.hasActiveTests() { 29 s.logger.Debugf("marking status as finished for testtrigger %s", triggerName) 30 status.done() 31 } 32 } 33 } 34 } 35 } 36 } 37 38 func (s *Service) checkForRunningTestExecutions(ctx context.Context, status *triggerStatus) { 39 testExecutionIDs := status.getExecutionIDs() 40 41 for _, id := range testExecutionIDs { 42 execution, err := s.resultRepository.Get(ctx, id) 43 if err == mongo.ErrNoDocuments { 44 s.logger.Warnf("trigger service: execution scraper component: no test execution found for id %s", id) 45 status.removeExecutionID(id) 46 continue 47 } else if err != nil { 48 s.logger.Errorf("trigger service: execution scraper component: error fetching test execution result: %v", err) 49 continue 50 } 51 if !execution.IsRunning() && !execution.IsQueued() { 52 s.logger.Debugf("trigger service: execution scraper component: test execution %s is finished", id) 53 status.removeExecutionID(id) 54 } 55 } 56 } 57 58 func (s *Service) checkForRunningTestSuiteExecutions(ctx context.Context, status *triggerStatus) { 59 testSuiteExecutionIDs := status.getTestSuiteExecutionIDs() 60 61 for _, id := range testSuiteExecutionIDs { 62 execution, err := s.testResultRepository.Get(ctx, id) 63 if err == mongo.ErrNoDocuments { 64 s.logger.Warnf("trigger service: execution scraper component: no testsuite execution found for id %s", id) 65 status.removeTestSuiteExecutionID(id) 66 continue 67 } else if err != nil { 68 s.logger.Errorf("trigger service: execution scraper component: error fetching testsuite execution result: %v", err) 69 continue 70 } 71 if !execution.IsRunning() && !execution.IsQueued() { 72 s.logger.Debugf("trigger service: execution scraper component: testsuite execution %s is finished", id) 73 status.removeTestSuiteExecutionID(id) 74 } 75 } 76 } 77 78 func (s *Service) abortExecutions(ctx context.Context, testTriggerName string, status *triggerStatus) { 79 s.logger.Debugf("trigger service: abort executions") 80 s.abortRunningTestExecutions(ctx, status) 81 s.abortRunningTestSuiteExecutions(ctx, status) 82 if !status.hasActiveTests() { 83 s.logger.Debugf("marking status as finished for testtrigger %s", testTriggerName) 84 status.done() 85 } 86 } 87 88 func (s *Service) abortRunningTestExecutions(ctx context.Context, status *triggerStatus) { 89 testExecutionIDs := status.getExecutionIDs() 90 91 for _, id := range testExecutionIDs { 92 execution, err := s.resultRepository.Get(ctx, id) 93 if err == mongo.ErrNoDocuments { 94 s.logger.Warnf("trigger service: execution scraper component: no test execution found for id %s", id) 95 status.removeExecutionID(id) 96 continue 97 } else if err != nil { 98 s.logger.Errorf("trigger service: execution scraper component: error fetching test execution result: %v", err) 99 continue 100 } 101 if execution.IsRunning() || execution.IsQueued() { 102 res, err := s.testExecutor.Abort(ctx, &execution) 103 if err != nil { 104 s.logger.Errorf("trigger service: execution scraper component: error aborting test execution: %v", err) 105 continue 106 } 107 s.metrics.IncAbortTest(execution.TestType, res.IsFailed()) 108 109 s.logger.Debugf("trigger service: execution scraper component: test execution %s is aborted", id) 110 status.removeExecutionID(id) 111 } 112 } 113 } 114 115 func (s *Service) abortRunningTestSuiteExecutions(ctx context.Context, status *triggerStatus) { 116 testSuiteExecutionIDs := status.getTestSuiteExecutionIDs() 117 118 for _, id := range testSuiteExecutionIDs { 119 execution, err := s.testResultRepository.Get(ctx, id) 120 if err == mongo.ErrNoDocuments { 121 s.logger.Warnf("trigger service: execution scraper component: no testsuite execution found for id %s", id) 122 status.removeTestSuiteExecutionID(id) 123 continue 124 } else if err != nil { 125 s.logger.Errorf("trigger service: execution scraper component: error fetching testsuite execution result: %v", err) 126 continue 127 } 128 if execution.IsRunning() || execution.IsQueued() { 129 err := s.eventsBus.PublishTopic(bus.InternalPublishTopic, testkube.NewEventEndTestSuiteAborted(&execution)) 130 if err != nil { 131 s.logger.Errorf("trigger service: execution scraper component: error aborting test suite execution: %v", err) 132 continue 133 } 134 135 s.logger.Debugf("trigger service: execution scraper component: testsuite execution %s is aborted", id) 136 status.removeTestSuiteExecutionID(id) 137 } 138 } 139 }