in internal/acceptance/acceptance.go [354:421]
func invokeApp(t *testing.T, cfg Test, image string, cache bool) {
t.Helper()
containerID, host, port, cleanup := startContainer(t, image, cfg.Entrypoint, cfg.RunEnv, cache)
defer cleanup()
// Check that the application responds with `PASS`.
start := time.Now()
reqType := HTTPType
if cfg.RequestType != "" {
reqType = cfg.RequestType
}
body, status, statusCode, err := sendRequest(host, port, cfg.Path, reqType)
if err != nil {
t.Fatalf("Unable to invoke app: %v", err)
}
t.Logf("Got response: status %v, body %q (in %s)", status, body, time.Since(start))
wantCode := http.StatusOK
if cfg.MustMatchStatusCode != 0 {
wantCode = cfg.MustMatchStatusCode
}
if statusCode != wantCode {
t.Errorf("Unexpected status code: got %d, want %d", statusCode, wantCode)
}
if reqType == HTTPType && cfg.MustMatch == "" {
cfg.MustMatch = "PASS"
}
if !strings.HasSuffix(body, cfg.MustMatch) {
t.Errorf("Response body does not contain suffix: got %q, want %q", body, cfg.MustMatch)
}
if cfg.MustRebuildOnChange != "" {
start = time.Now()
// Modify a source file in the running container.
if _, err := runOutput("docker", "exec", containerID, "sed", "-i", "s/PASS/UPDATED/", cfg.MustRebuildOnChange); err != nil {
t.Fatalf("Unable to modify a source file in the running container %q: %v", containerID, err)
}
// Check that the application responds with `UPDATED`.
tries := 30
for try := tries; try >= 1; try-- {
time.Sleep(1 * time.Second)
body, status, _, err := sendRequestWithTimeout(host, port, cfg.Path, 10*time.Second, reqType)
// An app that is rebuilding can be unresponsive.
if err != nil {
if try == 1 {
t.Fatalf("Unable to invoke app after updating source with %d attempts: %v", tries, err)
}
continue
}
want := "UPDATED"
if body == want {
t.Logf("Got response: status %v, body %q (in %s)", status, body, time.Since(start))
break
}
if try == 1 {
t.Errorf("Wrong body: got %q, want %q", body, want)
}
}
}
}