...

Source file src/github.com/onsi/gomega/gexec/session_test.go

Documentation: github.com/onsi/gomega/gexec

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package gexec_test
     5  
     6  import (
     7  	"io"
     8  	"os/exec"
     9  	"syscall"
    10  	"time"
    11  
    12  	. "github.com/onsi/gomega/gbytes"
    13  	. "github.com/onsi/gomega/gexec"
    14  
    15  	. "github.com/onsi/ginkgo/v2"
    16  	. "github.com/onsi/gomega"
    17  )
    18  
    19  var _ = Describe("Session", func() {
    20  	Context("firefly binary", func() {
    21  		var fireflyPath string
    22  		var command *exec.Cmd
    23  		var session *Session
    24  
    25  		var outWriter, errWriter io.Writer
    26  
    27  		BeforeEach(func() {
    28  			outWriter = nil
    29  			errWriter = nil
    30  
    31  			var err error
    32  			fireflyPath, err = Build("./_fixture/firefly")
    33  			Expect(err).ShouldNot(HaveOccurred())
    34  
    35  		})
    36  
    37  		JustBeforeEach(func() {
    38  			command = exec.Command(fireflyPath)
    39  			var err error
    40  			session, err = Start(command, outWriter, errWriter)
    41  			Expect(err).ShouldNot(HaveOccurred())
    42  		})
    43  
    44  		Context("running a command", func() {
    45  			It("should start the process", func() {
    46  				Expect(command.Process).ShouldNot(BeNil())
    47  			})
    48  
    49  			It("should wrap the process's stdout and stderr with gbytes buffers", func() {
    50  				Eventually(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
    51  				Eventually(session.Err).Should(Say("Ah, curse your sudden but inevitable betrayal!"))
    52  				defer session.Out.CancelDetects()
    53  
    54  				select {
    55  				case <-session.Out.Detect("Can we maybe vote on the whole murdering people issue"):
    56  					Eventually(session).Should(Exit(0))
    57  				case <-session.Out.Detect("I swear by my pretty floral bonnet, I will end you."):
    58  					Eventually(session).Should(Exit(1))
    59  				case <-session.Out.Detect("My work's illegal, but at least it's honest."):
    60  					Eventually(session).Should(Exit(2))
    61  				case <-time.After(5 * time.Second):
    62  					Fail("timed out waiting for detection")
    63  				}
    64  			})
    65  
    66  			It("should satisfy the gbytes.BufferProvider interface, passing Stdout", func() {
    67  				Eventually(session).Should(Say("We've done the impossible, and that makes us mighty"))
    68  				Eventually(session).Should(Exit())
    69  			})
    70  		})
    71  
    72  		Describe("providing the exit code", func() {
    73  			It("should provide the app's exit code", func() {
    74  				Expect(session.ExitCode()).Should(Equal(-1))
    75  
    76  				Eventually(session).Should(Exit())
    77  				Expect(session.ExitCode()).Should(BeNumerically(">=", 0))
    78  				Expect(session.ExitCode()).Should(BeNumerically("<", 3))
    79  			})
    80  		})
    81  
    82  		Describe("wait", func() {
    83  			It("should wait till the command exits", func() {
    84  				Expect(session.ExitCode()).Should(Equal(-1))
    85  				Expect(session.Wait().ExitCode()).Should(BeNumerically(">=", 0))
    86  				Expect(session.Wait().ExitCode()).Should(BeNumerically("<", 3))
    87  			})
    88  		})
    89  
    90  		Describe("exited", func() {
    91  			It("should close when the command exits", func() {
    92  				Eventually(session.Exited).Should(BeClosed())
    93  				Expect(session.ExitCode()).ShouldNot(Equal(-1))
    94  			})
    95  		})
    96  
    97  		Describe("kill", func() {
    98  			It("should kill the command", func() {
    99  				session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   100  				Expect(err).ShouldNot(HaveOccurred())
   101  
   102  				session.Kill()
   103  				Eventually(session).Should(Exit(128 + 9))
   104  			})
   105  		})
   106  
   107  		Describe("interrupt", func() {
   108  			It("should interrupt the command", func() {
   109  				session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   110  				Expect(err).ShouldNot(HaveOccurred())
   111  
   112  				session.Interrupt()
   113  				Eventually(session).Should(Exit(128 + 2))
   114  			})
   115  		})
   116  
   117  		Describe("terminate", func() {
   118  			It("should terminate the command", func() {
   119  				session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   120  				Expect(err).ShouldNot(HaveOccurred())
   121  
   122  				session.Terminate()
   123  				Eventually(session).Should(Exit(128 + 15))
   124  			})
   125  		})
   126  
   127  		Describe("signal", func() {
   128  			It("should send the signal to the command", func() {
   129  				session, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   130  				Expect(err).ShouldNot(HaveOccurred())
   131  
   132  				session.Signal(syscall.SIGABRT)
   133  				Eventually(session).WithTimeout(5 * time.Second).Should(Exit(128 + 6))
   134  			})
   135  
   136  			It("should ignore sending a signal if the command did not start", func() {
   137  				session, err := Start(exec.Command("notexisting"), GinkgoWriter, GinkgoWriter)
   138  				Expect(err).To(HaveOccurred())
   139  
   140  				Expect(func() { session.Signal(syscall.SIGUSR1) }).NotTo(Panic())
   141  			})
   142  		})
   143  
   144  		Context("tracking sessions", func() {
   145  			BeforeEach(func() {
   146  				KillAndWait()
   147  			})
   148  
   149  			Describe("kill", func() {
   150  				It("should kill all the started sessions", func() {
   151  					session1, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   152  					Expect(err).ShouldNot(HaveOccurred())
   153  
   154  					session2, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   155  					Expect(err).ShouldNot(HaveOccurred())
   156  
   157  					session3, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   158  					Expect(err).ShouldNot(HaveOccurred())
   159  
   160  					Kill()
   161  
   162  					Eventually(session1).Should(Exit(128 + 9))
   163  					Eventually(session2).Should(Exit(128 + 9))
   164  					Eventually(session3).Should(Exit(128 + 9))
   165  				})
   166  
   167  				It("should not track unstarted sessions", func() {
   168  					_, err := Start(exec.Command("does not exist", "10000000"), GinkgoWriter, GinkgoWriter)
   169  					Expect(err).Should(HaveOccurred())
   170  
   171  					session2, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   172  					Expect(err).ShouldNot(HaveOccurred())
   173  
   174  					session3, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   175  					Expect(err).ShouldNot(HaveOccurred())
   176  
   177  					Kill()
   178  
   179  					Eventually(session2).Should(Exit(128 + 9))
   180  					Eventually(session3).Should(Exit(128 + 9))
   181  				})
   182  
   183  			})
   184  
   185  			Describe("killAndWait", func() {
   186  				It("should kill all the started sessions and wait for them to finish", func() {
   187  					session1, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   188  					Expect(err).ShouldNot(HaveOccurred())
   189  
   190  					session2, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   191  					Expect(err).ShouldNot(HaveOccurred())
   192  
   193  					session3, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   194  					Expect(err).ShouldNot(HaveOccurred())
   195  
   196  					KillAndWait()
   197  					Expect(session1).Should(Exit(128+9), "Should have exited")
   198  					Expect(session2).Should(Exit(128+9), "Should have exited")
   199  					Expect(session3).Should(Exit(128+9), "Should have exited")
   200  				})
   201  			})
   202  
   203  			Describe("terminate", func() {
   204  				It("should terminate all the started sessions", func() {
   205  					session1, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   206  					Expect(err).ShouldNot(HaveOccurred())
   207  
   208  					session2, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   209  					Expect(err).ShouldNot(HaveOccurred())
   210  
   211  					session3, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   212  					Expect(err).ShouldNot(HaveOccurred())
   213  
   214  					Terminate()
   215  
   216  					Eventually(session1).Should(Exit(128 + 15))
   217  					Eventually(session2).Should(Exit(128 + 15))
   218  					Eventually(session3).Should(Exit(128 + 15))
   219  				})
   220  			})
   221  
   222  			Describe("terminateAndWait", func() {
   223  				It("should terminate all the started sessions, and wait for them to exit", func() {
   224  					session1, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   225  					Expect(err).ShouldNot(HaveOccurred())
   226  
   227  					session2, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   228  					Expect(err).ShouldNot(HaveOccurred())
   229  
   230  					session3, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   231  					Expect(err).ShouldNot(HaveOccurred())
   232  
   233  					TerminateAndWait()
   234  
   235  					Expect(session1).Should(Exit(128+15), "Should have exited")
   236  					Expect(session2).Should(Exit(128+15), "Should have exited")
   237  					Expect(session3).Should(Exit(128+15), "Should have exited")
   238  				})
   239  			})
   240  
   241  			Describe("signal", func() {
   242  				It("should signal all the started sessions", func() {
   243  					session1, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   244  					Expect(err).ShouldNot(HaveOccurred())
   245  
   246  					session2, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   247  					Expect(err).ShouldNot(HaveOccurred())
   248  
   249  					session3, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   250  					Expect(err).ShouldNot(HaveOccurred())
   251  
   252  					Signal(syscall.SIGABRT)
   253  
   254  					Eventually(session1).WithTimeout(5 * time.Second).Should(Exit(128 + 6))
   255  					Eventually(session2).WithTimeout(5 * time.Second).Should(Exit(128 + 6))
   256  					Eventually(session3).WithTimeout(5 * time.Second).Should(Exit(128 + 6))
   257  				})
   258  			})
   259  
   260  			Describe("interrupt", func() {
   261  				It("should interrupt all the started sessions, and not wait", func() {
   262  					session1, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   263  					Expect(err).ShouldNot(HaveOccurred())
   264  
   265  					session2, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   266  					Expect(err).ShouldNot(HaveOccurred())
   267  
   268  					session3, err := Start(exec.Command("sleep", "10000000"), GinkgoWriter, GinkgoWriter)
   269  					Expect(err).ShouldNot(HaveOccurred())
   270  
   271  					Interrupt()
   272  
   273  					Eventually(session1).Should(Exit(128 + 2))
   274  					Eventually(session2).Should(Exit(128 + 2))
   275  					Eventually(session3).Should(Exit(128 + 2))
   276  				})
   277  			})
   278  		})
   279  
   280  		When("the command exits", func() {
   281  			It("should close the buffers", func() {
   282  				Eventually(session).Should(Exit())
   283  
   284  				Expect(session.Out.Closed()).Should(BeTrue())
   285  				Expect(session.Err.Closed()).Should(BeTrue())
   286  
   287  				Expect(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
   288  			})
   289  
   290  			var So = It
   291  
   292  			So("this means that eventually should short circuit", func() {
   293  				t := time.Now()
   294  				failures := InterceptGomegaFailures(func() {
   295  					Eventually(session).Should(Say("blah blah blah blah blah"))
   296  				})
   297  				Expect(time.Since(t)).Should(BeNumerically("<", time.Second))
   298  				Expect(failures).Should(HaveLen(1))
   299  			})
   300  		})
   301  
   302  		When("wrapping out and err", func() {
   303  			var (
   304  				outWriterBuffer, errWriterBuffer *Buffer
   305  			)
   306  
   307  			BeforeEach(func() {
   308  				outWriterBuffer = NewBuffer()
   309  				outWriter = outWriterBuffer
   310  				errWriterBuffer = NewBuffer()
   311  				errWriter = errWriterBuffer
   312  			})
   313  
   314  			It("should route to both the provided writers and the gbytes buffers", func() {
   315  				Eventually(session.Out).Should(Say("We've done the impossible, and that makes us mighty"))
   316  				Eventually(session.Err).Should(Say("Ah, curse your sudden but inevitable betrayal!"))
   317  
   318  				Expect(outWriterBuffer.Contents()).Should(ContainSubstring("We've done the impossible, and that makes us mighty"))
   319  				Expect(errWriterBuffer.Contents()).Should(ContainSubstring("Ah, curse your sudden but inevitable betrayal!"))
   320  
   321  				Eventually(session).Should(Exit())
   322  
   323  				Expect(outWriterBuffer.Contents()).Should(Equal(session.Out.Contents()))
   324  				Expect(errWriterBuffer.Contents()).Should(Equal(session.Err.Contents()))
   325  			})
   326  
   327  			When("discarding the output of the command", func() {
   328  				BeforeEach(func() {
   329  					outWriter = io.Discard
   330  					errWriter = io.Discard
   331  				})
   332  
   333  				It("executes succesfuly", func() {
   334  					Eventually(session).Should(Exit())
   335  				})
   336  			})
   337  		})
   338  	})
   339  
   340  	Context("firefly tests", func() {
   341  		var fireflyTestPath string
   342  		var command *exec.Cmd
   343  		var session *Session
   344  
   345  		var outWriter, errWriter io.Writer
   346  
   347  		BeforeEach(func() {
   348  			outWriter = nil
   349  			errWriter = nil
   350  
   351  			var err error
   352  			fireflyTestPath, err = CompileTest("./_fixture/firefly")
   353  			Expect(err).ShouldNot(HaveOccurred())
   354  		})
   355  
   356  		JustBeforeEach(func() {
   357  			command = exec.Command(fireflyTestPath)
   358  			var err error
   359  			session, err = Start(command, outWriter, errWriter)
   360  			Expect(err).ShouldNot(HaveOccurred())
   361  		})
   362  
   363  		When("wrapping out and err", func() {
   364  			var (
   365  				outWriterBuffer, errWriterBuffer *Buffer
   366  			)
   367  
   368  			BeforeEach(func() {
   369  				outWriterBuffer = NewBuffer()
   370  				outWriter = outWriterBuffer
   371  				errWriterBuffer = NewBuffer()
   372  				errWriter = errWriterBuffer
   373  			})
   374  
   375  			It("should route to both the provided writers and the gbytes buffers", func() {
   376  				Eventually(session.Out).Should(Say("PASS"))
   377  				Eventually(session.Err).Should(Say(""))
   378  
   379  				Expect(outWriterBuffer.Contents()).Should(ContainSubstring("PASS"))
   380  				Expect(errWriterBuffer.Contents()).Should(BeEmpty())
   381  
   382  				Eventually(session).Should(Exit())
   383  
   384  				Expect(outWriterBuffer.Contents()).Should(Equal(session.Out.Contents()))
   385  				Expect(errWriterBuffer.Contents()).Should(Equal(session.Err.Contents()))
   386  			})
   387  
   388  			When("discarding the output of the command", func() {
   389  				BeforeEach(func() {
   390  					outWriter = io.Discard
   391  					errWriter = io.Discard
   392  				})
   393  
   394  				It("executes succesfuly", func() {
   395  					Eventually(session).Should(Exit())
   396  				})
   397  			})
   398  		})
   399  	})
   400  
   401  	Describe("when the command fails to start", func() {
   402  		It("should return an error", func() {
   403  			_, err := Start(exec.Command("agklsjdfas"), nil, nil)
   404  			Expect(err).Should(HaveOccurred())
   405  		})
   406  	})
   407  })
   408  

View as plain text