github.com/buildkite/agent-stack-k8s@v0.4.0/scheduler/scheduler_test.go (about) 1 package scheduler 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "testing" 7 8 "github.com/buildkite/agent-stack-k8s/api" 9 "github.com/buildkite/agent-stack-k8s/monitor" 10 "github.com/stretchr/testify/require" 11 "go.uber.org/zap/zaptest" 12 corev1 "k8s.io/api/core/v1" 13 ) 14 15 //go:generate mockgen -destination=mock_handler_test.go -source=scheduler.go -package scheduler_test 16 func TestJobPluginConversion(t *testing.T) { 17 pluginConfig := KubernetesPlugin{ 18 PodSpec: &corev1.PodSpec{ 19 Containers: []corev1.Container{ 20 { 21 Image: "alpine:latest", 22 Command: []string{"hello world a=b=c"}, 23 EnvFrom: []corev1.EnvFromSource{ 24 { 25 ConfigMapRef: &corev1.ConfigMapEnvSource{ 26 LocalObjectReference: corev1.LocalObjectReference{Name: "some-configmap"}, 27 }, 28 }, 29 }, 30 }, 31 }, 32 }, 33 GitEnvFrom: []corev1.EnvFromSource{ 34 { 35 SecretRef: &corev1.SecretEnvSource{ 36 LocalObjectReference: corev1.LocalObjectReference{Name: "git-secret"}, 37 }, 38 }, 39 }, 40 } 41 pluginsJSON, err := json.Marshal([]map[string]interface{}{ 42 { 43 "github.com/buildkite-plugins/kubernetes-buildkite-plugin": pluginConfig, 44 }, 45 { 46 "github.com/buildkite-plugins/some-other-buildkite-plugin": map[string]interface{}{"foo": "bar"}, 47 }, 48 }) 49 require.NoError(t, err) 50 51 input := &monitor.Job{ 52 CommandJob: api.CommandJob{ 53 Uuid: "abc", 54 Env: []string{fmt.Sprintf("BUILDKITE_PLUGINS=%s", string(pluginsJSON))}, 55 }, 56 Tag: "queue=kubernetes", 57 } 58 wrapper := NewJobWrapper(zaptest.NewLogger(t), input, api.Config{AgentTokenSecret: "token-secret"}) 59 result, err := wrapper.ParsePlugins().Build() 60 require.NoError(t, err) 61 62 require.Len(t, result.Spec.Template.Spec.Containers, 3) 63 64 commandContainer := findContainer(t, result.Spec.Template.Spec.Containers, "container-0") 65 commandEnv := findEnv(t, commandContainer.Env, "BUILDKITE_COMMAND") 66 require.Equal(t, pluginConfig.PodSpec.Containers[0].Command[0], commandEnv.Value) 67 68 var envFromNames []string 69 for _, envFrom := range commandContainer.EnvFrom { 70 if envFrom.ConfigMapRef != nil { 71 envFromNames = append(envFromNames, envFrom.ConfigMapRef.Name) 72 } 73 if envFrom.SecretRef != nil { 74 envFromNames = append(envFromNames, envFrom.SecretRef.Name) 75 } 76 } 77 require.ElementsMatch(t, envFromNames, []string{"some-configmap", "git-secret"}) 78 79 tokenEnv := findEnv(t, commandContainer.Env, "BUILDKITE_AGENT_TOKEN") 80 require.Equal(t, "token-secret", tokenEnv.ValueFrom.SecretKeyRef.Name) 81 82 tagLabel := result.Labels[api.TagLabel] 83 require.Equal(t, api.TagToLabel(input.Tag), tagLabel) 84 85 pluginsEnv := findEnv(t, commandContainer.Env, "BUILDKITE_PLUGINS") 86 require.Equal(t, pluginsEnv.Value, `[{"github.com/buildkite-plugins/some-other-buildkite-plugin":{"foo":"bar"}}]`) 87 } 88 89 func TestJobWithNoKubernetesPlugin(t *testing.T) { 90 input := &monitor.Job{ 91 CommandJob: api.CommandJob{ 92 Uuid: "abc", 93 Command: "echo hello world", 94 }, 95 } 96 wrapper := NewJobWrapper(zaptest.NewLogger(t), input, api.Config{}) 97 result, err := wrapper.ParsePlugins().Build() 98 require.NoError(t, err) 99 100 require.Len(t, result.Spec.Template.Spec.Containers, 3) 101 102 commandContainer := findContainer(t, result.Spec.Template.Spec.Containers, "container-0") 103 commandEnv := findEnv(t, commandContainer.Env, "BUILDKITE_COMMAND") 104 require.Equal(t, input.Command, commandEnv.Value) 105 pluginsEnv := findEnv(t, commandContainer.Env, "BUILDKITE_PLUGINS") 106 require.Nil(t, pluginsEnv) 107 } 108 109 func TestFailureJobs(t *testing.T) { 110 pluginsJSON, err := json.Marshal([]map[string]interface{}{ 111 { 112 "github.com/buildkite-plugins/kubernetes-buildkite-plugin": `"some-invalid-json"`, 113 }, 114 }) 115 116 input := &monitor.Job{ 117 CommandJob: api.CommandJob{ 118 Uuid: "abc", 119 Env: []string{fmt.Sprintf("BUILDKITE_PLUGINS=%s", string(pluginsJSON))}, 120 }, 121 Tag: "queue=kubernetes", 122 } 123 wrapper := NewJobWrapper(zaptest.NewLogger(t), input, api.Config{}) 124 _, err = wrapper.ParsePlugins().Build() 125 require.Error(t, err) 126 127 result, err := wrapper.BuildFailureJob(err) 128 require.NoError(t, err) 129 130 commandContainer := findContainer(t, result.Spec.Template.Spec.Containers, "container-0") 131 commandEnv := findEnv(t, commandContainer.Env, "BUILDKITE_COMMAND") 132 require.Equal(t, `echo "failed parsing Kubernetes plugin: json: cannot unmarshal string into Go value of type scheduler.KubernetesPlugin" && exit 1`, commandEnv.Value) 133 134 } 135 136 func findContainer(t *testing.T, containers []corev1.Container, name string) corev1.Container { 137 for _, container := range containers { 138 if container.Name == name { 139 return container 140 } 141 } 142 t.Helper() 143 require.FailNow(t, "container not found") 144 145 return corev1.Container{} 146 } 147 148 func findEnv(t *testing.T, envs []corev1.EnvVar, name string) *corev1.EnvVar { 149 for _, env := range envs { 150 if env.Name == name { 151 return &env 152 } 153 } 154 155 return nil 156 }