Skip to content

Commit

Permalink
feat: [TKC-1579] test suite step license change (#5108) (#5110)
Browse files Browse the repository at this point in the history
* feat: test suite step license change

* fix: go mod tidy
  • Loading branch information
vLia authored Mar 6, 2024
1 parent e7f03c0 commit d265697
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 246 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/joshdk/go-junit v1.0.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/kubepug/kubepug v1.7.1
github.com/kubeshop/testkube-operator v1.16.30
github.com/kubeshop/testkube-operator v1.16.31
github.com/minio/minio-go/v7 v7.0.47
github.com/montanaflynn/stats v0.6.6
github.com/moogar0880/problems v0.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubepug/kubepug v1.7.1 h1:LKhfSxS8Y5mXs50v+3Lpyec+cogErDLcV7CMUuiaisw=
github.com/kubepug/kubepug v1.7.1/go.mod h1:lv+HxD0oTFL7ZWjj0u6HKhMbbTIId3eG7aWIW0gyF8g=
github.com/kubeshop/testkube-operator v1.16.30 h1:EJd7EZ/nvOs+p2K/hbun4jBdFb2ya8mn4L5aA/3/vd0=
github.com/kubeshop/testkube-operator v1.16.30/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk=
github.com/kubeshop/testkube-operator v1.16.31 h1:RuT6CDp2iS93awZvgX0gYF6ydyel7Ax1ofI4EgADWsI=
github.com/kubeshop/testkube-operator v1.16.31/go.mod h1:P47tw1nKQFufdsZndyq2HG2MSa0zK/lU0XpRfZtEmIk=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
Expand Down
99 changes: 68 additions & 31 deletions internal/app/api/v1/testsuites.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
testsuitesmapper "github.com/kubeshop/testkube/pkg/mapper/testsuites"
"github.com/kubeshop/testkube/pkg/repository/testresult"
"github.com/kubeshop/testkube/pkg/scheduler"
"github.com/kubeshop/testkube/pkg/tcl/testsuitestcl"
"github.com/kubeshop/testkube/pkg/types"
"github.com/kubeshop/testkube/pkg/utils"
"github.com/kubeshop/testkube/pkg/workerpool"
Expand All @@ -44,16 +43,6 @@ func (s TestkubeAPI) CreateTestSuiteHandler() fiber.Handler {
if err := decoder.Decode(&testSuite); err != nil {
return s.Error(c, http.StatusBadRequest, fmt.Errorf("%s: could not parse yaml request: %w", errPrefix, err))
}
// Pro/Enterprise feature: step execution requests
if testsuitestcl.HasStepsExecutionRequest(testSuite) {
ok, err := s.SubscriptionChecker.IsOrgPlanActive()
if err != nil {
return s.Error(c, http.StatusForbidden, fmt.Errorf("%s: test suite step execution requests are a Pro feature: %w", errPrefix, err))
}
if !ok {
return s.Error(c, http.StatusForbidden, fmt.Errorf("%s: test suite step execution requests are not available: inactive subscription plan", errPrefix))
}
}
errPrefix = errPrefix + " " + testSuite.Name
} else {
var request testkube.TestSuiteUpsertRequest
Expand Down Expand Up @@ -126,16 +115,6 @@ func (s TestkubeAPI) UpdateTestSuiteHandler() fiber.Handler {
if err := decoder.Decode(&testSuite); err != nil {
return s.Error(c, http.StatusBadRequest, fmt.Errorf("%s: could not parse yaml request: %w", errPrefix, err))
}
// Pro/Enterprise feature: step execution requests
if testsuitestcl.HasStepsExecutionRequest(testSuite) {
ok, err := s.SubscriptionChecker.IsOrgPlanActive()
if err != nil {
return s.Error(c, http.StatusForbidden, fmt.Errorf("%s: test suite step execution requests are a Pro feature: %w", errPrefix, err))
}
if !ok {
return s.Error(c, http.StatusForbidden, fmt.Errorf("%s: test suite step execution requests are not available: inactive subscription plan", errPrefix))
}
}
request = testsuitesmapper.MapTestSuiteTestCRDToUpdateRequest(&testSuite)
} else {
data := c.Body()
Expand Down Expand Up @@ -583,16 +562,6 @@ func (s TestkubeAPI) ExecuteTestSuitesHandler() fiber.Handler {

return s.Error(c, http.StatusBadGateway, fmt.Errorf("%s: client could get test suite: %w", errPrefix, err))
}
// Pro/Enterprise feature: step execution requests
if testsuitestcl.HasStepsExecutionRequest(*testSuite) {
ok, err := s.SubscriptionChecker.IsOrgPlanActive()
if err != nil {
return s.Error(c, http.StatusForbidden, fmt.Errorf("%s: test suite step execution requests are a pro feature: %w", errPrefix, err))
}
if !ok {
return s.Error(c, http.StatusForbidden, fmt.Errorf("%s: test suite step execution requests are not available: inactive subscription plan", errPrefix))
}
}
testSuites = append(testSuites, *testSuite)
} else {
testSuiteList, err := s.TestsSuitesClient.List(selector)
Expand Down Expand Up @@ -903,3 +872,71 @@ func getExecutionsFilterFromRequest(c *fiber.Ctx) testresult.Filter {

return filter
}

// MergeStepRequest inherits step request fields with execution request
func MergeStepRequest(stepRequest *testkube.TestSuiteStepExecutionRequest, executionRequest testkube.ExecutionRequest) testkube.ExecutionRequest {
if stepRequest == nil {
return executionRequest
}
if stepRequest.ExecutionLabels != nil {
executionRequest.ExecutionLabels = stepRequest.ExecutionLabels
}

if stepRequest.Variables != nil {
executionRequest.Variables = mergeVariables(executionRequest.Variables, stepRequest.Variables)
}

if len(stepRequest.Args) != 0 {
if stepRequest.ArgsMode == string(testkube.ArgsModeTypeAppend) || stepRequest.ArgsMode == "" {
executionRequest.Args = append(executionRequest.Args, stepRequest.Args...)
}

if stepRequest.ArgsMode == string(testkube.ArgsModeTypeOverride) || stepRequest.ArgsMode == string(testkube.ArgsModeTypeReplace) {
executionRequest.Args = stepRequest.Args
}
}

if stepRequest.Command != nil {
executionRequest.Command = stepRequest.Command
}
executionRequest.Sync = stepRequest.Sync
executionRequest.HttpProxy = setStringField(executionRequest.HttpProxy, stepRequest.HttpProxy)
executionRequest.HttpsProxy = setStringField(executionRequest.HttpsProxy, stepRequest.HttpsProxy)
executionRequest.CronJobTemplate = setStringField(executionRequest.CronJobTemplate, stepRequest.CronJobTemplate)
executionRequest.CronJobTemplateReference = setStringField(executionRequest.CronJobTemplateReference, stepRequest.CronJobTemplateReference)
executionRequest.JobTemplate = setStringField(executionRequest.JobTemplate, stepRequest.JobTemplate)
executionRequest.JobTemplateReference = setStringField(executionRequest.JobTemplateReference, stepRequest.JobTemplateReference)
executionRequest.ScraperTemplate = setStringField(executionRequest.ScraperTemplate, stepRequest.ScraperTemplate)
executionRequest.ScraperTemplateReference = setStringField(executionRequest.ScraperTemplateReference, stepRequest.ScraperTemplateReference)
executionRequest.PvcTemplate = setStringField(executionRequest.PvcTemplate, stepRequest.PvcTemplate)
executionRequest.PvcTemplateReference = setStringField(executionRequest.PvcTemplate, stepRequest.PvcTemplateReference)

if stepRequest.RunningContext != nil {
executionRequest.RunningContext = &testkube.RunningContext{
Type_: string(stepRequest.RunningContext.Type_),
Context: stepRequest.RunningContext.Context,
}
}

return executionRequest
}

func setStringField(oldValue string, newValue string) string {
if newValue != "" {
return newValue
}
return oldValue
}

func mergeVariables(vars1 map[string]testkube.Variable, vars2 map[string]testkube.Variable) map[string]testkube.Variable {
variables := map[string]testkube.Variable{}
for k, v := range vars1 {
variables[k] = v
}

for k, v := range vars2 {
variables[k] = v
}

return variables
}
56 changes: 52 additions & 4 deletions pkg/mapper/testsuites/kube_openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
commonv1 "github.com/kubeshop/testkube-operator/api/common/v1"
testsuitesv3 "github.com/kubeshop/testkube-operator/api/testsuite/v3"
"github.com/kubeshop/testkube/pkg/api/v1/testkube"
"github.com/kubeshop/testkube/pkg/tcl/testsuitestcl"
)

// MapTestSuiteListKubeToAPI maps TestSuiteList CRD to list of OpenAPI spec TestSuite
Expand Down Expand Up @@ -81,9 +80,8 @@ func mapCRStepToAPI(crstep testsuitesv3.TestSuiteStepSpec) (teststep testkube.Te
switch true {
case crstep.Test != "":
teststep = testkube.TestSuiteStep{
Test: crstep.Test,
// Pro/Enterprise feature: step execution requests
ExecutionRequest: testsuitestcl.MapTestStepExecutionRequestCRDToAPI(crstep.ExecutionRequest),
Test: crstep.Test,
ExecutionRequest: MapTestStepExecutionRequestCRDToAPI(crstep.ExecutionRequest),
}

case crstep.Delay.Duration != 0:
Expand Down Expand Up @@ -358,3 +356,53 @@ func MapSpecExecutionRequestToExecutionUpdateRequest(request *testsuitesv3.TestS

return executionRequest
}

func MapTestStepExecutionRequestCRDToAPI(request *testsuitesv3.TestSuiteStepExecutionRequest) *testkube.TestSuiteStepExecutionRequest {
if request == nil {
return nil
}
variables := map[string]testkube.Variable{}
for k, v := range request.Variables {
varType := testkube.VariableType(v.Type_)
variables[k] = testkube.Variable{
Name: v.Name,
Value: v.Value,
Type_: &varType,
}
}

var runningContext *testkube.RunningContext

if request.RunningContext != nil {
runningContext = &testkube.RunningContext{
Type_: string(request.RunningContext.Type_),
Context: request.RunningContext.Context,
}
}

argsMode := ""
if request.ArgsMode != "" {
argsMode = string(request.ArgsMode)
}

return &testkube.TestSuiteStepExecutionRequest{
ExecutionLabels: request.ExecutionLabels,
Variables: variables,
Command: request.Command,
Args: request.Args,
ArgsMode: argsMode,
Sync: request.Sync,
HttpProxy: request.HttpProxy,
HttpsProxy: request.HttpsProxy,
NegativeTest: request.NegativeTest,
JobTemplate: request.JobTemplate,
JobTemplateReference: request.JobTemplateReference,
CronJobTemplate: request.CronJobTemplate,
CronJobTemplateReference: request.CronJobTemplateReference,
ScraperTemplate: request.ScraperTemplate,
ScraperTemplateReference: request.ScraperTemplateReference,
PvcTemplate: request.PvcTemplate,
PvcTemplateReference: request.PvcTemplateReference,
RunningContext: runningContext,
}
}
49 changes: 46 additions & 3 deletions pkg/mapper/testsuites/openapi_kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

v1 "github.com/kubeshop/testkube-operator/api/common/v1"
testsuitesv3 "github.com/kubeshop/testkube-operator/api/testsuite/v3"
"github.com/kubeshop/testkube/pkg/api/v1/testkube"
"github.com/kubeshop/testkube/pkg/tcl/testsuitestcl"
"github.com/kubeshop/testkube/pkg/types"
)

Expand Down Expand Up @@ -199,8 +199,7 @@ func mapTestStepToCRD(step testkube.TestSuiteStep) (stepSpec testsuitesv3.TestSu
}
case testkube.TestSuiteStepTypeExecuteTest:
stepSpec.Test = step.Test
// Pro/Enterprise feature: step execution requests
stepSpec.ExecutionRequest = testsuitestcl.MapTestStepExecutionRequestCRD(step.ExecutionRequest)
stepSpec.ExecutionRequest = MapTestStepExecutionRequestCRD(step.ExecutionRequest)
}

return stepSpec, nil
Expand Down Expand Up @@ -440,3 +439,47 @@ func MapExecutionToTestSuiteStatus(execution *testkube.TestSuiteExecution) (spec

return specStatus
}

func MapTestStepExecutionRequestCRD(request *testkube.TestSuiteStepExecutionRequest) *testsuitesv3.TestSuiteStepExecutionRequest {
if request == nil {
return nil
}

variables := map[string]testsuitesv3.Variable{}
for k, v := range request.Variables {
variables[k] = testsuitesv3.Variable{
Name: v.Name,
Value: v.Value,
Type_: string(*v.Type_),
}
}

var runningContext *v1.RunningContext
if request.RunningContext != nil {
runningContext = &v1.RunningContext{
Type_: v1.RunningContextType(request.RunningContext.Type_),
Context: request.RunningContext.Context,
}
}

return &testsuitesv3.TestSuiteStepExecutionRequest{
ExecutionLabels: request.ExecutionLabels,
Variables: variables,
Args: request.Args,
ArgsMode: testsuitesv3.ArgsModeType(request.ArgsMode),
Command: request.Command,
Sync: request.Sync,
HttpProxy: request.HttpProxy,
HttpsProxy: request.HttpsProxy,
NegativeTest: request.NegativeTest,
JobTemplate: request.JobTemplate,
JobTemplateReference: request.JobTemplateReference,
CronJobTemplate: request.CronJobTemplate,
CronJobTemplateReference: request.CronJobTemplateReference,
ScraperTemplate: request.ScraperTemplate,
ScraperTemplateReference: request.ScraperTemplateReference,
PvcTemplate: request.PvcTemplate,
PvcTemplateReference: request.PvcTemplateReference,
RunningContext: runningContext,
}
}
59 changes: 56 additions & 3 deletions pkg/scheduler/testsuite_scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/kubeshop/testkube/pkg/event/bus"
testsuiteexecutionsmapper "github.com/kubeshop/testkube/pkg/mapper/testsuiteexecutions"
testsuitesmapper "github.com/kubeshop/testkube/pkg/mapper/testsuites"
"github.com/kubeshop/testkube/pkg/tcl/testsuitestcl"

"github.com/kubeshop/testkube/pkg/telemetry"
"github.com/kubeshop/testkube/pkg/version"
Expand Down Expand Up @@ -510,8 +509,7 @@ func (s *Scheduler) executeTestStep(ctx context.Context, testsuiteExecution test
for i := range testTuples {
req.Name = fmt.Sprintf("%s-%s", testSuiteName, testTuples[i].test.Name)
req.Id = testTuples[i].executionID
// Pro/Enterprise feature: step execution requests
req = testsuitestcl.MergeStepRequest(testTuples[i].stepRequest, req)
req = MergeStepRequest(testTuples[i].stepRequest, req)
requests[i] = workerpool.Request[testkube.Test, testkube.ExecutionRequest, testkube.Execution]{
Object: testTuples[i].test,
Options: req,
Expand Down Expand Up @@ -625,3 +623,58 @@ func (s *Scheduler) delayWithAbortionCheck(duration time.Duration, testSuiteId s
}
}
}

// MergeStepRequest inherits step request fields with execution request
func MergeStepRequest(stepRequest *testkube.TestSuiteStepExecutionRequest, executionRequest testkube.ExecutionRequest) testkube.ExecutionRequest {
if stepRequest == nil {
return executionRequest
}
if stepRequest.ExecutionLabels != nil {
executionRequest.ExecutionLabels = stepRequest.ExecutionLabels
}

if stepRequest.Variables != nil {
executionRequest.Variables = mergeVariables(executionRequest.Variables, stepRequest.Variables)
}

if len(stepRequest.Args) != 0 {
if stepRequest.ArgsMode == string(testkube.ArgsModeTypeAppend) || stepRequest.ArgsMode == "" {
executionRequest.Args = append(executionRequest.Args, stepRequest.Args...)
}

if stepRequest.ArgsMode == string(testkube.ArgsModeTypeOverride) || stepRequest.ArgsMode == string(testkube.ArgsModeTypeReplace) {
executionRequest.Args = stepRequest.Args
}
}

if stepRequest.Command != nil {
executionRequest.Command = stepRequest.Command
}
executionRequest.Sync = stepRequest.Sync
executionRequest.HttpProxy = setStringField(executionRequest.HttpProxy, stepRequest.HttpProxy)
executionRequest.HttpsProxy = setStringField(executionRequest.HttpsProxy, stepRequest.HttpsProxy)
executionRequest.CronJobTemplate = setStringField(executionRequest.CronJobTemplate, stepRequest.CronJobTemplate)
executionRequest.CronJobTemplateReference = setStringField(executionRequest.CronJobTemplateReference, stepRequest.CronJobTemplateReference)
executionRequest.JobTemplate = setStringField(executionRequest.JobTemplate, stepRequest.JobTemplate)
executionRequest.JobTemplateReference = setStringField(executionRequest.JobTemplateReference, stepRequest.JobTemplateReference)
executionRequest.ScraperTemplate = setStringField(executionRequest.ScraperTemplate, stepRequest.ScraperTemplate)
executionRequest.ScraperTemplateReference = setStringField(executionRequest.ScraperTemplateReference, stepRequest.ScraperTemplateReference)
executionRequest.PvcTemplate = setStringField(executionRequest.PvcTemplate, stepRequest.PvcTemplate)
executionRequest.PvcTemplateReference = setStringField(executionRequest.PvcTemplate, stepRequest.PvcTemplateReference)

if stepRequest.RunningContext != nil {
executionRequest.RunningContext = &testkube.RunningContext{
Type_: string(stepRequest.RunningContext.Type_),
Context: stepRequest.RunningContext.Context,
}
}

return executionRequest
}

func setStringField(oldValue string, newValue string) string {
if newValue != "" {
return newValue
}
return oldValue
}
Loading

0 comments on commit d265697

Please sign in to comment.