Skip to content

Commit

Permalink
Fix odo log flake (#3733)
Browse files Browse the repository at this point in the history
* Fix odo log flake

* fix some spells

* pass Stderr stream to buffer as well
`

* Use seperate buffer for stderr
  • Loading branch information
Aditi Sharma authored Aug 18, 2020
1 parent a01dc88 commit eec93d3
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 5 deletions.
62 changes: 62 additions & 0 deletions tests/helper/helper_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package helper
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -168,6 +170,66 @@ func WatchNonRetCmdStdOut(cmdStr string, timeout time.Duration, success func(out
}
}

// RunCmdWithMatchOutputFromBuffer starts the command, and command stdout is attached to buffer.
// we read data from buffer line by line, and if expected string is matched it returns true
// It is different from WaitforCmdOut which gives stdout in one go using session.Out.Contents()
// for commands like odo log -f which streams continuous data and does not terminate by their own
// we need to read the stream data from buffer.
func RunCmdWithMatchOutputFromBuffer(timeoutAfter time.Duration, matchString, program string, args ...string) (bool, error) {
var buf, errBuf bytes.Buffer

command := exec.Command(program, args...)
command.Stdout = &buf
command.Stderr = &errBuf

timeoutCh := time.After(timeoutAfter)
matchOutputCh := make(chan bool)
errorCh := make(chan error)

_, err := fmt.Fprintln(GinkgoWriter, runningCmd(command))
if err != nil {
return false, err
}

err = command.Start()
if err != nil {
return false, err
}

// go routine which is reading data from buffer until expected string matched
go func() {
for {
line, err := buf.ReadString('\n')
if err != nil && err != io.EOF {
errorCh <- err
}
if len(line) > 0 {
_, err = fmt.Fprintln(GinkgoWriter, line)
if err != nil {
errorCh <- err
}
if strings.Contains(line, matchString) {
matchOutputCh <- true
}
}
}
}()

for {
select {
case <-timeoutCh:
fmt.Fprintln(GinkgoWriter, errBuf.String())
return false, errors.New("Timeout waiting for the conditon")
case <-matchOutputCh:
return true, nil
case <-errorCh:
fmt.Fprintln(GinkgoWriter, errBuf.String())
return false, <-errorCh
}
}

}

// GetUserHomeDir gets the user home directory
func GetUserHomeDir() string {
homeDir, err := os.UserHomeDir()
Expand Down
12 changes: 7 additions & 5 deletions tests/integration/devfile/cmd_devfile_log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ var _ = Describe("odo devfile log command tests", func() {
output := helper.CmdShouldPass("odo", "log")
Expect(output).To(ContainSubstring("ODO_COMMAND_RUN"))

// test with follow flag
output = helper.CmdShouldRunWithTimeout(1*time.Second, "odo", "log", "-f")
Expect(output).To(ContainSubstring("program=devrun"))
// Test odo log -f
match, err := helper.RunCmdWithMatchOutputFromBuffer(30*time.Second, "program=devrun", "odo", "log", "-f")
Expect(err).To(BeNil())
Expect(match).To(BeTrue())

})

Expand All @@ -83,8 +84,9 @@ var _ = Describe("odo devfile log command tests", func() {
Expect(output).To(ContainSubstring("ODO_COMMAND_DEBUG"))

// test with follow flag
output = helper.CmdShouldRunWithTimeout(1*time.Second, "odo", "log", "-f")
Expect(output).To(ContainSubstring("program=debugrun"))
match, err := helper.RunCmdWithMatchOutputFromBuffer(30*time.Second, "program=debugrun", "odo", "log", "-f")
Expect(err).To(BeNil())
Expect(match).To(BeTrue())

})

Expand Down

0 comments on commit eec93d3

Please sign in to comment.