2023-01-12 18:24:11 -05:00
package actionssummerwindnet
2020-06-27 17:26:46 +09:00
import (
2021-06-23 20:25:03 +09:00
"context"
2020-06-27 17:26:46 +09:00
"fmt"
2020-10-07 17:00:44 -07:00
"net/http/httptest"
"net/url"
"testing"
2022-12-28 01:38:34 +01:00
"github.com/actions/actions-runner-controller/apis/actions.summerwind.net/v1alpha1"
"github.com/actions/actions-runner-controller/github"
"github.com/actions/actions-runner-controller/github/fake"
2020-06-27 17:26:46 +09:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)
func newGithubClient ( server * httptest . Server ) * github . Client {
2020-10-28 15:15:53 +02:00
c := github . Config {
Token : "token" ,
}
client , err := c . NewClient ()
2020-06-27 17:26:46 +09:00
if err != nil {
panic ( err )
}
baseURL , err := url . Parse ( server . URL + "/" )
if err != nil {
panic ( err )
}
client . Client . BaseURL = baseURL
return client
}
func TestDetermineDesiredReplicas_RepositoryRunner ( t * testing . T ) {
intPtr := func ( v int ) * int {
return & v
}
metav1Now := metav1 . Now ()
testcases := [] struct {
2022-04-24 14:41:34 +09:00
description string
repo string
org string
labels [] string
2021-02-16 18:55:55 +09:00
fixed * int
max * int
min * int
sReplicas * int
sTime * metav1 . Time
workflowRuns string
workflowRuns_queued string
workflowRuns_in_progress string
2020-10-07 17:00:44 -07:00
workflowJobs map [ int ] string
2020-06-27 17:26:46 +09:00
want int
err string
}{
2023-07-25 02:04:54 +02:00
// case_0
2020-10-07 17:00:44 -07:00
// Legacy functionality
2023-07-25 02:04:54 +02:00
// 0 demanded due to zero runID, min at 2
2020-06-27 17:26:46 +09:00
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}]}"` ,
2023-07-25 02:04:54 +02:00
want : 2 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_1
// Explicitly specified the default `self-hosted` label which is ignored by the simulator,
2022-04-24 14:41:34 +09:00
// as we assume that GitHub Actions automatically associates the `self-hosted` label to every self-hosted runner.
// 3 demanded, max at 3
{
repo : "test/valid" ,
labels : [] string { "self-hosted" },
min : intPtr ( 2 ),
max : intPtr ( 3 ),
2023-07-25 02:04:54 +02:00
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status": "queued", "labels":["self-hosted"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}]}` ,
},
want : 3 ,
2022-04-24 14:41:34 +09:00
},
2023-07-25 02:04:54 +02:00
// case_2
2020-06-27 17:26:46 +09:00
// 2 demanded, max at 3, currently 3, delay scaling down due to grace period
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 3 ),
sReplicas : intPtr ( 3 ),
sTime : & metav1Now ,
workflowRuns : `{"total_count": 3, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 3 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_3
2020-06-27 17:26:46 +09:00
// 3 demanded, max at 2
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 2 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}]}"` ,
want : 2 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_4
2020-06-27 17:26:46 +09:00
// 2 demanded, min at 2
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 3, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 2 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_5
2020-06-27 17:26:46 +09:00
// 1 demanded, min at 2
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"queued"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 0, "workflow_runs":[]}"` ,
want : 2 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_6
2020-06-27 17:26:46 +09:00
// 1 demanded, min at 2
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 2 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_7
2020-06-27 17:26:46 +09:00
// 1 demanded, min at 1
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 1 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"queued"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 0, "workflow_runs":[]}"` ,
want : 1 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_8
2020-06-27 17:26:46 +09:00
// 1 demanded, min at 1
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 1 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 1 ,
2020-06-27 17:26:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_9
2020-06-27 17:26:46 +09:00
// fixed at 3
{
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 1 ),
max : intPtr ( 3 ),
fixed : intPtr ( 3 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 3, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}, {"status":"in_progress"}]}"` ,
2023-07-25 02:04:54 +02:00
want : 1 ,
},
// Case for empty GitHub Actions reponse - should not trigger scale up
{
description : "GitHub Actions Jobs Array is empty - no scale up" ,
repo : "test/valid" ,
min : intPtr ( 0 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"queued"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": []}` ,
},
want : 0 ,
},
// Case for hosted GitHub Actions run
{
description : "Hosted GitHub Actions run - no scale up" ,
repo : "test/valid" ,
min : intPtr ( 0 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"id": 1, "status":"queued"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued"}]}` ,
},
want : 0 ,
2020-06-27 17:26:46 +09:00
},
2020-10-07 17:00:44 -07:00
{
2022-04-28 00:24:21 +09:00
description : "Job-level autoscaling with no explicit runner label (runners have implicit self-hosted, requested self-hosted, 5 jobs from 3 workflows)" ,
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted"]}, {"status":"queued", "labels":["self-hosted"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}, {"status":"completed", "labels":["self-hosted"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}, {"status":"queued", "labels":["self-hosted"]}]}` ,
},
want : 5 ,
},
{
description : "Skipped job-level autoscaling with no explicit runner label (runners have implicit self-hosted, requested self-hosted+custom, 0 jobs from 3 workflows)" ,
2022-04-24 14:41:34 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
2022-04-28 00:24:21 +09:00
want : 2 ,
2022-04-24 14:41:34 +09:00
},
{
2022-04-28 00:24:21 +09:00
description : "Skipped job-level autoscaling with no label (runners have implicit self-hosted, jobs had no labels, 0 jobs from 3 workflows)" ,
2021-02-16 18:55:55 +09:00
repo : "test/valid" ,
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
2020-10-07 17:00:44 -07:00
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued"}, {"status":"queued"}]}` ,
2 : `{"jobs": [{"status": "in_progress"}, {"status":"completed"}]}` ,
3 : `{"jobs": [{"status": "in_progress"}, {"status":"queued"}]}` ,
},
2022-04-24 14:41:34 +09:00
want : 2 ,
},
{
2022-04-28 00:24:21 +09:00
description : "Skipped job-level autoscaling with default runner label (runners have self-hosted only, requested self-hosted+custom, 0 jobs from 3 workflows)" ,
2022-04-24 14:41:34 +09:00
repo : "test/valid" ,
labels : [] string { "self-hosted" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
2022-04-28 00:24:21 +09:00
want : 2 ,
2022-04-24 14:41:34 +09:00
},
{
2022-04-28 00:24:21 +09:00
description : "Skipped job-level autoscaling with custom runner label (runners have custom2, requested self-hosted+custom, 0 jobs from 5 workflows" ,
2022-04-24 14:41:34 +09:00
repo : "test/valid" ,
labels : [] string { "custom2" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
want : 2 ,
},
{
2022-04-28 00:24:21 +09:00
description : "Skipped job-level autoscaling with default runner label (runners have self-hosted, requested managed-runner-label, 0 jobs from 3 runs)" ,
2022-04-24 14:41:34 +09:00
repo : "test/valid" ,
labels : [] string { "self-hosted" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["managed-runner-label"]}, {"status":"queued", "labels":["managed-runner-label"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["managed-runner-label"]}, {"status":"completed", "labels":["managed-runner-label"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["managed-runner-label"]}, {"status":"queued", "labels":["managed-runner-label"]}]}` ,
},
want : 2 ,
},
{
2022-04-28 00:24:21 +09:00
description : "Job-level autoscaling with default + custom runner label (runners have self-hosted+custom, requested self-hosted+custom, 5 jobs from 3 workflows)" ,
2022-04-24 14:41:34 +09:00
repo : "test/valid" ,
labels : [] string { "self-hosted" , "custom" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
want : 5 ,
},
{
2022-04-28 00:24:21 +09:00
description : "Job-level autoscaling with custom runner label (runners have custom, requested self-hosted+custom, 5 jobs from 3 workflows)" ,
2022-04-24 14:41:34 +09:00
repo : "test/valid" ,
labels : [] string { "custom" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
2020-10-07 17:00:44 -07:00
want : 5 ,
},
2020-06-27 17:26:46 +09:00
}
for i := range testcases {
tc := testcases [ i ]
log := zap . New ( func ( o * zap . Options ) {
o . Development = true
})
scheme := runtime . NewScheme ()
_ = clientgoscheme . AddToScheme ( scheme )
_ = v1alpha1 . AddToScheme ( scheme )
2022-04-24 14:41:34 +09:00
testName := fmt . Sprintf ( "case %d" , i )
if tc . description != "" {
testName = tc . description
}
t . Run ( testName , func ( t * testing . T ) {
2021-02-07 17:37:27 +09:00
server := fake . NewServer (
2021-02-16 18:55:55 +09:00
fake . WithListRepositoryWorkflowRunsResponse ( 200 , tc . workflowRuns , tc . workflowRuns_queued , tc . workflowRuns_in_progress ),
2021-02-07 17:37:27 +09:00
fake . WithListWorkflowJobsResponse ( 200 , tc . workflowJobs ),
fake . WithListRunnersResponse ( 200 , fake . RunnersListBody ),
)
2020-06-27 17:26:46 +09:00
defer server . Close ()
client := newGithubClient ( server )
2020-07-19 18:42:06 +09:00
h := & HorizontalRunnerAutoscalerReconciler {
2022-04-20 03:09:09 +01:00
Log : log ,
Scheme : scheme ,
DefaultScaleDownDelay : DefaultScaleDownDelay ,
2020-06-27 17:26:46 +09:00
}
rd := v1alpha1 . RunnerDeployment {
TypeMeta : metav1 . TypeMeta {},
2020-07-19 18:42:06 +09:00
ObjectMeta : metav1 . ObjectMeta {
Name : "testrd" ,
},
2020-06-27 17:26:46 +09:00
Spec : v1alpha1 . RunnerDeploymentSpec {
Template : v1alpha1 . RunnerTemplate {
Spec : v1alpha1 . RunnerSpec {
2021-06-22 17:10:09 +09:00
RunnerConfig : v1alpha1 . RunnerConfig {
Repository : tc . repo ,
2022-04-24 14:41:34 +09:00
Labels : tc . labels ,
2021-06-22 17:10:09 +09:00
},
2020-06-27 17:26:46 +09:00
},
},
2020-07-19 18:42:06 +09:00
Replicas : tc . fixed ,
},
Status : v1alpha1 . RunnerDeploymentStatus {
2021-05-22 08:29:53 +09:00
DesiredReplicas : tc . sReplicas ,
2020-07-19 18:42:06 +09:00
},
}
hra := v1alpha1 . HorizontalRunnerAutoscaler {
Spec : v1alpha1 . HorizontalRunnerAutoscalerSpec {
2020-06-27 17:26:46 +09:00
MaxReplicas : tc . max ,
MinReplicas : tc . min ,
2022-04-24 13:36:42 +09:00
Metrics : [] v1alpha1 . MetricSpec {
{
Type : "TotalNumberOfQueuedAndInProgressWorkflowRuns" ,
},
},
2020-06-27 17:26:46 +09:00
},
2020-07-19 18:42:06 +09:00
Status : v1alpha1 . HorizontalRunnerAutoscalerStatus {
DesiredReplicas : tc . sReplicas ,
2020-06-27 17:26:46 +09:00
LastSuccessfulScaleOutTime : tc . sTime ,
},
}
2021-05-22 08:29:53 +09:00
minReplicas , _ , _ , err := h . getMinReplicas ( log , metav1Now . Time , hra )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2021-06-23 20:25:03 +09:00
st := h . scaleTargetFromRD ( context . Background (), rd )
2022-07-12 09:45:00 +09:00
got , err := h . computeReplicasWithCache ( client , log , metav1Now . Time , st , hra , minReplicas )
2020-06-27 17:26:46 +09:00
if err != nil {
if tc . err == "" {
t . Fatalf ( "unexpected error: expected none, got %v" , err )
} else if err . Error () != tc . err {
t . Fatalf ( "unexpected error: expected %v, got %v" , tc . err , err )
}
return
}
2021-03-19 12:58:02 +09:00
if got != tc . want {
t . Errorf ( "%d: incorrect desired replicas: want %d, got %d" , i , tc . want , got )
2020-06-27 17:26:46 +09:00
}
})
}
}
2020-07-03 09:05:46 +09:00
func TestDetermineDesiredReplicas_OrganizationalRunner ( t * testing . T ) {
intPtr := func ( v int ) * int {
return & v
}
metav1Now := metav1 . Now ()
testcases := [] struct {
2022-04-24 14:41:34 +09:00
description string
repos [] string
org string
labels [] string
2021-02-16 18:55:55 +09:00
fixed * int
max * int
min * int
sReplicas * int
sTime * metav1 . Time
workflowRuns string
workflowRuns_queued string
workflowRuns_in_progress string
2020-10-07 17:00:44 -07:00
workflowJobs map [ int ] string
2020-07-03 09:05:46 +09:00
want int
err string
}{
2023-07-25 02:04:54 +02:00
// case_0
// 0 demanded due to zero runID, min at 2
2020-07-03 09:05:46 +09:00
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}]}"` ,
2023-07-25 02:04:54 +02:00
want : 2 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_1
2020-07-03 09:05:46 +09:00
// 2 demanded, max at 3, currently 3, delay scaling down due to grace period
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 3 ),
sReplicas : intPtr ( 3 ),
sTime : & metav1Now ,
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 3 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_2
2020-07-03 09:05:46 +09:00
// 3 demanded, max at 2
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 2 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}]}"` ,
want : 2 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_3
2020-07-03 09:05:46 +09:00
// 2 demanded, min at 2
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 3, "workflow_runs":[{"status":"queued"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 2 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_4
2020-07-03 09:05:46 +09:00
// 1 demanded, min at 2
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"queued"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 0, "workflow_runs":[]}"` ,
want : 2 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_5
2020-07-03 09:05:46 +09:00
// 1 demanded, min at 2
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 2 ,
2020-07-03 09:05:46 +09:00
},
// 1 demanded, min at 1
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 1 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"queued"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 0, "workflow_runs":[]}"` ,
want : 1 ,
2020-07-03 09:05:46 +09:00
},
// 1 demanded, min at 1
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 1 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
want : 1 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_6
2020-07-03 09:05:46 +09:00
// fixed at 3
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
fixed : intPtr ( 1 ),
min : intPtr ( 1 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 3, "workflow_runs":[{"status":"in_progress"},{"status":"in_progress"},{"status":"in_progress"}]}"` ,
2023-07-25 02:04:54 +02:00
want : 1 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_7
2020-07-03 09:05:46 +09:00
// org runner, fixed at 3
{
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
fixed : intPtr ( 1 ),
min : intPtr ( 1 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"status":"in_progress"}, {"status":"in_progress"}, {"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 3, "workflow_runs":[{"status":"in_progress"},{"status":"in_progress"},{"status":"in_progress"}]}"` ,
2023-07-25 02:04:54 +02:00
want : 1 ,
2020-07-03 09:05:46 +09:00
},
2023-07-25 02:04:54 +02:00
// case_8
2020-07-03 09:05:46 +09:00
// org runner, 1 demanded, min at 1, no repos
{
2021-02-16 18:55:55 +09:00
org : "test" ,
min : intPtr ( 1 ),
max : intPtr ( 3 ),
workflowRuns : `{"total_count": 2, "workflow_runs":[{"status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 0, "workflow_runs":[]}"` ,
workflowRuns_in_progress : `{"total_count": 1, "workflow_runs":[{"status":"in_progress"}]}"` ,
err : "validating autoscaling metrics: spec.autoscaling.metrics[].repositoryNames is required and must have one more more entries for organizational runner deployment" ,
2020-07-03 09:05:46 +09:00
},
2020-10-07 17:00:44 -07:00
{
2022-04-28 00:24:21 +09:00
description : "Job-level autoscaling (runners have implicit self-hosted, requested self-hosted, 5 jobs from 3 runs)" ,
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted"]}, {"status":"queued", "labels":["self-hosted"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}, {"status":"completed", "labels":["self-hosted"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}, {"status":"queued", "labels":["self-hosted"]}]}` ,
},
want : 5 ,
},
{
description : "Job-level autoscaling (runners have explicit self-hosted, requested self-hosted, 5 jobs from 3 runs)" ,
org : "test" ,
repos : [] string { "valid" },
labels : [] string { "self-hosted" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted"]}, {"status":"queued", "labels":["self-hosted"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}, {"status":"completed", "labels":["self-hosted"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted"]}, {"status":"queued", "labels":["self-hosted"]}]}` ,
},
want : 5 ,
},
{
description : "Skipped job-level autoscaling (jobs lack labels, 0 requested from 3 workflows)" ,
2021-02-16 18:55:55 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
2020-10-07 17:00:44 -07:00
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued"}, {"status":"queued"}]}` ,
2 : `{"jobs": [{"status": "in_progress"}, {"status":"completed"}]}` ,
3 : `{"jobs": [{"status": "in_progress"}, {"status":"queued"}]}` ,
},
2022-04-24 14:41:34 +09:00
want : 2 ,
},
{
2022-04-28 00:24:21 +09:00
description : "Skipped job-level autoscaling (runners have valid and implicit self-hosted, requested self-hosted+custom, 0 jobs from 3 runs)" ,
2022-04-24 14:41:34 +09:00
org : "test" ,
repos : [] string { "valid" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
2022-04-28 00:24:21 +09:00
want : 2 ,
2020-10-07 17:00:44 -07:00
},
2022-04-24 14:41:34 +09:00
{
2022-04-28 00:24:21 +09:00
description : "Skipped job-level autoscaling (runners have self-hosted, requested self-hosted+custom, 0 jobs from 3 workflows)" ,
2022-04-24 14:41:34 +09:00
org : "test" ,
repos : [] string { "valid" },
labels : [] string { "self-hosted" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
2022-04-28 00:24:21 +09:00
want : 2 ,
2022-04-24 14:41:34 +09:00
},
{
2022-04-28 00:24:21 +09:00
description : "Job-level autoscaling (runners have custom, requested self-hosted+custom, 5 requested from 3 workflows)" ,
2022-04-24 14:41:34 +09:00
org : "test" ,
repos : [] string { "valid" },
labels : [] string { "custom" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
want : 5 ,
},
2022-04-28 00:24:21 +09:00
{
description : "Job-level autoscaling (runners have custom, requested custom, 5 requested from 3 workflows)" ,
org : "test" ,
repos : [] string { "valid" },
labels : [] string { "custom" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["custom"]}, {"status":"queued", "labels":["custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["custom"]}, {"status":"completed", "labels":["custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["custom"]}, {"status":"queued", "labels":["custom"]}]}` ,
},
want : 5 ,
},
2022-04-24 14:41:34 +09:00
{
description : "Skipped job-level autoscaling (specified custom2, 0 requested from 3 workflows)" ,
org : "test" ,
repos : [] string { "valid" },
labels : [] string { "custom2" },
min : intPtr ( 2 ),
max : intPtr ( 10 ),
workflowRuns : `{"total_count": 4, "workflow_runs":[{"id": 1, "status":"queued"}, {"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowRuns_queued : `{"total_count": 1, "workflow_runs":[{"id": 1, "status":"queued"}]}"` ,
workflowRuns_in_progress : `{"total_count": 2, "workflow_runs":[{"id": 2, "status":"in_progress"}, {"id": 3, "status":"in_progress"}, {"status":"completed"}]}"` ,
workflowJobs : map [ int ] string {
1 : `{"jobs": [{"status":"queued", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
2 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"completed", "labels":["self-hosted", "custom"]}]}` ,
3 : `{"jobs": [{"status": "in_progress", "labels":["self-hosted", "custom"]}, {"status":"queued", "labels":["self-hosted", "custom"]}]}` ,
},
want : 2 ,
},
2020-07-03 09:05:46 +09:00
}
for i := range testcases {
tc := testcases [ i ]
log := zap . New ( func ( o * zap . Options ) {
o . Development = true
})
scheme := runtime . NewScheme ()
_ = clientgoscheme . AddToScheme ( scheme )
_ = v1alpha1 . AddToScheme ( scheme )
2022-04-24 14:41:34 +09:00
testName := fmt . Sprintf ( "case %d" , i )
if tc . description != "" {
testName = tc . description
}
t . Run ( testName , func ( t * testing . T ) {
2021-03-19 12:58:02 +09:00
t . Helper ()
2021-02-07 17:37:27 +09:00
server := fake . NewServer (
2021-02-16 18:55:55 +09:00
fake . WithListRepositoryWorkflowRunsResponse ( 200 , tc . workflowRuns , tc . workflowRuns_queued , tc . workflowRuns_in_progress ),
2021-02-07 17:37:27 +09:00
fake . WithListWorkflowJobsResponse ( 200 , tc . workflowJobs ),
fake . WithListRunnersResponse ( 200 , fake . RunnersListBody ),
)
2020-07-03 09:05:46 +09:00
defer server . Close ()
client := newGithubClient ( server )
2020-07-19 18:42:06 +09:00
h := & HorizontalRunnerAutoscalerReconciler {
2022-04-20 03:09:09 +01:00
Log : log ,
Scheme : scheme ,
DefaultScaleDownDelay : DefaultScaleDownDelay ,
2020-07-03 09:05:46 +09:00
}
rd := v1alpha1 . RunnerDeployment {
2020-07-19 18:42:06 +09:00
ObjectMeta : metav1 . ObjectMeta {
Name : "testrd" ,
},
2020-07-03 09:05:46 +09:00
Spec : v1alpha1 . RunnerDeploymentSpec {
2021-03-05 10:15:39 +09:00
Selector : & metav1 . LabelSelector {
MatchLabels : map [ string ] string {
"foo" : "bar" ,
},
},
2020-07-03 09:05:46 +09:00
Template : v1alpha1 . RunnerTemplate {
2021-03-05 10:15:39 +09:00
ObjectMeta : metav1 . ObjectMeta {
Labels : map [ string ] string {
"foo" : "bar" ,
},
},
2020-07-03 09:05:46 +09:00
Spec : v1alpha1 . RunnerSpec {
2021-06-22 17:10:09 +09:00
RunnerConfig : v1alpha1 . RunnerConfig {
Organization : tc . org ,
2022-04-24 14:41:34 +09:00
Labels : tc . labels ,
2021-06-22 17:10:09 +09:00
},
2020-07-03 09:05:46 +09:00
},
},
2020-07-19 18:42:06 +09:00
Replicas : tc . fixed ,
2020-07-03 09:05:46 +09:00
},
Status : v1alpha1 . RunnerDeploymentStatus {
2021-05-22 08:29:53 +09:00
DesiredReplicas : tc . sReplicas ,
2020-07-19 18:42:06 +09:00
},
}
hra := v1alpha1 . HorizontalRunnerAutoscaler {
Spec : v1alpha1 . HorizontalRunnerAutoscalerSpec {
ScaleTargetRef : v1alpha1 . ScaleTargetRef {
Name : "testrd" ,
},
MaxReplicas : tc . max ,
MinReplicas : tc . min ,
Metrics : [] v1alpha1 . MetricSpec {
{
Type : v1alpha1 . AutoscalingMetricTypeTotalNumberOfQueuedAndInProgressWorkflowRuns ,
RepositoryNames : tc . repos ,
},
},
},
Status : v1alpha1 . HorizontalRunnerAutoscalerStatus {
DesiredReplicas : tc . sReplicas ,
2020-07-03 09:05:46 +09:00
LastSuccessfulScaleOutTime : tc . sTime ,
},
}
2021-05-22 08:29:53 +09:00
minReplicas , _ , _ , err := h . getMinReplicas ( log , metav1Now . Time , hra )
if err != nil {
t . Fatalf ( "unexpected error: %v" , err )
}
2021-06-23 20:25:03 +09:00
st := h . scaleTargetFromRD ( context . Background (), rd )
2022-07-12 09:45:00 +09:00
got , err := h . computeReplicasWithCache ( client , log , metav1Now . Time , st , hra , minReplicas )
2020-07-03 09:05:46 +09:00
if err != nil {
if tc . err == "" {
t . Fatalf ( "unexpected error: expected none, got %v" , err )
} else if err . Error () != tc . err {
t . Fatalf ( "unexpected error: expected %v, got %v" , tc . err , err )
}
return
}
2021-03-19 12:58:02 +09:00
if got != tc . want {
t . Errorf ( "%d: incorrect desired replicas: want %d, got %d" , i , tc . want , got )
2020-07-03 09:05:46 +09:00
}
})
}
}