Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/grafana/k6-operator
go 1.23.0

require (
github.com/buildkite/interpolate v0.1.5
github.com/go-logr/logr v1.4.2
github.com/go-test/deep v1.0.7
github.com/google/uuid v1.6.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
github.com/buildkite/interpolate v0.1.5 h1:v2Ji3voik69UZlbfoqzx+qfcsOKLA61nHdU79VV+tPU=
github.com/buildkite/interpolate v0.1.5/go.mod h1:dHnrwHew5O8VNOAgMDpwRlFnhL5VSN6M1bHVmRZ9Ccc=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
Expand Down
10 changes: 10 additions & 0 deletions pkg/resources/jobs/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,13 @@ func getInitContainers(pod *v1alpha1.Pod, script *types.Script) []corev1.Contain

return initContainers
}

func convertEnvVarsToStringSlice(envVars []corev1.EnvVar) []string {
var envSlice []string
for _, envVar := range envVars {
if envVar.Value != "" {
envSlice = append(envSlice, envVar.Name+"="+envVar.Value)
}
}
return envSlice
}
66 changes: 66 additions & 0 deletions pkg/resources/jobs/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,69 @@ func TestNewIstioEnvVarFalseValues(t *testing.T) {
t.Errorf("new envVars were incorrect, got: %v, want: %v.", envVars, expectedOutcome)
}
}
func TestConvertEnvVars(t *testing.T) {
testCases := []struct {
name string
input []corev1.EnvVar
expected []string
}{
{
name: "empty slice",
input: []corev1.EnvVar{},
expected: []string{},
},
{
name: "single env var",
input: []corev1.EnvVar{
{Name: "TEST_VAR", Value: "test_value"},
},
expected: []string{"TEST_VAR=test_value"},
},
{
name: "multiple env vars",
input: []corev1.EnvVar{
{Name: "VAR1", Value: "value1"},
{Name: "VAR2", Value: "value2"},
{Name: "my-env", Value: "myValue"},
},
expected: []string{"VAR1=value1", "VAR2=value2", "my-env=myValue"},
},
{
name: "empty value should be skipped",
input: []corev1.EnvVar{
{Name: "EMPTY_VAR", Value: ""},
{Name: "VALID_VAR", Value: "valid_value"},
},
expected: []string{"VALID_VAR=valid_value"},
},
{
name: "special characters in value",
input: []corev1.EnvVar{
{Name: "SPECIAL", Value: "value with spaces!@#"},
{Name: "URL", Value: "https://example.com?param=value"},
},
expected: []string{"SPECIAL=value with spaces!@#", "URL=https://example.com?param=value"},
},
{
name: "nil slice",
input: nil,
expected: []string{},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := convertEnvVarsToStringSlice(tc.input)

// Check if both are empty (handles nil vs empty slice issue)
if len(result) == 0 && len(tc.expected) == 0 {
return // Both empty, test passes
}

// For non-empty cases, use reflect.DeepEqual
if !reflect.DeepEqual(result, tc.expected) {
t.Errorf("%s failed. Got %v, expected %v", tc.name, result, tc.expected)
}
})
}
}
82 changes: 44 additions & 38 deletions pkg/resources/jobs/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package jobs

import (
"fmt"
"github.com/buildkite/interpolate"
"strconv"
"strings"

Expand Down Expand Up @@ -48,8 +49,50 @@ func NewRunnerJob(k6 *v1alpha1.TestRun, index int, tokenInfo *cloud.TokenInfo) (
return nil, err
}

// Conslidate envs
env := newIstioEnvVar(k6.GetSpec().Scuttle, istioEnabled)

// this is a cloud test run
if len(k6.TestRunID()) > 0 {
// cloud output case
tokenVar := corev1.EnvVar{
Name: "K6_CLOUD_TOKEN",
Value: tokenInfo.Value(),
}

if v1alpha1.IsTrue(k6, v1alpha1.CloudPLZTestRun) {
// temporary hack
k6.GetStatus().AggregationVars = "2|5s|3s|10s|10"
tokenVar = corev1.EnvVar{
Name: "K6_CLOUD_TOKEN",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: tokenInfo.SecretName()},
Key: "token",
},
},
}
}

aggregationVars, err := cloud.DecodeAggregationConfig(k6.GetStatus().AggregationVars)
if err != nil {
return nil, err
}
env = append(env, aggregationVars...)
env = append(env, corev1.EnvVar{
Name: "K6_CLOUD_PUSH_REF_ID",
Value: k6.GetStatus().TestRunID,
}, tokenVar)
}

env = append(env, k6.GetSpec().Runner.Env...)

if k6.GetSpec().Arguments != "" {
args := strings.Split(k6.GetSpec().Arguments, " ")
// Expand on environment variables using envmap from `env`
envStringSlice := convertEnvVarsToStringSlice(env)
envMap := interpolate.NewSliceEnv(envStringSlice)
expandedArgs, _ := interpolate.Interpolate(envMap, k6.GetSpec().Arguments)
args := strings.Split(expandedArgs, " ")
command = append(command, args...)
}

Expand Down Expand Up @@ -117,43 +160,6 @@ func NewRunnerJob(k6 *v1alpha1.TestRun, index int, tokenInfo *cloud.TokenInfo) (
ports := []corev1.ContainerPort{{ContainerPort: 6565}}
ports = append(ports, k6.GetSpec().Ports...)

env := newIstioEnvVar(k6.GetSpec().Scuttle, istioEnabled)

// this is a cloud test run
if len(k6.TestRunID()) > 0 {
// cloud output case
tokenVar := corev1.EnvVar{
Name: "K6_CLOUD_TOKEN",
Value: tokenInfo.Value(),
}

if v1alpha1.IsTrue(k6, v1alpha1.CloudPLZTestRun) {
// temporary hack
k6.GetStatus().AggregationVars = "2|5s|3s|10s|10"
tokenVar = corev1.EnvVar{
Name: "K6_CLOUD_TOKEN",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{Name: tokenInfo.SecretName()},
Key: "token",
},
},
}
}

aggregationVars, err := cloud.DecodeAggregationConfig(k6.GetStatus().AggregationVars)
if err != nil {
return nil, err
}
env = append(env, aggregationVars...)
env = append(env, corev1.EnvVar{
Name: "K6_CLOUD_PUSH_REF_ID",
Value: k6.GetStatus().TestRunID,
}, tokenVar)
}

env = append(env, k6.GetSpec().Runner.Env...)

volumes := script.Volume()
volumes = append(volumes, k6.GetSpec().Runner.Volumes...)

Expand Down
Loading