Skip to content

Commit

Permalink
Merge pull request #30 from SimonBaeumer/gofmt-fixes
Browse files Browse the repository at this point in the history
Gofmt fixes
  • Loading branch information
SimonBaeumer authored Mar 17, 2019
2 parents bffe6a0 + 85b8f73 commit bc706dc
Show file tree
Hide file tree
Showing 13 changed files with 621 additions and 609 deletions.
8 changes: 4 additions & 4 deletions cmd/commander/commander.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package main

import (
"fmt"
"io/ioutil"
"log"
"os"
"github.com/urfave/cli"
"github.com/SimonBaeumer/commander/pkg/output"
"github.com/SimonBaeumer/commander/pkg/runtime"
"github.com/SimonBaeumer/commander/pkg/suite"
"github.com/urfave/cli"
"io/ioutil"
"log"
"os"
)

const (
Expand Down
167 changes: 84 additions & 83 deletions pkg/cmd/command.go
Original file line number Diff line number Diff line change
@@ -1,124 +1,125 @@
package cmd

import (
"bytes"
"fmt"
"log"
"os/exec"
"strings"
"syscall"
"time"
"bytes"
"fmt"
"log"
"os/exec"
"strings"
"syscall"
"time"
)

//Command represents a single command which can be executed
type Command struct {
Cmd string
Env []string
Dir string
Timeout time.Duration
executed bool
stderr string
stdout string
exitCode int
Cmd string
Env []string
Dir string
Timeout time.Duration
executed bool
stderr string
stdout string
exitCode int
}

//NewCommand creates a new command
func NewCommand(cmd string) *Command {
return &Command{
Cmd: cmd,
Timeout: 1 * time.Minute,
executed: false,
}
return &Command{
Cmd: cmd,
Timeout: 1 * time.Minute,
executed: false,
}
}

//SetTimeoutMS sets the timeout in milliseconds
func (c *Command) SetTimeoutMS(ms int) {
if ms == 0 {
c.Timeout = 1 * time.Minute
}
c.Timeout = time.Duration(ms) * time.Millisecond
if ms == 0 {
c.Timeout = 1 * time.Minute
}
c.Timeout = time.Duration(ms) * time.Millisecond
}

//Stdout returns the output to stdout
func (c *Command) Stdout() string {
c.isExecuted("Stdout")
return c.stdout
c.isExecuted("Stdout")
return c.stdout
}

//Stderr returns the output to stderr
func (c *Command) Stderr() string {
c.isExecuted("Stderr")
return c.stderr
c.isExecuted("Stderr")
return c.stderr
}

//ExitCode returns the exit code of the command
func (c *Command) ExitCode() int {
c.isExecuted("ExitCode")
return c.exitCode
c.isExecuted("ExitCode")
return c.exitCode
}

//Executed returns if the command was already executed
func (c *Command) Executed() bool {
return c.executed
return c.executed
}

func (c *Command) isExecuted(property string) {
if !c.executed {
panic("Can not read " + property + " if command was not executed.")
}
if !c.executed {
panic("Can not read " + property + " if command was not executed.")
}
}

//Execute executes the commande
func (c *Command) Execute() error {
cmd := exec.Command("sh", "-c", c.Cmd)
cmd.Env = c.Env
cmd.Dir = c.Dir

var (
outBuff bytes.Buffer
errBuff bytes.Buffer
)
cmd.Stdout = &outBuff
cmd.Stderr = &errBuff

err := cmd.Start()
if err != nil {
return err
}

done := make(chan error)
go func() {
done <- cmd.Wait()
}()

select {
case err := <- done:
if err != nil {
log.Println("Command exited with error", c.Cmd, err.Error())
c.getExitCode(err)
break
}
log.Println("Command exited successfully", c.Cmd)
c.exitCode = 0
case <- time.After(c.Timeout):
log.Println("Command timed out", c.Cmd)
if err := cmd.Process.Kill(); err != nil {
return fmt.Errorf("Timeout occured and can not kill process with pid %v", cmd.Process.Pid)
}
return fmt.Errorf("Command timed out after %v", c.Timeout)
}

// Remove leading and trailing whitespaces
c.stderr = strings.Trim(errBuff.String(), "\n")
c.stdout = strings.Trim(outBuff.String(), "\n")
c.executed = true

return nil
cmd := exec.Command("sh", "-c", c.Cmd)
cmd.Env = c.Env
cmd.Dir = c.Dir

var (
outBuff bytes.Buffer
errBuff bytes.Buffer
)
cmd.Stdout = &outBuff
cmd.Stderr = &errBuff

err := cmd.Start()
if err != nil {
return err
}

done := make(chan error)
go func() {
done <- cmd.Wait()
}()

select {
case err := <-done:
if err != nil {
log.Println("Command exited with error", c.Cmd, err.Error())
c.getExitCode(err)
break
}
log.Println("Command exited successfully", c.Cmd)
c.exitCode = 0
case <-time.After(c.Timeout):
log.Println("Command timed out", c.Cmd)
if err := cmd.Process.Kill(); err != nil {
return fmt.Errorf("Timeout occurred and can not kill process with pid %v", cmd.Process.Pid)
}
return fmt.Errorf("Command timed out after %v", c.Timeout)
}

// Remove leading and trailing whitespaces
c.stderr = strings.Trim(errBuff.String(), "\n")
c.stdout = strings.Trim(outBuff.String(), "\n")
c.executed = true

return nil
}

func (c *Command) getExitCode(err error) {
if exitErr, ok := err.(*exec.ExitError); ok {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
c.exitCode = status.ExitStatus()
}
}
if exitErr, ok := err.(*exec.ExitError); ok {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
c.exitCode = status.ExitStatus()
}
}
}
60 changes: 30 additions & 30 deletions pkg/cmd/command_test.go
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
package cmd

import (
"github.com/stretchr/testify/assert"
"testing"
"github.com/stretchr/testify/assert"
"testing"
)

func TestCommand_NewCommand(t *testing.T) {
cmd := NewCommand("")
assert.False(t, cmd.Executed())
cmd := NewCommand("")
assert.False(t, cmd.Executed())
}

func TestCommand_Execute(t *testing.T) {
cmd := NewCommand("/bin/echo hello")
cmd := NewCommand("/bin/echo hello")

err := cmd.Execute()
err := cmd.Execute()

assert.Nil(t, err)
assert.True(t, cmd.Executed())
assert.Equal(t, cmd.Stdout(), "hello")
assert.Nil(t, err)
assert.True(t, cmd.Executed())
assert.Equal(t, cmd.Stdout(), "hello")
}

func TestCommand_ExecuteStderr(t *testing.T) {
cmd := NewCommand(">&2 /bin/echo hello")
cmd := NewCommand(">&2 /bin/echo hello")

err := cmd.Execute()
err := cmd.Execute()

assert.Nil(t, err)
assert.Equal(t, "hello", cmd.Stderr())
assert.Nil(t, err)
assert.Equal(t, "hello", cmd.Stderr())
}

func TestCommand_ExitCode(t *testing.T) {
cmd := NewCommand("exit 120")
cmd := NewCommand("exit 120")

err := cmd.Execute()
err := cmd.Execute()

assert.Nil(t, err)
assert.Equal(t, 120, cmd.ExitCode())
assert.Nil(t, err)
assert.Equal(t, 120, cmd.ExitCode())
}

func TestCommand_WithEnvVariables(t *testing.T) {
cmd := NewCommand("echo $TEST")
cmd.Env = []string{"TEST=hey"}
cmd := NewCommand("echo $TEST")
cmd.Env = []string{"TEST=hey"}

_ = cmd.Execute()
_ = cmd.Execute()

assert.Equal(t, "hey", cmd.Stdout())
assert.Equal(t, "hey", cmd.Stdout())
}

func TestCommand_WithTimeout(t *testing.T) {
cmd := NewCommand("sleep 0.005;")
cmd.SetTimeoutMS(5)
cmd := NewCommand("sleep 0.005;")
cmd.SetTimeoutMS(5)

err := cmd.Execute()
err := cmd.Execute()

assert.NotNil(t, err)
assert.Equal(t, "Command timed out after 5ms", err.Error())
assert.NotNil(t, err)
assert.Equal(t, "Command timed out after 5ms", err.Error())
}

func TestCommand_WithValidTimeout(t *testing.T) {
cmd := NewCommand("sleep 0.01;")
cmd.SetTimeoutMS(500)
cmd := NewCommand("sleep 0.01;")
cmd.SetTimeoutMS(500)

err := cmd.Execute()
err := cmd.Execute()

assert.Nil(t, err)
assert.Nil(t, err)
}
Loading

0 comments on commit bc706dc

Please sign in to comment.