github.com/kubeshop/testkube@v1.17.23/pkg/api/v1/client/testsuite.go (about)

     1  package client
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"strconv"
     8  	"time"
     9  
    10  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    11  )
    12  
    13  // NewTestSuiteClient creates new TestSuite client
    14  func NewTestSuiteClient(
    15  	testSuiteTransport Transport[testkube.TestSuite],
    16  	testSuiteExecutionTransport Transport[testkube.TestSuiteExecution],
    17  	testSuiteWithExecutionTransport Transport[testkube.TestSuiteWithExecution],
    18  	testSuiteWithExecutionSummaryTransport Transport[testkube.TestSuiteWithExecutionSummary],
    19  	testSuiteExecutionsResultTransport Transport[testkube.TestSuiteExecutionsResult],
    20  	testSuiteArtifactTransport Transport[testkube.Artifact],
    21  ) TestSuiteClient {
    22  	return TestSuiteClient{
    23  		testSuiteTransport:                     testSuiteTransport,
    24  		testSuiteExecutionTransport:            testSuiteExecutionTransport,
    25  		testSuiteWithExecutionTransport:        testSuiteWithExecutionTransport,
    26  		testSuiteWithExecutionSummaryTransport: testSuiteWithExecutionSummaryTransport,
    27  		testSuiteExecutionsResultTransport:     testSuiteExecutionsResultTransport,
    28  		testSuiteArtifactTransport:             testSuiteArtifactTransport,
    29  	}
    30  }
    31  
    32  // TestSuiteClient is a client for test suites
    33  type TestSuiteClient struct {
    34  	testSuiteTransport                     Transport[testkube.TestSuite]
    35  	testSuiteExecutionTransport            Transport[testkube.TestSuiteExecution]
    36  	testSuiteWithExecutionTransport        Transport[testkube.TestSuiteWithExecution]
    37  	testSuiteWithExecutionSummaryTransport Transport[testkube.TestSuiteWithExecutionSummary]
    38  	testSuiteExecutionsResultTransport     Transport[testkube.TestSuiteExecutionsResult]
    39  	testSuiteArtifactTransport             Transport[testkube.Artifact]
    40  }
    41  
    42  // GetTestSuite returns single test suite by id
    43  func (c TestSuiteClient) GetTestSuite(id string) (testSuite testkube.TestSuite, err error) {
    44  	uri := c.testSuiteTransport.GetURI("/test-suites/%s", id)
    45  	return c.testSuiteTransport.Execute(http.MethodGet, uri, nil, nil)
    46  }
    47  
    48  // GetTestSuitWithExecution returns single test suite by id with execution
    49  func (c TestSuiteClient) GetTestSuiteWithExecution(id string) (test testkube.TestSuiteWithExecution, err error) {
    50  	uri := c.testSuiteWithExecutionTransport.GetURI("/test-suite-with-executions/%s", id)
    51  	return c.testSuiteWithExecutionTransport.Execute(http.MethodGet, uri, nil, nil)
    52  }
    53  
    54  // ListTestSuites list all test suites
    55  func (c TestSuiteClient) ListTestSuites(selector string) (testSuites testkube.TestSuites, err error) {
    56  	uri := c.testSuiteTransport.GetURI("/test-suites")
    57  	params := map[string]string{
    58  		"selector": selector,
    59  	}
    60  
    61  	return c.testSuiteTransport.ExecuteMultiple(http.MethodGet, uri, nil, params)
    62  }
    63  
    64  // ListTestSuiteWithExecutionSummaries list all test suite with execution summaries
    65  func (c TestSuiteClient) ListTestSuiteWithExecutionSummaries(selector string) (
    66  	testSuiteWithExecutionSummaries testkube.TestSuiteWithExecutionSummaries, err error) {
    67  	uri := c.testSuiteWithExecutionSummaryTransport.GetURI("/test-suite-with-executions")
    68  	params := map[string]string{
    69  		"selector": selector,
    70  	}
    71  
    72  	return c.testSuiteWithExecutionSummaryTransport.ExecuteMultiple(http.MethodGet, uri, nil, params)
    73  }
    74  
    75  // CreateTestSuite creates new TestSuite Custom Resource
    76  func (c TestSuiteClient) CreateTestSuite(options UpsertTestSuiteOptions) (testSuite testkube.TestSuite, err error) {
    77  	uri := c.testSuiteTransport.GetURI("/test-suites")
    78  	request := testkube.TestSuiteUpsertRequest(options)
    79  
    80  	body, err := json.Marshal(request)
    81  	if err != nil {
    82  		return testSuite, err
    83  	}
    84  
    85  	return c.testSuiteTransport.Execute(http.MethodPost, uri, body, nil)
    86  }
    87  
    88  // UpdateTestSuite updates TestSuite Custom Resource
    89  func (c TestSuiteClient) UpdateTestSuite(options UpdateTestSuiteOptions) (testSuite testkube.TestSuite, err error) {
    90  	name := ""
    91  	if options.Name != nil {
    92  		name = *options.Name
    93  	}
    94  
    95  	uri := c.testSuiteTransport.GetURI("/test-suites/%s", name)
    96  	request := testkube.TestSuiteUpdateRequest(options)
    97  
    98  	body, err := json.Marshal(request)
    99  	if err != nil {
   100  		return testSuite, err
   101  	}
   102  
   103  	return c.testSuiteTransport.Execute(http.MethodPatch, uri, body, nil)
   104  }
   105  
   106  // DeleteTestSuites deletes all test suites
   107  func (c TestSuiteClient) DeleteTestSuites(selector string) error {
   108  	uri := c.testSuiteTransport.GetURI("/test-suites")
   109  	return c.testSuiteTransport.Delete(uri, selector, true)
   110  }
   111  
   112  // DeleteTestSuite deletes single test suite by name
   113  func (c TestSuiteClient) DeleteTestSuite(name string) error {
   114  	if name == "" {
   115  		return fmt.Errorf("test suite name '%s' is not valid", name)
   116  	}
   117  
   118  	uri := c.testSuiteTransport.GetURI("/test-suites/%s", name)
   119  	return c.testSuiteTransport.Delete(uri, "", true)
   120  }
   121  
   122  // GetTestSuiteExecution returns test suite execution by excution id
   123  func (c TestSuiteClient) GetTestSuiteExecution(executionID string) (execution testkube.TestSuiteExecution, err error) {
   124  	uri := c.testSuiteExecutionTransport.GetURI("/test-suite-executions/%s", executionID)
   125  	return c.testSuiteExecutionTransport.Execute(http.MethodGet, uri, nil, nil)
   126  }
   127  
   128  // AbortTestSuiteExecution aborts a test suite execution
   129  func (c TestSuiteClient) AbortTestSuiteExecution(executionID string) error {
   130  	uri := c.testSuiteExecutionTransport.GetURI("/test-suite-executions/%s", executionID)
   131  	return c.testSuiteExecutionTransport.ExecuteMethod(http.MethodPatch, uri, "", false)
   132  }
   133  
   134  // AbortTestSuiteExecutions aborts all test suite executions
   135  func (c TestSuiteClient) AbortTestSuiteExecutions(testSuiteName string) error {
   136  	uri := c.testSuiteExecutionTransport.GetURI("/test-suites/%s/abort", testSuiteName)
   137  	return c.testSuiteExecutionTransport.ExecuteMethod(http.MethodPost, uri, "", false)
   138  }
   139  
   140  // GetTestSuiteExecutionArtifacts returns test suite execution artifacts by excution id
   141  func (c TestSuiteClient) GetTestSuiteExecutionArtifacts(executionID string) (artifacts testkube.Artifacts, err error) {
   142  	uri := c.testSuiteArtifactTransport.GetURI("/test-suite-executions/%s/artifacts", executionID)
   143  	return c.testSuiteArtifactTransport.ExecuteMultiple(http.MethodGet, uri, nil, nil)
   144  }
   145  
   146  // ExecuteTestSuite starts new external test suite execution, reads data and returns ID
   147  // Execution is started asynchronously client can check later for results
   148  func (c TestSuiteClient) ExecuteTestSuite(id, executionName string, options ExecuteTestSuiteOptions) (execution testkube.TestSuiteExecution, err error) {
   149  	uri := c.testSuiteExecutionTransport.GetURI("/test-suites/%s/executions", id)
   150  	executionRequest := testkube.TestSuiteExecutionRequest{
   151  		Name:                     executionName,
   152  		Variables:                options.ExecutionVariables,
   153  		HttpProxy:                options.HTTPProxy,
   154  		HttpsProxy:               options.HTTPSProxy,
   155  		ExecutionLabels:          options.ExecutionLabels,
   156  		ContentRequest:           options.ContentRequest,
   157  		RunningContext:           options.RunningContext,
   158  		ConcurrencyLevel:         options.ConcurrencyLevel,
   159  		JobTemplate:              options.JobTemplate,
   160  		JobTemplateReference:     options.JobTemplateReference,
   161  		ScraperTemplate:          options.ScraperTemplate,
   162  		ScraperTemplateReference: options.ScraperTemplateReference,
   163  		PvcTemplate:              options.PvcTemplate,
   164  		PvcTemplateReference:     options.PvcTemplateReference,
   165  	}
   166  
   167  	body, err := json.Marshal(executionRequest)
   168  	if err != nil {
   169  		return execution, err
   170  	}
   171  
   172  	return c.testSuiteExecutionTransport.Execute(http.MethodPost, uri, body, nil)
   173  }
   174  
   175  // ExecuteTestSuites starts new external test suite executions, reads data and returns IDs
   176  // Executions are started asynchronously client can check later for results
   177  func (c TestSuiteClient) ExecuteTestSuites(selector string, concurrencyLevel int, options ExecuteTestSuiteOptions) (executions []testkube.TestSuiteExecution, err error) {
   178  	uri := c.testSuiteExecutionTransport.GetURI("/test-suite-executions")
   179  	executionRequest := testkube.TestSuiteExecutionRequest{
   180  		Variables:                options.ExecutionVariables,
   181  		HttpProxy:                options.HTTPProxy,
   182  		HttpsProxy:               options.HTTPSProxy,
   183  		ExecutionLabels:          options.ExecutionLabels,
   184  		ContentRequest:           options.ContentRequest,
   185  		RunningContext:           options.RunningContext,
   186  		ConcurrencyLevel:         options.ConcurrencyLevel,
   187  		JobTemplate:              options.JobTemplate,
   188  		JobTemplateReference:     options.JobTemplateReference,
   189  		ScraperTemplate:          options.ScraperTemplate,
   190  		ScraperTemplateReference: options.ScraperTemplateReference,
   191  		PvcTemplate:              options.PvcTemplate,
   192  		PvcTemplateReference:     options.PvcTemplateReference,
   193  	}
   194  
   195  	body, err := json.Marshal(executionRequest)
   196  	if err != nil {
   197  		return executions, err
   198  	}
   199  
   200  	params := map[string]string{
   201  		"selector":    selector,
   202  		"concurrency": strconv.Itoa(concurrencyLevel),
   203  	}
   204  
   205  	return c.testSuiteExecutionTransport.ExecuteMultiple(http.MethodPost, uri, body, params)
   206  }
   207  
   208  // WatchTestSuiteExecution watches for changes in channels of test suite executions steps
   209  func (c TestSuiteClient) WatchTestSuiteExecution(executionID string) (respCh chan testkube.WatchTestSuiteExecutionResponse) {
   210  	respCh = make(chan testkube.WatchTestSuiteExecutionResponse)
   211  
   212  	go func() {
   213  		defer close(respCh)
   214  
   215  		execution, err := c.GetTestSuiteExecution(executionID)
   216  		if err != nil {
   217  			respCh <- testkube.WatchTestSuiteExecutionResponse{
   218  				Error: err,
   219  			}
   220  			return
   221  		}
   222  
   223  		respCh <- testkube.WatchTestSuiteExecutionResponse{
   224  			Execution: execution,
   225  		}
   226  
   227  		for range time.NewTicker(time.Second).C {
   228  			execution, err = c.GetTestSuiteExecution(executionID)
   229  			if err != nil {
   230  				respCh <- testkube.WatchTestSuiteExecutionResponse{
   231  					Error: err,
   232  				}
   233  				return
   234  			}
   235  
   236  			if execution.IsCompleted() {
   237  				respCh <- testkube.WatchTestSuiteExecutionResponse{
   238  					Execution: execution,
   239  				}
   240  				return
   241  			}
   242  
   243  			respCh <- testkube.WatchTestSuiteExecutionResponse{
   244  				Execution: execution,
   245  			}
   246  		}
   247  	}()
   248  	return respCh
   249  }
   250  
   251  // ListTestSuiteExecutions list all executions for given test suite
   252  func (c TestSuiteClient) ListTestSuiteExecutions(testID string, limit int, selector string) (executions testkube.TestSuiteExecutionsResult, err error) {
   253  	uri := c.testSuiteExecutionsResultTransport.GetURI("/test-suite-executions")
   254  	params := map[string]string{
   255  		"selector": selector,
   256  		"pageSize": fmt.Sprintf("%d", limit),
   257  		"id":       testID,
   258  	}
   259  
   260  	return c.testSuiteExecutionsResultTransport.Execute(http.MethodGet, uri, nil, params)
   261  }