Path: blob/main/components/registry-facade/pkg/registry/layersource_test.go
2499 views
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.1// Licensed under the GNU Affero General Public License (AGPL).2// See License.AGPL.txt in the project root for license information.34package registry56import (7"bytes"8"context"9"encoding/json"10"flag"11"io"12"os"13"testing"14"time"1516ctesting "github.com/gitpod-io/gitpod/common-go/testing"17"golang.org/x/xerrors"1819"github.com/containerd/containerd/remotes"20"github.com/containerd/containerd/remotes/docker"21ocispec "github.com/opencontainers/image-spec/specs-go/v1"22)2324type testStaticLayerSourceFixture struct {25SourceRef string `json:"sourceRef"`26Content map[string][]byte `json:"content"`27Envs []string `json:"envs"`28}2930var fetchFixture = flag.String("fetch-fixture", "", "create a new fixture from an image ref")3132func TestStaticLayerSource(t *testing.T) {33if *fetchFixture != "" {34ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)35defer cancel()3637fix, err := createFixtureFromImage(ctx, docker.NewResolver(docker.ResolverOptions{}), *fetchFixture)38if err != nil {39t.Fatalf("cannot download ref: %+q", err)40}4142out, err := json.MarshalIndent(fix, "", " ")43if err != nil {44t.Fatalf("cannot marshal fixture: %+q", err)45}4647err = os.WriteFile("fixtures/layersrc_new.json", out, 0600)48if err != nil {49t.Fatalf("cannot write fixture: %+q", err)50}5152t.Log("wrote fixture to fixtures/layersrc_new.json")53return54}5556type gold struct {57Error string `json:"error"`58Layer []AddonLayer `json:"layer"`59Envs []string `json:"envs"`60}61test := ctesting.FixtureTest{62T: t,63Path: "fixtures/layersrc_*.json",64Test: func(t *testing.T, input interface{}) interface{} {65fixture := input.(*testStaticLayerSourceFixture)6667src, err := NewStaticSourceFromImage(context.Background(), func() remotes.Resolver { return &fakeFetcher{Content: fixture.Content} }, fixture.SourceRef)68if err != nil {69return &gold{Error: err.Error()}70}7172res := make([]AddonLayer, len(src.layers))73for i := range src.layers {74res[i] = src.layers[i].AddonLayer75}76envs := parseEnvs(fixture.Envs)77for _, e := range src.envs {78e(envs)79}80return &gold{Layer: res, Envs: envs.serialize()}81},82Fixture: func() interface{} { return &testStaticLayerSourceFixture{} },83Gold: func() interface{} { return &gold{} },84}85test.Run()86}8788func createFixtureFromImage(ctx context.Context, resolver remotes.Resolver, ref string) (*testStaticLayerSourceFixture, error) {89fetcher, err := resolver.Fetcher(ctx, ref)90if err != nil {91return nil, err92}9394content := make(map[string][]byte)95_, desc, err := resolver.Resolve(ctx, ref)96if err != nil {97return nil, err98}99content[ref], err = json.Marshal(desc)100if err != nil {101return nil, err102}103104mf, _, err := DownloadManifest(ctx, AsFetcherFunc(fetcher), desc)105if err != nil {106return nil, err107}108content[desc.Digest.Encoded()], err = json.Marshal(mf)109if err != nil {110return nil, err111}112113cfg, err := DownloadConfig(ctx, AsFetcherFunc(fetcher), ref, mf.Config)114if err != nil {115return nil, err116}117content[mf.Config.Digest.Encoded()], err = json.Marshal(cfg)118if err != nil {119return nil, err120}121122return &testStaticLayerSourceFixture{123SourceRef: ref,124Content: content,125}, nil126}127128type fakeFetcher struct {129Content map[string][]byte130}131132func (f *fakeFetcher) Resolve(ctx context.Context, ref string) (name string, desc ocispec.Descriptor, err error) {133name = ref134c, ok := f.Content[ref]135if !ok {136err = xerrors.Errorf("not found")137return138}139140err = json.Unmarshal(c, &desc)141return142}143144// Pusher returns a new pusher for the provided reference145func (f *fakeFetcher) Pusher(ctx context.Context, ref string) (remotes.Pusher, error) {146return nil, xerrors.Errorf("not implemented")147}148149// Fetcher returns a new fetcher for the provided reference.150// All content fetched from the returned fetcher will be151// from the namespace referred to by ref.152func (f *fakeFetcher) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {153return f, nil154}155156func (f *fakeFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) {157c, ok := f.Content[desc.Digest.Encoded()]158if !ok {159return nil, xerrors.Errorf("not found")160}161return io.NopCloser(bytes.NewReader(c)), nil162}163164165