github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/daemon/routes_navcycle_kustomize_test.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/go-test/deep"
     9  	"github.com/golang/mock/gomock"
    10  	"github.com/replicatedhq/ship/pkg/lifecycle/daemon/daemontypes"
    11  	"github.com/replicatedhq/ship/pkg/state"
    12  	mockstate "github.com/replicatedhq/ship/pkg/test-mocks/state"
    13  	"github.com/replicatedhq/ship/pkg/testing/logger"
    14  	"github.com/replicatedhq/ship/pkg/testing/matchers"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  type kustomizeSaveFileTestCase struct {
    19  	Name        string
    20  	InState     state.V1
    21  	Body        SaveOverlayRequest
    22  	ExpectState state.Kustomize
    23  }
    24  
    25  func TestV2KustomizeSaveFile(t *testing.T) {
    26  	tests := []kustomizeSaveFileTestCase{
    27  		{
    28  			Name: "empty add patch",
    29  			Body: SaveOverlayRequest{
    30  				Contents: "foo/bar/baz",
    31  				Path:     "deployment.yaml",
    32  			},
    33  			ExpectState: state.Kustomize{
    34  				Overlays: map[string]state.Overlay{
    35  					"ship": {
    36  						ExcludedBases: []string{},
    37  						Patches: map[string]string{
    38  							"deployment.yaml": "foo/bar/baz",
    39  						},
    40  						Resources: map[string]string{},
    41  					},
    42  				},
    43  			},
    44  		},
    45  		{
    46  			Name: "empty add resource",
    47  			Body: SaveOverlayRequest{
    48  				Contents:   "foo/bar/baz",
    49  				Path:       "deployment.yaml",
    50  				IsResource: true,
    51  			},
    52  			ExpectState: state.Kustomize{
    53  				Overlays: map[string]state.Overlay{
    54  					"ship": {
    55  						ExcludedBases: []string{},
    56  						Patches:       map[string]string{},
    57  						Resources: map[string]string{
    58  							"deployment.yaml": "foo/bar/baz",
    59  						},
    60  					},
    61  				},
    62  			},
    63  		},
    64  		{
    65  			Name: "add resource when patch exists",
    66  			Body: SaveOverlayRequest{
    67  				Contents:   "foo/bar/baz",
    68  				Path:       "service.yaml",
    69  				IsResource: true,
    70  			},
    71  			InState: state.V1{
    72  				Kustomize: &state.Kustomize{
    73  					Overlays: map[string]state.Overlay{
    74  						"ship": {
    75  							ExcludedBases: []string{},
    76  							Patches: map[string]string{
    77  								"deployment.yaml": "foo/bar/baz",
    78  							},
    79  						},
    80  					},
    81  				},
    82  			},
    83  			ExpectState: state.Kustomize{
    84  				Overlays: map[string]state.Overlay{
    85  					"ship": {
    86  						ExcludedBases: []string{},
    87  						Patches: map[string]string{
    88  							"deployment.yaml": "foo/bar/baz",
    89  						},
    90  						Resources: map[string]string{
    91  							"service.yaml": "foo/bar/baz",
    92  						},
    93  					},
    94  				},
    95  			},
    96  		},
    97  		{
    98  			Name: "merge into existing",
    99  			Body: SaveOverlayRequest{
   100  				Contents:   "foo/bar/baz",
   101  				Path:       "service.yaml",
   102  				IsResource: true,
   103  			},
   104  			InState: state.V1{
   105  				Kustomize: &state.Kustomize{
   106  					Overlays: map[string]state.Overlay{
   107  						"ship": {
   108  							ExcludedBases: []string{},
   109  							Resources: map[string]string{
   110  								"deployment.yaml": "foo/bar/baz",
   111  							},
   112  							Patches: map[string]string{
   113  								"deployment.yaml": "foo/bar/baz",
   114  							},
   115  						},
   116  					},
   117  				},
   118  			},
   119  			ExpectState: state.Kustomize{
   120  				Overlays: map[string]state.Overlay{
   121  					"ship": {
   122  						ExcludedBases: []string{},
   123  						Resources: map[string]string{
   124  							"deployment.yaml": "foo/bar/baz",
   125  							"service.yaml":    "foo/bar/baz",
   126  						},
   127  						Patches: map[string]string{
   128  							"deployment.yaml": "foo/bar/baz",
   129  						},
   130  					},
   131  				},
   132  			},
   133  		},
   134  	}
   135  	for _, test := range tests {
   136  		t.Run(test.Name, func(t *testing.T) {
   137  			req := require.New(t)
   138  
   139  			mc := gomock.NewController(t)
   140  			fakeState := mockstate.NewMockManager(mc)
   141  			testLogger := &logger.TestLogger{T: t}
   142  			progressmap := &daemontypes.ProgressMap{}
   143  
   144  			v2 := &NavcycleRoutes{
   145  				Logger:       testLogger,
   146  				StateManager: fakeState,
   147  				StepProgress: progressmap,
   148  			}
   149  
   150  			fakeState.EXPECT().CachedState().Return(state.State{
   151  				V1: &test.InState,
   152  			}, nil).AnyTimes()
   153  
   154  			fakeState.EXPECT().SaveKustomize(&matchers.Is{
   155  				Test: func(v interface{}) bool {
   156  					c, ok := v.(*state.Kustomize)
   157  					if !ok {
   158  						return false
   159  					}
   160  					diff := deep.Equal(&test.ExpectState, c)
   161  					if len(diff) != 0 {
   162  						fmt.Printf("Failed diff compare with %s", strings.Join(diff, "\n"))
   163  						return false
   164  					}
   165  					return true
   166  				},
   167  				Describe: fmt.Sprintf("expect state equal to %+v", test.ExpectState),
   168  			}).Return(nil).AnyTimes()
   169  
   170  			err := v2.kustomizeDoSaveOverlay(test.Body)
   171  			req.NoError(err)
   172  			mc.Finish()
   173  		})
   174  	}
   175  }
   176  
   177  type kustomizeDeleteFileTestCase struct {
   178  	Name             string
   179  	InState          state.V1
   180  	DeleteFileParams deleteFileParams
   181  	ExpectState      state.Kustomize
   182  }
   183  
   184  type deleteFileParams struct {
   185  	pathQueryParam string
   186  	getFiles       func(overlay state.Overlay) map[string]string
   187  }
   188  
   189  func TestV2KustomizeDeleteFile(t *testing.T) {
   190  	tests := []kustomizeDeleteFileTestCase{
   191  		{
   192  			Name: "delete patch",
   193  			DeleteFileParams: deleteFileParams{
   194  				pathQueryParam: "deployment.yaml",
   195  				getFiles: func(overlay state.Overlay) map[string]string {
   196  					return overlay.Patches
   197  				},
   198  			},
   199  			InState: state.V1{
   200  				Kustomize: &state.Kustomize{
   201  					Overlays: map[string]state.Overlay{
   202  						"ship": {
   203  							Patches: map[string]string{
   204  								"deployment.yaml": "foo/bar/baz",
   205  							},
   206  							Resources: map[string]string{
   207  								"resource.yaml": "hi",
   208  							},
   209  						},
   210  					},
   211  				},
   212  			},
   213  			ExpectState: state.Kustomize{
   214  				Overlays: map[string]state.Overlay{
   215  					"ship": {
   216  						Patches: map[string]string{},
   217  						Resources: map[string]string{
   218  							"resource.yaml": "hi",
   219  						},
   220  					},
   221  				},
   222  			},
   223  		},
   224  		{
   225  			Name: "delete resource, nil patches",
   226  			DeleteFileParams: deleteFileParams{
   227  				pathQueryParam: "resource.yaml",
   228  				getFiles: func(overlay state.Overlay) map[string]string {
   229  					return overlay.Resources
   230  				},
   231  			},
   232  			InState: state.V1{
   233  				Kustomize: &state.Kustomize{
   234  					Overlays: map[string]state.Overlay{
   235  						"ship": {
   236  							Patches: nil,
   237  							Resources: map[string]string{
   238  								"resource.yaml":      "bye",
   239  								"dont-touch-me.yaml": "forever",
   240  							},
   241  						},
   242  					},
   243  				},
   244  			},
   245  			ExpectState: state.Kustomize{
   246  				Overlays: map[string]state.Overlay{
   247  					"ship": {
   248  						Patches: nil,
   249  						Resources: map[string]string{
   250  							"dont-touch-me.yaml": "forever",
   251  						},
   252  					},
   253  				},
   254  			},
   255  		},
   256  	}
   257  	for _, test := range tests {
   258  		t.Run(test.Name, func(t *testing.T) {
   259  			req := require.New(t)
   260  
   261  			mc := gomock.NewController(t)
   262  			fakeState := mockstate.NewMockManager(mc)
   263  			testLogger := &logger.TestLogger{T: t}
   264  			progressmap := &daemontypes.ProgressMap{}
   265  
   266  			v2 := &NavcycleRoutes{
   267  				Logger:       testLogger,
   268  				StateManager: fakeState,
   269  				StepProgress: progressmap,
   270  			}
   271  
   272  			fakeState.EXPECT().CachedState().Return(state.State{
   273  				V1: &test.InState,
   274  			}, nil).AnyTimes()
   275  
   276  			fakeState.EXPECT().SaveKustomize(&matchers.Is{
   277  				Test: func(v interface{}) bool {
   278  					c, ok := v.(*state.Kustomize)
   279  					if !ok {
   280  						return false
   281  					}
   282  					diff := deep.Equal(&test.ExpectState, c)
   283  					if len(diff) != 0 {
   284  						fmt.Printf("Failed diff compare with %s", strings.Join(diff, "\n"))
   285  						return false
   286  					}
   287  					return true
   288  				},
   289  				Describe: fmt.Sprintf("expect state equal to %+v", test.ExpectState),
   290  			}).Return(nil).AnyTimes()
   291  
   292  			err := v2.deleteFile(test.DeleteFileParams.pathQueryParam, test.DeleteFileParams.getFiles)
   293  			req.NoError(err)
   294  			mc.Finish()
   295  		})
   296  	}
   297  }