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  }