github.com/kubeshop/testkube@v1.17.23/pkg/mapper/testsuites/openapi_kube.go (about)

     1  package testsuites
     2  
     3  import (
     4  	"time"
     5  
     6  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     7  
     8  	v1 "github.com/kubeshop/testkube-operator/api/common/v1"
     9  	testsuitesv3 "github.com/kubeshop/testkube-operator/api/testsuite/v3"
    10  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
    11  	"github.com/kubeshop/testkube/pkg/types"
    12  )
    13  
    14  // TODO move to testuites mapper
    15  func MapToTestExecutionSummary(executions []testkube.TestSuiteExecution) []testkube.TestSuiteExecutionSummary {
    16  	result := make([]testkube.TestSuiteExecutionSummary, len(executions))
    17  
    18  	for i, execution := range executions {
    19  		var executionsSummary []testkube.TestSuiteBatchStepExecutionSummary
    20  
    21  		if len(execution.StepResults) != 0 {
    22  			executionsSummary = make([]testkube.TestSuiteBatchStepExecutionSummary, len(execution.StepResults))
    23  			for j, stepResult := range execution.StepResults {
    24  				executionsSummary[j] = testkube.TestSuiteBatchStepExecutionSummary{
    25  					Execute: []testkube.TestSuiteStepExecutionSummary{mapStepResultV2ToStepExecutionSummary(stepResult)},
    26  				}
    27  			}
    28  		}
    29  
    30  		if len(execution.ExecuteStepResults) != 0 {
    31  			executionsSummary = make([]testkube.TestSuiteBatchStepExecutionSummary, len(execution.ExecuteStepResults))
    32  			for j, stepResult := range execution.ExecuteStepResults {
    33  				executionsSummary[j] = mapBatchStepResultToExecutionSummary(stepResult)
    34  			}
    35  		}
    36  
    37  		result[i] = testkube.TestSuiteExecutionSummary{
    38  			Id:            execution.Id,
    39  			Name:          execution.Name,
    40  			TestSuiteName: execution.TestSuite.Name,
    41  			Status:        execution.Status,
    42  			StartTime:     execution.StartTime,
    43  			EndTime:       execution.EndTime,
    44  			Duration:      types.FormatDuration(execution.Duration),
    45  			DurationMs:    types.FormatDurationMs(execution.Duration),
    46  			Execution:     executionsSummary,
    47  			Labels:        execution.Labels,
    48  		}
    49  	}
    50  
    51  	return result
    52  }
    53  
    54  func mapStepResultV2ToStepExecutionSummary(r testkube.TestSuiteStepExecutionResultV2) testkube.TestSuiteStepExecutionSummary {
    55  	var id, testName, name string
    56  	var status *testkube.ExecutionStatus = testkube.ExecutionStatusPassed
    57  	var stepType *testkube.TestSuiteStepType
    58  
    59  	if r.Test != nil {
    60  		testName = r.Test.Name
    61  	}
    62  
    63  	if r.Execution != nil {
    64  		id = r.Execution.Id
    65  		if r.Execution.ExecutionResult != nil {
    66  			status = r.Execution.ExecutionResult.Status
    67  		}
    68  	}
    69  
    70  	if r.Step != nil {
    71  		stepType = r.Step.Type()
    72  		name = r.Step.FullName()
    73  	}
    74  
    75  	return testkube.TestSuiteStepExecutionSummary{
    76  		Id:       id,
    77  		Name:     name,
    78  		TestName: testName,
    79  		Status:   status,
    80  		Type_:    stepType,
    81  	}
    82  }
    83  
    84  func mapBatchStepResultToExecutionSummary(r testkube.TestSuiteBatchStepExecutionResult) testkube.TestSuiteBatchStepExecutionSummary {
    85  	batch := make([]testkube.TestSuiteStepExecutionSummary, len(r.Execute))
    86  	for i := range r.Execute {
    87  		batch[i] = mapStepResultToStepExecutionSummary(r.Execute[i])
    88  	}
    89  
    90  	return testkube.TestSuiteBatchStepExecutionSummary{
    91  		Execute: batch,
    92  	}
    93  }
    94  
    95  func mapStepResultToStepExecutionSummary(r testkube.TestSuiteStepExecutionResult) testkube.TestSuiteStepExecutionSummary {
    96  	var id, testName, name string
    97  	var status *testkube.ExecutionStatus = testkube.ExecutionStatusPassed
    98  	var stepType *testkube.TestSuiteStepType
    99  
   100  	if r.Test != nil {
   101  		testName = r.Test.Name
   102  	}
   103  
   104  	if r.Execution != nil {
   105  		id = r.Execution.Id
   106  		if r.Execution.ExecutionResult != nil {
   107  			status = r.Execution.ExecutionResult.Status
   108  		}
   109  	}
   110  
   111  	if r.Step != nil {
   112  		stepType = r.Step.Type()
   113  		name = r.Step.FullName()
   114  	}
   115  
   116  	return testkube.TestSuiteStepExecutionSummary{
   117  		Id:       id,
   118  		Name:     name,
   119  		TestName: testName,
   120  		Status:   status,
   121  		Type_:    stepType,
   122  	}
   123  }
   124  
   125  func MapTestSuiteUpsertRequestToTestCRD(request testkube.TestSuiteUpsertRequest) (testsuite testsuitesv3.TestSuite, err error) {
   126  	before, err := mapTestBatchStepsToCRD(request.Before)
   127  	if err != nil {
   128  		return testsuite, err
   129  	}
   130  
   131  	steps, err := mapTestBatchStepsToCRD(request.Steps)
   132  	if err != nil {
   133  		return testsuite, err
   134  	}
   135  
   136  	after, err := mapTestBatchStepsToCRD(request.After)
   137  	if err != nil {
   138  		return testsuite, err
   139  	}
   140  
   141  	return testsuitesv3.TestSuite{
   142  		ObjectMeta: metav1.ObjectMeta{
   143  			Name:      request.Name,
   144  			Namespace: request.Namespace,
   145  			Labels:    request.Labels,
   146  		},
   147  		Spec: testsuitesv3.TestSuiteSpec{
   148  			Repeats:          int(request.Repeats),
   149  			Description:      request.Description,
   150  			Before:           before,
   151  			Steps:            steps,
   152  			After:            after,
   153  			Schedule:         request.Schedule,
   154  			ExecutionRequest: MapExecutionRequestToSpecExecutionRequest(request.ExecutionRequest),
   155  		},
   156  	}, nil
   157  }
   158  
   159  func mapTestBatchStepsToCRD(batches []testkube.TestSuiteBatchStep) (out []testsuitesv3.TestSuiteBatchStep, err error) {
   160  	for _, batch := range batches {
   161  		steps := make([]testsuitesv3.TestSuiteStepSpec, len(batch.Execute))
   162  		for i := range batch.Execute {
   163  			steps[i], err = mapTestStepToCRD(batch.Execute[i])
   164  			if err != nil {
   165  				return nil, err
   166  			}
   167  		}
   168  
   169  		var downloadArtifacts *testsuitesv3.DownloadArtifactOptions
   170  		if batch.DownloadArtifacts != nil {
   171  			downloadArtifacts = &testsuitesv3.DownloadArtifactOptions{
   172  				AllPreviousSteps:    batch.DownloadArtifacts.AllPreviousSteps,
   173  				PreviousStepNumbers: batch.DownloadArtifacts.PreviousStepNumbers,
   174  				PreviousTestNames:   batch.DownloadArtifacts.PreviousTestNames,
   175  			}
   176  		}
   177  
   178  		out = append(out, testsuitesv3.TestSuiteBatchStep{
   179  			StopOnFailure:     batch.StopOnFailure,
   180  			DownloadArtifacts: downloadArtifacts,
   181  			Execute:           steps,
   182  		})
   183  	}
   184  
   185  	return out, nil
   186  }
   187  
   188  func mapTestStepToCRD(step testkube.TestSuiteStep) (stepSpec testsuitesv3.TestSuiteStepSpec, err error) {
   189  	switch step.Type() {
   190  
   191  	case testkube.TestSuiteStepTypeDelay:
   192  		if step.Delay != "" {
   193  			duration, err := time.ParseDuration(step.Delay)
   194  			if err != nil {
   195  				return stepSpec, err
   196  			}
   197  
   198  			stepSpec.Delay = metav1.Duration{Duration: duration}
   199  		}
   200  	case testkube.TestSuiteStepTypeExecuteTest:
   201  		stepSpec.Test = step.Test
   202  		stepSpec.ExecutionRequest = MapTestStepExecutionRequestCRD(step.ExecutionRequest)
   203  	}
   204  
   205  	return stepSpec, nil
   206  }
   207  
   208  // MapExecutionRequestToSpecExecutionRequest maps ExecutionRequest OpenAPI spec to ExecutionRequest CRD spec
   209  func MapExecutionRequestToSpecExecutionRequest(executionRequest *testkube.TestSuiteExecutionRequest) *testsuitesv3.TestSuiteExecutionRequest {
   210  	if executionRequest == nil {
   211  		return nil
   212  	}
   213  
   214  	return &testsuitesv3.TestSuiteExecutionRequest{
   215  		Name:                     executionRequest.Name,
   216  		Labels:                   executionRequest.Labels,
   217  		ExecutionLabels:          executionRequest.ExecutionLabels,
   218  		Namespace:                executionRequest.Namespace,
   219  		Variables:                MapCRDVariables(executionRequest.Variables),
   220  		SecretUUID:               executionRequest.SecretUUID,
   221  		Sync:                     executionRequest.Sync,
   222  		HttpProxy:                executionRequest.HttpProxy,
   223  		HttpsProxy:               executionRequest.HttpsProxy,
   224  		Timeout:                  executionRequest.Timeout,
   225  		JobTemplate:              executionRequest.JobTemplate,
   226  		JobTemplateReference:     executionRequest.JobTemplateReference,
   227  		CronJobTemplate:          executionRequest.CronJobTemplate,
   228  		CronJobTemplateReference: executionRequest.CronJobTemplateReference,
   229  		ScraperTemplate:          executionRequest.ScraperTemplate,
   230  		ScraperTemplateReference: executionRequest.ScraperTemplateReference,
   231  		PvcTemplate:              executionRequest.PvcTemplate,
   232  		PvcTemplateReference:     executionRequest.PvcTemplateReference,
   233  	}
   234  }
   235  
   236  // MapTestSuiteUpsertRequestToTestCRD maps TestSuiteUpdateRequest OpenAPI spec to TestSuite CRD spec
   237  func MapTestSuiteUpdateRequestToTestCRD(request testkube.TestSuiteUpdateRequest,
   238  	testSuite *testsuitesv3.TestSuite) (*testsuitesv3.TestSuite, error) {
   239  	var fields = []struct {
   240  		source      *string
   241  		destination *string
   242  	}{
   243  		{
   244  			request.Name,
   245  			&testSuite.Name,
   246  		},
   247  		{
   248  			request.Namespace,
   249  			&testSuite.Namespace,
   250  		},
   251  		{
   252  			request.Description,
   253  			&testSuite.Spec.Description,
   254  		},
   255  		{
   256  			request.Schedule,
   257  			&testSuite.Spec.Schedule,
   258  		},
   259  	}
   260  
   261  	for _, field := range fields {
   262  		if field.source != nil {
   263  			*field.destination = *field.source
   264  		}
   265  	}
   266  
   267  	var err error
   268  	if request.Before != nil {
   269  		testSuite.Spec.Before, err = mapTestBatchStepsToCRD(*request.Before)
   270  		if err != nil {
   271  			return nil, err
   272  		}
   273  	}
   274  
   275  	if request.Steps != nil {
   276  		testSuite.Spec.Steps, err = mapTestBatchStepsToCRD(*request.Steps)
   277  		if err != nil {
   278  			return nil, err
   279  		}
   280  	}
   281  
   282  	if request.After != nil {
   283  		testSuite.Spec.After, err = mapTestBatchStepsToCRD(*request.After)
   284  		if err != nil {
   285  			return nil, err
   286  		}
   287  	}
   288  
   289  	if request.Labels != nil {
   290  		testSuite.Labels = *request.Labels
   291  	}
   292  
   293  	if request.Repeats != nil {
   294  		testSuite.Spec.Repeats = int(*request.Repeats)
   295  	}
   296  
   297  	if request.ExecutionRequest != nil {
   298  		testSuite.Spec.ExecutionRequest = MapExecutionUpdateRequestToSpecExecutionRequest(*request.ExecutionRequest, testSuite.Spec.ExecutionRequest)
   299  	}
   300  
   301  	return testSuite, nil
   302  }
   303  
   304  // MapExecutionUpdateRequestToSpecExecutionRequest maps ExecutionUpdateRequest OpenAPI spec to ExecutionRequest CRD spec
   305  func MapExecutionUpdateRequestToSpecExecutionRequest(executionRequest *testkube.TestSuiteExecutionUpdateRequest,
   306  	request *testsuitesv3.TestSuiteExecutionRequest) *testsuitesv3.TestSuiteExecutionRequest {
   307  	if executionRequest == nil {
   308  		return nil
   309  	}
   310  
   311  	if request == nil {
   312  		request = &testsuitesv3.TestSuiteExecutionRequest{}
   313  	}
   314  
   315  	empty := true
   316  	var fields = []struct {
   317  		source      *string
   318  		destination *string
   319  	}{
   320  		{
   321  			executionRequest.Name,
   322  			&request.Name,
   323  		},
   324  		{
   325  			executionRequest.Namespace,
   326  			&request.Namespace,
   327  		},
   328  		{
   329  			executionRequest.SecretUUID,
   330  			&request.SecretUUID,
   331  		},
   332  		{
   333  			executionRequest.HttpProxy,
   334  			&request.HttpProxy,
   335  		},
   336  		{
   337  			executionRequest.HttpsProxy,
   338  			&request.HttpsProxy,
   339  		},
   340  		{
   341  			executionRequest.JobTemplate,
   342  			&request.JobTemplate,
   343  		},
   344  		{
   345  			executionRequest.JobTemplateReference,
   346  			&request.JobTemplateReference,
   347  		},
   348  		{
   349  			executionRequest.CronJobTemplate,
   350  			&request.CronJobTemplate,
   351  		},
   352  		{
   353  			executionRequest.CronJobTemplateReference,
   354  			&request.CronJobTemplateReference,
   355  		},
   356  		{
   357  			executionRequest.ScraperTemplate,
   358  			&request.ScraperTemplate,
   359  		},
   360  		{
   361  			executionRequest.ScraperTemplateReference,
   362  			&request.ScraperTemplateReference,
   363  		},
   364  		{
   365  			executionRequest.PvcTemplate,
   366  			&request.PvcTemplate,
   367  		},
   368  		{
   369  			executionRequest.PvcTemplateReference,
   370  			&request.PvcTemplateReference,
   371  		},
   372  	}
   373  
   374  	for _, field := range fields {
   375  		if field.source != nil {
   376  			*field.destination = *field.source
   377  			empty = false
   378  		}
   379  	}
   380  
   381  	if executionRequest.Labels != nil {
   382  		request.Labels = *executionRequest.Labels
   383  		empty = false
   384  	}
   385  
   386  	if executionRequest.ExecutionLabels != nil {
   387  		request.ExecutionLabels = *executionRequest.ExecutionLabels
   388  		empty = false
   389  	}
   390  
   391  	if executionRequest.Sync != nil {
   392  		request.Sync = *executionRequest.Sync
   393  		empty = false
   394  	}
   395  
   396  	if executionRequest.Timeout != nil {
   397  		request.Timeout = *executionRequest.Timeout
   398  		empty = false
   399  	}
   400  
   401  	if executionRequest.Variables != nil {
   402  		request.Variables = MapCRDVariables(*executionRequest.Variables)
   403  		empty = false
   404  	}
   405  
   406  	if empty {
   407  		return nil
   408  	}
   409  
   410  	return request
   411  }
   412  
   413  // MapStatusToSpec maps OpenAPI spec TestSuiteStatus to CRD
   414  func MapStatusToSpec(testSuiteStatus *testkube.TestSuiteStatus) (specStatus testsuitesv3.TestSuiteStatus) {
   415  	if testSuiteStatus == nil || testSuiteStatus.LatestExecution == nil {
   416  		return specStatus
   417  	}
   418  
   419  	specStatus.LatestExecution = &testsuitesv3.TestSuiteExecutionCore{
   420  		Id:     testSuiteStatus.LatestExecution.Id,
   421  		Status: (*testsuitesv3.TestSuiteExecutionStatus)(testSuiteStatus.LatestExecution.Status),
   422  	}
   423  
   424  	specStatus.LatestExecution.StartTime.Time = testSuiteStatus.LatestExecution.StartTime
   425  	specStatus.LatestExecution.EndTime.Time = testSuiteStatus.LatestExecution.EndTime
   426  
   427  	return specStatus
   428  }
   429  
   430  // MapExecutionToTestSuiteStatus maps OpenAPI Execution to TestSuiteStatus CRD
   431  func MapExecutionToTestSuiteStatus(execution *testkube.TestSuiteExecution) (specStatus testsuitesv3.TestSuiteStatus) {
   432  	specStatus.LatestExecution = &testsuitesv3.TestSuiteExecutionCore{
   433  		Id:     execution.Id,
   434  		Status: (*testsuitesv3.TestSuiteExecutionStatus)(execution.Status),
   435  	}
   436  
   437  	specStatus.LatestExecution.StartTime.Time = execution.StartTime
   438  	specStatus.LatestExecution.EndTime.Time = execution.EndTime
   439  
   440  	return specStatus
   441  }
   442  
   443  func MapTestStepExecutionRequestCRD(request *testkube.TestSuiteStepExecutionRequest) *testsuitesv3.TestSuiteStepExecutionRequest {
   444  	if request == nil {
   445  		return nil
   446  	}
   447  
   448  	variables := map[string]testsuitesv3.Variable{}
   449  	for k, v := range request.Variables {
   450  		variables[k] = testsuitesv3.Variable{
   451  			Name:  v.Name,
   452  			Value: v.Value,
   453  			Type_: string(*v.Type_),
   454  		}
   455  	}
   456  
   457  	var runningContext *v1.RunningContext
   458  	if request.RunningContext != nil {
   459  		runningContext = &v1.RunningContext{
   460  			Type_:   v1.RunningContextType(request.RunningContext.Type_),
   461  			Context: request.RunningContext.Context,
   462  		}
   463  	}
   464  
   465  	return &testsuitesv3.TestSuiteStepExecutionRequest{
   466  		ExecutionLabels:          request.ExecutionLabels,
   467  		Variables:                variables,
   468  		Args:                     request.Args,
   469  		ArgsMode:                 testsuitesv3.ArgsModeType(request.ArgsMode),
   470  		Command:                  request.Command,
   471  		Sync:                     request.Sync,
   472  		HttpProxy:                request.HttpProxy,
   473  		HttpsProxy:               request.HttpsProxy,
   474  		NegativeTest:             request.NegativeTest,
   475  		JobTemplate:              request.JobTemplate,
   476  		JobTemplateReference:     request.JobTemplateReference,
   477  		CronJobTemplate:          request.CronJobTemplate,
   478  		CronJobTemplateReference: request.CronJobTemplateReference,
   479  		ScraperTemplate:          request.ScraperTemplate,
   480  		ScraperTemplateReference: request.ScraperTemplateReference,
   481  		PvcTemplate:              request.PvcTemplate,
   482  		PvcTemplateReference:     request.PvcTemplateReference,
   483  		RunningContext:           runningContext,
   484  	}
   485  }