blob: 4130336684a85b29cbd8c6982e37b3c4877e883d [file] [log] [blame]
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main_test
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"sync"
"testing"
)
const comment = "This is a txtar archive.\n"
const testdata = `This is a txtar archive.
-- one.txt --
one
-- dir/two.txt --
two
-- $SPECIAL_LOCATION/three.txt --
three
`
func TestMain(m *testing.M) {
code := m.Run()
txtarBin.once.Do(func() {})
if txtarBin.name != "" {
os.Remove(txtarBin.name)
}
os.Exit(code)
}
func TestRoundTrip(t *testing.T) {
os.Setenv("SPECIAL_LOCATION", "special")
defer os.Unsetenv("SPECIAL_LOCATION")
// Expand the testdata archive into a temporary directory.
parentDir, err := ioutil.TempDir("", "txtar")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(parentDir)
dir := filepath.Join(parentDir, "dir")
if err := os.Mkdir(dir, 0755); err != nil {
t.Fatal(err)
}
if out := txtar(t, dir, testdata, "--extract"); out != comment {
t.Fatalf("txtar --extract: stdout:\n%s\nwant:\n%s", out, comment)
}
// Now, re-archive its contents explicitly and ensure that the result matches
// the original.
args := []string{"one.txt", "dir", "$SPECIAL_LOCATION"}
if out := txtar(t, dir, comment, args...); out != testdata {
t.Fatalf("txtar %s: archive:\n%s\n\nwant:\n%s", strings.Join(args, " "), out, testdata)
}
}
// txtar runs the txtar command in the given directory with the given input and
// arguments.
func txtar(t *testing.T, dir, input string, args ...string) string {
t.Helper()
cmd := exec.Command(txtarName(t), args...)
cmd.Dir = dir
cmd.Stdin = strings.NewReader(input)
stderr := new(strings.Builder)
cmd.Stderr = stderr
out, err := cmd.Output()
if err != nil {
t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, stderr)
}
if stderr.String() != "" {
t.Logf("OK: %s\n%s", strings.Join(cmd.Args, " "), stderr)
}
return string(out)
}
var txtarBin struct {
once sync.Once
name string
err error
}
// txtarName returns the name of the txtar executable, building it if needed.
func txtarName(t *testing.T) string {
t.Helper()
if _, err := exec.LookPath("go"); err != nil {
t.Skipf("cannot build txtar binary: %v", err)
}
txtarBin.once.Do(func() {
exe, err := ioutil.TempFile("", "txtar-*.exe")
if err != nil {
txtarBin.err = err
return
}
exe.Close()
txtarBin.name = exe.Name()
cmd := exec.Command("go", "build", "-o", txtarBin.name, ".")
out, err := cmd.CombinedOutput()
if err != nil {
txtarBin.err = fmt.Errorf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
}
})
if txtarBin.err != nil {
if runtime.GOOS == "android" {
t.Skipf("skipping test after failing to build txtar binary: go_android_exec may have failed to copy needed dependencies (see https://golang.org/issue/37088)")
}
t.Fatal(txtarBin.err)
}
return txtarBin.name
}