github.com/release-engineering/exodus-rsync@v1.11.2/internal/cmd/cmd_sync_mixed_test.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "os/exec" 8 "path" 9 "reflect" 10 "strings" 11 "testing" 12 13 "github.com/golang/mock/gomock" 14 "github.com/release-engineering/exodus-rsync/internal/args" 15 "github.com/release-engineering/exodus-rsync/internal/gw" 16 "github.com/release-engineering/exodus-rsync/internal/rsync" 17 ) 18 19 type fakeRsync struct { 20 delegate rsync.Interface 21 prefix []string 22 err error 23 } 24 25 func (r *fakeRsync) Command(ctx context.Context, args []string) (*exec.Cmd, error) { 26 if r.err != nil { 27 // Immediately return the error provided. 28 return nil, r.err 29 } 30 31 cmd, err := r.delegate.Command(ctx, args) 32 cmd.Path = r.prefix[0] 33 cmd.Args = append(r.prefix, cmd.Args...) 34 35 if !strings.Contains(cmd.Path, "/") { 36 newPath, err := exec.LookPath(cmd.Path) 37 if err != nil { 38 panic(err) 39 } 40 cmd.Path = newPath 41 } 42 43 return cmd, err 44 } 45 46 func (r *fakeRsync) Exec(ctx context.Context, args args.Config) error { 47 return fmt.Errorf("this test is not supposed to Exec") 48 } 49 50 func (r *fakeRsync) RawExec(ctx context.Context, args []string) error { 51 return fmt.Errorf("this test is not supposed to RawExec") 52 } 53 54 func TestMainSyncMixedOk(t *testing.T) { 55 wd, err := os.Getwd() 56 if err != nil { 57 t.Fatal(err) 58 } 59 60 rsync := &fakeRsync{delegate: ext.rsync} 61 62 // Make it just run "echo" instead of real rsync, thus forcing rsync 63 // to "succeed". Sleep is to get predictable timing, with exodus publish 64 // finishing first - assists in reaching 100% coverage. 65 rsync.prefix = []string{"/bin/sh", "-c", "sleep 2; echo FAKE RSYNC", "--"} 66 67 SetConfig(t, CONFIG) 68 ctrl := MockController(t) 69 70 log := CaptureLogger(t) 71 72 mockGw := gw.NewMockInterface(ctrl) 73 ext.gw = mockGw 74 75 ext.rsync = rsync 76 77 client := FakeClient{blobs: make(map[string]string)} 78 mockGw.EXPECT().NewClient(gomock.Any(), EnvMatcher{"best-env"}).Return(&client, nil) 79 80 srcPath := path.Clean(wd + "/../../test/data/srctrees/links") 81 82 args := []string{ 83 "rsync", 84 "-vvv", 85 srcPath + "/", 86 "exodus-mixed:/dest", 87 } 88 89 got := Main(args) 90 91 // It should complete successfully. 92 if got != 0 { 93 t.Error("returned incorrect exit code", got) 94 } 95 96 // It should have created one publish. 97 if len(client.publishes) != 1 { 98 t.Error("expected to create 1 publish, instead created", len(client.publishes)) 99 } 100 101 p := client.publishes[0] 102 103 // Build up a URI => Key mapping of what was published 104 itemMap := make(map[string]string) 105 for _, item := range p.items { 106 if _, ok := itemMap[item.WebURI]; ok { 107 t.Error("tried to publish this URI more than once:", item.WebURI) 108 } 109 itemMap[item.WebURI] = item.ObjectKey 110 } 111 112 // It should have been exactly this 113 expectedItems := map[string]string{ 114 "/dest/link-to-regular-file": "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", 115 "/dest/some/dir/link-to-somefile": "57921e8a0929eaff5003cc9dd528c3421296055a4de2ba72429dc7f41bfa8411", 116 "/dest/some/somefile": "57921e8a0929eaff5003cc9dd528c3421296055a4de2ba72429dc7f41bfa8411", 117 "/dest/subdir/regular-file": "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", 118 "/dest/subdir/rand1": "57921e8a0929eaff5003cc9dd528c3421296055a4de2ba72429dc7f41bfa8411", 119 "/dest/subdir/rand2": "f3a5340ae2a400803b8150f455ad285d173cbdcf62c8e9a214b30f467f45b310", 120 "/dest/subdir2/dir-link/regular-file": "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", 121 "/dest/subdir2/dir-link/rand1": "57921e8a0929eaff5003cc9dd528c3421296055a4de2ba72429dc7f41bfa8411", 122 "/dest/subdir2/dir-link/rand2": "f3a5340ae2a400803b8150f455ad285d173cbdcf62c8e9a214b30f467f45b310", 123 } 124 125 if !reflect.DeepEqual(itemMap, expectedItems) { 126 t.Error("did not publish expected items, published:", itemMap) 127 } 128 129 // It should have committed the publish (once) 130 if p.committed != 1 { 131 t.Error("expected to commit publish (once), instead p.committed ==", p.committed) 132 } 133 134 // It should have logged the output of rsync, which can be found 135 // as entries with 'rsync' field 136 rsyncText := "" 137 for _, entry := range log.Entries { 138 _, ok := entry.Fields["rsync"] 139 if ok { 140 rsyncText = rsyncText + entry.Message + "\n" 141 } 142 } 143 144 if !strings.Contains(rsyncText, "FAKE RSYNC") { 145 t.Errorf("Did not generate expected rsync logs, got: %v", rsyncText) 146 } 147 }