| package docker |
| |
| import ( |
| "context" |
| "fmt" |
| "testing" |
| "time" |
| |
| "github.com/stretchr/testify/require" |
| "go.skia.org/infra/go/mockhttpclient" |
| ) |
| |
| const ( |
| fakeRegistry = "fake-registry" |
| fakeRepository = "my-image" |
| fakeTag = "latest" |
| |
| getManifestResponse = `{ |
| "schemaVersion": 2, |
| "mediaType": "application/vnd.docker.distribution.manifest.v2+json", |
| "config": { |
| "mediaType": "application/vnd.docker.container.image.v1+json", |
| "size": 3316, |
| "digest": "sha256:413668c8e4f58c8c979f9f8c4e3fbc9a5447149cc7f3a7e345b6d67a0615c5d6" |
| }, |
| "layers": [ |
| { |
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| "size": 27811285, |
| "digest": "sha256:82e01e20eb1d1a8e24c1a2568fdd977d3748c4e0d2a35d08853a0828f1282cb6" |
| }, |
| { |
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| "size": 15056296, |
| "digest": "sha256:9b108e8a453a70d884144cba59cc1bd4bf60e38ddf7aae08e71c5447611c0927" |
| }, |
| { |
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| "size": 194179534, |
| "digest": "sha256:386084a6509c415a2a231cd627ff75ea7b55650509d983d213e54ddc3df295cd" |
| }, |
| { |
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| "size": 16449088, |
| "digest": "sha256:118cf07964a5e185090d3b6997100c9917318a6c38790ffc5a509598d31c9ef6" |
| }, |
| { |
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| "size": 404878875, |
| "digest": "sha256:d19501fed31b581d3025ebe52e59ff8d16025b7e770b8749c1af9127298045bb" |
| }, |
| { |
| "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| "size": 49, |
| "digest": "sha256:3c2cba919283a210665e480bcbf943eaaf4ed87a83f02e81bb286b8bdead0e75" |
| } |
| ] |
| }` |
| getConfigResponse = `{ |
| "architecture": "amd64", |
| "author": "Bazel", |
| "config": { |
| "AttachStderr": true, |
| "AttachStdout": true, |
| "Cmd": [ |
| "bash" |
| ], |
| "Entrypoint": [ |
| "" |
| ], |
| "Env": [ |
| "CIPD_ROOT=/cipd", |
| "PATH=/cipd/go/bin:/cipd/go/bin:/cipd:/cipd/cipd_bin_packages:/cipd/cipd_bin_packages/bin:/cipd/cipd_bin_packages/cpython:/cipd/cipd_bin_packages/cpython/bin:/cipd/cipd_bin_packages/cpython3:/cipd/cipd_bin_packages/cpython3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
| ], |
| "Hostname": "100bdce963b2", |
| "Image": "30079d3d793b32475f48a8559425d35f35536c646ebefbeb93b890ea6e183562", |
| "User": "skia" |
| }, |
| "container": "100bdce963b25eb74e074ef49f3fda76d68f75884c3669c933db7318a545b4df", |
| "created": "1970-01-01T00:00:00Z", |
| "docker_version": "20.10.23", |
| "history": [ |
| { |
| "author": "Bazel", |
| "created": "1970-01-01T00:00:00Z", |
| "created_by": "bazel build ..." |
| }, |
| { |
| "author": "Bazel", |
| "created": "1970-01-01T00:00:00Z", |
| "created_by": "bazel build ..." |
| }, |
| { |
| "created": "2020-08-04T15:46:23.612778871Z", |
| "created_by": "/bin/sh -c #(nop) ADD file:dee7987945ea8b67359e7fa5814228ccd127cbc5c9ebdd608c89f89a7fb6d2d0 in / " |
| }, |
| { |
| "created": "2020-08-04T15:46:23.859725865Z", |
| "created_by": "/bin/sh -c #(nop) CMD [\"bash\"]", |
| "empty_layer": true |
| }, |
| { |
| "created": "2020-08-24T13:44:22.205739623Z", |
| "created_by": "/bin/sh -c apt-get update && apt-get upgrade -y && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* && addgroup --gid 2000 skia && adduser --uid 2000 --gid 2000 skia" |
| }, |
| { |
| "created": "2020-08-24T13:44:22.574114965Z", |
| "created_by": "/bin/sh -c #(nop) USER skia:skia", |
| "empty_layer": true |
| }, |
| { |
| "created": "2020-08-24T13:45:24.072952145Z", |
| "created_by": "/bin/sh -c #(nop) ARG CIPD_ROOT", |
| "empty_layer": true |
| }, |
| { |
| "created": "2020-08-24T13:45:24.256039559Z", |
| "created_by": "/bin/sh -c #(nop) ENV CIPD_ROOT=/cipd", |
| "empty_layer": true |
| }, |
| { |
| "created": "2021-09-27T13:57:56.814739607Z", |
| "created_by": "/bin/sh -c #(nop) COPY dir:f55d8860fc73e9ab333e1bf01c0864ddcc415e81086e9294e263d9fb06744040 in /cipd " |
| }, |
| { |
| "created": "2021-09-27T13:58:00.314301887Z", |
| "created_by": "/bin/sh -c #(nop) ENV PATH=/cipd:/cipd/cipd_bin_packages:/cipd/cipd_bin_packages/bin:/cipd/cipd_bin_packages/cpython:/cipd/cipd_bin_packages/cpython/bin:/cipd/cipd_bin_packages/cpython3:/cipd/cipd_bin_packages/cpython3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
| "empty_layer": true |
| }, |
| { |
| "created": "2023-04-25T04:33:13.177574832Z", |
| "created_by": "sh -c apt-get update && apt-get install -y wget openssh-client curl procps unzip vim less build-essential g++ g++-11 gcc gcc-11 gcc-11-base cpp cpp-11 libgcc-11-dev libstdc++-11-dev cmake && wget --output-document=/usr/local/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.14.0/bazelisk-linux-amd64 && chmod a+x /usr/local/bin/bazelisk && cipd install skia/bots/go --root=/cipd" |
| } |
| ], |
| "os": "linux", |
| "rootfs": { |
| "diff_ids": [ |
| "sha256:2760827628c28b78cd38417202a35f4ebfb74fa15d8d8d29486efe2f9e7d8ef7", |
| "sha256:ac98c2b90fe0c941922d78822d9db0ef473792027a6a623047073d0d67dc097c", |
| "sha256:44177851d94bc2e39573ffacb0e8eee5fb14c016a99f21eed076849f4909d41b", |
| "sha256:b122b9c4c2b6de00cf3bd051500faa0ddb81d9b147693b7bf3556e6d3095366c", |
| "sha256:403a461f89b41095e2b047b63864a02f6a74e26708b9bca48fab41b4ef39de28", |
| "sha256:84ff92691f909a05b224e1c56abb4864f01b4f8e3c854e4bb4c7baf1d3f6d652" |
| ], |
| "type": "layers" |
| } |
| } |
| ` |
| listTagsResponse = ` |
| { |
| "child": [], |
| "manifest": { |
| "sha256:000ba24df84b6490d68069cdee599d6599f3891f6420a37cdaa65852c9f1ecbc": { |
| "imageSizeBytes": "485929608", |
| "layerId": "", |
| "mediaType": "application/vnd.docker.distribution.manifest.v2+json", |
| "tag": [ |
| "2022-06-22T19_11_03Z-louhi-7d6a680-clean" |
| ], |
| "timeCreatedMs": "0", |
| "timeUploadedMs": "1655925303330" |
| }, |
| "sha256:001f6469f9513cda89206710c1711bb3f2cc169d7613d9d6bf688a7109eeeb30": { |
| "imageSizeBytes": "654679661", |
| "layerId": "", |
| "mediaType": "application/vnd.docker.distribution.manifest.v2+json", |
| "tag": [ |
| "2023-03-27T13_22_20Z-louhi-378431d-clean" |
| ], |
| "timeCreatedMs": "0", |
| "timeUploadedMs": "1679924189163" |
| } |
| }, |
| "name": "skia-public/autoroll-be", |
| "tags": [ |
| "2022-06-22T19_11_03Z-louhi-7d6a680-clean", |
| "2023-03-27T13_22_20Z-louhi-378431d-clean" |
| ] |
| } |
| ` |
| |
| listRepositoriesResponse1 = `{ |
| "next": "https://gcr.io/v2/_catalog?n=100&last=skia-public/img3", |
| "repositories": [ |
| "skia-public/img1", |
| "skia-public/img2", |
| "skia-public/img3" |
| ] |
| }` |
| listRepositoriesResponse2 = `{ |
| "next": "", |
| "repositories": [ |
| "skia-public/img4", |
| "other/img5", |
| "other/img6" |
| ] |
| }` |
| |
| fakeDigest = "000ba24df84b6490d68069cdee599d6599f3891f6420a37cdaa65852c9f1ecbc" |
| ) |
| |
| func TestGetManifest(t *testing.T) { |
| ctx := context.Background() |
| md := mockhttpclient.MockGetDialogue([]byte(getManifestResponse)) |
| md.RequestHeader(acceptHeader, manifestContentType) |
| md.ResponseHeader(digestHeader, fakeDigest) |
| urlmock := mockhttpclient.NewURLMock() |
| fakeURL := fmt.Sprintf(manifestURLTemplate, fakeRegistry, fakeRepository, fakeTag) |
| urlmock.MockOnce(fakeURL, md) |
| client := &ClientImpl{ |
| client: urlmock.Client(), |
| } |
| |
| manifest, err := client.GetManifest(ctx, fakeRegistry, fakeRepository, fakeTag) |
| require.NoError(t, err) |
| require.Equal(t, &Manifest{ |
| SchemaVersion: 2, |
| MediaType: "application/vnd.docker.distribution.manifest.v2+json", |
| Digest: "000ba24df84b6490d68069cdee599d6599f3891f6420a37cdaa65852c9f1ecbc", |
| Config: MediaConfig{ |
| MediaType: "application/vnd.docker.container.image.v1+json", |
| Size: 3316, |
| Digest: "sha256:413668c8e4f58c8c979f9f8c4e3fbc9a5447149cc7f3a7e345b6d67a0615c5d6", |
| }, |
| Layers: []MediaConfig{ |
| { |
| MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| Size: 27811285, |
| Digest: "sha256:82e01e20eb1d1a8e24c1a2568fdd977d3748c4e0d2a35d08853a0828f1282cb6", |
| }, |
| { |
| MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| Size: 15056296, |
| Digest: "sha256:9b108e8a453a70d884144cba59cc1bd4bf60e38ddf7aae08e71c5447611c0927", |
| }, |
| { |
| MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| Size: 194179534, |
| Digest: "sha256:386084a6509c415a2a231cd627ff75ea7b55650509d983d213e54ddc3df295cd", |
| }, |
| { |
| MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| Size: 16449088, |
| Digest: "sha256:118cf07964a5e185090d3b6997100c9917318a6c38790ffc5a509598d31c9ef6", |
| }, |
| { |
| MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| Size: 404878875, |
| Digest: "sha256:d19501fed31b581d3025ebe52e59ff8d16025b7e770b8749c1af9127298045bb", |
| }, |
| { |
| MediaType: "application/vnd.docker.image.rootfs.diff.tar.gzip", |
| Size: 49, |
| Digest: "sha256:3c2cba919283a210665e480bcbf943eaaf4ed87a83f02e81bb286b8bdead0e75", |
| }, |
| }, |
| }, manifest) |
| } |
| |
| func TestGetDigest(t *testing.T) { |
| ctx := context.Background() |
| md := mockhttpclient.MockGetDialogue([]byte(getManifestResponse)) |
| md.RequestHeader(acceptHeader, manifestContentType) |
| md.ResponseHeader(digestHeader, fakeDigest) |
| urlmock := mockhttpclient.NewURLMock() |
| fakeURL := fmt.Sprintf(manifestURLTemplate, fakeRegistry, fakeRepository, fakeTag) |
| urlmock.MockOnce(fakeURL, md) |
| client := &ClientImpl{ |
| client: urlmock.Client(), |
| } |
| |
| digest, err := GetDigest(ctx, client, fakeRegistry, fakeRepository, fakeTag) |
| require.NoError(t, err) |
| require.Equal(t, fakeDigest, digest) |
| } |
| |
| func TestGetConfig(t *testing.T) { |
| ctx := context.Background() |
| md := mockhttpclient.MockGetDialogue([]byte(getConfigResponse)) |
| urlmock := mockhttpclient.NewURLMock() |
| // Repo digest and config digest are different, but for the purpose of this |
| // test we don't care. |
| configDigest := fakeDigest |
| fakeURL := fmt.Sprintf(blobURLTemplate, fakeRegistry, fakeRepository, configDigest) |
| urlmock.MockOnce(fakeURL, md) |
| client := &ClientImpl{ |
| client: urlmock.Client(), |
| } |
| |
| config, err := client.GetConfig(ctx, fakeRegistry, fakeRepository, configDigest) |
| require.NoError(t, err) |
| require.Equal(t, &ImageConfig{ |
| Architecture: "amd64", |
| Author: "Bazel", |
| Config: ImageConfig_Config{ |
| AttachStderr: true, |
| AttachStdout: true, |
| Cmd: []string{"bash"}, |
| Entrypoint: []string{""}, |
| Env: []string{ |
| "CIPD_ROOT=/cipd", |
| "PATH=/cipd/go/bin:/cipd/go/bin:/cipd:/cipd/cipd_bin_packages:/cipd/cipd_bin_packages/bin:/cipd/cipd_bin_packages/cpython:/cipd/cipd_bin_packages/cpython/bin:/cipd/cipd_bin_packages/cpython3:/cipd/cipd_bin_packages/cpython3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
| }, |
| Hostname: "100bdce963b2", |
| Image: "30079d3d793b32475f48a8559425d35f35536c646ebefbeb93b890ea6e183562", |
| User: "skia", |
| }, |
| Container: "100bdce963b25eb74e074ef49f3fda76d68f75884c3669c933db7318a545b4df", |
| Created: time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC), |
| DockerVersion: "20.10.23", |
| History: []ImageConfig_History{ |
| {Author: "Bazel", Created: time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC), CreatedBy: "bazel build ...", EmptyLayer: false}, |
| {Author: "Bazel", Created: time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC), CreatedBy: "bazel build ...", EmptyLayer: false}, |
| {Author: "", Created: time.Date(2020, time.August, 4, 15, 46, 23, 612778871, time.UTC), CreatedBy: "/bin/sh -c #(nop) ADD file:dee7987945ea8b67359e7fa5814228ccd127cbc5c9ebdd608c89f89a7fb6d2d0 in / ", EmptyLayer: false}, |
| {Author: "", Created: time.Date(2020, time.August, 4, 15, 46, 23, 859725865, time.UTC), CreatedBy: "/bin/sh -c #(nop) CMD [\"bash\"]", EmptyLayer: true}, |
| {Author: "", Created: time.Date(2020, time.August, 24, 13, 44, 22, 205739623, time.UTC), CreatedBy: "/bin/sh -c apt-get update && apt-get upgrade -y && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* && addgroup --gid 2000 skia && adduser --uid 2000 --gid 2000 skia", EmptyLayer: false}, |
| {Author: "", Created: time.Date(2020, time.August, 24, 13, 44, 22, 574114965, time.UTC), CreatedBy: "/bin/sh -c #(nop) USER skia:skia", EmptyLayer: true}, |
| {Author: "", Created: time.Date(2020, time.August, 24, 13, 45, 24, 72952145, time.UTC), CreatedBy: "/bin/sh -c #(nop) ARG CIPD_ROOT", EmptyLayer: true}, |
| {Author: "", Created: time.Date(2020, time.August, 24, 13, 45, 24, 256039559, time.UTC), CreatedBy: "/bin/sh -c #(nop) ENV CIPD_ROOT=/cipd", EmptyLayer: true}, |
| {Author: "", Created: time.Date(2021, time.September, 27, 13, 57, 56, 814739607, time.UTC), CreatedBy: "/bin/sh -c #(nop) COPY dir:f55d8860fc73e9ab333e1bf01c0864ddcc415e81086e9294e263d9fb06744040 in /cipd ", EmptyLayer: false}, |
| {Author: "", Created: time.Date(2021, time.September, 27, 13, 58, 0, 314301887, time.UTC), CreatedBy: "/bin/sh -c #(nop) ENV PATH=/cipd:/cipd/cipd_bin_packages:/cipd/cipd_bin_packages/bin:/cipd/cipd_bin_packages/cpython:/cipd/cipd_bin_packages/cpython/bin:/cipd/cipd_bin_packages/cpython3:/cipd/cipd_bin_packages/cpython3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", EmptyLayer: true}, |
| {Author: "", Created: time.Date(2023, time.April, 25, 4, 33, 13, 177574832, time.UTC), CreatedBy: "sh -c apt-get update && apt-get install -y wget openssh-client curl procps unzip vim less build-essential g++ g++-11 gcc gcc-11 gcc-11-base cpp cpp-11 libgcc-11-dev libstdc++-11-dev cmake && wget --output-document=/usr/local/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.14.0/bazelisk-linux-amd64 && chmod a+x /usr/local/bin/bazelisk && cipd install skia/bots/go --root=/cipd", EmptyLayer: false}, |
| }, |
| OS: "linux", |
| RootFS: ImageConfig_RootFS{ |
| DiffIDs: []string{ |
| "sha256:2760827628c28b78cd38417202a35f4ebfb74fa15d8d8d29486efe2f9e7d8ef7", |
| "sha256:ac98c2b90fe0c941922d78822d9db0ef473792027a6a623047073d0d67dc097c", |
| "sha256:44177851d94bc2e39573ffacb0e8eee5fb14c016a99f21eed076849f4909d41b", |
| "sha256:b122b9c4c2b6de00cf3bd051500faa0ddb81d9b147693b7bf3556e6d3095366c", |
| "sha256:403a461f89b41095e2b047b63864a02f6a74e26708b9bca48fab41b4ef39de28", |
| "sha256:84ff92691f909a05b224e1c56abb4864f01b4f8e3c854e4bb4c7baf1d3f6d652", |
| }, |
| Type: "layers"}, |
| }, config) |
| } |
| |
| func TestListInstances(t *testing.T) { |
| ctx := context.Background() |
| md := mockhttpclient.MockGetDialogue([]byte(listTagsResponse)) |
| urlmock := mockhttpclient.NewURLMock() |
| fakeURL := fmt.Sprintf(listTagsURLTemplate, fakeRegistry, fakeRepository, pageSize) |
| urlmock.MockOnce(fakeURL, md) |
| client := &ClientImpl{ |
| client: urlmock.Client(), |
| } |
| |
| instances, err := client.ListInstances(ctx, fakeRegistry, fakeRepository) |
| require.NoError(t, err) |
| require.Equal(t, map[string]*ImageInstance{ |
| "sha256:000ba24df84b6490d68069cdee599d6599f3891f6420a37cdaa65852c9f1ecbc": { |
| Digest: "sha256:000ba24df84b6490d68069cdee599d6599f3891f6420a37cdaa65852c9f1ecbc", |
| SizeBytes: 485929608, |
| Tags: []string{ |
| "2022-06-22T19_11_03Z-louhi-7d6a680-clean", |
| }, |
| Created: time.Unix(0, 0), |
| Uploaded: time.Unix(0, 1655925303330000000), |
| }, |
| "sha256:001f6469f9513cda89206710c1711bb3f2cc169d7613d9d6bf688a7109eeeb30": { |
| Digest: "sha256:001f6469f9513cda89206710c1711bb3f2cc169d7613d9d6bf688a7109eeeb30", |
| SizeBytes: 654679661, |
| Tags: []string{ |
| "2023-03-27T13_22_20Z-louhi-378431d-clean", |
| }, |
| Created: time.Unix(0, 0), |
| Uploaded: time.Unix(0, 1679924189163000000), |
| }, |
| }, instances) |
| } |
| |
| func TestListTags(t *testing.T) { |
| ctx := context.Background() |
| md := mockhttpclient.MockGetDialogue([]byte(listTagsResponse)) |
| urlmock := mockhttpclient.NewURLMock() |
| fakeURL := fmt.Sprintf(listTagsURLTemplate, fakeRegistry, fakeRepository, pageSize) |
| urlmock.MockOnce(fakeURL, md) |
| client := &ClientImpl{ |
| client: urlmock.Client(), |
| } |
| |
| repos, err := client.ListTags(ctx, fakeRegistry, fakeRepository) |
| require.NoError(t, err) |
| require.Equal(t, []string{ |
| "2022-06-22T19_11_03Z-louhi-7d6a680-clean", |
| "2023-03-27T13_22_20Z-louhi-378431d-clean", |
| }, repos) |
| } |
| |
| func TestListRepositories(t *testing.T) { |
| ctx := context.Background() |
| urlmock := mockhttpclient.NewURLMock() |
| url1 := fmt.Sprintf(catalogURLTemplate, fakeRegistry, pageSize) |
| md1 := mockhttpclient.MockGetDialogue([]byte(listRepositoriesResponse1)) |
| urlmock.MockOnce(url1, md1) |
| |
| url2 := "https://gcr.io/v2/_catalog?n=100&last=skia-public/img3" |
| md2 := mockhttpclient.MockGetDialogue([]byte(listRepositoriesResponse2)) |
| urlmock.MockOnce(url2, md2) |
| |
| client := &ClientImpl{ |
| client: urlmock.Client(), |
| } |
| repos, err := client.ListRepositories(ctx, fakeRegistry) |
| require.NoError(t, err) |
| require.Equal(t, []string{ |
| "skia-public/img1", |
| "skia-public/img2", |
| "skia-public/img3", |
| "skia-public/img4", |
| "other/img5", |
| "other/img6", |
| }, repos) |
| } |
| |
| func TestSetTag(t *testing.T) { |
| ctx := context.Background() |
| const newTag = "new-tag" |
| urlmock := mockhttpclient.NewURLMock() |
| |
| url1 := fmt.Sprintf(manifestURLTemplate, fakeRegistry, fakeRepository, fakeTag) |
| md1 := mockhttpclient.MockGetDialogue([]byte(getManifestResponse)) |
| md1.RequestHeader(acceptHeader, manifestContentType) |
| md1.ResponseHeader(digestHeader, fakeDigest) |
| urlmock.MockOnce(url1, md1) |
| |
| url2 := fmt.Sprintf(manifestURLTemplate, fakeRegistry, fakeRepository, newTag) |
| md2 := mockhttpclient.MockPutDialogue(manifestContentType, []byte(getManifestResponse), nil) |
| urlmock.MockOnce(url2, md2) |
| |
| client := &ClientImpl{ |
| client: urlmock.Client(), |
| } |
| require.NoError(t, client.SetTag(ctx, fakeRegistry, fakeRepository, fakeTag, newTag)) |
| require.True(t, urlmock.Empty()) |
| } |
| |
| func TestSplitImage(t *testing.T) { |
| test := func(inp, expectRegistry, expectRepository, expectRef, expectErr string) { |
| actualRegistry, actualRepository, actualRef, actualErr := SplitImage(inp) |
| if expectErr == "" { |
| require.NoError(t, actualErr) |
| } else { |
| require.Error(t, actualErr) |
| require.Contains(t, actualErr.Error(), expectErr) |
| } |
| require.Equal(t, expectRegistry, actualRegistry) |
| require.Equal(t, expectRepository, actualRepository) |
| require.Equal(t, expectRef, actualRef) |
| } |
| // Success cases. |
| test("gcr.io/skia-public/autoroll-be", "gcr.io", "skia-public/autoroll-be", "", "") |
| test("gcr.io/skia-public/autoroll-be:latest", "gcr.io", "skia-public/autoroll-be", "latest", "") |
| test("gcr.io/skia-public/autoroll-be@sha256:6f90b59938db7b10e2225aa151714578361481562f8b0192778aaf78ca9f0e4a", "gcr.io", "skia-public/autoroll-be", "sha256:6f90b59938db7b10e2225aa151714578361481562f8b0192778aaf78ca9f0e4a", "") |
| test("gcr.io/blahblah", "gcr.io", "blahblah", "", "") |
| test("gcr.io/blahblah:myTag.with-interesting_chars", "gcr.io", "blahblah", "myTag.with-interesting_chars", "") |
| test("gcr.io/image_With.interesting-chars/path", "gcr.io", "image_With.interesting-chars/path", "", "") |
| |
| // Failure cases. |
| test("", "", "", "", "invalid Docker image format") |
| test("gcr.io", "", "", "", "invalid Docker image format") |
| test("my-image", "", "", "", "invalid Docker image format") |
| test(":tag", "", "", "", "invalid Docker image format") |
| test("@sha256:6f90b59938db7b10e2225aa151714578361481562f8b0192778aaf78ca9f0e4a", "", "", "", "invalid Docker image format") |
| test("my-image:tag", "", "", "", "invalid Docker image format") |
| test("my-image@sha256:6f90b59938db7b10e2225aa151714578361481562f8b0192778aaf78ca9f0e4a", "", "", "", "invalid Docker image format") |
| test("gcr.io/my-image@sha256:6f90b59938db7b10e2225aa151714578361481562f8b0192778aaf78ca9f0e4", "", "", "", "invalid Docker image format") |
| } |