|
1 | 1 | package controller_test |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "testing" |
5 | | - "time" |
| 4 | + "testing" |
| 5 | + "time" |
6 | 6 |
|
7 | | - "github.com/buildkite/agent-stack-k8s/v2/cmd/controller" |
8 | | - "github.com/buildkite/agent-stack-k8s/v2/internal/controller/config" |
9 | | - "github.com/google/go-cmp/cmp" |
10 | | - "github.com/spf13/cobra" |
11 | | - "github.com/stretchr/testify/require" |
12 | | - corev1 "k8s.io/api/core/v1" |
13 | | - "k8s.io/apimachinery/pkg/api/resource" |
| 7 | + "github.com/buildkite/agent-stack-k8s/v2/cmd/controller" |
| 8 | + "github.com/buildkite/agent-stack-k8s/v2/internal/controller/config" |
| 9 | + "github.com/google/go-cmp/cmp" |
| 10 | + "github.com/spf13/cobra" |
| 11 | + "github.com/stretchr/testify/require" |
| 12 | + corev1 "k8s.io/api/core/v1" |
| 13 | + "k8s.io/apimachinery/pkg/api/resource" |
14 | 14 | ) |
15 | 15 |
|
16 | 16 | func ptr[T any](v T) *T { |
17 | | - return &v |
| 17 | + return &v |
18 | 18 | } |
19 | 19 |
|
20 | 20 | func TestReadAndParseConfig(t *testing.T) { |
21 | | - expected := config.Config{ |
22 | | - Debug: true, |
23 | | - AgentTokenSecret: "my-kubernetes-secret", |
24 | | - BuildkiteToken: "my-graphql-enabled-token", |
25 | | - Image: "my.registry.dev/buildkite-agent:latest", |
26 | | - JobTTL: 300 * time.Second, |
27 | | - JobActiveDeadlineSeconds: 21600, |
28 | | - DefaultTerminationGracePeriodSeconds: 80, |
29 | | - JobPrefix: "testkite-", |
30 | | - ImagePullBackOffGracePeriod: 60 * time.Second, |
31 | | - JobCancelCheckerPollInterval: 10 * time.Second, |
32 | | - EmptyJobGracePeriod: 50 * time.Second, |
33 | | - PollInterval: 5 * time.Second, |
34 | | - JobCreationConcurrency: 5, |
35 | | - MaxInFlight: 100, |
36 | | - K8sClientRateLimiterQPS: 20, |
37 | | - K8sClientRateLimiterBurst: 30, |
38 | | - Namespace: "my-buildkite-ns", |
39 | | - Queue: "my-queue", |
40 | | - Tags: []string{"priority=high"}, |
41 | | - PrometheusPort: 9216, |
42 | | - ProhibitKubernetesPlugin: true, |
43 | | - PaginationPageSize: 1000, |
44 | | - PaginationDepthLimit: 5, |
45 | | - QueryResetInterval: 10 * time.Second, |
46 | | - DefaultImagePullPolicy: "Never", |
47 | | - DefaultImageCheckPullPolicy: "IfNotPresent", |
48 | | - EnableQueuePause: true, |
49 | | - WorkQueueLimit: 2_000_000, |
50 | | - ImageCheckContainerCPULimit: "201m", |
51 | | - ImageCheckContainerMemoryLimit: "129Mi", |
52 | | - LogFormat: "logfmt", |
53 | | - LogLevel: "info", |
54 | | - NoColor: false, |
| 21 | + expected := config.Config{ |
| 22 | + Debug: true, |
| 23 | + AgentTokenSecret: "my-kubernetes-secret", |
| 24 | + BuildkiteToken: "my-graphql-enabled-token", |
| 25 | + Image: "my.registry.dev/buildkite-agent:latest", |
| 26 | + JobTTL: 300 * time.Second, |
| 27 | + JobActiveDeadlineSeconds: 21600, |
| 28 | + DefaultTerminationGracePeriodSeconds: 80, |
| 29 | + JobPrefix: "testkite-", |
| 30 | + ImagePullBackOffGracePeriod: 60 * time.Second, |
| 31 | + JobCancelCheckerPollInterval: 10 * time.Second, |
| 32 | + EmptyJobGracePeriod: 50 * time.Second, |
| 33 | + PollInterval: 5 * time.Second, |
| 34 | + JobCreationConcurrency: 5, |
| 35 | + MaxInFlight: 100, |
| 36 | + K8sClientRateLimiterQPS: 20, |
| 37 | + K8sClientRateLimiterBurst: 30, |
| 38 | + Namespace: "my-buildkite-ns", |
| 39 | + Queue: "my-queue", |
| 40 | + Tags: []string{"priority=high"}, |
| 41 | + PrometheusPort: 9216, |
| 42 | + ProhibitKubernetesPlugin: true, |
| 43 | + PaginationPageSize: 1000, |
| 44 | + PaginationDepthLimit: 5, |
| 45 | + QueryResetInterval: 10 * time.Second, |
| 46 | + DefaultImagePullPolicy: "Never", |
| 47 | + DefaultImageCheckPullPolicy: "IfNotPresent", |
| 48 | + EnableQueuePause: true, |
| 49 | + WorkQueueLimit: 2_000_000, |
| 50 | + ImageCheckContainerCPULimit: "201m", |
| 51 | + ImageCheckContainerMemoryLimit: "129Mi", |
| 52 | + LogFormat: "logfmt", |
| 53 | + LogLevel: "info", |
| 54 | + NoColor: false, |
55 | 55 |
|
56 | | - ResourceClasses: map[string]*config.ResourceClass{ |
57 | | - "small": { |
58 | | - Resource: &corev1.ResourceRequirements{ |
59 | | - Requests: corev1.ResourceList{ |
60 | | - "cpu": resource.MustParse("500m"), |
61 | | - "memory": resource.MustParse("512Mi"), |
62 | | - "hugepages-2Mi": resource.MustParse("1Mi"), |
63 | | - }, |
64 | | - }, |
65 | | - }, |
66 | | - }, |
| 56 | + ResourceClasses: map[string]*config.ResourceClass{ |
| 57 | + "small": { |
| 58 | + Resource: &corev1.ResourceRequirements{ |
| 59 | + Requests: corev1.ResourceList{ |
| 60 | + "cpu": resource.MustParse("500m"), |
| 61 | + "memory": resource.MustParse("512Mi"), |
| 62 | + "hugepages-2Mi": resource.MustParse("1Mi"), |
| 63 | + }, |
| 64 | + }, |
| 65 | + }, |
| 66 | + }, |
| 67 | + DefaultResourceClassName: "small", |
67 | 68 |
|
68 | | - WorkspaceVolume: &corev1.Volume{ |
69 | | - Name: "workspace-2-the-reckoning", |
70 | | - VolumeSource: corev1.VolumeSource{ |
71 | | - Ephemeral: &corev1.EphemeralVolumeSource{ |
72 | | - VolumeClaimTemplate: &corev1.PersistentVolumeClaimTemplate{ |
73 | | - Spec: corev1.PersistentVolumeClaimSpec{ |
74 | | - AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, |
75 | | - StorageClassName: ptr("my-special-storage-class"), |
76 | | - Resources: corev1.VolumeResourceRequirements{ |
77 | | - Requests: corev1.ResourceList{ |
78 | | - "storage": resource.MustParse("1Gi"), |
79 | | - }, |
80 | | - }, |
81 | | - }, |
82 | | - }, |
83 | | - }, |
84 | | - }, |
85 | | - }, |
86 | | - AgentConfig: &config.AgentConfig{ |
87 | | - Endpoint: ptr("http://agent.buildkite.localhost/v3"), |
88 | | - }, |
89 | | - DefaultCommandParams: &config.CommandParams{ |
90 | | - Interposer: config.InterposerVector, |
91 | | - EnvFrom: []corev1.EnvFromSource{{ |
92 | | - Prefix: "DEPLOY_", |
93 | | - SecretRef: &corev1.SecretEnvSource{ |
94 | | - LocalObjectReference: corev1.LocalObjectReference{ |
95 | | - Name: "deploy-secrets", |
96 | | - }, |
97 | | - }, |
98 | | - }}, |
99 | | - }, |
100 | | - DefaultCheckoutParams: &config.CheckoutParams{ |
101 | | - GitCredentialsSecret: &corev1.SecretVolumeSource{ |
102 | | - SecretName: "my-git-credentials", |
103 | | - }, |
104 | | - EnvFrom: []corev1.EnvFromSource{{ |
105 | | - Prefix: "GITHUB_", |
106 | | - SecretRef: &corev1.SecretEnvSource{ |
107 | | - LocalObjectReference: corev1.LocalObjectReference{ |
108 | | - Name: "github-secrets", |
109 | | - }, |
110 | | - }, |
111 | | - }}, |
112 | | - }, |
113 | | - DefaultSidecarParams: &config.SidecarParams{ |
114 | | - EnvFrom: []corev1.EnvFromSource{{ |
115 | | - Prefix: "LOGGING_", |
116 | | - ConfigMapRef: &corev1.ConfigMapEnvSource{ |
117 | | - LocalObjectReference: corev1.LocalObjectReference{ |
118 | | - Name: "logging-config", |
119 | | - }, |
120 | | - }, |
121 | | - }}, |
122 | | - }, |
123 | | - DefaultMetadata: config.Metadata{ |
124 | | - Annotations: map[string]string{ |
125 | | - "imageregistry": "https://hub.docker.com/", |
126 | | - }, |
127 | | - Labels: map[string]string{ |
128 | | - "argocd.argoproj.io/tracking-id": "example-id-here", |
129 | | - }, |
130 | | - }, |
131 | | - PodSpecPatch: &corev1.PodSpec{ |
132 | | - ServiceAccountName: "buildkite-agent-sa", |
133 | | - AutomountServiceAccountToken: ptr(true), |
134 | | - NodeSelector: map[string]string{ |
135 | | - "selectors.example.com/my-selector": "example-value", |
136 | | - }, |
137 | | - Containers: []corev1.Container{ |
138 | | - { |
139 | | - Name: "container-0", |
140 | | - Image: "example.org/my-container@latest", |
141 | | - Env: []corev1.EnvVar{ |
142 | | - { |
143 | | - Name: "GITHUB_TOKEN", |
144 | | - ValueFrom: &corev1.EnvVarSource{ |
145 | | - SecretKeyRef: &corev1.SecretKeySelector{ |
146 | | - LocalObjectReference: corev1.LocalObjectReference{ |
147 | | - Name: "github-secrets", |
148 | | - }, |
149 | | - Key: "github-token", |
150 | | - }, |
151 | | - }, |
152 | | - }, |
153 | | - }, |
154 | | - Resources: corev1.ResourceRequirements{ |
155 | | - Requests: corev1.ResourceList{ |
156 | | - "cpu": resource.MustParse("1000m"), |
157 | | - "mem": resource.MustParse("4Gi"), |
158 | | - "hugepages-2Mi": resource.MustParse("2Mi"), |
159 | | - }, |
160 | | - }, |
161 | | - }, |
162 | | - }, |
163 | | - }, |
164 | | - } |
| 69 | + WorkspaceVolume: &corev1.Volume{ |
| 70 | + Name: "workspace-2-the-reckoning", |
| 71 | + VolumeSource: corev1.VolumeSource{ |
| 72 | + Ephemeral: &corev1.EphemeralVolumeSource{ |
| 73 | + VolumeClaimTemplate: &corev1.PersistentVolumeClaimTemplate{ |
| 74 | + Spec: corev1.PersistentVolumeClaimSpec{ |
| 75 | + AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce}, |
| 76 | + StorageClassName: ptr("my-special-storage-class"), |
| 77 | + Resources: corev1.VolumeResourceRequirements{ |
| 78 | + Requests: corev1.ResourceList{ |
| 79 | + "storage": resource.MustParse("1Gi"), |
| 80 | + }, |
| 81 | + }, |
| 82 | + }, |
| 83 | + }, |
| 84 | + }, |
| 85 | + }, |
| 86 | + }, |
| 87 | + AgentConfig: &config.AgentConfig{ |
| 88 | + Endpoint: ptr("http://agent.buildkite.localhost/v3"), |
| 89 | + }, |
| 90 | + DefaultCommandParams: &config.CommandParams{ |
| 91 | + Interposer: config.InterposerVector, |
| 92 | + EnvFrom: []corev1.EnvFromSource{{ |
| 93 | + Prefix: "DEPLOY_", |
| 94 | + SecretRef: &corev1.SecretEnvSource{ |
| 95 | + LocalObjectReference: corev1.LocalObjectReference{ |
| 96 | + Name: "deploy-secrets", |
| 97 | + }, |
| 98 | + }, |
| 99 | + }}, |
| 100 | + }, |
| 101 | + DefaultCheckoutParams: &config.CheckoutParams{ |
| 102 | + GitCredentialsSecret: &corev1.SecretVolumeSource{ |
| 103 | + SecretName: "my-git-credentials", |
| 104 | + }, |
| 105 | + EnvFrom: []corev1.EnvFromSource{{ |
| 106 | + Prefix: "GITHUB_", |
| 107 | + SecretRef: &corev1.SecretEnvSource{ |
| 108 | + LocalObjectReference: corev1.LocalObjectReference{ |
| 109 | + Name: "github-secrets", |
| 110 | + }, |
| 111 | + }, |
| 112 | + }}, |
| 113 | + }, |
| 114 | + DefaultSidecarParams: &config.SidecarParams{ |
| 115 | + EnvFrom: []corev1.EnvFromSource{{ |
| 116 | + Prefix: "LOGGING_", |
| 117 | + ConfigMapRef: &corev1.ConfigMapEnvSource{ |
| 118 | + LocalObjectReference: corev1.LocalObjectReference{ |
| 119 | + Name: "logging-config", |
| 120 | + }, |
| 121 | + }, |
| 122 | + }}, |
| 123 | + }, |
| 124 | + DefaultMetadata: config.Metadata{ |
| 125 | + Annotations: map[string]string{ |
| 126 | + "imageregistry": "https://hub.docker.com/", |
| 127 | + }, |
| 128 | + Labels: map[string]string{ |
| 129 | + "argocd.argoproj.io/tracking-id": "example-id-here", |
| 130 | + }, |
| 131 | + }, |
| 132 | + PodSpecPatch: &corev1.PodSpec{ |
| 133 | + ServiceAccountName: "buildkite-agent-sa", |
| 134 | + AutomountServiceAccountToken: ptr(true), |
| 135 | + NodeSelector: map[string]string{ |
| 136 | + "selectors.example.com/my-selector": "example-value", |
| 137 | + }, |
| 138 | + Containers: []corev1.Container{ |
| 139 | + { |
| 140 | + Name: "container-0", |
| 141 | + Image: "example.org/my-container@latest", |
| 142 | + Env: []corev1.EnvVar{ |
| 143 | + { |
| 144 | + Name: "GITHUB_TOKEN", |
| 145 | + ValueFrom: &corev1.EnvVarSource{ |
| 146 | + SecretKeyRef: &corev1.SecretKeySelector{ |
| 147 | + LocalObjectReference: corev1.LocalObjectReference{ |
| 148 | + Name: "github-secrets", |
| 149 | + }, |
| 150 | + Key: "github-token", |
| 151 | + }, |
| 152 | + }, |
| 153 | + }, |
| 154 | + }, |
| 155 | + Resources: corev1.ResourceRequirements{ |
| 156 | + Requests: corev1.ResourceList{ |
| 157 | + "cpu": resource.MustParse("1000m"), |
| 158 | + "mem": resource.MustParse("4Gi"), |
| 159 | + "hugepages-2Mi": resource.MustParse("2Mi"), |
| 160 | + }, |
| 161 | + }, |
| 162 | + }, |
| 163 | + }, |
| 164 | + }, |
| 165 | + } |
165 | 166 |
|
166 | | - // These need to be unset to as it is set in CI which pollutes the test environment |
167 | | - t.Setenv("INTEGRATION_TEST_BUILDKITE_TOKEN", "") |
168 | | - t.Setenv("IMAGE", "") |
169 | | - t.Setenv("NAMESPACE", "") |
170 | | - t.Setenv("AGENT_TOKEN_SECRET", "") |
| 167 | + // These need to be unset to as it is set in CI which pollutes the test environment |
| 168 | + t.Setenv("INTEGRATION_TEST_BUILDKITE_TOKEN", "") |
| 169 | + t.Setenv("IMAGE", "") |
| 170 | + t.Setenv("NAMESPACE", "") |
| 171 | + t.Setenv("AGENT_TOKEN_SECRET", "") |
171 | 172 |
|
172 | | - cmd := &cobra.Command{} |
173 | | - controller.AddConfigFlags(cmd) |
174 | | - v, err := controller.ReadConfigFromFileArgsAndEnv(cmd, []string{}) |
175 | | - require.NoError(t, err) |
| 173 | + cmd := &cobra.Command{} |
| 174 | + controller.AddConfigFlags(cmd) |
| 175 | + v, err := controller.ReadConfigFromFileArgsAndEnv(cmd, []string{}) |
| 176 | + require.NoError(t, err) |
176 | 177 |
|
177 | | - // We need to read the config file from the test |
178 | | - v.SetConfigFile("../../examples/config.yaml") |
179 | | - require.NoError(t, v.ReadInConfig()) |
| 178 | + // We need to read the config file from the test |
| 179 | + v.SetConfigFile("../../examples/config.yaml") |
| 180 | + require.NoError(t, v.ReadInConfig()) |
180 | 181 |
|
181 | | - actual, err := controller.ParseAndValidateConfig(v) |
182 | | - require.NoError(t, err) |
| 182 | + actual, err := controller.ParseAndValidateConfig(v) |
| 183 | + require.NoError(t, err) |
183 | 184 |
|
184 | | - if diff := cmp.Diff(*actual, expected); diff != "" { |
185 | | - t.Errorf("parsed config diff (-got +want):\n%s", diff) |
186 | | - } |
| 185 | + if diff := cmp.Diff(*actual, expected); diff != "" { |
| 186 | + t.Errorf("parsed config diff (-got +want):\n%s", diff) |
| 187 | + } |
187 | 188 | } |
0 commit comments