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  }