func buildApp()

in internal/acceptance/acceptance.go [963:1034]


func buildApp(t *testing.T, srcDir, image, builderName, runName string, env map[string]string, cache bool, cfg Test) {
	t.Helper()

	attempts := cfg.FlakyBuildAttempts
	if attempts < 1 {
		attempts = 1
	}

	start := time.Now()
	var outb, errb bytes.Buffer

	for attempt := 1; attempt <= attempts; attempt++ {

		filename := fmt.Sprintf("%s-cache-%t", image, cache)
		if attempt > 1 {
			filename = fmt.Sprintf("%s-attempt-%d", filename, attempt)
		}
		outFile, errFile, cleanup := outFiles(t, builderName, "pack-build", filename)
		defer cleanup()

		bcmd := buildCommand(srcDir, image, builderName, runName, env, cache)
		cmd := exec.Command(bcmd[0], bcmd[1:]...)
		cmd.Stdout = io.MultiWriter(outFile, &outb) // pack emits detect output to stdout.
		cmd.Stderr = io.MultiWriter(errFile, &errb) // pack emits build output to stderr.

		t.Logf("Building application %s (logs %s)", image, filepath.Dir(outFile.Name()))
		if err := cmd.Run(); err != nil {
			if attempt < attempts {
				t.Logf("Error building application %s, attempt %d of %d: %v, logs:\n%s\n%s", image, attempt, attempts, err, outb.String(), errb.String())
				outb.Reset()
				errb.Reset()
			} else {
				t.Fatalf("Error building application %s: %v, logs:\n%s\n%s", image, err, outb.String(), errb.String())
			}
		} else {
			// The application built successfully.
			break
		}
	}

	// Check that expected output is found in the logs.
	mustOutput := cfg.MustOutput
	mustNotOutput := cfg.MustNotOutput
	if cache {
		mustOutput = cfg.MustOutputCached
		mustNotOutput = cfg.MustNotOutputCached
	}

	for _, text := range mustOutput {
		if !strings.Contains(errb.String(), text) {
			t.Errorf("Build logs must contain %q:\n%s", text, errb.String())
		}
	}
	for _, text := range mustNotOutput {
		if strings.Contains(errb.String(), text) {
			t.Errorf("Build logs must not contain %q:\n%s", text, errb.String())
		}
	}

	// Scan for incorrect cache hits/misses.
	if cache {
		if strings.Contains(errb.String(), cacheMissMessage) {
			t.Fatalf("FAIL: Cached build had a cache miss:\n%s", errb.String())
		}
	} else {
		if strings.Contains(errb.String(), cacheHitMessage) {
			t.Fatalf("FAIL: Non-cache build had a cache hit:\n%s", errb.String())
		}
	}

	t.Logf("Successfully built application: %s (in %s)", image, time.Since(start))
}