261 lines
12 KiB
Go
261 lines
12 KiB
Go
package actionsgithubcom
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
func TestLabelPropagation(t *testing.T) {
|
|
autoscalingRunnerSet := v1alpha1.AutoscalingRunnerSet{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test-scale-set",
|
|
Namespace: "test-ns",
|
|
Labels: map[string]string{
|
|
LabelKeyKubernetesPartOf: labelValueKubernetesPartOf,
|
|
LabelKeyKubernetesVersion: "0.2.0",
|
|
"arbitrary-label": "random-value",
|
|
"example.com/label": "example-value",
|
|
"example.com/example": "example-value",
|
|
"directly.excluded.org/label": "excluded-value",
|
|
"directly.excluded.org/arbitrary": "not-excluded-value",
|
|
},
|
|
Annotations: map[string]string{
|
|
runnerScaleSetIdAnnotationKey: "1",
|
|
AnnotationKeyGitHubRunnerGroupName: "test-group",
|
|
AnnotationKeyGitHubRunnerScaleSetName: "test-scale-set",
|
|
},
|
|
},
|
|
Spec: v1alpha1.AutoscalingRunnerSetSpec{
|
|
GitHubConfigUrl: "https://github.com/org/repo",
|
|
},
|
|
}
|
|
|
|
b := ResourceBuilder{
|
|
ExcludeLabelPropagationPrefixes: []string{
|
|
"example.com/",
|
|
"directly.excluded.org/label",
|
|
},
|
|
}
|
|
ephemeralRunnerSet, err := b.newEphemeralRunnerSet(&autoscalingRunnerSet)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, labelValueKubernetesPartOf, ephemeralRunnerSet.Labels[LabelKeyKubernetesPartOf])
|
|
assert.Equal(t, "runner-set", ephemeralRunnerSet.Labels[LabelKeyKubernetesComponent])
|
|
assert.Equal(t, autoscalingRunnerSet.Labels[LabelKeyKubernetesVersion], ephemeralRunnerSet.Labels[LabelKeyKubernetesVersion])
|
|
assert.NotEmpty(t, ephemeralRunnerSet.Annotations[annotationKeyRunnerSpecHash])
|
|
assert.Equal(t, autoscalingRunnerSet.Name, ephemeralRunnerSet.Labels[LabelKeyGitHubScaleSetName])
|
|
assert.Equal(t, autoscalingRunnerSet.Namespace, ephemeralRunnerSet.Labels[LabelKeyGitHubScaleSetNamespace])
|
|
assert.Equal(t, "", ephemeralRunnerSet.Labels[LabelKeyGitHubEnterprise])
|
|
assert.Equal(t, "org", ephemeralRunnerSet.Labels[LabelKeyGitHubOrganization])
|
|
assert.Equal(t, "repo", ephemeralRunnerSet.Labels[LabelKeyGitHubRepository])
|
|
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName])
|
|
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName])
|
|
assert.Equal(t, autoscalingRunnerSet.Labels["arbitrary-label"], ephemeralRunnerSet.Labels["arbitrary-label"])
|
|
|
|
listener, err := b.newAutoScalingListener(&autoscalingRunnerSet, ephemeralRunnerSet, autoscalingRunnerSet.Namespace, "test:latest", nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, labelValueKubernetesPartOf, listener.Labels[LabelKeyKubernetesPartOf])
|
|
assert.Equal(t, "runner-scale-set-listener", listener.Labels[LabelKeyKubernetesComponent])
|
|
assert.Equal(t, autoscalingRunnerSet.Labels[LabelKeyKubernetesVersion], listener.Labels[LabelKeyKubernetesVersion])
|
|
assert.NotEmpty(t, ephemeralRunnerSet.Annotations[annotationKeyRunnerSpecHash])
|
|
assert.Equal(t, autoscalingRunnerSet.Name, listener.Labels[LabelKeyGitHubScaleSetName])
|
|
assert.Equal(t, autoscalingRunnerSet.Namespace, listener.Labels[LabelKeyGitHubScaleSetNamespace])
|
|
assert.Equal(t, "", listener.Labels[LabelKeyGitHubEnterprise])
|
|
assert.Equal(t, "org", listener.Labels[LabelKeyGitHubOrganization])
|
|
assert.Equal(t, "repo", listener.Labels[LabelKeyGitHubRepository])
|
|
assert.Equal(t, autoscalingRunnerSet.Labels["arbitrary-label"], listener.Labels["arbitrary-label"])
|
|
|
|
assert.NotContains(t, listener.Labels, "example.com/label")
|
|
assert.NotContains(t, listener.Labels, "example.com/example")
|
|
assert.NotContains(t, listener.Labels, "directly.excluded.org/label")
|
|
assert.Equal(t, "not-excluded-value", listener.Labels["directly.excluded.org/arbitrary"])
|
|
|
|
listenerServiceAccount := &corev1.ServiceAccount{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
},
|
|
}
|
|
listenerPod, err := b.newScaleSetListenerPod(listener, &corev1.Secret{}, listenerServiceAccount, nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, listenerPod.Labels, listener.Labels)
|
|
|
|
ephemeralRunner := b.newEphemeralRunner(ephemeralRunnerSet)
|
|
require.NoError(t, err)
|
|
|
|
for _, key := range commonLabelKeys {
|
|
if key == LabelKeyKubernetesComponent {
|
|
continue
|
|
}
|
|
assert.Equal(t, ephemeralRunnerSet.Labels[key], ephemeralRunner.Labels[key])
|
|
}
|
|
assert.Equal(t, "runner", ephemeralRunner.Labels[LabelKeyKubernetesComponent])
|
|
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName], ephemeralRunner.Annotations[AnnotationKeyGitHubRunnerGroupName])
|
|
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName])
|
|
|
|
runnerSecret := &corev1.Secret{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
},
|
|
}
|
|
pod := b.newEphemeralRunnerPod(context.TODO(), ephemeralRunner, runnerSecret)
|
|
for key := range ephemeralRunner.Labels {
|
|
assert.Equal(t, ephemeralRunner.Labels[key], pod.Labels[key])
|
|
}
|
|
}
|
|
|
|
func TestGitHubURLTrimLabelValues(t *testing.T) {
|
|
enterprise := strings.Repeat("a", 64)
|
|
organization := strings.Repeat("b", 64)
|
|
repository := strings.Repeat("c", 64)
|
|
|
|
autoscalingRunnerSet := v1alpha1.AutoscalingRunnerSet{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test-scale-set",
|
|
Namespace: "test-ns",
|
|
Labels: map[string]string{
|
|
LabelKeyKubernetesPartOf: labelValueKubernetesPartOf,
|
|
LabelKeyKubernetesVersion: "0.2.0",
|
|
},
|
|
Annotations: map[string]string{
|
|
runnerScaleSetIdAnnotationKey: "1",
|
|
AnnotationKeyGitHubRunnerGroupName: "test-group",
|
|
AnnotationKeyGitHubRunnerScaleSetName: "test-scale-set",
|
|
},
|
|
},
|
|
}
|
|
|
|
t.Run("org/repo", func(t *testing.T) {
|
|
autoscalingRunnerSet := autoscalingRunnerSet.DeepCopy()
|
|
autoscalingRunnerSet.Spec = v1alpha1.AutoscalingRunnerSetSpec{
|
|
GitHubConfigUrl: fmt.Sprintf("https://github.com/%s/%s", organization, repository),
|
|
}
|
|
|
|
var b ResourceBuilder
|
|
ephemeralRunnerSet, err := b.newEphemeralRunnerSet(autoscalingRunnerSet)
|
|
require.NoError(t, err)
|
|
assert.Len(t, ephemeralRunnerSet.Labels[LabelKeyGitHubEnterprise], 0)
|
|
assert.Len(t, ephemeralRunnerSet.Labels[LabelKeyGitHubOrganization], 63)
|
|
assert.Len(t, ephemeralRunnerSet.Labels[LabelKeyGitHubRepository], 63)
|
|
assert.True(t, strings.HasSuffix(ephemeralRunnerSet.Labels[LabelKeyGitHubOrganization], trimLabelVauleSuffix))
|
|
assert.True(t, strings.HasSuffix(ephemeralRunnerSet.Labels[LabelKeyGitHubRepository], trimLabelVauleSuffix))
|
|
|
|
listener, err := b.newAutoScalingListener(autoscalingRunnerSet, ephemeralRunnerSet, autoscalingRunnerSet.Namespace, "test:latest", nil)
|
|
require.NoError(t, err)
|
|
assert.Len(t, listener.Labels[LabelKeyGitHubEnterprise], 0)
|
|
assert.Len(t, listener.Labels[LabelKeyGitHubOrganization], 63)
|
|
assert.Len(t, listener.Labels[LabelKeyGitHubRepository], 63)
|
|
assert.True(t, strings.HasSuffix(ephemeralRunnerSet.Labels[LabelKeyGitHubOrganization], trimLabelVauleSuffix))
|
|
assert.True(t, strings.HasSuffix(ephemeralRunnerSet.Labels[LabelKeyGitHubRepository], trimLabelVauleSuffix))
|
|
})
|
|
|
|
t.Run("enterprise", func(t *testing.T) {
|
|
autoscalingRunnerSet := autoscalingRunnerSet.DeepCopy()
|
|
autoscalingRunnerSet.Spec = v1alpha1.AutoscalingRunnerSetSpec{
|
|
GitHubConfigUrl: fmt.Sprintf("https://github.com/enterprises/%s", enterprise),
|
|
}
|
|
|
|
var b ResourceBuilder
|
|
ephemeralRunnerSet, err := b.newEphemeralRunnerSet(autoscalingRunnerSet)
|
|
require.NoError(t, err)
|
|
assert.Len(t, ephemeralRunnerSet.Labels[LabelKeyGitHubEnterprise], 63)
|
|
assert.True(t, strings.HasSuffix(ephemeralRunnerSet.Labels[LabelKeyGitHubEnterprise], trimLabelVauleSuffix))
|
|
assert.Len(t, ephemeralRunnerSet.Labels[LabelKeyGitHubOrganization], 0)
|
|
assert.Len(t, ephemeralRunnerSet.Labels[LabelKeyGitHubRepository], 0)
|
|
|
|
listener, err := b.newAutoScalingListener(autoscalingRunnerSet, ephemeralRunnerSet, autoscalingRunnerSet.Namespace, "test:latest", nil)
|
|
require.NoError(t, err)
|
|
assert.Len(t, listener.Labels[LabelKeyGitHubEnterprise], 63)
|
|
assert.True(t, strings.HasSuffix(ephemeralRunnerSet.Labels[LabelKeyGitHubEnterprise], trimLabelVauleSuffix))
|
|
assert.Len(t, listener.Labels[LabelKeyGitHubOrganization], 0)
|
|
assert.Len(t, listener.Labels[LabelKeyGitHubRepository], 0)
|
|
})
|
|
}
|
|
|
|
func TestOwnershipRelationships(t *testing.T) {
|
|
// Create an AutoscalingRunnerSet
|
|
autoscalingRunnerSet := v1alpha1.AutoscalingRunnerSet{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test-scale-set",
|
|
Namespace: "test-ns",
|
|
UID: "test-autoscaling-runner-set-uid",
|
|
Labels: map[string]string{
|
|
LabelKeyKubernetesPartOf: labelValueKubernetesPartOf,
|
|
LabelKeyKubernetesVersion: "0.2.0",
|
|
},
|
|
Annotations: map[string]string{
|
|
runnerScaleSetIdAnnotationKey: "1",
|
|
AnnotationKeyGitHubRunnerGroupName: "test-group",
|
|
AnnotationKeyGitHubRunnerScaleSetName: "test-scale-set",
|
|
annotationKeyValuesHash: "test-hash",
|
|
},
|
|
},
|
|
Spec: v1alpha1.AutoscalingRunnerSetSpec{
|
|
GitHubConfigUrl: "https://github.com/org/repo",
|
|
},
|
|
}
|
|
|
|
// Initialize ResourceBuilder
|
|
b := ResourceBuilder{}
|
|
|
|
// Create EphemeralRunnerSet
|
|
ephemeralRunnerSet, err := b.newEphemeralRunnerSet(&autoscalingRunnerSet)
|
|
require.NoError(t, err)
|
|
|
|
// Test EphemeralRunnerSet ownership
|
|
require.Len(t, ephemeralRunnerSet.OwnerReferences, 1, "EphemeralRunnerSet should have exactly one owner reference")
|
|
ownerRef := ephemeralRunnerSet.OwnerReferences[0]
|
|
assert.Equal(t, autoscalingRunnerSet.GetName(), ownerRef.Name, "Owner reference name should match AutoscalingRunnerSet name")
|
|
assert.Equal(t, autoscalingRunnerSet.GetUID(), ownerRef.UID, "Owner reference UID should match AutoscalingRunnerSet UID")
|
|
assert.Equal(t, true, *ownerRef.Controller, "Controller flag should be true")
|
|
assert.Equal(t, true, *ownerRef.BlockOwnerDeletion, "BlockOwnerDeletion flag should be true")
|
|
|
|
// Create EphemeralRunner
|
|
ephemeralRunner := b.newEphemeralRunner(ephemeralRunnerSet)
|
|
|
|
// Test EphemeralRunner ownership
|
|
require.Len(t, ephemeralRunner.OwnerReferences, 1, "EphemeralRunner should have exactly one owner reference")
|
|
ownerRef = ephemeralRunner.OwnerReferences[0]
|
|
assert.Equal(t, ephemeralRunnerSet.GetName(), ownerRef.Name, "Owner reference name should match EphemeralRunnerSet name")
|
|
assert.Equal(t, ephemeralRunnerSet.GetUID(), ownerRef.UID, "Owner reference UID should match EphemeralRunnerSet UID")
|
|
assert.Equal(t, true, *ownerRef.Controller, "Controller flag should be true")
|
|
assert.Equal(t, true, *ownerRef.BlockOwnerDeletion, "BlockOwnerDeletion flag should be true")
|
|
|
|
// Create EphemeralRunnerPod
|
|
runnerSecret := &corev1.Secret{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test-secret",
|
|
},
|
|
}
|
|
pod := b.newEphemeralRunnerPod(context.TODO(), ephemeralRunner, runnerSecret)
|
|
|
|
// Test EphemeralRunnerPod ownership
|
|
require.Len(t, pod.OwnerReferences, 1, "EphemeralRunnerPod should have exactly one owner reference")
|
|
ownerRef = pod.OwnerReferences[0]
|
|
assert.Equal(t, ephemeralRunner.GetName(), ownerRef.Name, "Owner reference name should match EphemeralRunner name")
|
|
assert.Equal(t, ephemeralRunner.GetUID(), ownerRef.UID, "Owner reference UID should match EphemeralRunner UID")
|
|
assert.Equal(t, true, *ownerRef.Controller, "Controller flag should be true")
|
|
assert.Equal(t, true, *ownerRef.BlockOwnerDeletion, "BlockOwnerDeletion flag should be true")
|
|
|
|
// Create AutoScalingListener in AutoScalingRunnerSet namespace
|
|
autoscalingListener, err := b.newAutoScalingListener(&autoscalingRunnerSet, ephemeralRunnerSet, autoscalingRunnerSet.Namespace, "test:latest", nil)
|
|
require.NoError(t, err)
|
|
require.Len(t, autoscalingListener.OwnerReferences, 1, "AutoScalingListener should have exactly one owner reference")
|
|
ownerRef = autoscalingListener.OwnerReferences[0]
|
|
assert.Equal(t, autoscalingRunnerSet.GetName(), ownerRef.Name, "Owner reference name should match AutoscalingRunnerSet name")
|
|
assert.Equal(t, autoscalingRunnerSet.GetUID(), ownerRef.UID, "Owner reference UID should match AutoscalingRunnerSet UID")
|
|
assert.Equal(t, true, *ownerRef.Controller, "Controller flag should be true")
|
|
assert.Equal(t, true, *ownerRef.BlockOwnerDeletion, "BlockOwnerDeletion flag should be true")
|
|
|
|
// Create AutoScalingListener in external controller namespace
|
|
autoscalingListener, err = b.newAutoScalingListener(&autoscalingRunnerSet, ephemeralRunnerSet, "controller-ns", "test:latest", nil)
|
|
require.NoError(t, err)
|
|
require.Len(t, autoscalingListener.OwnerReferences, 0, "AutoScalingListener should not have any owner references")
|
|
}
|