Skip to content

Commit

Permalink
Add unit-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BigDarkClown authored and atwamahmoud committed Feb 20, 2024
1 parent 14d18ab commit a00db07
Show file tree
Hide file tree
Showing 2 changed files with 383 additions and 0 deletions.
226 changes: 226 additions & 0 deletions cluster-autoscaler/cloudprovider/gce/kube_env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package gce

import (
"testing"

"github.com/stretchr/testify/assert"
gce "google.golang.org/api/compute/v1"
)

func TestExtractKubeEnv(t *testing.T) {
templateName := "instance-template"
correctKubeEnv := "VAR1: VALUE1\nVAR2: VALUE2"
someValue := "Lorem ipsum dolor sit amet"

testCases := []struct {
name string
template *gce.InstanceTemplate
wantKubeEnv KubeEnv
wantErr bool
}{
{
name: "template is nil",
template: nil,
wantErr: true,
},
{
name: "template without instance properties",
template: &gce.InstanceTemplate{},
wantErr: true,
},
{
name: "template without instance properties metadata",
template: &gce.InstanceTemplate{
Properties: &gce.InstanceProperties{},
},
wantErr: true,
},
{
name: "template without kube-env",
template: &gce.InstanceTemplate{
Name: templateName,
Properties: &gce.InstanceProperties{
Metadata: &gce.Metadata{
Items: []*gce.MetadataItems{
{Key: "key-1", Value: &someValue},
{Key: "key-2", Value: &someValue},
},
},
},
},
wantKubeEnv: KubeEnv{templateName: templateName},
},
{
name: "template with nil kube-env",
template: &gce.InstanceTemplate{
Name: templateName,
Properties: &gce.InstanceProperties{
Metadata: &gce.Metadata{
Items: []*gce.MetadataItems{
{Key: "key-1", Value: &someValue},
{Key: "key-2", Value: &someValue},
{Key: "kube-env", Value: nil},
},
},
},
},
wantErr: true,
},
{
name: "template with incorrect kube-env",
template: &gce.InstanceTemplate{
Properties: &gce.InstanceProperties{
Metadata: &gce.Metadata{
Items: []*gce.MetadataItems{
{Key: "key-1", Value: &someValue},
{Key: "key-2", Value: &someValue},
{Key: "kube-env", Value: &someValue},
},
},
},
},
wantErr: true,
},
{
name: "template with correct kube-env",
template: &gce.InstanceTemplate{
Name: templateName,
Properties: &gce.InstanceProperties{
Metadata: &gce.Metadata{
Items: []*gce.MetadataItems{
{Key: "key-1", Value: &someValue},
{Key: "key-2", Value: &someValue},
{Key: "kube-env", Value: &correctKubeEnv},
},
},
},
},
wantKubeEnv: KubeEnv{
templateName: templateName,
env: map[string]string{
"VAR1": "VALUE1",
"VAR2": "VALUE2",
},
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
kubeEnv, err := ExtractKubeEnv(tc.template)
if tc.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.wantKubeEnv, kubeEnv)
}
})
}
}

func TestParseKubeEnv(t *testing.T) {
templateName := "instance-template"
testCases := []struct {
name string
kubeEnvValue string
wantKubeEnv KubeEnv
wantErr bool
}{
{
name: "kube-env value is empty",
kubeEnvValue: "",
wantKubeEnv: KubeEnv{
templateName: templateName,
env: map[string]string{},
},
},
{
name: "kube-env value is incorrect",
kubeEnvValue: "Lorem ipsum dolor sit amet",
wantErr: true,
},
{
name: "kube-env value is correct",
kubeEnvValue: "VAR1: VALUE1\nVAR2: VALUE2",
wantKubeEnv: KubeEnv{
templateName: templateName,
env: map[string]string{
"VAR1": "VALUE1",
"VAR2": "VALUE2",
},
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
kubeEnv, err := ParseKubeEnv(templateName, tc.kubeEnvValue)
if tc.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.wantKubeEnv, kubeEnv)
}
})
}
}

func TestKubeEnvVar(t *testing.T) {
testCases := []struct {
name string
kubeEnv KubeEnv
variable string
wantValue string
wantFound bool
}{
{
name: "kube-env is nil",
variable: "VAR1",
wantFound: false,
},
{
name: "kube-env does not have this variable",
kubeEnv: KubeEnv{
env: map[string]string{
"VAR1": "VALUE1",
"VAR2": "VALUE2",
},
},
variable: "VAR3",
wantFound: false,
},
{
name: "kube-env has this variable",
kubeEnv: KubeEnv{
env: map[string]string{
"VAR1": "VALUE1",
"VAR2": "VALUE2",
},
},
variable: "VAR2",
wantValue: "VALUE2",
wantFound: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
value, found := tc.kubeEnv.Var(tc.variable)
assert.Equal(t, tc.wantValue, value)
assert.Equal(t, tc.wantFound, found)
})
}
}
157 changes: 157 additions & 0 deletions cluster-autoscaler/cloudprovider/gce/mig_info_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,163 @@ func TestGetMigInstanceTemplate(t *testing.T) {
}
}

func TestGetMigInstanceKubeEnv(t *testing.T) {
templateName := "template-name"
kubeEnvValue := "VAR1: VALUE1\nVAR2: VALUE2"
kubeEnv, err := ParseKubeEnv(templateName, kubeEnvValue)
assert.NoError(t, err)
template := &gce.InstanceTemplate{
Name: templateName,
Description: "instance template",
Properties: &gce.InstanceProperties{
Metadata: &gce.Metadata{
Items: []*gce.MetadataItems{
{Key: "kube-env", Value: &kubeEnvValue},
},
},
},
}

oldTemplateName := "old-template-name"
oldKubeEnvValue := "VAR3: VALUE3\nVAR4: VALUE4"
oldKubeEnv, err := ParseKubeEnv(oldTemplateName, oldKubeEnvValue)
assert.NoError(t, err)
oldTemplate := &gce.InstanceTemplate{
Name: oldTemplateName,
Description: "old instance template",
Properties: &gce.InstanceProperties{
Metadata: &gce.Metadata{
Items: []*gce.MetadataItems{
{Key: "kube-env", Value: &oldKubeEnvValue},
},
},
},
}

testCases := []struct {
name string
cache *GceCache
fetchMigs func(string) ([]*gce.InstanceGroupManager, error)
fetchMigTemplateName func(GceRef) (string, error)
fetchMigTemplate func(GceRef, string) (*gce.InstanceTemplate, error)
expectedKubeEnv KubeEnv
expectedCachedKubeEnv KubeEnv
expectedErr error
}{
{
name: "kube-env in cache",
cache: &GceCache{
migs: map[GceRef]Mig{mig.GceRef(): mig},
instanceTemplateNameCache: map[GceRef]string{mig.GceRef(): templateName},
kubeEnvCache: map[GceRef]KubeEnv{mig.GceRef(): kubeEnv},
},
expectedKubeEnv: kubeEnv,
expectedCachedKubeEnv: kubeEnv,
},
{
name: "cache without kube-env, template in cache",
cache: &GceCache{
migs: map[GceRef]Mig{mig.GceRef(): mig},
instanceTemplateNameCache: map[GceRef]string{mig.GceRef(): templateName},
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{mig.GceRef(): template},
kubeEnvCache: make(map[GceRef]KubeEnv),
},
expectedKubeEnv: kubeEnv,
expectedCachedKubeEnv: kubeEnv,
},
{
name: "cache without kube-env, fetch success",
cache: &GceCache{
migs: map[GceRef]Mig{mig.GceRef(): mig},
instanceTemplateNameCache: map[GceRef]string{mig.GceRef(): templateName},
instanceTemplatesCache: make(map[GceRef]*gce.InstanceTemplate),
kubeEnvCache: make(map[GceRef]KubeEnv),
},
fetchMigTemplate: fetchMigTemplateConst(template),
expectedKubeEnv: kubeEnv,
expectedCachedKubeEnv: kubeEnv,
},
{
name: "cache with old kube-env, new template cached",
cache: &GceCache{
migs: map[GceRef]Mig{mig.GceRef(): mig},
instanceTemplateNameCache: map[GceRef]string{mig.GceRef(): templateName},
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{mig.GceRef(): template},
kubeEnvCache: map[GceRef]KubeEnv{mig.GceRef(): oldKubeEnv},
},
expectedKubeEnv: kubeEnv,
expectedCachedKubeEnv: kubeEnv,
},
{
name: "cache with old kube-env, fetch success",
cache: &GceCache{
migs: map[GceRef]Mig{mig.GceRef(): mig},
instanceTemplateNameCache: map[GceRef]string{mig.GceRef(): templateName},
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{mig.GceRef(): oldTemplate},
kubeEnvCache: map[GceRef]KubeEnv{mig.GceRef(): oldKubeEnv},
},
fetchMigTemplate: fetchMigTemplateConst(template),
expectedKubeEnv: kubeEnv,
expectedCachedKubeEnv: kubeEnv,
},
{
name: "cache without kube-env, fetch failure",
cache: &GceCache{
migs: map[GceRef]Mig{mig.GceRef(): mig},
instanceTemplateNameCache: map[GceRef]string{mig.GceRef(): templateName},
instanceTemplatesCache: make(map[GceRef]*gce.InstanceTemplate),
kubeEnvCache: make(map[GceRef]KubeEnv),
},
fetchMigTemplate: fetchMigTemplateFail,
expectedErr: errFetchMigTemplate,
},
{
name: "cache with old kube-env, fetch failure",
cache: &GceCache{
migs: map[GceRef]Mig{mig.GceRef(): mig},
instanceTemplateNameCache: map[GceRef]string{mig.GceRef(): templateName},
instanceTemplatesCache: map[GceRef]*gce.InstanceTemplate{mig.GceRef(): oldTemplate},
kubeEnvCache: map[GceRef]KubeEnv{mig.GceRef(): oldKubeEnv},
},
fetchMigTemplate: fetchMigTemplateFail,
expectedCachedKubeEnv: oldKubeEnv,
expectedErr: errFetchMigTemplate,
},
{
name: "template name fetch failure",
cache: emptyCache(),
fetchMigs: fetchMigsFail,
fetchMigTemplateName: fetchMigTemplateNameFail,
expectedErr: errFetchMigTemplateName,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
client := &mockAutoscalingGceClient{
fetchMigs: tc.fetchMigs,
fetchMigTemplateName: tc.fetchMigTemplateName,
fetchMigTemplate: tc.fetchMigTemplate,
}
migLister := NewMigLister(tc.cache)
provider := NewCachingMigInfoProvider(tc.cache, migLister, client, mig.GceRef().Project, 1, 0*time.Second)

kubeEnv, err := provider.GetMigKubeEnv(mig.GceRef())
cachedKubeEnv, found := tc.cache.GetMigKubeEnv(mig.GceRef())

assert.Equal(t, tc.expectedErr, err)
if tc.expectedErr == nil {
assert.Equal(t, tc.expectedKubeEnv, kubeEnv)
}

assert.Equal(t, tc.expectedCachedKubeEnv.env != nil, found)
if tc.expectedCachedKubeEnv.env != nil {
assert.Equal(t, tc.expectedCachedKubeEnv, cachedKubeEnv)
}
})
}
}

func TestGetMigMachineType(t *testing.T) {
knownZone := "us-cache1-a"
unknownZone := "us-nocache42-c"
Expand Down

0 comments on commit a00db07

Please sign in to comment.