/* Start starts the passed-in *exec.Cmd command. It wraps the command in a *gexec.Session. The session pipes the command's stdout and stderr to two *gbytes.Buffers available as properties on the session: session.Out and session.Err. These buffers can be used with the gbytes.Say matcher to match against unread output: Ω(session.Out).Should(gbytes.Say("foo-out")) Ω(session.Err).Should(gbytes.Say("foo-err")) In addition, Session satisfies the gbytes.BufferProvider interface and provides the stdout *gbytes.Buffer. This allows you to replace the first line, above, with: Ω(session).Should(gbytes.Say("foo-out")) When outWriter and/or errWriter are non-nil, the session will pipe stdout and/or stderr output both into the session *gybtes.Buffers and to the passed-in outWriter/errWriter. This is useful for capturing the process's output or logging it to screen. In particular, when using Ginkgo it can be convenient to direct output to the GinkgoWriter: session, err := Start(command, GinkgoWriter, GinkgoWriter) This will log output when running tests in verbose mode, but - otherwise - will only log output when a test fails. The session wrapper is responsible for waiting on the *exec.Cmd command. You *should not* call command.Wait() yourself. Instead, to assert that the command has exited you can use the gexec.Exit matcher: Ω(session).Should(gexec.Exit()) When the session exits it closes the stdout and stderr gbytes buffers. This will short circuit any Eventuallys waiting fo the buffers to Say something. */ func Start(command *exec.Cmd, outWriter io.Writer, errWriter io.Writer) (*Session, error) { session := &Session{ Command: command, Out: gbytes.NewBuffer(), Err: gbytes.NewBuffer(), lock: &sync.Mutex{}, exitCode: -1, } var commandOut, commandErr io.Writer commandOut, commandErr = session.Out, session.Err if outWriter != nil && !reflect.ValueOf(outWriter).IsNil() { commandOut = io.MultiWriter(commandOut, outWriter) } if errWriter != nil && !reflect.ValueOf(errWriter).IsNil() { commandErr = io.MultiWriter(commandErr, errWriter) } command.Stdout = commandOut command.Stderr = commandErr err := command.Start() if err == nil { go session.monitorForExit() } return session, err }
func newFakeStreamer() *fake_log_streamer.FakeLogStreamer { fakeStreamer := new(fake_log_streamer.FakeLogStreamer) stdoutBuffer := gbytes.NewBuffer() stderrBuffer := gbytes.NewBuffer() fakeStreamer.StdoutReturns(stdoutBuffer) fakeStreamer.StderrReturns(stderrBuffer) return fakeStreamer }
func createLink(socketPath string) (*linkpkg.Link, io.WriteCloser, io.WriteCloser, error) { linkStdout := gbytes.NewBuffer() linkStderr := gbytes.NewBuffer() var l *linkpkg.Link var err error for i := 0; i < 100; i++ { time.Sleep(10 * time.Millisecond) l, err = linkpkg.Create(socketPath, linkStdout, linkStderr) if err == nil { break } } return l, linkStdout, linkStderr, err }
func (example Example) Run() { input := bytes.NewBufferString(example.Input) output := gbytes.NewBuffer() interaction := interact.NewInteraction(example.Prompt, choices...) interaction.Input = input interaction.Output = output resolveErr := interaction.Resolve(destination) if example.ExpectedErr != nil { Expect(resolveErr).To(Equal(example.ExpectedErr)) } else { Expect(resolveErr).ToNot(HaveOccurred()) } var finalDestination interface{} switch d := destination.(type) { case interact.RequiredDestination: finalDestination = d.Destination default: finalDestination = destination } Expect(reflect.Indirect(reflect.ValueOf(finalDestination)).Interface()).To(Equal(example.ExpectedAnswer)) Expect(output.Contents()).To(Equal([]byte(example.ExpectedOutput))) }
func (matcher *haveFileMatcher) Match(actual interface{}) (success bool, err error) { container, ok := actual.(garden.Container) if !ok { return false, fmt.Errorf("HaveFile matcher expects an garden.Container") } out := gbytes.NewBuffer() proc, err := container.Run( garden.ProcessSpec{ Path: "ls", Args: []string{matcher.expected}, }, garden.ProcessIO{ Stdout: io.MultiWriter(ginkgo.GinkgoWriter, out), Stderr: io.MultiWriter(ginkgo.GinkgoWriter, out), }) if err != nil { return false, err } exitCode, err := proc.Wait() if err != nil { return false, err } if exitCode != 0 { return false, nil } return true, nil }
func canCreateAndUseFuseFileSystem(container garden.Container, user string) { mountpoint := "/tmp/fuse-test" process, err := container.Run(garden.ProcessSpec{ User: user, Path: "mkdir", Args: []string{"-p", mountpoint}, }, garden.ProcessIO{Stdout: GinkgoWriter, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Could not make temporary directory!") process, err = container.Run(garden.ProcessSpec{ User: user, Path: "/usr/bin/hellofs", Args: []string{mountpoint}, }, garden.ProcessIO{Stdout: GinkgoWriter, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Failed to mount hello filesystem.") stdout := gbytes.NewBuffer() process, err = container.Run(garden.ProcessSpec{ User: user, Path: "cat", Args: []string{filepath.Join(mountpoint, "hello")}, }, garden.ProcessIO{Stdout: stdout, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Failed to find hello file.") Expect(stdout).To(gbytes.Say("Hello World!")) process, err = container.Run(garden.ProcessSpec{ User: user, Path: "fusermount", Args: []string{"-u", mountpoint}, }, garden.ProcessIO{Stdout: GinkgoWriter, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Failed to unmount user filesystem.") stdout2 := gbytes.NewBuffer() process, err = container.Run(garden.ProcessSpec{ User: user, Path: "ls", Args: []string{mountpoint}, }, garden.ProcessIO{Stdout: stdout2, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0)) Expect(stdout2).ToNot(gbytes.Say("hello"), "Fuse filesystem appears still to be visible after being unmounted.") }
func NewTestSink() *TestSink { buffer := gbytes.NewBuffer() return &TestSink{ Sink: lager.NewWriterSink(buffer, lager.DEBUG), buffer: buffer, } }
func TestPerformance(t *testing.T) { RegisterFailHandler(Fail) SetDefaultEventuallyTimeout(5 * time.Second) BeforeEach(func() { gardenHost = os.Getenv("GARDEN_ADDRESS") if gardenHost == "" { gardenHost = "10.244.16.6" } gardenPort = os.Getenv("GARDEN_PORT") if gardenPort == "" { gardenPort = "7777" } rootfs = "docker:///cfgarden/garden-busybox" }) JustBeforeEach(func() { gardenClient = client.New(connection.New("tcp", fmt.Sprintf("%s:%s", gardenHost, gardenPort))) var err error container, err = gardenClient.Create(garden.ContainerSpec{ RootFSPath: rootfs, }) Expect(err).ToNot(HaveOccurred()) stdout := gbytes.NewBuffer() stderr := gbytes.NewBuffer() process, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sh", Args: []string{"-c", "while true; do sleep 1; done"}, }, garden.ProcessIO{ Stdout: stdout, Stderr: stderr, }) Expect(err).ToNot(HaveOccurred()) go process.Wait() }) AfterEach(func() { Expect(gardenClient.Destroy(container.Handle())).To(Succeed()) }) RunSpecs(t, "Performance Suite") }
func linkUp(netNsName, linkName string) bool { cmd := exec.Command("ip", "netns", "exec", netNsName, "ip", "link", "list", linkName) buffer := gbytes.NewBuffer() sess, err := gexec.Start(cmd, buffer, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(gexec.Exit(0)) return !strings.Contains(string(buffer.Contents()), "DOWN") }
func (c *FakeContainer) StreamIn(dst string) (io.WriteCloser, error) { buffer := gbytes.NewBuffer() c.StreamedIn = append(c.StreamedIn, StreamInSpec{ InStream: buffer, DestPath: dst, }) return buffer, c.StreamInError }
func NewExpector(in io.Reader, defaultTimeout time.Duration) *Expector { buffer := gbytes.NewBuffer() go func() { io.Copy(buffer, in) buffer.Close() }() return NewBufferExpector(buffer, defaultTimeout) }
func FakeFd(fd uintptr) *fakefd { pipeReader, pipeWriter := io.Pipe() buff := gbytes.NewBuffer() return &fakefd{ fd, buff, pipeReader, pipeWriter, } }
func sendRequest(ip string, port uint32) *gbytes.Buffer { stdout := gbytes.NewBuffer() cmd := exec.Command("nc", "-w1", ip, fmt.Sprintf("%d", port)) cmd.Stdout = stdout cmd.Stderr = GinkgoWriter err := cmd.Run() Expect(err).ToNot(HaveOccurred()) return stdout }
func runInContainer(container garden.Container, script string) (garden.Process, *gbytes.Buffer) { out := gbytes.NewBuffer() process, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sh", Args: []string{"-c", script}, }, garden.ProcessIO{ Stdout: io.MultiWriter(out, GinkgoWriter), Stderr: GinkgoWriter, }) Expect(err).ToNot(HaveOccurred()) return process, out }
/* Start starts the passed-in *exec.Cmd command. It wraps the command in a *gexec.Session. The session pipes the command's stdout and stderr to two *gbytes.Buffers available as properties on the session: session.Out and session.Err. These buffers can be used with the gbytes.Say matcher to match against unread output: Ω(session.Out).Should(gbytes.Say("foo-out")) Ω(session.Err).Should(gbytes.Say("foo-err")) In addition, Session satisfies the gbytes.BufferProvider interface and provides the stdout *gbytes.Buffer. This allows you to replace the first line, above, with: Ω(session).Should(gbytes.Say("foo-out")) When outWriter and/or errWriter are non-nil, the session will pipe stdout and/or stderr output both into the session *gybtes.Buffers and to the passed-in outWriter/errWriter. This is useful for capturing the process's output or logging it to screen. In particular, when using Ginkgo it can be convenient to direct output to the GinkgoWriter: session, err := Start(command, GinkgoWriter, GinkgoWriter) This will log output when running tests in verbose mode, but - otherwise - will only log output when a test fails. The session wrapper is responsible for waiting on the *exec.Cmd command. You *should not* call command.Wait() yourself. Instead, to assert that the command has exited you can use the gexec.Exit matcher: Ω(session).Should(gexec.Exit()) When the session exits it closes the stdout and stderr gbytes buffers. This will short circuit any Eventuallys waiting for the buffers to Say something. */ func Start(command *exec.Cmd, outWriter io.Writer, errWriter io.Writer) (*Session, error) { exited := make(chan struct{}) session := &Session{ Command: command, Out: gbytes.NewBuffer(), Err: gbytes.NewBuffer(), Exited: exited, lock: &sync.Mutex{}, exitCode: -1, } var commandOut, commandErr io.Writer commandOut, commandErr = session.Out, session.Err if outWriter != nil && !reflect.ValueOf(outWriter).IsNil() { commandOut = io.MultiWriter(commandOut, outWriter) } if errWriter != nil && !reflect.ValueOf(errWriter).IsNil() { commandErr = io.MultiWriter(commandErr, errWriter) } command.Stdout = commandOut command.Stderr = commandErr err := command.Start() if err == nil { go session.monitorForExit(exited) trackedSessionsMutex.Lock() defer trackedSessionsMutex.Unlock() trackedSessions = append(trackedSessions, session) } return session, err }
func (s *SSHServer) Start() (address string) { Expect(s.listener).To(BeNil(), "test server already started") var err error s.listener, err = net.Listen("tcp", "127.0.0.1:0") Expect(err).NotTo(HaveOccurred()) s.closeChan = make(chan struct{}) s.CommandChan = make(chan string) s.Data = gbytes.NewBuffer() go s.listen() return s.listener.Addr().String() }
func (connection *FakeConnection) StreamIn(handle string, dstPath string) (io.WriteCloser, error) { buffer := gbytes.NewBuffer() connection.lock.Lock() connection.streamedIn[handle] = append(connection.streamedIn[handle], StreamInSpec{ Destination: dstPath, WriteBuffer: buffer, }) connection.lock.Unlock() if connection.WhenStreamingIn != nil { return connection.WhenStreamingIn(handle, dstPath) } return buffer, nil }
func linkDefaultGW(netNsName, linkName string) string { cmd := exec.Command("ip", "netns", "exec", netNsName, "ip", "route", "list", "dev", linkName) buffer := gbytes.NewBuffer() sess, err := gexec.Start(cmd, buffer, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(gexec.Exit(0)) re, err := regexp.Compile(`default via ([0-9.]+)`) Expect(err).NotTo(HaveOccurred()) ret := re.FindStringSubmatch(string(buffer.Contents())) Expect(ret).NotTo(BeEmpty()) return ret[1] }
func linkMTU(netNsName, linkName string) int { cmd := exec.Command("ip", "netns", "exec", netNsName, "ifconfig", linkName) buffer := gbytes.NewBuffer() sess, err := gexec.Start(cmd, buffer, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(gexec.Exit(0)) re, err := regexp.Compile(`MTU:([0-9]+)`) Expect(err).NotTo(HaveOccurred()) ret := re.FindStringSubmatch(string(buffer.Contents())) Expect(ret).NotTo(BeEmpty()) mtu, err := strconv.ParseInt(ret[1], 10, 32) Expect(err).NotTo(HaveOccurred()) return int(mtu) }
func startClique(cfg config.Config, args ...string) (*runner.ClqProcess, error) { if useIperf && !cfg.UseIperf { cfg.UseIperf = true cfg.IperfPort = testhelpers.SelectPort(GinkgoParallelNode()) } configFile, err := ioutil.TempFile("", "clique-agent-config") if err != nil { return nil, err } configFilePath := configFile.Name() encoder := json.NewEncoder(configFile) if err := encoder.Encode(cfg); err != nil { configFile.Close() os.Remove(configFilePath) return nil, err } configFile.Close() finalArgs := []string{"-config", configFilePath, "-debug"} finalArgs = append(finalArgs, args...) cmd := exec.Command(cliqueAgentBin, finalArgs...) buffer := gbytes.NewBuffer() cmd.Stdout = io.MultiWriter(buffer, GinkgoWriter) cmd.Stderr = io.MultiWriter(buffer, GinkgoWriter) if err := cmd.Start(); err != nil { os.Remove(configFilePath) return nil, err } Eventually(buffer).Should(gbytes.Say("Clique Agent")) return &runner.ClqProcess{ Cmd: cmd, Buffer: buffer, Config: cfg, ConfigDirPath: configFilePath, }, nil }
func ethInterfaceName(container garden.Container) string { buffer := gbytes.NewBuffer() proc, err := container.Run( garden.ProcessSpec{ Path: "sh", Args: []string{"-c", "ifconfig | grep 'Ethernet' | cut -f 1 -d ' '"}, User: "******", }, garden.ProcessIO{ Stdout: buffer, Stderr: GinkgoWriter, }, ) Expect(err).NotTo(HaveOccurred()) Expect(proc.Wait()).To(Equal(0)) contIfaceName := string(buffer.Contents()) // g3-abc-1 return contIfaceName[:len(contIfaceName)-2] + "0" // g3-abc-0 }
fakeAppExaminer *fake_app_examiner.FakeAppExaminer outputBuffer *gbytes.Buffer terminalUI terminal.UI domain string = "192.168.11.11.xip.io" fakeClock *fakeclock.FakeClock fakeDockerMetadataFetcher *fake_docker_metadata_fetcher.FakeDockerMetadataFetcher appRunnerCommandFactoryConfig command_factory.DockerRunnerCommandFactoryConfig logger lager.Logger fakeTailedLogsOutputter *fake_tailed_logs_outputter.FakeTailedLogsOutputter fakeExitHandler *fake_exit_handler.FakeExitHandler ) BeforeEach(func() { fakeAppRunner = &fake_app_runner.FakeAppRunner{} fakeAppExaminer = &fake_app_examiner.FakeAppExaminer{} outputBuffer = gbytes.NewBuffer() terminalUI = terminal.NewUI(nil, outputBuffer, nil) fakeDockerMetadataFetcher = &fake_docker_metadata_fetcher.FakeDockerMetadataFetcher{} fakeClock = fakeclock.NewFakeClock(time.Now()) logger = lager.NewLogger("ltc-test") fakeTailedLogsOutputter = fake_tailed_logs_outputter.NewFakeTailedLogsOutputter() fakeExitHandler = &fake_exit_handler.FakeExitHandler{} }) Describe("CreateAppCommand", func() { var createCommand cli.Command BeforeEach(func() { env := []string{"SHELL=/bin/bash", "COLOR=Blue"} appRunnerCommandFactoryConfig = command_factory.DockerRunnerCommandFactoryConfig{ AppRunner: fakeAppRunner,
"github.com/onsi/gomega/gbytes" ) type TestRunner struct { RunCalled bool } func (f *TestRunner) Run() error { f.RunCalled = true return nil } var _ = Describe("Stager", func() { Describe("Running a buildpack", func() { It("should tell a buildpack runner to run", func() { buffer := gbytes.NewBuffer() testrunner := new(TestRunner) err := stager.RunBuildpack(buffer, testrunner) Expect(testrunner.RunCalled).To(Equal(true)) Expect(err).ShouldNot(HaveOccurred()) Eventually(buffer).Should(gbytes.Say(`Running Buildpacks...`)) }) }) Describe("Getting a buildpack runner", func() { It("should return the address of a valid buildpack runner, with a correct buildpack list", func() { buildpackDir, _ := ioutil.TempDir(os.TempDir(), "cfocker-buildpackrunner-test") os.Mkdir(buildpackDir+"/test-buildpack", 0755) ioutil.WriteFile(buildpackDir+"/test-buildpack"+"/testfile", []byte("test"), 0644) runner := stager.NewBuildpackRunner(buildpackDir) var runnerVar *buildpackrunner.Runner
}) It("keeps retrying", func() { Enable() Eventually(fakeClient.HeartbeatCallCount).Should(BeNumerically(">=", 10)) }) }) Context("when getting the eureka client fails", func() { var ( expectedErr = errors.New("some-error") buf io.ReadWriter ) BeforeEach(func() { buf = gbytes.NewBuffer() log.SetOutput(io.MultiWriter(buf, GinkgoWriter)) clientProvider = func() (Client, error) { return fakeClient, expectedErr } }) AfterEach(func() { log.SetOutput(GinkgoWriter) }) It("exits with a non-zero exit code", func() { Enable() Expect(atomic.LoadInt32(&exitCode)).ToNot(BeZero()) })
Expect(reaper.Start(cmd1)).To(Succeed()) Expect(reaper.Start(cmd2)).To(Succeed()) Expect(reaper.Wait(cmd1)).To(Equal(byte(3))) Expect(reaper.Wait(cmd2)).To(Equal(byte(33))) }) Context("when there are grandchildren processes", func() { It("waits for a process to return and returns its exit status", func() { cmd := exec.Command("sh", "-c", "sleep 1; exit 3") Expect(reaper.Start(cmd)).To(Succeed()) Expect(reaper.Wait(cmd)).To(Equal(byte(3))) }) It("the child process can receive SIGCHLD when a grandchild terminates", func() { stdout := gbytes.NewBuffer() trap := exec.Command("sh", "-c", "trap 'echo caught SIGCHLD' CHLD; (ls / >/dev/null 2/&1); exit 0") trap.Stdout = stdout Expect(reaper.Start(trap)).To(Succeed()) Expect(reaper.Wait(trap)).To(Equal(byte(0))) Eventually(stdout).Should(gbytes.Say("caught SIGCHLD\n")) }) }) It("returns correct exit statuses of short-lived processes", func(done Done) { for i := 0; i < 100; i++ { cmd := exec.Command("sh", "-c", "exit 42") Expect(reaper.Start(cmd)).To(Succeed()) cmd2 := exec.Command("sh", "-c", "exit 43")
} workerMetadata = worker.Metadata{ PipelineName: "some-pipeline", Type: db.ContainerTypePut, StepName: "some-step", } ) BeforeEach(func() { fakeWorkerClient = new(wfakes.FakeClient) fakeTracker = new(rfakes.FakeTracker) fakeTrackerFactory = new(fakes.FakeTrackerFactory) factory = NewGardenFactory(fakeWorkerClient, fakeTracker) stdoutBuf = gbytes.NewBuffer() stderrBuf = gbytes.NewBuffer() }) Describe("Put", func() { var ( putDelegate *fakes.FakePutDelegate resourceConfig atc.ResourceConfig params atc.Params tags []string resourceTypes atc.ResourceTypes inStep *fakes.FakeStep repo *SourceRepository fakeSource *fakes.FakeArtifactSource
"exit_status": 3, }) }, ), stdoutStream("foo-handle", 42, 123, func(conn net.Conn) { conn.Write([]byte("stdout data")) conn.Write([]byte(fmt.Sprintf("roundtripped %s", <-stdInContent))) }), stderrStream("foo-handle", 42, 123, func(conn net.Conn) { conn.Write([]byte("stderr data")) }), ) }) It("streams the data, closes the destinations, and notifies of exit", func() { stdout := gbytes.NewBuffer() stderr := gbytes.NewBuffer() process, err := connection.Run("foo-handle", spec, garden.ProcessIO{ Stdin: bytes.NewBufferString("stdin data"), Stdout: stdout, Stderr: stderr, }) Ω(err).ShouldNot(HaveOccurred()) Ω(process.ID()).Should(Equal(uint32(42))) Eventually(stdout).Should(gbytes.Say("stdout data")) Eventually(stdout).Should(gbytes.Say("roundtripped stdin data")) Eventually(stderr).Should(gbytes.Say("stderr data"))
Expect(filepath.IsAbs(configFile)).To(BeTrue()) }) Describe("Read config", func() { var ( tempDir string buffer *gbytes.Buffer ) BeforeEach(func() { var err error tempDir, err = ioutil.TempDir("", "config") if err != nil { panic(err) } buffer = gbytes.NewBuffer() }) AfterEach(func() { os.RemoveAll(tempDir) }) Context("With a nonexistent config file", func() { var nonexistentConfigFile string BeforeEach(func() { nonexistentConfigFile = filepath.Join(tempDir, ".right_st.yml") }) It("Returns an error", func() { err := ReadConfig(nonexistentConfigFile, "")
Expect(err).ToNot(HaveOccurred()) Expect(status).To(Equal(42)) }) Describe("signalling a running process", func() { var ( process garden.Process stdout *gbytes.Buffer cmd *exec.Cmd ) JustBeforeEach(func() { var err error cmd = exec.Command(testPrintBin) stdout = gbytes.NewBuffer() process, err = processTracker.Run( 2, cmd, garden.ProcessIO{ Stdout: io.MultiWriter(stdout, GinkgoWriter), Stderr: GinkgoWriter, }, nil, signaller) Expect(err).NotTo(HaveOccurred()) Eventually(stdout).Should(gbytes.Say("pid")) }) AfterEach(func() { if cmd.ProcessState != nil && !cmd.ProcessState.Exited() { cmd.Process.Signal(os.Kill) }
stderrBuf *gbytes.Buffer identifier = worker.Identifier{ Name: "some-session-id", } sourceName SourceName = "some-source-name" ) BeforeEach(func() { fakeTracker = new(rfakes.FakeTracker) fakeWorkerClient = new(wfakes.FakeClient) factory = NewGardenFactory(fakeWorkerClient, fakeTracker, func() string { return "" }) stdoutBuf = gbytes.NewBuffer() stderrBuf = gbytes.NewBuffer() }) Describe("DependentGet", func() { var ( getDelegate *fakes.FakeGetDelegate resourceConfig atc.ResourceConfig params atc.Params version atc.Version tags []string inStep *fakes.FakeStep repo *SourceRepository step Step