2471 lines
100 KiB
Go
2471 lines
100 KiB
Go
package tests
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
v1alpha1 "github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1"
|
|
actionsgithubcom "github.com/actions/actions-runner-controller/controllers/actions.github.com"
|
|
"github.com/gruntwork-io/terratest/modules/helm"
|
|
"github.com/gruntwork-io/terratest/modules/k8s"
|
|
"github.com/gruntwork-io/terratest/modules/logger"
|
|
"github.com/gruntwork-io/terratest/modules/random"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
corev1 "k8s.io/api/core/v1"
|
|
rbacv1 "k8s.io/api/rbac/v1"
|
|
)
|
|
|
|
func TestTemplateRenderedGitHubSecretWithGitHubToken(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
|
|
|
var githubSecret corev1.Secret
|
|
helm.UnmarshalK8SYaml(t, output, &githubSecret)
|
|
|
|
assert.Equal(t, namespaceName, githubSecret.Namespace)
|
|
assert.Equal(t, "test-runners-gha-rs-github-secret", githubSecret.Name)
|
|
assert.Equal(t, "gh_token12345", string(githubSecret.Data["github_token"]))
|
|
assert.Equal(t, "actions.github.com/cleanup-protection", githubSecret.Finalizers[0])
|
|
}
|
|
|
|
func TestTemplateRenderedGitHubSecretWithGitHubApp(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_app_id": "10",
|
|
"githubConfigSecret.github_app_installation_id": "100",
|
|
"githubConfigSecret.github_app_private_key": "private_key",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
|
|
|
var githubSecret corev1.Secret
|
|
helm.UnmarshalK8SYaml(t, output, &githubSecret)
|
|
|
|
assert.Equal(t, namespaceName, githubSecret.Namespace)
|
|
assert.Equal(t, "10", string(githubSecret.Data["github_app_id"]))
|
|
assert.Equal(t, "100", string(githubSecret.Data["github_app_installation_id"]))
|
|
assert.Equal(t, "private_key", string(githubSecret.Data["github_app_private_key"]))
|
|
}
|
|
|
|
func TestTemplateRenderedGitHubSecretErrorWithMissingAuthInput(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_app_id": "",
|
|
"githubConfigSecret.github_token": "",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
|
require.Error(t, err)
|
|
|
|
assert.ErrorContains(t, err, "provide .Values.githubConfigSecret.github_token or .Values.githubConfigSecret.github_app_id")
|
|
}
|
|
|
|
func TestTemplateRenderedGitHubSecretErrorWithMissingAppInput(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_app_id": "10",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
|
require.Error(t, err)
|
|
|
|
assert.ErrorContains(t, err, "provide .Values.githubConfigSecret.github_app_installation_id and .Values.githubConfigSecret.github_app_private_key")
|
|
}
|
|
|
|
func TestTemplateNotRenderedGitHubSecretWithPredefinedSecret(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secret",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
|
assert.ErrorContains(t, err, "could not find template templates/githubsecret.yaml in chart", "secret should not be rendered since a pre-defined secret is provided")
|
|
}
|
|
|
|
func TestTemplateRenderedSetServiceAccountToNoPermission(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/no_permission_serviceaccount.yaml"})
|
|
var serviceAccount corev1.ServiceAccount
|
|
helm.UnmarshalK8SYaml(t, output, &serviceAccount)
|
|
|
|
assert.Equal(t, namespaceName, serviceAccount.Namespace)
|
|
assert.Equal(t, "test-runners-gha-rs-no-permission", serviceAccount.Name)
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, "test-runners-gha-rs-no-permission", ars.Spec.Template.Spec.ServiceAccountName)
|
|
assert.Empty(t, ars.Annotations[actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName]) // no finalizer protections in place
|
|
}
|
|
|
|
func TestTemplateRenderedSetServiceAccountToKubeMode(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_serviceaccount.yaml"})
|
|
var serviceAccount corev1.ServiceAccount
|
|
helm.UnmarshalK8SYaml(t, output, &serviceAccount)
|
|
|
|
assert.Equal(t, namespaceName, serviceAccount.Namespace)
|
|
assert.Equal(t, "test-runners-gha-rs-kube-mode", serviceAccount.Name)
|
|
assert.Equal(t, "actions.github.com/cleanup-protection", serviceAccount.Finalizers[0])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role.yaml"})
|
|
var role rbacv1.Role
|
|
helm.UnmarshalK8SYaml(t, output, &role)
|
|
|
|
assert.Equal(t, namespaceName, role.Namespace)
|
|
assert.Equal(t, "test-runners-gha-rs-kube-mode", role.Name)
|
|
|
|
assert.Equal(t, "actions.github.com/cleanup-protection", role.Finalizers[0])
|
|
|
|
assert.Len(t, role.Rules, 5, "kube mode role should have 5 rules")
|
|
assert.Equal(t, "pods", role.Rules[0].Resources[0])
|
|
assert.Equal(t, "pods/exec", role.Rules[1].Resources[0])
|
|
assert.Equal(t, "pods/log", role.Rules[2].Resources[0])
|
|
assert.Equal(t, "jobs", role.Rules[3].Resources[0])
|
|
assert.Equal(t, "secrets", role.Rules[4].Resources[0])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role_binding.yaml"})
|
|
var roleBinding rbacv1.RoleBinding
|
|
helm.UnmarshalK8SYaml(t, output, &roleBinding)
|
|
|
|
assert.Equal(t, namespaceName, roleBinding.Namespace)
|
|
assert.Equal(t, "test-runners-gha-rs-kube-mode", roleBinding.Name)
|
|
assert.Len(t, roleBinding.Subjects, 1)
|
|
assert.Equal(t, "test-runners-gha-rs-kube-mode", roleBinding.Subjects[0].Name)
|
|
assert.Equal(t, namespaceName, roleBinding.Subjects[0].Namespace)
|
|
assert.Equal(t, "test-runners-gha-rs-kube-mode", roleBinding.RoleRef.Name)
|
|
assert.Equal(t, "Role", roleBinding.RoleRef.Kind)
|
|
assert.Equal(t, "actions.github.com/cleanup-protection", serviceAccount.Finalizers[0])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
expectedServiceAccountName := "test-runners-gha-rs-kube-mode"
|
|
assert.Equal(t, expectedServiceAccountName, ars.Spec.Template.Spec.ServiceAccountName)
|
|
assert.Equal(t, expectedServiceAccountName, ars.Annotations[actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName])
|
|
}
|
|
|
|
func TestTemplateRenderedUserProvideSetServiceAccount(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"template.spec.serviceAccountName": "test-service-account",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/no_permission_serviceaccount.yaml"})
|
|
assert.ErrorContains(t, err, "could not find template templates/no_permission_serviceaccount.yaml in chart", "no permission service account should not be rendered")
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, "test-service-account", ars.Spec.Template.Spec.ServiceAccountName)
|
|
assert.Empty(t, ars.Annotations[actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName])
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, namespaceName, ars.Namespace)
|
|
assert.Equal(t, "test-runners", ars.Name)
|
|
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/name"])
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
|
assert.Equal(t, "gha-rs", ars.Labels["app.kubernetes.io/part-of"])
|
|
assert.Equal(t, "autoscaling-runner-set", ars.Labels["app.kubernetes.io/component"])
|
|
assert.NotEmpty(t, ars.Labels["app.kubernetes.io/version"])
|
|
|
|
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
|
assert.Equal(t, "test-runners-gha-rs-github-secret", ars.Spec.GitHubConfigSecret)
|
|
|
|
assert.Empty(t, ars.Spec.RunnerGroup, "RunnerGroup should be empty")
|
|
|
|
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
|
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
|
assert.Nil(t, ars.Spec.Proxy, "Proxy should be nil")
|
|
assert.Nil(t, ars.Spec.GitHubServerTLS, "GitHubServerTLS should be nil")
|
|
|
|
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "Template.Spec should have 1 container")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
|
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_RunnerScaleSetName(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
nameOverride := "test-runner-scale-set-name"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"runnerScaleSetName": nameOverride,
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, namespaceName, ars.Namespace)
|
|
assert.Equal(t, nameOverride, ars.Name)
|
|
|
|
assert.Equal(t, nameOverride, ars.Labels["app.kubernetes.io/name"])
|
|
assert.Equal(t, nameOverride, ars.Labels["app.kubernetes.io/instance"])
|
|
assert.Equal(t, nameOverride, ars.Labels["actions.github.com/scale-set-name"])
|
|
assert.Equal(t, namespaceName, ars.Labels["actions.github.com/scale-set-namespace"])
|
|
assert.Equal(t, "gha-rs", ars.Labels["app.kubernetes.io/part-of"])
|
|
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
|
assert.Equal(t, nameOverride+"-gha-rs-github-secret", ars.Spec.GitHubConfigSecret)
|
|
assert.Equal(t, "test-runner-scale-set-name", ars.Spec.RunnerScaleSetName)
|
|
|
|
assert.Empty(t, ars.Spec.RunnerGroup, "RunnerGroup should be empty")
|
|
|
|
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
|
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
|
assert.Nil(t, ars.Spec.Proxy, "Proxy should be nil")
|
|
assert.Nil(t, ars.Spec.GitHubServerTLS, "GitHubServerTLS should be nil")
|
|
|
|
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "Template.Spec should have 1 container")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
|
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_ProvideMetadata(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"template.metadata.labels.test1": "test1",
|
|
"template.metadata.labels.test2": "test2",
|
|
"template.metadata.annotations.test3": "test3",
|
|
"template.metadata.annotations.test4": "test4",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, namespaceName, ars.Namespace)
|
|
assert.Equal(t, "test-runners", ars.Name)
|
|
|
|
assert.NotNil(t, ars.Spec.Template.Labels, "Template.Spec.Labels should not be nil")
|
|
assert.Equal(t, "test1", ars.Spec.Template.Labels["test1"], "Template.Spec.Labels should have test1")
|
|
assert.Equal(t, "test2", ars.Spec.Template.Labels["test2"], "Template.Spec.Labels should have test2")
|
|
|
|
assert.NotNil(t, ars.Spec.Template.Annotations, "Template.Spec.Annotations should not be nil")
|
|
assert.Equal(t, "test3", ars.Spec.Template.Annotations["test3"], "Template.Spec.Annotations should have test3")
|
|
assert.Equal(t, "test4", ars.Spec.Template.Annotations["test4"], "Template.Spec.Annotations should have test4")
|
|
|
|
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "Template.Spec should have 1 container")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
|
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_MaxRunnersValidationError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"maxRunners": "-1",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
require.Error(t, err)
|
|
|
|
assert.ErrorContains(t, err, "maxRunners has to be greater or equal to 0")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_MinRunnersValidationError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"maxRunners": "1",
|
|
"minRunners": "-1",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
require.Error(t, err)
|
|
|
|
assert.ErrorContains(t, err, "minRunners has to be greater or equal to 0")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidationError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"maxRunners": "0",
|
|
"minRunners": "1",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
require.Error(t, err)
|
|
|
|
assert.ErrorContains(t, err, "maxRunners has to be greater or equal to minRunners")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidationSameValue(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"maxRunners": "0",
|
|
"minRunners": "0",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, 0, *ars.Spec.MinRunners, "MinRunners should be 0")
|
|
assert.Equal(t, 0, *ars.Spec.MaxRunners, "MaxRunners should be 0")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidation_OnlyMin(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"minRunners": "5",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, 5, *ars.Spec.MinRunners, "MinRunners should be 5")
|
|
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunnersValidation_OnlyMax(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"maxRunners": "5",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, 5, *ars.Spec.MaxRunners, "MaxRunners should be 5")
|
|
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_MinMaxRunners_FromValuesFile(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, 5, *ars.Spec.MinRunners, "MinRunners should be 5")
|
|
assert.Equal(t, 10, *ars.Spec.MaxRunners, "MaxRunners should be 10")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_ExtraVolumes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_extra_volumes.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Volumes, 3, "Volumes should be 3")
|
|
assert.Equal(t, "foo", ars.Spec.Template.Spec.Volumes[0].Name, "Volume name should be foo")
|
|
assert.Equal(t, "bar", ars.Spec.Template.Spec.Volumes[1].Name, "Volume name should be bar")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Volumes[2].Name, "Volume name should be work")
|
|
assert.Equal(t, "/data", ars.Spec.Template.Spec.Volumes[2].HostPath.Path, "Volume host path should be /data")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_DinD_ExtraInitContainers(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_dind_extra_init_containers.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.InitContainers, 3, "InitContainers should be 3")
|
|
assert.Equal(t, "kube-init", ars.Spec.Template.Spec.InitContainers[1].Name, "InitContainers[1] Name should be kube-init")
|
|
assert.Equal(t, "runner-image:latest", ars.Spec.Template.Spec.InitContainers[1].Image, "InitContainers[1] Image should be runner-image:latest")
|
|
assert.Equal(t, "sudo", ars.Spec.Template.Spec.InitContainers[1].Command[0], "InitContainers[1] Command[0] should be sudo")
|
|
assert.Equal(t, "chown", ars.Spec.Template.Spec.InitContainers[1].Command[1], "InitContainers[1] Command[1] should be chown")
|
|
assert.Equal(t, "-R", ars.Spec.Template.Spec.InitContainers[1].Command[2], "InitContainers[1] Command[2] should be -R")
|
|
assert.Equal(t, "1001:123", ars.Spec.Template.Spec.InitContainers[1].Command[3], "InitContainers[1] Command[3] should be 1001:123")
|
|
assert.Equal(t, "/home/runner/_work", ars.Spec.Template.Spec.InitContainers[1].Command[4], "InitContainers[1] Command[4] should be /home/runner/_work")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.InitContainers[1].VolumeMounts[0].Name, "InitContainers[1] VolumeMounts[0] Name should be work")
|
|
assert.Equal(t, "/home/runner/_work", ars.Spec.Template.Spec.InitContainers[1].VolumeMounts[0].MountPath, "InitContainers[1] VolumeMounts[0] MountPath should be /home/runner/_work")
|
|
|
|
assert.Equal(t, "ls", ars.Spec.Template.Spec.InitContainers[2].Name, "InitContainers[2] Name should be ls")
|
|
assert.Equal(t, "ubuntu:latest", ars.Spec.Template.Spec.InitContainers[2].Image, "InitContainers[2] Image should be ubuntu:latest")
|
|
assert.Equal(t, "ls", ars.Spec.Template.Spec.InitContainers[2].Command[0], "InitContainers[2] Command[0] should be ls")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_DinD_ExtraVolumes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_dind_extra_volumes.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Volumes, 5, "Volumes should be 5")
|
|
assert.Equal(t, "dind-sock", ars.Spec.Template.Spec.Volumes[0].Name, "Volume name should be dind-sock")
|
|
assert.Equal(t, "dind-externals", ars.Spec.Template.Spec.Volumes[1].Name, "Volume name should be dind-externals")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Volumes[2].Name, "Volume name should be work")
|
|
assert.Equal(t, "/data", ars.Spec.Template.Spec.Volumes[2].HostPath.Path, "Volume host path should be /data")
|
|
assert.Equal(t, "foo", ars.Spec.Template.Spec.Volumes[3].Name, "Volume name should be foo")
|
|
assert.Equal(t, "bar", ars.Spec.Template.Spec.Volumes[4].Name, "Volume name should be bar")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_K8S_ExtraVolumes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_k8s_extra_volumes.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Volumes, 3, "Volumes should be 3")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Volumes[0].Name, "Volume name should be work")
|
|
assert.Equal(t, "/data", ars.Spec.Template.Spec.Volumes[0].HostPath.Path, "Volume host path should be /data")
|
|
assert.Equal(t, "foo", ars.Spec.Template.Spec.Volumes[1].Name, "Volume name should be foo")
|
|
assert.Equal(t, "bar", ars.Spec.Template.Spec.Volumes[2].Name, "Volume name should be bar")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_EnableDinD(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"containerMode.type": "dind",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, namespaceName, ars.Namespace)
|
|
assert.Equal(t, "test-runners", ars.Name)
|
|
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/name"])
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
|
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
|
assert.Equal(t, "test-runners-gha-rs-github-secret", ars.Spec.GitHubConfigSecret)
|
|
|
|
assert.Empty(t, ars.Spec.RunnerGroup, "RunnerGroup should be empty")
|
|
|
|
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
|
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
|
assert.Nil(t, ars.Spec.Proxy, "Proxy should be nil")
|
|
assert.Nil(t, ars.Spec.GitHubServerTLS, "GitHubServerTLS should be nil")
|
|
|
|
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.InitContainers, 1, "Template.Spec should have 1 init container")
|
|
assert.Equal(t, "init-dind-externals", ars.Spec.Template.Spec.InitContainers[0].Name)
|
|
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.InitContainers[0].Image)
|
|
assert.Equal(t, "cp", ars.Spec.Template.Spec.InitContainers[0].Command[0])
|
|
assert.Equal(t, "-r /home/runner/externals/. /home/runner/tmpDir/", strings.Join(ars.Spec.Template.Spec.InitContainers[0].Args, " "))
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 2, "Template.Spec should have 2 container")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
|
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers[0].Env, 2, "The runner container should have 2 env vars, DOCKER_HOST and RUNNER_WAIT_FOR_DOCKER_IN_SECONDS")
|
|
assert.Equal(t, "DOCKER_HOST", ars.Spec.Template.Spec.Containers[0].Env[0].Name)
|
|
assert.Equal(t, "unix:///var/run/docker.sock", ars.Spec.Template.Spec.Containers[0].Env[0].Value)
|
|
assert.Equal(t, "RUNNER_WAIT_FOR_DOCKER_IN_SECONDS", ars.Spec.Template.Spec.Containers[0].Env[1].Name)
|
|
assert.Equal(t, "120", ars.Spec.Template.Spec.Containers[0].Env[1].Value)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, 2, "The runner container should have 2 volume mounts, dind-sock and work")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name)
|
|
assert.Equal(t, "/home/runner/_work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath)
|
|
assert.False(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].ReadOnly)
|
|
|
|
assert.Equal(t, "dind-sock", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].Name)
|
|
assert.Equal(t, "/var/run", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath)
|
|
|
|
assert.Equal(t, "dind", ars.Spec.Template.Spec.Containers[1].Name)
|
|
assert.Equal(t, "docker:dind", ars.Spec.Template.Spec.Containers[1].Image)
|
|
assert.True(t, *ars.Spec.Template.Spec.Containers[1].SecurityContext.Privileged)
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers[1].VolumeMounts, 3, "The dind container should have 3 volume mounts, dind-sock, work and externals")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Containers[1].VolumeMounts[0].Name)
|
|
assert.Equal(t, "/home/runner/_work", ars.Spec.Template.Spec.Containers[1].VolumeMounts[0].MountPath)
|
|
|
|
assert.Equal(t, "dind-sock", ars.Spec.Template.Spec.Containers[1].VolumeMounts[1].Name)
|
|
assert.Equal(t, "/var/run", ars.Spec.Template.Spec.Containers[1].VolumeMounts[1].MountPath)
|
|
|
|
assert.Equal(t, "dind-externals", ars.Spec.Template.Spec.Containers[1].VolumeMounts[2].Name)
|
|
assert.Equal(t, "/home/runner/externals", ars.Spec.Template.Spec.Containers[1].VolumeMounts[2].MountPath)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Volumes, 3, "Volumes should be 3")
|
|
assert.Equal(t, "dind-sock", ars.Spec.Template.Spec.Volumes[0].Name, "Volume name should be dind-sock")
|
|
assert.Equal(t, "dind-externals", ars.Spec.Template.Spec.Volumes[1].Name, "Volume name should be dind-externals")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Volumes[2].Name, "Volume name should be work")
|
|
assert.NotNil(t, ars.Spec.Template.Spec.Volumes[2].EmptyDir, "Volume work should be an emptyDir")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_EnableKubernetesMode(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, namespaceName, ars.Namespace)
|
|
assert.Equal(t, "test-runners", ars.Name)
|
|
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/name"])
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
|
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
|
assert.Equal(t, "test-runners-gha-rs-github-secret", ars.Spec.GitHubConfigSecret)
|
|
|
|
assert.Empty(t, ars.Spec.RunnerGroup, "RunnerGroup should be empty")
|
|
assert.Nil(t, ars.Spec.MinRunners, "MinRunners should be nil")
|
|
assert.Nil(t, ars.Spec.MaxRunners, "MaxRunners should be nil")
|
|
assert.Nil(t, ars.Spec.Proxy, "Proxy should be nil")
|
|
assert.Nil(t, ars.Spec.GitHubServerTLS, "GitHubServerTLS should be nil")
|
|
|
|
assert.NotNil(t, ars.Spec.Template.Spec, "Template.Spec should not be nil")
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "Template.Spec should have 1 container")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name)
|
|
assert.Equal(t, "ghcr.io/actions/actions-runner:latest", ars.Spec.Template.Spec.Containers[0].Image)
|
|
|
|
assert.Equal(t, "ACTIONS_RUNNER_CONTAINER_HOOKS", ars.Spec.Template.Spec.Containers[0].Env[0].Name)
|
|
assert.Equal(t, "/home/runner/k8s/index.js", ars.Spec.Template.Spec.Containers[0].Env[0].Value)
|
|
assert.Equal(t, "ACTIONS_RUNNER_POD_NAME", ars.Spec.Template.Spec.Containers[0].Env[1].Name)
|
|
assert.Equal(t, "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER", ars.Spec.Template.Spec.Containers[0].Env[2].Name)
|
|
assert.Equal(t, "true", ars.Spec.Template.Spec.Containers[0].Env[2].Value)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Volumes, 1, "Template.Spec should have 1 volume")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Volumes[0].Name)
|
|
assert.NotNil(t, ars.Spec.Template.Spec.Volumes[0].Ephemeral, "Template.Spec should have 1 ephemeral volume")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoscalingRunnerSet_ListenerPodTemplate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_listener_template.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
require.NotNil(t, ars.Spec.ListenerTemplate, "ListenerPodTemplate should not be nil")
|
|
|
|
assert.Equal(t, ars.Spec.ListenerTemplate.Spec.Hostname, "example")
|
|
|
|
require.Len(t, ars.Spec.ListenerTemplate.Spec.Containers, 2, "ListenerPodTemplate should have 2 containers")
|
|
assert.Equal(t, ars.Spec.ListenerTemplate.Spec.Containers[0].Name, "listener")
|
|
assert.Equal(t, ars.Spec.ListenerTemplate.Spec.Containers[0].Image, "listener:latest")
|
|
assert.ElementsMatch(t, ars.Spec.ListenerTemplate.Spec.Containers[0].Command, []string{"/path/to/entrypoint"})
|
|
assert.Len(t, ars.Spec.ListenerTemplate.Spec.Containers[0].VolumeMounts, 1, "VolumeMounts should be 1")
|
|
assert.Equal(t, ars.Spec.ListenerTemplate.Spec.Containers[0].VolumeMounts[0].Name, "work")
|
|
assert.Equal(t, ars.Spec.ListenerTemplate.Spec.Containers[0].VolumeMounts[0].MountPath, "/home/example")
|
|
|
|
assert.Equal(t, ars.Spec.ListenerTemplate.Spec.Containers[1].Name, "side-car")
|
|
assert.Equal(t, ars.Spec.ListenerTemplate.Spec.Containers[1].Image, "nginx:latest")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_UsePredefinedSecret(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, namespaceName, ars.Namespace)
|
|
assert.Equal(t, "test-runners", ars.Name)
|
|
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/name"])
|
|
assert.Equal(t, "test-runners", ars.Labels["app.kubernetes.io/instance"])
|
|
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
|
assert.Equal(t, "pre-defined-secrets", ars.Spec.GitHubConfigSecret)
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_ErrorOnEmptyPredefinedSecret(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
require.Error(t, err)
|
|
|
|
assert.ErrorContains(t, err, "Values.githubConfigSecret is required for setting auth with GitHub server")
|
|
}
|
|
|
|
func TestTemplateRenderedWithProxy(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
"proxy.http.url": "http://proxy.example.com",
|
|
"proxy.http.credentialSecretRef": "http-secret",
|
|
"proxy.https.url": "https://proxy.example.com",
|
|
"proxy.https.credentialSecretRef": "https-secret",
|
|
"proxy.noProxy": "{example.com,example.org}",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
require.NotNil(t, ars.Spec.Proxy)
|
|
require.NotNil(t, ars.Spec.Proxy.HTTP)
|
|
assert.Equal(t, "http://proxy.example.com", ars.Spec.Proxy.HTTP.Url)
|
|
assert.Equal(t, "http-secret", ars.Spec.Proxy.HTTP.CredentialSecretRef)
|
|
|
|
require.NotNil(t, ars.Spec.Proxy.HTTPS)
|
|
assert.Equal(t, "https://proxy.example.com", ars.Spec.Proxy.HTTPS.Url)
|
|
assert.Equal(t, "https-secret", ars.Spec.Proxy.HTTPS.CredentialSecretRef)
|
|
|
|
require.NotNil(t, ars.Spec.Proxy.NoProxy)
|
|
require.Len(t, ars.Spec.Proxy.NoProxy, 2)
|
|
assert.Contains(t, ars.Spec.Proxy.NoProxy, "example.com")
|
|
assert.Contains(t, ars.Spec.Proxy.NoProxy, "example.org")
|
|
}
|
|
|
|
func TestTemplateRenderedWithTLS(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
render := func(t *testing.T, options *helm.Options) v1alpha1.AutoscalingRunnerSet {
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
|
|
output := helm.RenderTemplate(
|
|
t,
|
|
options,
|
|
helmChartPath,
|
|
releaseName,
|
|
[]string{"templates/autoscalingrunnerset.yaml"},
|
|
)
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
return ars
|
|
}
|
|
|
|
t.Run("providing githubServerTLS.runnerMountPath", func(t *testing.T) {
|
|
t.Run("mode: default", func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.key": "cert.pem",
|
|
"githubServerTLS.runnerMountPath": "/runner/mount/path",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
ars := render(t, options)
|
|
|
|
require.NotNil(t, ars.Spec.GitHubServerTLS)
|
|
expected := &v1alpha1.GitHubServerTLSConfig{
|
|
CertificateFrom: &v1alpha1.TLSCertificateSource{
|
|
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "certs-configmap",
|
|
},
|
|
Key: "cert.pem",
|
|
},
|
|
},
|
|
}
|
|
assert.Equal(t, expected, ars.Spec.GitHubServerTLS)
|
|
|
|
var volume *corev1.Volume
|
|
for _, v := range ars.Spec.Template.Spec.Volumes {
|
|
if v.Name == "github-server-tls-cert" {
|
|
volume = &v
|
|
break
|
|
}
|
|
}
|
|
require.NotNil(t, volume)
|
|
assert.Equal(t, "certs-configmap", volume.ConfigMap.Name)
|
|
assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Key)
|
|
assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Path)
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
|
|
Name: "github-server-tls-cert",
|
|
MountPath: "/runner/mount/path/cert.pem",
|
|
SubPath: "cert.pem",
|
|
})
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "NODE_EXTRA_CA_CERTS",
|
|
Value: "/runner/mount/path/cert.pem",
|
|
})
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "RUNNER_UPDATE_CA_CERTS",
|
|
Value: "1",
|
|
})
|
|
})
|
|
|
|
t.Run("mode: dind", func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.key": "cert.pem",
|
|
"githubServerTLS.runnerMountPath": "/runner/mount/path/",
|
|
"containerMode.type": "dind",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
ars := render(t, options)
|
|
|
|
require.NotNil(t, ars.Spec.GitHubServerTLS)
|
|
expected := &v1alpha1.GitHubServerTLSConfig{
|
|
CertificateFrom: &v1alpha1.TLSCertificateSource{
|
|
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "certs-configmap",
|
|
},
|
|
Key: "cert.pem",
|
|
},
|
|
},
|
|
}
|
|
assert.Equal(t, expected, ars.Spec.GitHubServerTLS)
|
|
|
|
var volume *corev1.Volume
|
|
for _, v := range ars.Spec.Template.Spec.Volumes {
|
|
if v.Name == "github-server-tls-cert" {
|
|
volume = &v
|
|
break
|
|
}
|
|
}
|
|
require.NotNil(t, volume)
|
|
assert.Equal(t, "certs-configmap", volume.ConfigMap.Name)
|
|
assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Key)
|
|
assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Path)
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
|
|
Name: "github-server-tls-cert",
|
|
MountPath: "/runner/mount/path/cert.pem",
|
|
SubPath: "cert.pem",
|
|
})
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "NODE_EXTRA_CA_CERTS",
|
|
Value: "/runner/mount/path/cert.pem",
|
|
})
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "RUNNER_UPDATE_CA_CERTS",
|
|
Value: "1",
|
|
})
|
|
})
|
|
|
|
t.Run("mode: kubernetes", func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.key": "cert.pem",
|
|
"githubServerTLS.runnerMountPath": "/runner/mount/path",
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
ars := render(t, options)
|
|
|
|
require.NotNil(t, ars.Spec.GitHubServerTLS)
|
|
expected := &v1alpha1.GitHubServerTLSConfig{
|
|
CertificateFrom: &v1alpha1.TLSCertificateSource{
|
|
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "certs-configmap",
|
|
},
|
|
Key: "cert.pem",
|
|
},
|
|
},
|
|
}
|
|
assert.Equal(t, expected, ars.Spec.GitHubServerTLS)
|
|
|
|
var volume *corev1.Volume
|
|
for _, v := range ars.Spec.Template.Spec.Volumes {
|
|
if v.Name == "github-server-tls-cert" {
|
|
volume = &v
|
|
break
|
|
}
|
|
}
|
|
require.NotNil(t, volume)
|
|
assert.Equal(t, "certs-configmap", volume.ConfigMap.Name)
|
|
assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Key)
|
|
assert.Equal(t, "cert.pem", volume.ConfigMap.Items[0].Path)
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
|
|
Name: "github-server-tls-cert",
|
|
MountPath: "/runner/mount/path/cert.pem",
|
|
SubPath: "cert.pem",
|
|
})
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "NODE_EXTRA_CA_CERTS",
|
|
Value: "/runner/mount/path/cert.pem",
|
|
})
|
|
|
|
assert.Contains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "RUNNER_UPDATE_CA_CERTS",
|
|
Value: "1",
|
|
})
|
|
})
|
|
})
|
|
|
|
t.Run("without providing githubServerTLS.runnerMountPath", func(t *testing.T) {
|
|
t.Run("mode: default", func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.key": "cert.pem",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
ars := render(t, options)
|
|
|
|
require.NotNil(t, ars.Spec.GitHubServerTLS)
|
|
expected := &v1alpha1.GitHubServerTLSConfig{
|
|
CertificateFrom: &v1alpha1.TLSCertificateSource{
|
|
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "certs-configmap",
|
|
},
|
|
Key: "cert.pem",
|
|
},
|
|
},
|
|
}
|
|
assert.Equal(t, expected, ars.Spec.GitHubServerTLS)
|
|
|
|
var volume *corev1.Volume
|
|
for _, v := range ars.Spec.Template.Spec.Volumes {
|
|
if v.Name == "github-server-tls-cert" {
|
|
volume = &v
|
|
break
|
|
}
|
|
}
|
|
assert.Nil(t, volume)
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
|
|
Name: "github-server-tls-cert",
|
|
MountPath: "/runner/mount/path/cert.pem",
|
|
SubPath: "cert.pem",
|
|
})
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "NODE_EXTRA_CA_CERTS",
|
|
Value: "/runner/mount/path/cert.pem",
|
|
})
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "RUNNER_UPDATE_CA_CERTS",
|
|
Value: "1",
|
|
})
|
|
})
|
|
|
|
t.Run("mode: dind", func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.key": "cert.pem",
|
|
"containerMode.type": "dind",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
ars := render(t, options)
|
|
|
|
require.NotNil(t, ars.Spec.GitHubServerTLS)
|
|
expected := &v1alpha1.GitHubServerTLSConfig{
|
|
CertificateFrom: &v1alpha1.TLSCertificateSource{
|
|
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "certs-configmap",
|
|
},
|
|
Key: "cert.pem",
|
|
},
|
|
},
|
|
}
|
|
assert.Equal(t, expected, ars.Spec.GitHubServerTLS)
|
|
|
|
var volume *corev1.Volume
|
|
for _, v := range ars.Spec.Template.Spec.Volumes {
|
|
if v.Name == "github-server-tls-cert" {
|
|
volume = &v
|
|
break
|
|
}
|
|
}
|
|
assert.Nil(t, volume)
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
|
|
Name: "github-server-tls-cert",
|
|
MountPath: "/runner/mount/path/cert.pem",
|
|
SubPath: "cert.pem",
|
|
})
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "NODE_EXTRA_CA_CERTS",
|
|
Value: "/runner/mount/path/cert.pem",
|
|
})
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "RUNNER_UPDATE_CA_CERTS",
|
|
Value: "1",
|
|
})
|
|
})
|
|
|
|
t.Run("mode: kubernetes", func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secrets",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.name": "certs-configmap",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.key": "cert.pem",
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
ars := render(t, options)
|
|
|
|
require.NotNil(t, ars.Spec.GitHubServerTLS)
|
|
expected := &v1alpha1.GitHubServerTLSConfig{
|
|
CertificateFrom: &v1alpha1.TLSCertificateSource{
|
|
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "certs-configmap",
|
|
},
|
|
Key: "cert.pem",
|
|
},
|
|
},
|
|
}
|
|
assert.Equal(t, expected, ars.Spec.GitHubServerTLS)
|
|
|
|
var volume *corev1.Volume
|
|
for _, v := range ars.Spec.Template.Spec.Volumes {
|
|
if v.Name == "github-server-tls-cert" {
|
|
volume = &v
|
|
break
|
|
}
|
|
}
|
|
assert.Nil(t, volume)
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
|
|
Name: "github-server-tls-cert",
|
|
MountPath: "/runner/mount/path/cert.pem",
|
|
SubPath: "cert.pem",
|
|
})
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "NODE_EXTRA_CA_CERTS",
|
|
Value: "/runner/mount/path/cert.pem",
|
|
})
|
|
|
|
assert.NotContains(t, ars.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
|
|
Name: "RUNNER_UPDATE_CA_CERTS",
|
|
Value: "1",
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestTemplateNamingConstraints(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
setValues := map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
}
|
|
|
|
tt := map[string]struct {
|
|
releaseName string
|
|
namespaceName string
|
|
expectedError string
|
|
}{
|
|
"Name too long": {
|
|
releaseName: strings.Repeat("a", 46),
|
|
namespaceName: "test-" + strings.ToLower(random.UniqueId()),
|
|
expectedError: "Name must have up to 45 characters",
|
|
},
|
|
"Namespace too long": {
|
|
releaseName: "test-" + strings.ToLower(random.UniqueId()),
|
|
namespaceName: strings.Repeat("a", 64),
|
|
expectedError: "Namespace must have up to 63 characters",
|
|
},
|
|
}
|
|
|
|
for name, tc := range tt {
|
|
t.Run(name, func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: setValues,
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", tc.namespaceName),
|
|
}
|
|
_, err = helm.RenderTemplateE(t, options, helmChartPath, tc.releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
require.Error(t, err)
|
|
assert.ErrorContains(t, err, tc.expectedError)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTemplateRenderedGitHubConfigUrlEndsWIthSlash(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions/",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, namespaceName, ars.Namespace)
|
|
assert.Equal(t, "test-runners", ars.Name)
|
|
assert.Equal(t, "https://github.com/actions", ars.Spec.GitHubConfigUrl)
|
|
}
|
|
|
|
func TestTemplate_CreateManagerRole(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/manager_role.yaml"})
|
|
|
|
var managerRole rbacv1.Role
|
|
helm.UnmarshalK8SYaml(t, output, &managerRole)
|
|
|
|
assert.Equal(t, namespaceName, managerRole.Namespace, "namespace should match the namespace of the Helm release")
|
|
assert.Equal(t, "test-runners-gha-rs-manager", managerRole.Name)
|
|
assert.Equal(t, "actions.github.com/cleanup-protection", managerRole.Finalizers[0])
|
|
assert.Equal(t, 6, len(managerRole.Rules))
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
}
|
|
|
|
func TestTemplate_CreateManagerRole_UseConfigMaps(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
"githubServerTLS.certificateFrom.configMapKeyRef.name": "test",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/manager_role.yaml"})
|
|
|
|
var managerRole rbacv1.Role
|
|
helm.UnmarshalK8SYaml(t, output, &managerRole)
|
|
|
|
assert.Equal(t, namespaceName, managerRole.Namespace, "namespace should match the namespace of the Helm release")
|
|
assert.Equal(t, "test-runners-gha-rs-manager", managerRole.Name)
|
|
assert.Equal(t, "actions.github.com/cleanup-protection", managerRole.Finalizers[0])
|
|
assert.Equal(t, 7, len(managerRole.Rules))
|
|
assert.Equal(t, "configmaps", managerRole.Rules[6].Resources[0])
|
|
}
|
|
|
|
func TestTemplate_CreateManagerRoleBinding(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/manager_role_binding.yaml"})
|
|
|
|
var managerRoleBinding rbacv1.RoleBinding
|
|
helm.UnmarshalK8SYaml(t, output, &managerRoleBinding)
|
|
|
|
assert.Equal(t, namespaceName, managerRoleBinding.Namespace, "namespace should match the namespace of the Helm release")
|
|
assert.Equal(t, "test-runners-gha-rs-manager", managerRoleBinding.Name)
|
|
assert.Equal(t, "test-runners-gha-rs-manager", managerRoleBinding.RoleRef.Name)
|
|
assert.Equal(t, "actions.github.com/cleanup-protection", managerRoleBinding.Finalizers[0])
|
|
assert.Equal(t, "arc", managerRoleBinding.Subjects[0].Name)
|
|
assert.Equal(t, "arc-system", managerRoleBinding.Subjects[0].Namespace)
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_ExtraContainers(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_extra_containers.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"}, "--debug")
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 2, "There should be 2 containers")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name, "Container name should be runner")
|
|
assert.Equal(t, "other", ars.Spec.Template.Spec.Containers[1].Name, "Container name should be other")
|
|
assert.Equal(t, "250m", ars.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu().String(), "CPU Limit should be set")
|
|
assert.Equal(t, "64Mi", ars.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().String(), "Memory Limit should be set")
|
|
assert.Equal(t, "250m", ars.Spec.Template.Spec.Containers[1].Resources.Limits.Cpu().String(), "CPU Limit should be set")
|
|
assert.Equal(t, "64Mi", ars.Spec.Template.Spec.Containers[1].Resources.Limits.Memory().String(), "Memory Limit should be set")
|
|
assert.Equal(t, "SOME_ENV", ars.Spec.Template.Spec.Containers[0].Env[0].Name, "SOME_ENV should be set")
|
|
assert.Equal(t, "SOME_VALUE", ars.Spec.Template.Spec.Containers[0].Env[0].Value, "SOME_ENV should be set to `SOME_VALUE`")
|
|
assert.Equal(t, "MY_NODE_NAME", ars.Spec.Template.Spec.Containers[0].Env[1].Name, "MY_NODE_NAME should be set")
|
|
assert.Equal(t, "spec.nodeName", ars.Spec.Template.Spec.Containers[0].Env[1].ValueFrom.FieldRef.FieldPath, "MY_NODE_NAME should be set to `spec.nodeName`")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name, "VolumeMount name should be work")
|
|
assert.Equal(t, "/work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath, "VolumeMount mountPath should be /work")
|
|
assert.Equal(t, "others", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].Name, "VolumeMount name should be others")
|
|
assert.Equal(t, "/others", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath, "VolumeMount mountPath should be /others")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Volumes[0].Name, "Volume name should be work")
|
|
assert.Equal(t, corev1.DNSNone, ars.Spec.Template.Spec.DNSPolicy, "DNS Policy should be None")
|
|
assert.Equal(t, "192.0.2.1", ars.Spec.Template.Spec.DNSConfig.Nameservers[0], "DNS Nameserver should be set")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_RestartPolicy(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, corev1.RestartPolicyNever, ars.Spec.Template.Spec.RestartPolicy, "RestartPolicy should be Never")
|
|
|
|
options = &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
"template.spec.restartPolicy": "Always",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"}, "--debug")
|
|
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Equal(t, corev1.RestartPolicyAlways, ars.Spec.Template.Spec.RestartPolicy, "RestartPolicy should be Always")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_ExtraPodSpec(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_extra_pod_spec.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "There should be 1 containers")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name, "Container name should be runner")
|
|
assert.Equal(t, corev1.DNSNone, ars.Spec.Template.Spec.DNSPolicy, "DNS Policy should be None")
|
|
assert.Equal(t, "192.0.2.1", ars.Spec.Template.Spec.DNSConfig.Nameservers[0], "DNS Nameserver should be set")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_DinDMergePodSpec(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_dind_merge_spec.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"}, "--debug")
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 2, "There should be 2 containers")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name, "Container name should be runner")
|
|
assert.Equal(t, "250m", ars.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu().String(), "CPU Limit should be set")
|
|
assert.Equal(t, "64Mi", ars.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().String(), "Memory Limit should be set")
|
|
assert.Equal(t, "DOCKER_HOST", ars.Spec.Template.Spec.Containers[0].Env[0].Name, "DOCKER_HOST should be set")
|
|
assert.Equal(t, "tcp://localhost:9999", ars.Spec.Template.Spec.Containers[0].Env[0].Value, "DOCKER_HOST should be set to `tcp://localhost:9999`")
|
|
assert.Equal(t, "MY_NODE_NAME", ars.Spec.Template.Spec.Containers[0].Env[1].Name, "MY_NODE_NAME should be set")
|
|
assert.Equal(t, "spec.nodeName", ars.Spec.Template.Spec.Containers[0].Env[1].ValueFrom.FieldRef.FieldPath, "MY_NODE_NAME should be set to `spec.nodeName`")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name, "VolumeMount name should be work")
|
|
assert.Equal(t, "/work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath, "VolumeMount mountPath should be /work")
|
|
assert.Equal(t, "others", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].Name, "VolumeMount name should be others")
|
|
assert.Equal(t, "/others", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath, "VolumeMount mountPath should be /others")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoScalingRunnerSet_KubeModeMergePodSpec(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values_k8s_merge_spec.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"}, "--debug")
|
|
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
|
|
assert.Len(t, ars.Spec.Template.Spec.Containers, 1, "There should be 1 containers")
|
|
assert.Equal(t, "runner", ars.Spec.Template.Spec.Containers[0].Name, "Container name should be runner")
|
|
assert.Equal(t, "250m", ars.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu().String(), "CPU Limit should be set")
|
|
assert.Equal(t, "64Mi", ars.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().String(), "Memory Limit should be set")
|
|
assert.Equal(t, "ACTIONS_RUNNER_CONTAINER_HOOKS", ars.Spec.Template.Spec.Containers[0].Env[0].Name, "ACTIONS_RUNNER_CONTAINER_HOOKS should be set")
|
|
assert.Equal(t, "/k8s/index.js", ars.Spec.Template.Spec.Containers[0].Env[0].Value, "ACTIONS_RUNNER_CONTAINER_HOOKS should be set to `/k8s/index.js`")
|
|
assert.Equal(t, "MY_NODE_NAME", ars.Spec.Template.Spec.Containers[0].Env[1].Name, "MY_NODE_NAME should be set")
|
|
assert.Equal(t, "spec.nodeName", ars.Spec.Template.Spec.Containers[0].Env[1].ValueFrom.FieldRef.FieldPath, "MY_NODE_NAME should be set to `spec.nodeName`")
|
|
assert.Equal(t, "ACTIONS_RUNNER_POD_NAME", ars.Spec.Template.Spec.Containers[0].Env[2].Name, "ACTIONS_RUNNER_POD_NAME should be set")
|
|
assert.Equal(t, "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER", ars.Spec.Template.Spec.Containers[0].Env[3].Name, "ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER should be set")
|
|
assert.Equal(t, "work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].Name, "VolumeMount name should be work")
|
|
assert.Equal(t, "/work", ars.Spec.Template.Spec.Containers[0].VolumeMounts[0].MountPath, "VolumeMount mountPath should be /work")
|
|
assert.Equal(t, "others", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].Name, "VolumeMount name should be others")
|
|
assert.Equal(t, "/others", ars.Spec.Template.Spec.Containers[0].VolumeMounts[1].MountPath, "VolumeMount mountPath should be /others")
|
|
}
|
|
|
|
func TestTemplateRenderedAutoscalingRunnerSetAnnotation_GitHubSecret(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
annotationExpectedTests := map[string]*helm.Options{
|
|
"GitHub token": {
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
},
|
|
"GitHub app": {
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_app_id": "10",
|
|
"githubConfigSecret.github_app_installation_id": "100",
|
|
"githubConfigSecret.github_app_private_key": "private_key",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
},
|
|
}
|
|
|
|
for name, options := range annotationExpectedTests {
|
|
t.Run("Annotation set: "+name, func(t *testing.T) {
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var autoscalingRunnerSet v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &autoscalingRunnerSet)
|
|
|
|
assert.NotEmpty(t, autoscalingRunnerSet.Annotations[actionsgithubcom.AnnotationKeyGitHubSecretName])
|
|
})
|
|
}
|
|
|
|
t.Run("Annotation should not be set", func(t *testing.T) {
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret": "pre-defined-secret",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var autoscalingRunnerSet v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &autoscalingRunnerSet)
|
|
|
|
assert.Empty(t, autoscalingRunnerSet.Annotations[actionsgithubcom.AnnotationKeyGitHubSecretName])
|
|
})
|
|
}
|
|
|
|
func TestTemplateRenderedAutoscalingRunnerSetAnnotation_KubernetesModeCleanup(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
"containerMode.type": "kubernetes",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var autoscalingRunnerSet v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &autoscalingRunnerSet)
|
|
|
|
annotationValues := map[string]string{
|
|
actionsgithubcom.AnnotationKeyGitHubSecretName: "test-runners-gha-rs-github-secret",
|
|
actionsgithubcom.AnnotationKeyManagerRoleName: "test-runners-gha-rs-manager",
|
|
actionsgithubcom.AnnotationKeyManagerRoleBindingName: "test-runners-gha-rs-manager",
|
|
actionsgithubcom.AnnotationKeyKubernetesModeServiceAccountName: "test-runners-gha-rs-kube-mode",
|
|
actionsgithubcom.AnnotationKeyKubernetesModeRoleName: "test-runners-gha-rs-kube-mode",
|
|
actionsgithubcom.AnnotationKeyKubernetesModeRoleBindingName: "test-runners-gha-rs-kube-mode",
|
|
}
|
|
|
|
for annotation, value := range annotationValues {
|
|
assert.Equal(t, value, autoscalingRunnerSet.Annotations[annotation], fmt.Sprintf("Annotation %q does not match the expected value", annotation))
|
|
}
|
|
}
|
|
|
|
func TestRunnerContainerEnvNotEmptyMap(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
type testModel struct {
|
|
Spec struct {
|
|
Template struct {
|
|
Spec struct {
|
|
Containers []map[string]any `yaml:"containers"`
|
|
} `yaml:"spec"`
|
|
} `yaml:"template"`
|
|
} `yaml:"spec"`
|
|
}
|
|
|
|
var m testModel
|
|
helm.UnmarshalK8SYaml(t, output, &m)
|
|
_, ok := m.Spec.Template.Spec.Containers[0]["env"]
|
|
assert.False(t, ok, "env should not be set")
|
|
}
|
|
|
|
func TestRunnerContainerVolumeNotEmptyMap(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
testValuesPath, err := filepath.Abs("../tests/values.yaml")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
ValuesFiles: []string{testValuesPath},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
type testModel struct {
|
|
Spec struct {
|
|
Template struct {
|
|
Spec struct {
|
|
Containers []map[string]any `yaml:"containers"`
|
|
} `yaml:"spec"`
|
|
} `yaml:"template"`
|
|
} `yaml:"spec"`
|
|
}
|
|
|
|
var m testModel
|
|
helm.UnmarshalK8SYaml(t, output, &m)
|
|
_, ok := m.Spec.Template.Spec.Containers[0]["volumeMounts"]
|
|
assert.False(t, ok, "volumeMounts should not be set")
|
|
}
|
|
|
|
func TestAutoscalingRunnerSetAnnotationValuesHash(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const valuesHash = "actions.github.com/values-hash"
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
var autoscalingRunnerSet v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &autoscalingRunnerSet)
|
|
|
|
firstHash := autoscalingRunnerSet.Annotations["actions.github.com/values-hash"]
|
|
assert.NotEmpty(t, firstHash)
|
|
assert.LessOrEqual(t, len(firstHash), 63)
|
|
|
|
helmChartPath, err = filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
options = &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token1234567890",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
|
|
helm.UnmarshalK8SYaml(t, output, &autoscalingRunnerSet)
|
|
secondHash := autoscalingRunnerSet.Annotations[valuesHash]
|
|
assert.NotEmpty(t, secondHash)
|
|
assert.NotEqual(t, firstHash, secondHash)
|
|
assert.LessOrEqual(t, len(secondHash), 63)
|
|
}
|
|
|
|
func TestCustomLabels(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
`labels.argocd\.argoproj\.io/sync-wave`: `"1"`,
|
|
`labels.app\.kubernetes\.io/part-of`: "no-override", // this shouldn't be overwritten
|
|
"resourceMeta.autoscalingRunnerSet.labels.ars-custom": "ars-custom-value",
|
|
"resourceMeta.githubConfigSecret.labels.gh-custom": "gh-custom-value",
|
|
"resourceMeta.kubernetesModeRole.labels.kmr-custom": "kmr-custom-value",
|
|
"resourceMeta.kubernetesModeRoleBinding.labels.kmrb-custom": "kmrb-custom-value",
|
|
"resourceMeta.kubernetesModeServiceAccount.labels.kmsa-custom": "kmsa-custom-value",
|
|
"resourceMeta.managerRole.labels.mr-custom": "mr-custom-value",
|
|
"resourceMeta.managerRoleBinding.labels.mrb-custom": "mrb-custom-value",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
|
|
|
const targetLabel = "argocd.argoproj.io/sync-wave"
|
|
const wantCustomValue = `"1"`
|
|
const reservedLabel = "app.kubernetes.io/part-of"
|
|
const wantReservedValue = "gha-rs"
|
|
|
|
var githubSecret corev1.Secret
|
|
helm.UnmarshalK8SYaml(t, output, &githubSecret)
|
|
assert.Equal(t, wantCustomValue, githubSecret.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, githubSecret.Labels[reservedLabel])
|
|
assert.Equal(t, "gh-custom-value", githubSecret.Labels["gh-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role.yaml"})
|
|
var role rbacv1.Role
|
|
helm.UnmarshalK8SYaml(t, output, &role)
|
|
assert.Equal(t, wantCustomValue, role.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, role.Labels[reservedLabel])
|
|
assert.Equal(t, "kmr-custom-value", role.Labels["kmr-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role_binding.yaml"})
|
|
var roleBinding rbacv1.RoleBinding
|
|
helm.UnmarshalK8SYaml(t, output, &roleBinding)
|
|
assert.Equal(t, wantCustomValue, roleBinding.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, roleBinding.Labels[reservedLabel])
|
|
assert.Equal(t, "kmrb-custom-value", roleBinding.Labels["kmrb-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
assert.Equal(t, wantCustomValue, ars.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, ars.Labels[reservedLabel])
|
|
assert.Equal(t, "ars-custom-value", ars.Labels["ars-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_serviceaccount.yaml"})
|
|
var serviceAccount corev1.ServiceAccount
|
|
helm.UnmarshalK8SYaml(t, output, &serviceAccount)
|
|
assert.Equal(t, wantCustomValue, serviceAccount.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, serviceAccount.Labels[reservedLabel])
|
|
assert.Equal(t, "kmsa-custom-value", serviceAccount.Labels["kmsa-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/manager_role.yaml"})
|
|
var managerRole rbacv1.Role
|
|
helm.UnmarshalK8SYaml(t, output, &managerRole)
|
|
assert.Equal(t, wantCustomValue, managerRole.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, managerRole.Labels[reservedLabel])
|
|
assert.Equal(t, "mr-custom-value", managerRole.Labels["mr-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/manager_role_binding.yaml"})
|
|
var managerRoleBinding rbacv1.RoleBinding
|
|
helm.UnmarshalK8SYaml(t, output, &managerRoleBinding)
|
|
assert.Equal(t, wantCustomValue, managerRoleBinding.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, managerRoleBinding.Labels[reservedLabel])
|
|
assert.Equal(t, "mrb-custom-value", managerRoleBinding.Labels["mrb-custom"])
|
|
|
|
options = &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
`labels.argocd\.argoproj\.io/sync-wave`: `"1"`,
|
|
"resourceMeta.noPermissionServiceAccount.labels.npsa-custom": "npsa-custom-value",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/no_permission_serviceaccount.yaml"})
|
|
var noPermissionServiceAccount corev1.ServiceAccount
|
|
helm.UnmarshalK8SYaml(t, output, &noPermissionServiceAccount)
|
|
assert.Equal(t, wantCustomValue, noPermissionServiceAccount.Labels[targetLabel])
|
|
assert.Equal(t, wantReservedValue, noPermissionServiceAccount.Labels[reservedLabel])
|
|
assert.Equal(t, "npsa-custom-value", noPermissionServiceAccount.Labels["npsa-custom"])
|
|
}
|
|
|
|
func TestCustomAnnotations(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Path to the helm chart we will test
|
|
helmChartPath, err := filepath.Abs("../../gha-runner-scale-set")
|
|
require.NoError(t, err)
|
|
|
|
releaseName := "test-runners"
|
|
namespaceName := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
options := &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
`annotations.argocd\.argoproj\.io/sync-wave`: `"1"`,
|
|
"resourceMeta.autoscalingRunnerSet.annotations.ars-custom": "ars-custom-value",
|
|
"resourceMeta.githubConfigSecret.annotations.gh-custom": "gh-custom-value",
|
|
"resourceMeta.kubernetesModeRole.annotations.kmr-custom": "kmr-custom-value",
|
|
"resourceMeta.kubernetesModeRoleBinding.annotations.kmrb-custom": "kmrb-custom-value",
|
|
"resourceMeta.kubernetesModeServiceAccount.annotations.kmsa-custom": "kmsa-custom-value",
|
|
"resourceMeta.managerRole.annotations.mr-custom": "mr-custom-value",
|
|
"resourceMeta.managerRoleBinding.annotations.mrb-custom": "mrb-custom-value",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
const targetAnnotations = "argocd.argoproj.io/sync-wave"
|
|
const wantCustomValue = `"1"`
|
|
|
|
output := helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/githubsecret.yaml"})
|
|
|
|
var githubSecret corev1.Secret
|
|
helm.UnmarshalK8SYaml(t, output, &githubSecret)
|
|
assert.Equal(t, wantCustomValue, githubSecret.Annotations[targetAnnotations])
|
|
assert.Equal(t, "gh-custom-value", githubSecret.Annotations["gh-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role.yaml"})
|
|
var role rbacv1.Role
|
|
helm.UnmarshalK8SYaml(t, output, &role)
|
|
assert.Equal(t, wantCustomValue, role.Annotations[targetAnnotations])
|
|
assert.Equal(t, "kmr-custom-value", role.Annotations["kmr-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_role_binding.yaml"})
|
|
var roleBinding rbacv1.RoleBinding
|
|
helm.UnmarshalK8SYaml(t, output, &roleBinding)
|
|
assert.Equal(t, wantCustomValue, roleBinding.Annotations[targetAnnotations])
|
|
assert.Equal(t, "kmrb-custom-value", roleBinding.Annotations["kmrb-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/autoscalingrunnerset.yaml"})
|
|
var ars v1alpha1.AutoscalingRunnerSet
|
|
helm.UnmarshalK8SYaml(t, output, &ars)
|
|
assert.Equal(t, wantCustomValue, ars.Annotations[targetAnnotations])
|
|
assert.Equal(t, "ars-custom-value", ars.Annotations["ars-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/kube_mode_serviceaccount.yaml"})
|
|
var serviceAccount corev1.ServiceAccount
|
|
helm.UnmarshalK8SYaml(t, output, &serviceAccount)
|
|
assert.Equal(t, wantCustomValue, serviceAccount.Annotations[targetAnnotations])
|
|
assert.Equal(t, "kmsa-custom-value", serviceAccount.Annotations["kmsa-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/manager_role.yaml"})
|
|
var managerRole rbacv1.Role
|
|
helm.UnmarshalK8SYaml(t, output, &managerRole)
|
|
assert.Equal(t, wantCustomValue, managerRole.Annotations[targetAnnotations])
|
|
assert.Equal(t, "mr-custom-value", managerRole.Annotations["mr-custom"])
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/manager_role_binding.yaml"})
|
|
var managerRoleBinding rbacv1.RoleBinding
|
|
helm.UnmarshalK8SYaml(t, output, &managerRoleBinding)
|
|
assert.Equal(t, wantCustomValue, managerRoleBinding.Annotations[targetAnnotations])
|
|
assert.Equal(t, "mrb-custom-value", managerRoleBinding.Annotations["mrb-custom"])
|
|
|
|
options = &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"githubConfigUrl": "https://github.com/actions",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"controllerServiceAccount.name": "arc",
|
|
"controllerServiceAccount.namespace": "arc-system",
|
|
`annotations.argocd\.argoproj\.io/sync-wave`: `"1"`,
|
|
"resourceMeta.noPermissionServiceAccount.annotations.npsa-custom": "npsa-custom-value",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
|
|
}
|
|
|
|
output = helm.RenderTemplate(t, options, helmChartPath, releaseName, []string{"templates/no_permission_serviceaccount.yaml"})
|
|
var noPermissionServiceAccount corev1.ServiceAccount
|
|
helm.UnmarshalK8SYaml(t, output, &noPermissionServiceAccount)
|
|
assert.Equal(t, wantCustomValue, noPermissionServiceAccount.Annotations[targetAnnotations])
|
|
assert.Equal(t, "npsa-custom-value", noPermissionServiceAccount.Annotations["npsa-custom"])
|
|
}
|
|
|
|
func TestNamespaceOverride(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
chartPath := "../../gha-runner-scale-set"
|
|
|
|
releaseName := "test"
|
|
releaseNamespace := "test-" + strings.ToLower(random.UniqueId())
|
|
namespaceOverride := "test-" + strings.ToLower(random.UniqueId())
|
|
|
|
tt := map[string]struct {
|
|
file string
|
|
options *helm.Options
|
|
}{
|
|
"manager_role": {
|
|
file: "manager_role.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
"manager_role_binding": {
|
|
file: "manager_role_binding.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
"no_permission_serviceaccount": {
|
|
file: "no_permission_serviceaccount.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
"autoscalingrunnerset": {
|
|
file: "autoscalingrunnerset.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
"githubsecret": {
|
|
file: "githubsecret.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
"kube_mode_role": {
|
|
file: "kube_mode_role.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
"kube_mode_role_binding": {
|
|
file: "kube_mode_role_binding.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
"kube_mode_serviceaccount": {
|
|
file: "kube_mode_serviceaccount.yaml",
|
|
options: &helm.Options{
|
|
Logger: logger.Discard,
|
|
SetValues: map[string]string{
|
|
"namespaceOverride": namespaceOverride,
|
|
"containerMode.type": "kubernetes",
|
|
"controllerServiceAccount.name": "foo",
|
|
"controllerServiceAccount.namespace": "bar",
|
|
"githubConfigSecret.github_token": "gh_token12345",
|
|
"githubConfigUrl": "https://github.com",
|
|
},
|
|
KubectlOptions: k8s.NewKubectlOptions("", "", releaseNamespace),
|
|
},
|
|
},
|
|
}
|
|
|
|
for name, tc := range tt {
|
|
c := tc
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
templateFile := filepath.Join("./templates", c.file)
|
|
|
|
output, err := helm.RenderTemplateE(t, c.options, chartPath, releaseName, []string{templateFile})
|
|
if err != nil {
|
|
t.Errorf("Error rendering template %s from chart %s: %s", c.file, chartPath, err)
|
|
}
|
|
|
|
type object struct {
|
|
Metadata metav1.ObjectMeta
|
|
}
|
|
var renderedObject object
|
|
helm.UnmarshalK8SYaml(t, output, &renderedObject)
|
|
assert.Equal(t, namespaceOverride, renderedObject.Metadata.Namespace)
|
|
})
|
|
}
|
|
}
|