github.com/cloudfoundry-attic/ltc@v0.0.0-20151123212628-098adc7919fc/cell-helpers/tee2metron/main_test.go (about) 1 // +build !windows 2 3 package main_test 4 5 import ( 6 "fmt" 7 "net" 8 "os" 9 "os/exec" 10 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 "github.com/onsi/gomega/gbytes" 14 "github.com/onsi/gomega/gexec" 15 ) 16 17 const maxUpdDatagramSize = 65507 18 19 var _ = Describe("tee2metron", func() { 20 It("prints stdout and stderr and streams them to metron", func() { 21 metronReceivedBuffer, port := startFakeMetron() 22 dropsondeDestinationFlag := "-dropsondeDestination=127.0.0.1:" + port 23 command := exec.Command(tee2MetronPath, dropsondeDestinationFlag, "-sourceInstance=cell-123", chattyProcessPath, "chattyArg1", "chattyArg2", "-chattyFlag") 24 25 session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) 26 Expect(err).NotTo(HaveOccurred()) 27 28 Consistently(session.Exited).ShouldNot(BeClosed()) 29 Eventually(gbytes.BufferWithBytes(*metronReceivedBuffer)).Should(gbytes.Say(chattyProcessPath)) 30 Eventually(gbytes.BufferWithBytes(*metronReceivedBuffer)).Should(gbytes.Say("lattice-debug")) 31 Eventually(gbytes.BufferWithBytes(*metronReceivedBuffer)).Should(gbytes.Say("cell-123")) 32 Eventually(gbytes.BufferWithBytes(*metronReceivedBuffer), 5).Should(gbytes.Say("Hi from stdout. My args are: [chattyArg1 chattyArg2 -chattyFlag]")) 33 Eventually(gbytes.BufferWithBytes(*metronReceivedBuffer), 5).Should(gbytes.Say("Oopsie from stderr")) 34 35 Eventually(session.Terminate()).Should(gexec.Exit(2)) 36 Expect(session.Out).To(gbytes.Say("Hi from stdout. My args are: [chattyArg1 chattyArg2 -chattyFlag]")) 37 Expect(session.Err).To(gbytes.Say("Oopsie from stderr")) 38 }) 39 40 Context("with a bad command", func() { 41 Context("when the command is missing", func() { 42 It("prints and error message and exits", func() { 43 command := exec.Command(tee2MetronPath, "-dropsondeDestination=127.0.0.1:4000", "-sourceInstance=cell-123") 44 session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) 45 Expect(err).NotTo(HaveOccurred()) 46 47 Eventually(session).Should(gexec.Exit(3)) 48 Expect(session.Out).To(gbytes.Say("Command not specified!")) 49 Expect(session.Out).To(gbytes.Say("Usage: tee2metron -dropsondeDestionation=127.0.0.1:3457 -sourceInstance=cell-21 COMMAND")) 50 }) 51 }) 52 Context("when there is an error executing the command", func() { 53 It("prints and error message and exits", func() { 54 command := exec.Command(tee2MetronPath, "-dropsondeDestination=127.0.0.1:4000", "-sourceInstance=cell-123", "do-the-fandango-for-me") 55 session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) 56 Expect(err).NotTo(HaveOccurred()) 57 58 Eventually(session).Should(gexec.Exit(3)) 59 Expect(session.Out).To(gbytes.Say(`exec: "do-the-fandango-for-me": executable file not found in \$PATH`)) 60 }) 61 }) 62 Context("when there is an no permission to execute", func() { 63 BeforeEach(func() { 64 Expect(os.Chmod(chattyProcessPath, 0644)).To(Succeed()) 65 }) 66 AfterEach(func() { 67 Expect(os.Chmod(chattyProcessPath, 0755)).To(Succeed()) 68 }) 69 It("prints and error message and exits", func() { 70 command := exec.Command(tee2MetronPath, "-dropsondeDestination=127.0.0.1:4000", "-sourceInstance=cell-123", chattyProcessPath, "chattyArg1", "chattyArg2", "-chattyFlag") 71 session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) 72 Expect(err).NotTo(HaveOccurred()) 73 74 Eventually(session).Should(gexec.Exit(3)) 75 Expect(session.Out).To(gbytes.Say("chatty_process: permission denied")) 76 }) 77 }) 78 }) 79 80 Describe("Flags", func() { 81 Context("when -dropsondeDestination is not passed", func() { 82 It("should specify the flag is required", func() { 83 command := exec.Command(tee2MetronPath, "-sourceInstance=cell-123", chattyProcessPath) 84 session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) 85 Expect(err).NotTo(HaveOccurred()) 86 87 Eventually(session).Should(gexec.Exit(1)) 88 Expect(session.Out).To(gbytes.Say("dropsondeDestination flag is required")) 89 }) 90 }) 91 92 Context("when -sourceInstance is not passed", func() { 93 It("should specify the flag is required", func() { 94 command := exec.Command(tee2MetronPath, "-dropsondeDestination=127.0.0.1:4000", chattyProcessPath) 95 session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) 96 Expect(err).NotTo(HaveOccurred()) 97 98 Eventually(session).Should(gexec.Exit(1)) 99 Expect(session.Out).To(gbytes.Say("sourceInstance flag is required")) 100 }) 101 }) 102 }) 103 }) 104 105 func startFakeMetron() (metronReceivedBufferPtr *[]byte, port string) { 106 connection, err := net.ListenPacket("udp", "") 107 if err != nil { 108 Fail("Error starting the integration test: Could not listen for udp packets on os-assigned port: " + err.Error()) 109 } 110 111 metronReceivedBuffer := make([]byte, maxUpdDatagramSize) 112 go func() { 113 defer connection.Close() 114 for { 115 _, _, err = connection.ReadFrom(metronReceivedBuffer) 116 if err != nil { 117 panic(err) 118 } 119 if string(metronReceivedBuffer) != string(make([]byte, maxUpdDatagramSize)) { 120 fmt.Fprintf(GinkgoWriter, "\nRead UDP Packet: %s\n", metronReceivedBuffer) 121 } 122 } 123 }() 124 125 _, listenPort, err := net.SplitHostPort(connection.LocalAddr().String()) 126 Expect(err).NotTo(HaveOccurred()) 127 128 return &metronReceivedBuffer, listenPort 129 }