github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/integration/sync_test.go (about) 1 package integration_test 2 3 import ( 4 "fmt" 5 "io" 6 "io/ioutil" 7 "net/http" 8 "os" 9 "os/exec" 10 "os/user" 11 "path/filepath" 12 "runtime" 13 14 "github.com/pf-qiu/concourse/v6/fly/version" 15 . "github.com/onsi/ginkgo" 16 . "github.com/onsi/gomega" 17 18 "github.com/onsi/gomega/gbytes" 19 "github.com/onsi/gomega/gexec" 20 "github.com/onsi/gomega/ghttp" 21 ) 22 23 var _ = Describe("Syncing", func() { 24 var ( 25 flyVersion string 26 copiedFlyDir string 27 copiedFlyPath string 28 ) 29 30 BeforeEach(func() { 31 copiedFlyDir, err := ioutil.TempDir("", "fly_sync") 32 Expect(err).ToNot(HaveOccurred()) 33 34 copiedFly, err := os.Create(filepath.Join(copiedFlyDir, filepath.Base(flyPath))) 35 Expect(err).ToNot(HaveOccurred()) 36 37 fly, err := os.Open(flyPath) 38 Expect(err).ToNot(HaveOccurred()) 39 40 _, err = io.Copy(copiedFly, fly) 41 Expect(err).ToNot(HaveOccurred()) 42 43 Expect(copiedFly.Close()).To(Succeed()) 44 45 Expect(fly.Close()).To(Succeed()) 46 47 copiedFlyPath = copiedFly.Name() 48 49 fi, err := os.Stat(flyPath) 50 Expect(err).ToNot(HaveOccurred()) 51 52 Expect(os.Chmod(copiedFlyPath, fi.Mode())).To(Succeed()) 53 54 atcServer.AppendHandlers(ghttp.CombineHandlers( 55 ghttp.VerifyRequest("GET", "/api/v1/cli"), 56 func(w http.ResponseWriter, r *http.Request) { 57 arch := r.URL.Query().Get("arch") 58 platform := r.URL.Query().Get("platform") 59 60 if arch != "amd64" && platform != runtime.GOOS { 61 http.Error(w, "bad params", 500) 62 return 63 } 64 65 w.WriteHeader(http.StatusOK) 66 fmt.Fprint(w, "this will totally execute") 67 }, 68 )) 69 }) 70 71 AfterEach(func() { 72 Expect(os.RemoveAll(copiedFlyDir)).To(Succeed()) 73 }) 74 75 downloadAndReplaceExecutable := func(arg ...string) { 76 flyCmd := exec.Command(copiedFlyPath, arg...) 77 flyCmd.Env = append(os.Environ(), "FAKE_FLY_VERSION="+flyVersion) 78 79 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 80 Expect(err).NotTo(HaveOccurred()) 81 82 <-sess.Exited 83 Expect(sess.ExitCode()).To(Equal(0)) 84 85 expected := []byte("this will totally execute") 86 expectBinaryToMatch(copiedFlyPath, expected[:8]) 87 } 88 89 Context("When versions mismatch between fly + atc", func() { 90 BeforeEach(func() { 91 major, minor, patch, err := version.GetSemver(atcVersion) 92 Expect(err).NotTo(HaveOccurred()) 93 94 flyVersion = fmt.Sprintf("%d.%d.%d", major, minor, patch+1) 95 }) 96 97 It("downloads and replaces the currently running executable with target", func() { 98 downloadAndReplaceExecutable("-t", targetName, "sync") 99 }) 100 101 It("downloads and replaces the currently running executable with target URL", func() { 102 downloadAndReplaceExecutable("sync", "-c", atcServer.URL()) 103 }) 104 105 Context("When the user running sync doesn't have write permissions for the target directory", func() { 106 It("returns an error, and doesn't download/replace the executable", func() { 107 me, err := user.Current() 108 Expect(err).ToNot(HaveOccurred()) 109 110 if me.Uid == "0" { 111 Skip("root can always write; not worth testing") 112 return 113 } 114 115 if runtime.GOOS == "windows" { 116 Skip("who knows how windows works; not worth testing") 117 return 118 } 119 120 Expect(os.Chmod(filepath.Dir(copiedFlyPath), 0500)).To(Succeed()) 121 122 expectedBinary := readBinary(copiedFlyPath) 123 124 flyCmd := exec.Command(copiedFlyPath, "sync", "-c", atcServer.URL()) 125 flyCmd.Env = append(os.Environ(), "FAKE_FLY_VERSION="+flyVersion) 126 127 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 128 Expect(err).NotTo(HaveOccurred()) 129 130 <-sess.Exited 131 Expect(sess.ExitCode()).To(Equal(1)) 132 Expect(sess.Err).To(gbytes.Say("update failed.*permission denied")) 133 134 expectBinaryToMatch(copiedFlyPath, expectedBinary) 135 }) 136 }) 137 }) 138 139 Context("When versions match between fly + atc", func() { 140 BeforeEach(func() { 141 flyVersion = atcVersion 142 }) 143 144 It("informs the user, and doesn't download/replace the executable", func() { 145 expectedBinary := readBinary(copiedFlyPath) 146 147 flyCmd := exec.Command(copiedFlyPath, "sync", "-c", atcServer.URL()) 148 flyCmd.Env = append(os.Environ(), "FAKE_FLY_VERSION="+flyVersion) 149 150 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 151 Expect(err).NotTo(HaveOccurred()) 152 153 <-sess.Exited 154 Expect(sess.ExitCode()).To(Equal(0)) 155 Expect(sess.Out).To(gbytes.Say(`version 6.3.1 already matches; skipping`)) 156 157 expectBinaryToMatch(copiedFlyPath, expectedBinary) 158 }) 159 }) 160 }) 161 162 func readBinary(path string) []byte { 163 expectedBinary, err := ioutil.ReadFile(flyPath) 164 Expect(err).NotTo(HaveOccurred()) 165 return expectedBinary[:8] 166 } 167 168 func expectBinaryToMatch(path string, expectedBinary []byte) { 169 contents, err := ioutil.ReadFile(path) 170 Expect(err).NotTo(HaveOccurred()) 171 172 // don't let ginkgo try and output the entire binary as ascii 173 // 174 // that is the way to the dark side 175 contents = contents[:8] 176 Expect(contents).To(Equal(expectedBinary)) 177 }