Skip to content

Commit e193d9d

Browse files
authored
tests: Add unit tests to image-updater pkg/image (#810)
Signed-off-by: Cheng Fang <[email protected]>
1 parent 94c7149 commit e193d9d

File tree

5 files changed

+361
-12
lines changed

5 files changed

+361
-12
lines changed

pkg/image/credentials_test.go

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package image
22

33
import (
4+
"fmt"
45
"os"
56
"path"
7+
"strings"
68
"testing"
79

8-
"github.com/argoproj-labs/argocd-image-updater/pkg/kube"
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
912

13+
"github.com/argoproj-labs/argocd-image-updater/pkg/kube"
1014
"github.com/argoproj-labs/argocd-image-updater/test/fake"
1115
"github.com/argoproj-labs/argocd-image-updater/test/fixture"
12-
13-
"github.com/stretchr/testify/assert"
14-
"github.com/stretchr/testify/require"
1516
)
1617

1718
func Test_ParseCredentialAnnotation(t *testing.T) {
@@ -101,6 +102,12 @@ func Test_ParseCredentialAnnotation(t *testing.T) {
101102
assert.Equal(t, "DUMMY_SECRET", src.EnvName)
102103
})
103104

105+
t.Run("Parse external script credentials", func(t *testing.T) {
106+
src, err := ParseCredentialSource("ext:/tmp/a.sh", false)
107+
require.NoError(t, err)
108+
assert.Equal(t, CredentialSourceExt, src.Type)
109+
assert.Equal(t, "/tmp/a.sh", src.ScriptPath)
110+
})
104111
}
105112

106113
func Test_ParseCredentialReference(t *testing.T) {
@@ -130,6 +137,53 @@ func Test_ParseCredentialReference(t *testing.T) {
130137

131138
}
132139

140+
func Test_FetchCredentialsFromSecret(t *testing.T) {
141+
t.Run("Fetch credentials from secret", func(t *testing.T) {
142+
secretData := make(map[string][]byte)
143+
secretData["username_password"] = []byte(fmt.Sprintf("%s:%s", "foo", "bar"))
144+
secret := fixture.NewSecret("test", "test", secretData)
145+
clientset := fake.NewFakeClientsetWithResources(secret)
146+
credSrc := &CredentialSource{
147+
Type: CredentialSourceSecret,
148+
SecretNamespace: "test",
149+
SecretName: "test",
150+
SecretField: "username_password",
151+
}
152+
creds, err := credSrc.FetchCredentials("NA", &kube.KubernetesClient{Clientset: clientset})
153+
require.NoError(t, err)
154+
require.NotNil(t, creds)
155+
assert.Equal(t, "foo", creds.Username)
156+
assert.Equal(t, "bar", creds.Password)
157+
158+
credSrc.SecretNamespace = "test1" // test with a wrong SecretNamespace
159+
creds, err = credSrc.FetchCredentials("NA", &kube.KubernetesClient{Clientset: clientset})
160+
require.Error(t, err)
161+
require.Nil(t, creds)
162+
})
163+
164+
t.Run("Fetch credentials from secret with invalid config", func(t *testing.T) {
165+
secretData := make(map[string][]byte)
166+
secretData["username_password"] = []byte(fmt.Sprintf("%s:%s", "foo", "bar"))
167+
secret := fixture.NewSecret("test", "test", secretData)
168+
clientset := fake.NewFakeClientsetWithResources(secret)
169+
credSrc := &CredentialSource{
170+
Type: CredentialSourceSecret,
171+
SecretNamespace: "test",
172+
SecretName: "test",
173+
SecretField: "username_password",
174+
}
175+
creds, err := credSrc.FetchCredentials("NA", nil)
176+
require.Error(t, err) // should fail with "could not fetch credentials: no Kubernetes client given"
177+
require.Nil(t, creds)
178+
179+
credSrc.SecretField = "BAD" // test with a wrong SecretField
180+
creds, err = credSrc.FetchCredentials("NA", &kube.KubernetesClient{Clientset: clientset})
181+
require.Error(t, err)
182+
require.Nil(t, creds)
183+
184+
})
185+
}
186+
133187
func Test_FetchCredentialsFromPullSecret(t *testing.T) {
134188
t.Run("Fetch credentials from pull secret", func(t *testing.T) {
135189
dockerJson := fixture.MustReadFile("../../test/testdata/docker/valid-config.json")
@@ -148,6 +202,33 @@ func Test_FetchCredentialsFromPullSecret(t *testing.T) {
148202
require.NotNil(t, creds)
149203
assert.Equal(t, "foo", creds.Username)
150204
assert.Equal(t, "bar", creds.Password)
205+
206+
credSrc.SecretNamespace = "test1" // test with a wrong SecretNamespace
207+
creds, err = credSrc.FetchCredentials("https://registry-1.docker.io", &kube.KubernetesClient{Clientset: clientset})
208+
require.Error(t, err)
209+
require.Nil(t, creds)
210+
})
211+
212+
t.Run("Fetch credentials from pull secret with invalid config", func(t *testing.T) {
213+
dockerJson := fixture.MustReadFile("../../test/testdata/docker/valid-config.json")
214+
dockerJson = strings.ReplaceAll(dockerJson, "auths", "BAD-KEY")
215+
secretData := make(map[string][]byte)
216+
secretData[pullSecretField] = []byte(dockerJson)
217+
pullSecret := fixture.NewSecret("test", "test", secretData)
218+
clientset := fake.NewFakeClientsetWithResources(pullSecret)
219+
credSrc := &CredentialSource{
220+
Type: CredentialSourcePullSecret,
221+
Registry: "https://registry-1.docker.io/v2",
222+
SecretNamespace: "test",
223+
SecretName: "test",
224+
}
225+
creds, err := credSrc.FetchCredentials("https://registry-1.docker.io", &kube.KubernetesClient{Clientset: clientset})
226+
require.Error(t, err) // should fail with "no credentials in image pull secret"
227+
require.Nil(t, creds)
228+
229+
creds, err = credSrc.FetchCredentials("https://registry-1.docker.io", nil)
230+
require.Error(t, err) // should fail with "could not fetch credentials: no Kubernetes client given"
231+
require.Nil(t, creds)
151232
})
152233

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

350+
func Test_FetchCredentialsFromUnknown(t *testing.T) {
351+
t.Run("Fetch credentials from unknown type", func(t *testing.T) {
352+
credSrc := &CredentialSource{
353+
Type: CredentialSourceType(-1),
354+
Registry: "https://registry-1.docker.io/v2",
355+
}
356+
creds, err := credSrc.FetchCredentials("https://registry-1.docker.io", nil)
357+
require.Error(t, err) // should fail with "unknown credential type"
358+
require.Nil(t, creds)
359+
})
360+
}
361+
269362
func Test_ParseDockerConfig(t *testing.T) {
270363
t.Run("Parse valid Docker configuration with matching registry", func(t *testing.T) {
271364
config := fixture.MustReadFile("../../test/testdata/docker/valid-config.json")
@@ -283,6 +376,22 @@ func Test_ParseDockerConfig(t *testing.T) {
283376
assert.Equal(t, "bar", password)
284377
})
285378

379+
t.Run("Parse valid Docker configuration with matching http registry as prefix", func(t *testing.T) {
380+
config := fixture.MustReadFile("../../test/testdata/docker/valid-config-noproto.json")
381+
username, password, err := parseDockerConfigJson("http://registry-1.docker.io", config)
382+
require.NoError(t, err)
383+
assert.Equal(t, "foo", username)
384+
assert.Equal(t, "bar", password)
385+
})
386+
387+
t.Run("Parse valid Docker configuration with matching no-protocol registry as prefix", func(t *testing.T) {
388+
config := fixture.MustReadFile("../../test/testdata/docker/valid-config-noproto.json")
389+
username, password, err := parseDockerConfigJson("registry-1.docker.io", config)
390+
require.NoError(t, err)
391+
assert.Equal(t, "foo", username)
392+
assert.Equal(t, "bar", password)
393+
})
394+
286395
t.Run("Parse valid Docker configuration with matching registry as prefix with / in the end", func(t *testing.T) {
287396
config := fixture.MustReadFile("../../test/testdata/docker/valid-config-noproto.json")
288397
username, password, err := parseDockerConfigJson("https://registry-1.docker.io/", config)

pkg/image/image_test.go

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"testing"
55
"time"
66

7-
"github.com/argoproj-labs/argocd-image-updater/pkg/tag"
8-
97
"github.com/stretchr/testify/assert"
108
"github.com/stretchr/testify/require"
9+
"golang.org/x/exp/slices"
10+
11+
"github.com/argoproj-labs/argocd-image-updater/pkg/tag"
1112
)
1213

1314
func Test_ParseImageTags(t *testing.T) {
@@ -160,9 +161,65 @@ func Test_ContainerList(t *testing.T) {
160161
for _, n := range image_names {
161162
images = append(images, NewFromIdentifier(n))
162163
}
164+
withKustomizeOverride := NewFromIdentifier("k1/k2:k3")
165+
withKustomizeOverride.KustomizeImage = images[0]
166+
images = append(images, withKustomizeOverride)
167+
163168
assert.NotNil(t, images.ContainsImage(NewFromIdentifier(image_names[0]), false))
164169
assert.NotNil(t, images.ContainsImage(NewFromIdentifier(image_names[1]), false))
165170
assert.NotNil(t, images.ContainsImage(NewFromIdentifier(image_names[2]), false))
166171
assert.Nil(t, images.ContainsImage(NewFromIdentifier("foo/bar"), false))
172+
173+
imageMatch := images.ContainsImage(withKustomizeOverride, false)
174+
assert.Equal(t, images[0], imageMatch)
167175
})
168176
}
177+
178+
func Test_getImageDigestFromTag(t *testing.T) {
179+
tagAndDigest := "test-tag@sha256:abcde"
180+
tagName, tagDigest := getImageDigestFromTag(tagAndDigest)
181+
assert.Equal(t, "test-tag", tagName)
182+
assert.Equal(t, "sha256:abcde", tagDigest)
183+
184+
tagAndDigest = "test-tag"
185+
tagName, tagDigest = getImageDigestFromTag(tagAndDigest)
186+
assert.Equal(t, "test-tag", tagName)
187+
assert.Empty(t, tagDigest)
188+
}
189+
190+
func Test_ContainerImageList_String_Originals(t *testing.T) {
191+
images := make(ContainerImageList, 0)
192+
originals := []string{}
193+
194+
assert.Equal(t, "", images.String())
195+
assert.True(t, slices.Equal(originals, images.Originals()))
196+
197+
images = append(images, NewFromIdentifier("foo/bar:0.1"))
198+
originals = append(originals, "foo/bar:0.1")
199+
assert.Equal(t, "foo/bar:0.1", images.String())
200+
assert.True(t, slices.Equal(originals, images.Originals()))
201+
202+
images = append(images, NewFromIdentifier("alias=foo/bar:0.2"))
203+
originals = append(originals, "alias=foo/bar:0.2")
204+
assert.Equal(t, "foo/bar:0.1,alias=foo/bar:0.2", images.String())
205+
assert.True(t, slices.Equal(originals, images.Originals()))
206+
}
207+
208+
func TestContainerImage_DiffersFrom(t *testing.T) {
209+
foo1 := NewFromIdentifier("x/foo:1")
210+
foo2 := NewFromIdentifier("x/foo:2")
211+
bar1 := NewFromIdentifier("x/bar:1")
212+
bar1WithRegistry := NewFromIdentifier("docker.io/x/bar:1")
213+
214+
assert.False(t, foo1.DiffersFrom(foo1, true))
215+
assert.False(t, foo1.DiffersFrom(foo2, false))
216+
assert.True(t, foo1.DiffersFrom(foo2, true))
217+
218+
assert.True(t, foo1.DiffersFrom(bar1, false))
219+
assert.True(t, bar1.DiffersFrom(foo1, false))
220+
assert.True(t, foo1.DiffersFrom(bar1, true))
221+
assert.True(t, bar1.DiffersFrom(foo1, true))
222+
assert.True(t, bar1.DiffersFrom(bar1WithRegistry, false))
223+
224+
assert.False(t, foo1.IsUpdatable("0.1", "^1.0"))
225+
}

pkg/image/kustomize_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package image
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_KustomizeImages_Find(t *testing.T) {
10+
images := KustomizeImages{
11+
"a/b:1.0",
12+
"a/b@sha256:aabb",
13+
"a/b:latest@sha256:aabb",
14+
"x/y=busybox",
15+
"x/y=foo.bar/a/c:0.23",
16+
}
17+
for _, image := range images {
18+
assert.True(t, images.Find(image) >= 0)
19+
}
20+
for _, image := range []string{"a/b:2", "x/y=foo.bar"} {
21+
assert.True(t, images.Find(KustomizeImage(image)) >= 0)
22+
}
23+
for _, image := range []string{"a/b", "x", "x/y"} {
24+
assert.Equal(t, -1, images.Find(KustomizeImage(image)))
25+
}
26+
}

0 commit comments

Comments
 (0)