Skip to content

Commit

Permalink
tests: Add unit tests to image-updater pkg/image (#810)
Browse files Browse the repository at this point in the history
Signed-off-by: Cheng Fang <[email protected]>
  • Loading branch information
chengfang authored Aug 7, 2024
1 parent 94c7149 commit e193d9d
Show file tree
Hide file tree
Showing 5 changed files with 361 additions and 12 deletions.
117 changes: 113 additions & 4 deletions pkg/image/credentials_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package image

import (
"fmt"
"os"
"path"
"strings"
"testing"

"github.com/argoproj-labs/argocd-image-updater/pkg/kube"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/argoproj-labs/argocd-image-updater/pkg/kube"
"github.com/argoproj-labs/argocd-image-updater/test/fake"
"github.com/argoproj-labs/argocd-image-updater/test/fixture"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_ParseCredentialAnnotation(t *testing.T) {
Expand Down Expand Up @@ -101,6 +102,12 @@ func Test_ParseCredentialAnnotation(t *testing.T) {
assert.Equal(t, "DUMMY_SECRET", src.EnvName)
})

t.Run("Parse external script credentials", func(t *testing.T) {
src, err := ParseCredentialSource("ext:/tmp/a.sh", false)
require.NoError(t, err)
assert.Equal(t, CredentialSourceExt, src.Type)
assert.Equal(t, "/tmp/a.sh", src.ScriptPath)
})
}

func Test_ParseCredentialReference(t *testing.T) {
Expand Down Expand Up @@ -130,6 +137,53 @@ func Test_ParseCredentialReference(t *testing.T) {

}

func Test_FetchCredentialsFromSecret(t *testing.T) {
t.Run("Fetch credentials from secret", func(t *testing.T) {
secretData := make(map[string][]byte)
secretData["username_password"] = []byte(fmt.Sprintf("%s:%s", "foo", "bar"))
secret := fixture.NewSecret("test", "test", secretData)
clientset := fake.NewFakeClientsetWithResources(secret)
credSrc := &CredentialSource{
Type: CredentialSourceSecret,
SecretNamespace: "test",
SecretName: "test",
SecretField: "username_password",
}
creds, err := credSrc.FetchCredentials("NA", &kube.KubernetesClient{Clientset: clientset})
require.NoError(t, err)
require.NotNil(t, creds)
assert.Equal(t, "foo", creds.Username)
assert.Equal(t, "bar", creds.Password)

credSrc.SecretNamespace = "test1" // test with a wrong SecretNamespace
creds, err = credSrc.FetchCredentials("NA", &kube.KubernetesClient{Clientset: clientset})
require.Error(t, err)
require.Nil(t, creds)
})

t.Run("Fetch credentials from secret with invalid config", func(t *testing.T) {
secretData := make(map[string][]byte)
secretData["username_password"] = []byte(fmt.Sprintf("%s:%s", "foo", "bar"))
secret := fixture.NewSecret("test", "test", secretData)
clientset := fake.NewFakeClientsetWithResources(secret)
credSrc := &CredentialSource{
Type: CredentialSourceSecret,
SecretNamespace: "test",
SecretName: "test",
SecretField: "username_password",
}
creds, err := credSrc.FetchCredentials("NA", nil)
require.Error(t, err) // should fail with "could not fetch credentials: no Kubernetes client given"
require.Nil(t, creds)

credSrc.SecretField = "BAD" // test with a wrong SecretField
creds, err = credSrc.FetchCredentials("NA", &kube.KubernetesClient{Clientset: clientset})
require.Error(t, err)
require.Nil(t, creds)

})
}

func Test_FetchCredentialsFromPullSecret(t *testing.T) {
t.Run("Fetch credentials from pull secret", func(t *testing.T) {
dockerJson := fixture.MustReadFile("../../test/testdata/docker/valid-config.json")
Expand All @@ -148,6 +202,33 @@ func Test_FetchCredentialsFromPullSecret(t *testing.T) {
require.NotNil(t, creds)
assert.Equal(t, "foo", creds.Username)
assert.Equal(t, "bar", creds.Password)

credSrc.SecretNamespace = "test1" // test with a wrong SecretNamespace
creds, err = credSrc.FetchCredentials("https://registry-1.docker.io", &kube.KubernetesClient{Clientset: clientset})
require.Error(t, err)
require.Nil(t, creds)
})

t.Run("Fetch credentials from pull secret with invalid config", func(t *testing.T) {
dockerJson := fixture.MustReadFile("../../test/testdata/docker/valid-config.json")
dockerJson = strings.ReplaceAll(dockerJson, "auths", "BAD-KEY")
secretData := make(map[string][]byte)
secretData[pullSecretField] = []byte(dockerJson)
pullSecret := fixture.NewSecret("test", "test", secretData)
clientset := fake.NewFakeClientsetWithResources(pullSecret)
credSrc := &CredentialSource{
Type: CredentialSourcePullSecret,
Registry: "https://registry-1.docker.io/v2",
SecretNamespace: "test",
SecretName: "test",
}
creds, err := credSrc.FetchCredentials("https://registry-1.docker.io", &kube.KubernetesClient{Clientset: clientset})
require.Error(t, err) // should fail with "no credentials in image pull secret"
require.Nil(t, creds)

creds, err = credSrc.FetchCredentials("https://registry-1.docker.io", nil)
require.Error(t, err) // should fail with "could not fetch credentials: no Kubernetes client given"
require.Nil(t, creds)
})

t.Run("Fetch credentials from pull secret with protocol stripped", func(t *testing.T) {
Expand Down Expand Up @@ -266,6 +347,18 @@ func Test_FetchCredentialsFromExt(t *testing.T) {
})
}

func Test_FetchCredentialsFromUnknown(t *testing.T) {
t.Run("Fetch credentials from unknown type", func(t *testing.T) {
credSrc := &CredentialSource{
Type: CredentialSourceType(-1),
Registry: "https://registry-1.docker.io/v2",
}
creds, err := credSrc.FetchCredentials("https://registry-1.docker.io", nil)
require.Error(t, err) // should fail with "unknown credential type"
require.Nil(t, creds)
})
}

func Test_ParseDockerConfig(t *testing.T) {
t.Run("Parse valid Docker configuration with matching registry", func(t *testing.T) {
config := fixture.MustReadFile("../../test/testdata/docker/valid-config.json")
Expand All @@ -283,6 +376,22 @@ func Test_ParseDockerConfig(t *testing.T) {
assert.Equal(t, "bar", password)
})

t.Run("Parse valid Docker configuration with matching http registry as prefix", func(t *testing.T) {
config := fixture.MustReadFile("../../test/testdata/docker/valid-config-noproto.json")
username, password, err := parseDockerConfigJson("http://registry-1.docker.io", config)
require.NoError(t, err)
assert.Equal(t, "foo", username)
assert.Equal(t, "bar", password)
})

t.Run("Parse valid Docker configuration with matching no-protocol registry as prefix", func(t *testing.T) {
config := fixture.MustReadFile("../../test/testdata/docker/valid-config-noproto.json")
username, password, err := parseDockerConfigJson("registry-1.docker.io", config)
require.NoError(t, err)
assert.Equal(t, "foo", username)
assert.Equal(t, "bar", password)
})

t.Run("Parse valid Docker configuration with matching registry as prefix with / in the end", func(t *testing.T) {
config := fixture.MustReadFile("../../test/testdata/docker/valid-config-noproto.json")
username, password, err := parseDockerConfigJson("https://registry-1.docker.io/", config)
Expand Down
61 changes: 59 additions & 2 deletions pkg/image/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"testing"
"time"

"github.com/argoproj-labs/argocd-image-updater/pkg/tag"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"

"github.com/argoproj-labs/argocd-image-updater/pkg/tag"
)

func Test_ParseImageTags(t *testing.T) {
Expand Down Expand Up @@ -160,9 +161,65 @@ func Test_ContainerList(t *testing.T) {
for _, n := range image_names {
images = append(images, NewFromIdentifier(n))
}
withKustomizeOverride := NewFromIdentifier("k1/k2:k3")
withKustomizeOverride.KustomizeImage = images[0]
images = append(images, withKustomizeOverride)

assert.NotNil(t, images.ContainsImage(NewFromIdentifier(image_names[0]), false))
assert.NotNil(t, images.ContainsImage(NewFromIdentifier(image_names[1]), false))
assert.NotNil(t, images.ContainsImage(NewFromIdentifier(image_names[2]), false))
assert.Nil(t, images.ContainsImage(NewFromIdentifier("foo/bar"), false))

imageMatch := images.ContainsImage(withKustomizeOverride, false)
assert.Equal(t, images[0], imageMatch)
})
}

func Test_getImageDigestFromTag(t *testing.T) {
tagAndDigest := "test-tag@sha256:abcde"
tagName, tagDigest := getImageDigestFromTag(tagAndDigest)
assert.Equal(t, "test-tag", tagName)
assert.Equal(t, "sha256:abcde", tagDigest)

tagAndDigest = "test-tag"
tagName, tagDigest = getImageDigestFromTag(tagAndDigest)
assert.Equal(t, "test-tag", tagName)
assert.Empty(t, tagDigest)
}

func Test_ContainerImageList_String_Originals(t *testing.T) {
images := make(ContainerImageList, 0)
originals := []string{}

assert.Equal(t, "", images.String())
assert.True(t, slices.Equal(originals, images.Originals()))

images = append(images, NewFromIdentifier("foo/bar:0.1"))
originals = append(originals, "foo/bar:0.1")
assert.Equal(t, "foo/bar:0.1", images.String())
assert.True(t, slices.Equal(originals, images.Originals()))

images = append(images, NewFromIdentifier("alias=foo/bar:0.2"))
originals = append(originals, "alias=foo/bar:0.2")
assert.Equal(t, "foo/bar:0.1,alias=foo/bar:0.2", images.String())
assert.True(t, slices.Equal(originals, images.Originals()))
}

func TestContainerImage_DiffersFrom(t *testing.T) {
foo1 := NewFromIdentifier("x/foo:1")
foo2 := NewFromIdentifier("x/foo:2")
bar1 := NewFromIdentifier("x/bar:1")
bar1WithRegistry := NewFromIdentifier("docker.io/x/bar:1")

assert.False(t, foo1.DiffersFrom(foo1, true))
assert.False(t, foo1.DiffersFrom(foo2, false))
assert.True(t, foo1.DiffersFrom(foo2, true))

assert.True(t, foo1.DiffersFrom(bar1, false))
assert.True(t, bar1.DiffersFrom(foo1, false))
assert.True(t, foo1.DiffersFrom(bar1, true))
assert.True(t, bar1.DiffersFrom(foo1, true))
assert.True(t, bar1.DiffersFrom(bar1WithRegistry, false))

assert.False(t, foo1.IsUpdatable("0.1", "^1.0"))
}
26 changes: 26 additions & 0 deletions pkg/image/kustomize_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package image

import (
"testing"

"github.com/stretchr/testify/assert"
)

func Test_KustomizeImages_Find(t *testing.T) {
images := KustomizeImages{
"a/b:1.0",
"a/b@sha256:aabb",
"a/b:latest@sha256:aabb",
"x/y=busybox",
"x/y=foo.bar/a/c:0.23",
}
for _, image := range images {
assert.True(t, images.Find(image) >= 0)
}
for _, image := range []string{"a/b:2", "x/y=foo.bar"} {
assert.True(t, images.Find(KustomizeImage(image)) >= 0)
}
for _, image := range []string{"a/b", "x", "x/y"} {
assert.Equal(t, -1, images.Find(KustomizeImage(image)))
}
}
Loading

0 comments on commit e193d9d

Please sign in to comment.