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

     1  package testsuiteexecutions
     2  
     3  import (
     4  	corev1 "k8s.io/api/core/v1"
     5  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     6  
     7  	testsuiteexecutionv1 "github.com/kubeshop/testkube-operator/api/testsuiteexecution/v1"
     8  	"github.com/kubeshop/testkube/pkg/api/v1/testkube"
     9  	mappertcl "github.com/kubeshop/testkube/pkg/tcl/mappertcl/testsuiteexecutions"
    10  )
    11  
    12  // MapCRDVariables maps variables between API and operator CRDs
    13  func MapCRDVariables(in map[string]testkube.Variable) map[string]testsuiteexecutionv1.Variable {
    14  	out := map[string]testsuiteexecutionv1.Variable{}
    15  	for k, v := range in {
    16  		variable := testsuiteexecutionv1.Variable{
    17  			Name:  v.Name,
    18  			Type_: string(*v.Type_),
    19  			Value: v.Value,
    20  		}
    21  
    22  		if v.SecretRef != nil {
    23  			variable.ValueFrom = corev1.EnvVarSource{
    24  				SecretKeyRef: &corev1.SecretKeySelector{
    25  					LocalObjectReference: corev1.LocalObjectReference{
    26  						Name: v.SecretRef.Name,
    27  					},
    28  					Key: v.SecretRef.Key,
    29  				},
    30  			}
    31  		}
    32  
    33  		if v.ConfigMapRef != nil {
    34  			variable.ValueFrom = corev1.EnvVarSource{
    35  				ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
    36  					LocalObjectReference: corev1.LocalObjectReference{
    37  						Name: v.ConfigMapRef.Name,
    38  					},
    39  					Key: v.ConfigMapRef.Key,
    40  				},
    41  			}
    42  		}
    43  
    44  		out[k] = variable
    45  	}
    46  	return out
    47  }
    48  
    49  // MapContentToSpecContent maps TestContent OpenAPI spec to TestContent CRD spec
    50  func MapContentToSpecContent(content *testkube.TestContent) (specContent *testsuiteexecutionv1.TestContent) {
    51  	if content == nil {
    52  		return
    53  	}
    54  
    55  	var repository *testsuiteexecutionv1.Repository
    56  	if content.Repository != nil {
    57  		repository = &testsuiteexecutionv1.Repository{
    58  			Type_:             content.Repository.Type_,
    59  			Uri:               content.Repository.Uri,
    60  			Branch:            content.Repository.Branch,
    61  			Commit:            content.Repository.Commit,
    62  			Path:              content.Repository.Path,
    63  			WorkingDir:        content.Repository.WorkingDir,
    64  			CertificateSecret: content.Repository.CertificateSecret,
    65  			AuthType:          testsuiteexecutionv1.GitAuthType(content.Repository.AuthType),
    66  		}
    67  
    68  		if content.Repository.UsernameSecret != nil {
    69  			repository.UsernameSecret = &testsuiteexecutionv1.SecretRef{
    70  				Name: content.Repository.UsernameSecret.Name,
    71  				Key:  content.Repository.UsernameSecret.Key,
    72  			}
    73  		}
    74  
    75  		if content.Repository.TokenSecret != nil {
    76  			repository.TokenSecret = &testsuiteexecutionv1.SecretRef{
    77  				Name: content.Repository.TokenSecret.Name,
    78  				Key:  content.Repository.TokenSecret.Key,
    79  			}
    80  		}
    81  	}
    82  
    83  	return &testsuiteexecutionv1.TestContent{
    84  		Repository: repository,
    85  		Data:       content.Data,
    86  		Uri:        content.Uri,
    87  		Type_:      testsuiteexecutionv1.TestContentType(content.Type_),
    88  	}
    89  }
    90  
    91  // MapExecutionResultToCRD maps OpenAPI spec ExecutionResult to CRD ExecutionResult
    92  func MapExecutionResultToCRD(result *testkube.ExecutionResult) *testsuiteexecutionv1.ExecutionResult {
    93  	if result == nil {
    94  		return nil
    95  	}
    96  
    97  	var status *testsuiteexecutionv1.ExecutionStatus
    98  	if result.Status != nil {
    99  		value := testsuiteexecutionv1.ExecutionStatus(*result.Status)
   100  		status = &value
   101  	}
   102  
   103  	var steps []testsuiteexecutionv1.ExecutionStepResult
   104  	for _, step := range result.Steps {
   105  		var asserstions []testsuiteexecutionv1.AssertionResult
   106  		for _, asserstion := range step.AssertionResults {
   107  			asserstions = append(asserstions, testsuiteexecutionv1.AssertionResult{
   108  				Name:         asserstion.Name,
   109  				Status:       asserstion.Status,
   110  				ErrorMessage: asserstion.ErrorMessage,
   111  			})
   112  		}
   113  
   114  		steps = append(steps, testsuiteexecutionv1.ExecutionStepResult{
   115  			Name:             step.Name,
   116  			Duration:         step.Duration,
   117  			Status:           step.Status,
   118  			AssertionResults: asserstions,
   119  		})
   120  	}
   121  
   122  	var reports *testsuiteexecutionv1.ExecutionResultReports
   123  	if result.Reports != nil {
   124  		reports = &testsuiteexecutionv1.ExecutionResultReports{
   125  			Junit: result.Reports.Junit,
   126  		}
   127  	}
   128  
   129  	return &testsuiteexecutionv1.ExecutionResult{
   130  		Status:       status,
   131  		ErrorMessage: result.ErrorMessage,
   132  		Steps:        steps,
   133  		Reports:      reports,
   134  	}
   135  }
   136  
   137  // MapExecutionCRD maps OpenAPI spec Execution to CRD
   138  func MapExecutionCRD(request *testkube.Execution) *testsuiteexecutionv1.Execution {
   139  	if request == nil {
   140  		return nil
   141  	}
   142  
   143  	var artifactRequest *testsuiteexecutionv1.ArtifactRequest
   144  	if request.ArtifactRequest != nil {
   145  		artifactRequest = &testsuiteexecutionv1.ArtifactRequest{
   146  			StorageClassName:           request.ArtifactRequest.StorageClassName,
   147  			VolumeMountPath:            request.ArtifactRequest.VolumeMountPath,
   148  			Dirs:                       request.ArtifactRequest.Dirs,
   149  			Masks:                      request.ArtifactRequest.Masks,
   150  			StorageBucket:              request.ArtifactRequest.StorageBucket,
   151  			OmitFolderPerExecution:     request.ArtifactRequest.OmitFolderPerExecution,
   152  			SharedBetweenPods:          request.ArtifactRequest.SharedBetweenPods,
   153  			UseDefaultStorageClassName: request.ArtifactRequest.UseDefaultStorageClassName,
   154  		}
   155  	}
   156  
   157  	var runningContext *testsuiteexecutionv1.RunningContext
   158  	if request.RunningContext != nil {
   159  		runningContext = &testsuiteexecutionv1.RunningContext{
   160  			Type_:   testsuiteexecutionv1.RunningContextType(request.RunningContext.Type_),
   161  			Context: request.RunningContext.Context,
   162  		}
   163  	}
   164  
   165  	var podRequest *testsuiteexecutionv1.PodRequest
   166  	if request.SlavePodRequest != nil {
   167  		podRequest = &testsuiteexecutionv1.PodRequest{}
   168  		if request.SlavePodRequest.Resources != nil {
   169  			podRequest.Resources = &testsuiteexecutionv1.PodResourcesRequest{}
   170  			if request.SlavePodRequest.Resources.Requests != nil {
   171  				podRequest.Resources.Requests = &testsuiteexecutionv1.ResourceRequest{
   172  					Cpu:    request.SlavePodRequest.Resources.Requests.Cpu,
   173  					Memory: request.SlavePodRequest.Resources.Requests.Memory,
   174  				}
   175  			}
   176  
   177  			if request.SlavePodRequest.Resources.Limits != nil {
   178  				podRequest.Resources.Limits = &testsuiteexecutionv1.ResourceRequest{
   179  					Cpu:    request.SlavePodRequest.Resources.Limits.Cpu,
   180  					Memory: request.SlavePodRequest.Resources.Limits.Memory,
   181  				}
   182  			}
   183  		}
   184  
   185  		podRequest.PodTemplate = request.SlavePodRequest.PodTemplate
   186  		podRequest.PodTemplateReference = request.SlavePodRequest.PodTemplateReference
   187  	}
   188  
   189  	result := &testsuiteexecutionv1.Execution{
   190  		Id:                                 request.Id,
   191  		TestName:                           request.TestName,
   192  		TestSuiteName:                      request.TestSuiteName,
   193  		TestNamespace:                      request.TestNamespace,
   194  		TestType:                           request.TestType,
   195  		Name:                               request.Name,
   196  		Number:                             request.Number,
   197  		Envs:                               request.Envs,
   198  		Command:                            request.Command,
   199  		Args:                               request.Args,
   200  		ArgsMode:                           testsuiteexecutionv1.ArgsModeType(request.ArgsMode),
   201  		Variables:                          MapCRDVariables(request.Variables),
   202  		IsVariablesFileUploaded:            request.IsVariablesFileUploaded,
   203  		VariablesFile:                      request.VariablesFile,
   204  		TestSecretUUID:                     request.TestSecretUUID,
   205  		Content:                            MapContentToSpecContent(request.Content),
   206  		Duration:                           request.Duration,
   207  		DurationMs:                         request.DurationMs,
   208  		ExecutionResult:                    MapExecutionResultToCRD(request.ExecutionResult),
   209  		Labels:                             request.Labels,
   210  		Uploads:                            request.Uploads,
   211  		BucketName:                         request.BucketName,
   212  		ArtifactRequest:                    artifactRequest,
   213  		PreRunScript:                       request.PreRunScript,
   214  		PostRunScript:                      request.PostRunScript,
   215  		ExecutePostRunScriptBeforeScraping: request.ExecutePostRunScriptBeforeScraping,
   216  		SourceScripts:                      request.SourceScripts,
   217  		RunningContext:                     runningContext,
   218  		ContainerShell:                     request.ContainerShell,
   219  		SlavePodRequest:                    podRequest,
   220  	}
   221  
   222  	result.StartTime.Time = request.StartTime
   223  	result.EndTime.Time = request.EndTime
   224  
   225  	// Pro edition only (tcl protected code)
   226  	return mappertcl.MapExecutionCRD(request, result)
   227  }
   228  
   229  func MapTestSuiteStepV2ToCRD(request *testkube.TestSuiteStepV2) *testsuiteexecutionv1.TestSuiteStepV2 {
   230  	if request == nil {
   231  		return nil
   232  	}
   233  
   234  	var execute *testsuiteexecutionv1.TestSuiteStepExecuteTestV2
   235  	var delay *testsuiteexecutionv1.TestSuiteStepDelayV2
   236  
   237  	if request.Execute != nil {
   238  		execute = &testsuiteexecutionv1.TestSuiteStepExecuteTestV2{
   239  			Name:      request.Execute.Name,
   240  			Namespace: request.Execute.Namespace,
   241  		}
   242  	}
   243  
   244  	if request.Delay != nil {
   245  		delay = &testsuiteexecutionv1.TestSuiteStepDelayV2{
   246  			Duration: request.Delay.Duration,
   247  		}
   248  	}
   249  
   250  	return &testsuiteexecutionv1.TestSuiteStepV2{
   251  		StopTestOnFailure: request.StopTestOnFailure,
   252  		Execute:           execute,
   253  		Delay:             delay,
   254  	}
   255  }
   256  
   257  func MapTestSuiteBatchStepToCRD(request *testkube.TestSuiteBatchStep) *testsuiteexecutionv1.TestSuiteBatchStep {
   258  	if request == nil {
   259  		return nil
   260  	}
   261  
   262  	var steps []testsuiteexecutionv1.TestSuiteStep
   263  	for _, step := range request.Execute {
   264  		steps = append(steps, testsuiteexecutionv1.TestSuiteStep{
   265  			Test:  step.Test,
   266  			Delay: step.Delay,
   267  		})
   268  	}
   269  
   270  	return &testsuiteexecutionv1.TestSuiteBatchStep{
   271  		StopOnFailure: request.StopOnFailure,
   272  		Execute:       steps,
   273  	}
   274  }
   275  
   276  // MapAPIToCRD maps OpenAPI spec Execution to CRD TestSuiteExecutionStatus
   277  func MapAPIToCRD(request *testkube.TestSuiteExecution, generation int64) testsuiteexecutionv1.TestSuiteExecutionStatus {
   278  	var testSuite *testsuiteexecutionv1.ObjectRef
   279  	if request.TestSuite != nil {
   280  		testSuite = &testsuiteexecutionv1.ObjectRef{
   281  			Name:      request.TestSuite.Name,
   282  			Namespace: request.TestSuite.Namespace,
   283  		}
   284  	}
   285  
   286  	var status *testsuiteexecutionv1.SuiteExecutionStatus
   287  	if request.Status != nil {
   288  		value := testsuiteexecutionv1.SuiteExecutionStatus(*request.Status)
   289  		status = &value
   290  	}
   291  
   292  	var runningContext *testsuiteexecutionv1.RunningContext
   293  	if request.RunningContext != nil {
   294  		runningContext = &testsuiteexecutionv1.RunningContext{
   295  			Type_:   testsuiteexecutionv1.RunningContextType(request.RunningContext.Type_),
   296  			Context: request.RunningContext.Context,
   297  		}
   298  	}
   299  
   300  	var stepResults []testsuiteexecutionv1.TestSuiteStepExecutionResultV2
   301  	for _, stepResult := range request.StepResults {
   302  		var test *testsuiteexecutionv1.ObjectRef
   303  		if stepResult.Test != nil {
   304  			test = &testsuiteexecutionv1.ObjectRef{
   305  				Name:      stepResult.Test.Name,
   306  				Namespace: stepResult.Test.Namespace,
   307  			}
   308  		}
   309  
   310  		stepResults = append(stepResults, testsuiteexecutionv1.TestSuiteStepExecutionResultV2{
   311  			Step:      MapTestSuiteStepV2ToCRD(stepResult.Step),
   312  			Test:      test,
   313  			Execution: MapExecutionCRD(stepResult.Execution),
   314  		})
   315  	}
   316  
   317  	var executeStepResults []testsuiteexecutionv1.TestSuiteBatchStepExecutionResult
   318  	for _, stepResult := range request.ExecuteStepResults {
   319  		var steps []testsuiteexecutionv1.TestSuiteStepExecutionResult
   320  		for _, step := range stepResult.Execute {
   321  			var testSuiteStep *testsuiteexecutionv1.TestSuiteStep
   322  			if step.Step != nil {
   323  				testSuiteStep = &testsuiteexecutionv1.TestSuiteStep{
   324  					Test:  step.Step.Test,
   325  					Delay: step.Step.Delay,
   326  				}
   327  			}
   328  
   329  			var test *testsuiteexecutionv1.ObjectRef
   330  			if step.Test != nil {
   331  				test = &testsuiteexecutionv1.ObjectRef{
   332  					Name:      step.Test.Name,
   333  					Namespace: step.Test.Namespace,
   334  				}
   335  			}
   336  
   337  			steps = append(steps, testsuiteexecutionv1.TestSuiteStepExecutionResult{
   338  				Step:      testSuiteStep,
   339  				Test:      test,
   340  				Execution: MapExecutionCRD(step.Execution),
   341  			})
   342  		}
   343  
   344  		executeStepResults = append(executeStepResults, testsuiteexecutionv1.TestSuiteBatchStepExecutionResult{
   345  			Step:      MapTestSuiteBatchStepToCRD(stepResult.Step),
   346  			Execute:   steps,
   347  			StartTime: metav1.Time{Time: stepResult.StartTime},
   348  			EndTime:   metav1.Time{Time: stepResult.EndTime},
   349  			Duration:  stepResult.Duration,
   350  		})
   351  	}
   352  
   353  	result := testsuiteexecutionv1.TestSuiteExecutionStatus{
   354  		Generation: generation,
   355  		LatestExecution: &testsuiteexecutionv1.SuiteExecution{
   356  			Id:                 request.Id,
   357  			Name:               request.Name,
   358  			TestSuite:          testSuite,
   359  			Status:             status,
   360  			Envs:               request.Envs,
   361  			Variables:          MapCRDVariables(request.Variables),
   362  			SecretUUID:         request.SecretUUID,
   363  			Duration:           request.Duration,
   364  			DurationMs:         request.DurationMs,
   365  			StepResults:        stepResults,
   366  			ExecuteStepResults: executeStepResults,
   367  			Labels:             request.Labels,
   368  			RunningContext:     runningContext,
   369  		},
   370  	}
   371  
   372  	result.LatestExecution.StartTime.Time = request.StartTime
   373  	result.LatestExecution.EndTime.Time = request.EndTime
   374  	return result
   375  }