github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/render/docker/step_test.go (about)

     1  package docker
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"testing"
     8  
     9  	"github.com/go-kit/kit/log"
    10  	"github.com/golang/mock/gomock"
    11  	"github.com/replicatedhq/libyaml"
    12  	"github.com/replicatedhq/ship/pkg/api"
    13  	"github.com/replicatedhq/ship/pkg/images"
    14  	"github.com/replicatedhq/ship/pkg/lifecycle/render/root"
    15  	"github.com/replicatedhq/ship/pkg/templates"
    16  	mockimages "github.com/replicatedhq/ship/pkg/test-mocks/images"
    17  	mocksaver "github.com/replicatedhq/ship/pkg/test-mocks/images/saver"
    18  	"github.com/replicatedhq/ship/pkg/test-mocks/state"
    19  	"github.com/replicatedhq/ship/pkg/testing/logger"
    20  	"github.com/spf13/afero"
    21  	"github.com/spf13/viper"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  func TestDockerStep(t *testing.T) {
    26  	tests := []struct {
    27  		name                    string
    28  		RegistrySecretSaveError error
    29  		InstallationIDSaveError error
    30  		Expect                  error
    31  	}{
    32  		{
    33  			name:                    "registry succeeds",
    34  			RegistrySecretSaveError: nil,
    35  			InstallationIDSaveError: nil,
    36  			Expect:                  nil,
    37  		},
    38  		{
    39  			name:                    "registry fails, install id succeeds",
    40  			RegistrySecretSaveError: errors.New("noooope"),
    41  			InstallationIDSaveError: nil,
    42  			Expect:                  nil,
    43  		},
    44  		{
    45  			name:                    "registry fails, install id fails",
    46  			RegistrySecretSaveError: errors.New("noooope"),
    47  			InstallationIDSaveError: errors.New("nope nope nope"),
    48  			Expect:                  errors.New("docker save image, both auth methods failed: nope nope nope"),
    49  		},
    50  	}
    51  	for _, test := range tests {
    52  		t.Run(test.name, func(t *testing.T) {
    53  			mc := gomock.NewController(t)
    54  			v := viper.New()
    55  			saver := mocksaver.NewMockImageSaver(mc)
    56  			urlResolver := mockimages.NewMockPullURLResolver(mc)
    57  			testLogger := &logger.TestLogger{T: t}
    58  			bb := templates.NewBuilderBuilder(testLogger, v, &state.MockManager{})
    59  			ctx := context.Background()
    60  
    61  			step := &DefaultStep{
    62  				Logger:         testLogger,
    63  				URLResolver:    urlResolver,
    64  				ImageSaver:     saver,
    65  				Viper:          v,
    66  				BuilderBuilder: bb,
    67  			}
    68  
    69  			asset := api.DockerAsset{
    70  				AssetShared: api.AssetShared{
    71  					Dest: "{{repl ConfigOption \"docker_dir\" }}/image.tar",
    72  				},
    73  				Image:  "registry.replicated.com/retracedio/api:v2.0.0",
    74  				Source: "replicated",
    75  			}
    76  			metadata := api.ReleaseMetadata{
    77  				CustomerID:     "tanker",
    78  				RegistrySecret: "lutz",
    79  				Images:         []api.Image{},
    80  			}
    81  			v.Set("installation-id", "vernon")
    82  
    83  			urlResolver.EXPECT().ResolvePullURL(asset, metadata).Return("some-pull-url", nil)
    84  
    85  			templateContext := map[string]interface{}{
    86  				"docker_dir": "images",
    87  			}
    88  			configGroups := []libyaml.ConfigGroup{
    89  				{
    90  					Name: "Test",
    91  					Items: []*libyaml.ConfigItem{
    92  						{
    93  							Name: "docker_dir",
    94  							Type: "text",
    95  						},
    96  					},
    97  				},
    98  			}
    99  
   100  			registrySecretSaveOpts := images.SaveOpts{
   101  				PullURL:   "some-pull-url",
   102  				SaveURL:   asset.Image,
   103  				IsPrivate: asset.Source != "public" && asset.Source != "",
   104  				Filename:  asset.Dest,
   105  				Username:  "tanker",
   106  				Password:  "lutz",
   107  			}
   108  
   109  			registrySaveCh := make(chan interface{})
   110  			go func() {
   111  				registrySaveCh <- test.RegistrySecretSaveError
   112  				close(registrySaveCh)
   113  			}()
   114  			saver.EXPECT().SaveImage(ctx, registrySecretSaveOpts).Return(registrySaveCh)
   115  
   116  			if test.RegistrySecretSaveError != nil {
   117  				installIDSaveCh := make(chan interface{})
   118  				go func() {
   119  					installIDSaveCh <- test.InstallationIDSaveError
   120  					close(installIDSaveCh)
   121  				}()
   122  
   123  				installationIDSaveOpts := images.SaveOpts{
   124  					PullURL:   "some-pull-url",
   125  					SaveURL:   asset.Image,
   126  					IsPrivate: asset.Source != "public" && asset.Source != "",
   127  					Filename:  asset.Dest,
   128  					Username:  "tanker",
   129  					Password:  "vernon",
   130  				}
   131  				saver.EXPECT().SaveImage(ctx, installationIDSaveOpts).Return(installIDSaveCh)
   132  			}
   133  
   134  			req := require.New(t)
   135  
   136  			// When
   137  			err := step.Execute(
   138  				root.Fs{
   139  					Afero:    afero.Afero{Fs: afero.NewMemMapFs()},
   140  					RootPath: "",
   141  				},
   142  				asset,
   143  				metadata,
   144  				mockProgress,
   145  				asset.Dest,
   146  				templateContext,
   147  				configGroups,
   148  			)(ctx)
   149  
   150  			// Then
   151  			if test.Expect == nil {
   152  				req.NoError(err)
   153  				return
   154  			}
   155  			if err == nil {
   156  				req.FailNowf("expected error did not occur", "expected error \"%v\" to be returned by step", test.Expect)
   157  			}
   158  
   159  			req.Equal(test.Expect.Error(), err.Error(), "expected errors to be equal")
   160  
   161  		})
   162  	}
   163  }
   164  
   165  func mockProgress(ch chan interface{}, debug log.Logger) error {
   166  	var saveError error
   167  	for msg := range ch {
   168  		if msg == nil {
   169  			continue
   170  		}
   171  		switch v := msg.(type) {
   172  		case error:
   173  			// continue reading on error to ensure channel is not blocked
   174  			saveError = v
   175  			debug.Log("event", "error", "message", fmt.Sprintf("%#v", v))
   176  		default:
   177  			debug.Log("event", "progress", "message", fmt.Sprintf("%#v", v))
   178  		}
   179  	}
   180  	return saveError
   181  }