Created
July 22, 2015 14:09
-
-
Save pawelniewie/118c2b5c54cc19502ccd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"os/exec" | |
"os/user" | |
"testing" | |
"net/http" | |
"io/ioutil" | |
"fmt" | |
"github.com/stretchr/testify/assert" | |
"syscall" | |
"strings" | |
"runtime" | |
"time" | |
. "gopkg.in/check.v1" | |
) | |
func Test(t *testing.T) { TestingT(t) } | |
type DockerSuite struct { | |
containerIp string | |
cID string | |
} | |
var _ = Suite(&DockerSuite{}) | |
func (s *DockerSuite) SetUpSuite(t *C) { | |
s.containerIp = "127.0.0.1" | |
if runtime.GOOS == "darwin" { | |
out, _, err := runCommandWithOutput("boot2docker", "ip") | |
if err != nil { | |
t.Fatalf("You don't have boot2docker installed, it is required on Mac OS X") | |
} else { | |
s.containerIp = strings.TrimSpace(out) | |
} | |
} else if (runtime.GOOS == "linux") { | |
out, _, _ := runCommandWithOutput("id") | |
if !strings.Contains(out, "(docker)") { | |
usr, _ := user.Current() | |
t.Fatalf("You don't have a permission to control docker, to fix this run (or ask your administrator):\n\nsudo usermod -aG docker %s\nexec su -l %s\n", usr.Username, usr.Username) | |
} | |
} | |
cID, _, err := runCommandWithOutput("docker", "run", "-d", "-p", "19090:80", "nginx") | |
if err != nil { | |
t.Fatalf("Failed to start container: %s", cID) | |
} else { | |
s.cID = strings.TrimSpace(cID) | |
t.Log("Started container: " + s.cID) | |
} | |
} | |
func (s *DockerSuite) TearDownSuite(t *C) { | |
if s.cID == "" { | |
t.Log("Seems like the container didn't start") | |
return | |
} | |
_, _, err := runCommandWithOutput("docker", "stop", s.cID) | |
if err != nil { | |
t.Fatalf("Failed to stop container: %s", s.cID) | |
} else { | |
t.Log("Stopped container " + s.cID) | |
} | |
_, _, err = runCommandWithOutput("docker", "rm", s.cID) | |
if err != nil { | |
t.Fatalf("Failed to remove container: %s", s.cID) | |
} else { | |
t.Log("Removed container " + s.cID) | |
} | |
} | |
type httpHandler func() (response *http.Response, err error) | |
func httpPoller(t *C, handler httpHandler, timeout time.Duration) (httpBody []byte, lastError error) { | |
finishAt := time.Now().Add(timeout) | |
for { | |
if (time.Now().After(finishAt)) { | |
return | |
} | |
response, err := handler() | |
if err == nil { | |
defer response.Body.Close() | |
contents, err := ioutil.ReadAll(response.Body) | |
if err != nil { | |
lastError = err | |
} else { | |
httpBody = contents | |
lastError = nil | |
return | |
} | |
} else { | |
lastError = err | |
} | |
time.Sleep(150 * time.Nanosecond) | |
} | |
} | |
func (s *DockerSuite) TestNginx(t *C) { | |
timeout := 30 * time.Second | |
httpBody, lastError := httpPoller(t, func() (response *http.Response, err error) { | |
response, err = http.Get(fmt.Sprintf("http://%s:19090/", s.containerIp)) | |
return | |
}, timeout); | |
if httpBody != nil { | |
assert.Contains(t, string(httpBody), "Welcome to nginx!", "HTML response does not contain welcome message") | |
} else { | |
t.Fatalf("Container didn't start in: %s, last error was: %s", timeout, lastError) | |
} | |
} | |
func processExitCode(err error) (exitCode int) { | |
if err != nil { | |
var exiterr error | |
if exitCode, exiterr = getExitCode(err); exiterr != nil { | |
// TODO: Fix this so we check the error's text. | |
// we've failed to retrieve exit code, so we set it to 127 | |
exitCode = 127 | |
} | |
} | |
return | |
} | |
func getExitCode(err error) (int, error) { | |
exitCode := 0 | |
if exiterr, ok := err.(*exec.ExitError); ok { | |
if procExit := exiterr.Sys().(syscall.WaitStatus); ok { | |
return procExit.ExitStatus(), nil | |
} | |
} | |
return exitCode, fmt.Errorf("failed to get exit code") | |
} | |
func runCommandWithOutput(name string, arg ...string) (output string, exitCode int, err error) { | |
exitCode = 0 | |
cmd := exec.Command(name, arg...) | |
out, err := cmd.CombinedOutput() | |
exitCode = processExitCode(err) | |
output = string(out) | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment