44 "errors"
55 "io"
66 "path"
7+ "path/filepath"
78 "reflect"
89 "strings"
910 "testing"
@@ -13,7 +14,7 @@ import (
1314
1415func TestCopyService (t * testing.T ) {
1516 s := & mockSource {localPath : "/tmp/testing" }
16- files := []string {"service-a/my-system/ my-file.yaml" , "service-a/my-system /this-file.yaml" }
17+ files := []string {"services/ service-a/base/config/ my-file.yaml" , "services/ service-a/base/config /this-file.yaml" }
1718 for _ , f := range files {
1819 s .addFile (f )
1920 }
@@ -29,18 +30,97 @@ func TestCopyService(t *testing.T) {
2930 }
3031}
3132
33+ func TestPathValidForPromotion (t * testing.T ) {
34+
35+ serviceBeingPromoted := "service-name"
36+ servicesNotBeingPromoted := []string {"svc" , "base" , "serviceName" , "services" }
37+ promoteTheseWhenServiceNameIsRight := []string {
38+ "services/service-name/base/config/kustomization.yaml" ,
39+ "services/service-name/base/config/deployment.yaml" ,
40+ "services/service-name/base/config/dir/below/it/may/contain/important.yaml" ,
41+ }
42+ for _ , filePath := range promoteTheseWhenServiceNameIsRight {
43+ if ! pathValidForPromotion (serviceBeingPromoted , filePath ) {
44+ t .Fatalf ("Valid path for promotion for %s incorrectly rejected: %s" , serviceBeingPromoted , filePath )
45+ }
46+ for _ , wrongService := range servicesNotBeingPromoted {
47+ if pathValidForPromotion (wrongService , filePath ) {
48+ t .Fatalf ("Path for service %s incorrectly accepted for promotion: %s" , wrongService , filePath )
49+ }
50+ }
51+ }
52+
53+ // These paths should never be promoted
54+ badServiceNames := []string {"svc" , "badService" }
55+ neverPromoteThese := []string {
56+ "services/svc/overlays/kustomization.yaml" ,
57+ "services/svc/kustomization.yaml" ,
58+ "svc/base/config/deployment.yaml" ,
59+ "services/badService/any/other/path/resource.yaml" ,
60+ }
61+ for _ , badPath := range neverPromoteThese {
62+ for _ , badServiceName := range badServiceNames {
63+ if pathValidForPromotion (badServiceName , badPath ) {
64+ t .Fatalf ("Invalid path %s for promotion of service %s incorrectly accepted" , badPath , badServiceName )
65+ }
66+ }
67+ }
68+ }
69+
70+ func TestPathForServiceConfig (t * testing.T ) {
71+ serviceName := "usefulService"
72+ correctPath := "services/usefulService"
73+ serviceConfigPath := pathForServiceConfig (serviceName )
74+ if serviceConfigPath != correctPath {
75+ t .Fatalf ("Invalid result for pathForServiceConfig(%s): wanted %s got %s" , serviceName , correctPath , serviceConfigPath )
76+ }
77+ }
78+
79+ func TestCopyServiceWithFailureCopying (t * testing.T ) {
80+ testError := errors .New ("this is a test error" )
81+ s := & mockSource {localPath : "/tmp/testing" }
82+ files := []string {"services/service-a/base/config/my-file.yaml" , "services/service-a/base/config/this-file.yaml" }
83+ for _ , f := range files {
84+ s .addFile (f )
85+ }
86+ d := & mockDestination {}
87+ d .copyError = testError
88+
89+ copied , err := CopyService ("service-a" , s , d )
90+ if err != testError {
91+ t .Fatalf ("unexpected error: got %v, wanted %v" , err , testError )
92+ }
93+ d .assertFilesWritten (t , []string {})
94+ if ! reflect .DeepEqual (copied , []string {}) {
95+ t .Fatalf ("failed to copy the files, got %#v, want %#v" , copied , []string {})
96+ }
97+ }
98+
3299type mockSource struct {
33100 files []string
34101 localPath string
35102}
36103
37- func (s * mockSource ) Walk (filePath string , cb func (string , string ) error ) error {
104+ // Walk: a mock function to emulate what happens in Repository.Walk()
105+ // The Mock version is different: it iterates over mockSource.files[] and then drives
106+ // the visitor callback in CopyService() as usual.
107+ //
108+ // To preserve the same behaviour, we see that Repository Walk receives /full/path/to/repo/services/service-name
109+ // and then calls filePath.Walk() on /full/path/to/repo/services/ .
110+ // When CopyService() drives Walk(), 'base' is typically services/service-name
111+ // Thus we take each /full/path/to/file/in/mockSource.files[] and split it at 'services/' as happens in the Walk() method we're mocking.
112+ func (s * mockSource ) Walk (base string , cb func (string , string ) error ) error {
38113 if s .files == nil {
39114 return nil
40115 }
116+
41117 for _ , f := range s .files {
42- if strings .HasPrefix (f , path .Join (s .localPath , filePath )) {
43- err := cb (f , strings .TrimPrefix (f , s .localPath + "/" ))
118+ if strings .HasPrefix (f , path .Join (s .localPath , base )) {
119+ splitString := filepath .Dir (base ) + "/"
120+ splitPoint := strings .Index (f , splitString ) + len (splitString )
121+ prefix := f [:splitPoint ]
122+ name := f [splitPoint :]
123+ err := cb (prefix , name )
44124 if err != nil {
45125 return err
46126 }
@@ -57,13 +137,17 @@ func (s *mockSource) addFile(name string) {
57137}
58138
59139type mockDestination struct {
60- written []string
140+ written []string
141+ copyError error
61142}
62143
63144func (d * mockDestination ) CopyFile (src , dst string ) error {
64145 if d .written == nil {
65146 d .written = []string {}
66147 }
148+ if d .copyError != nil {
149+ return d .copyError
150+ }
67151 d .written = append (d .written , dst )
68152 return nil
69153}
0 commit comments