blob: 264ada5dc1fe82a5ba6a70752238cd1c33e4d160 [file] [log] [blame]
// Copyright 2019 The Chromium OS 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 gtest
import (
"context"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"regexp"
"testing"
"time"
"chromiumos/tast/errors"
)
func TestParseTestList(t *testing.T) {
const content = `TestSuite1.
TestCase1
TestCase2
TestSuite2.
TestCase3
TestCase4
TestCase5/0
TestCase5/1
TestCase5/2 # GetParam() = foo
`
expected := []string{
"TestSuite1.TestCase1",
"TestSuite1.TestCase2",
"TestSuite2.TestCase3",
"TestSuite2.TestCase4",
"TestSuite2.TestCase5/0",
"TestSuite2.TestCase5/1",
"TestSuite2.TestCase5/2",
}
result := parseTestList(content)
if !reflect.DeepEqual(result, expected) {
t.Errorf("parseTestList returns %s; want %s", result, expected)
}
}
func TestGTestArgs(t *testing.T) {
for _, tc := range []struct {
expected []string
opts []option
}{{
expected: []string{"testexec", "--gtest_filter=pattern"},
opts: []option{Filter("pattern")},
}, {
expected: []string{"testexec"},
opts: []option{Filter("")},
}, {
expected: []string{"testexec", "--gtest_repeat=-1"},
opts: []option{Repeat(-1)},
}, {
expected: []string{"testexec", "a", "b", "c"},
opts: []option{ExtraArgs("a", "b", "c")},
}, {
expected: []string{"sudo", "--user=#10", "testexec"},
opts: []option{UID(10)},
}} {
args, err := New("testexec", tc.opts...).Args()
if err != nil {
t.Error("Unexpected fail: ", err)
}
if !reflect.DeepEqual(args, tc.expected) {
t.Errorf("Unexpected args: got %#v; want %#v", args, tc.expected)
}
}
// Test error case of ExtraArgs.
if _, err := New("testexec", ExtraArgs("--gtest_something")).Args(); err == nil {
t.Error("Unexpected success for ExtraArgs with --gtest prefix")
}
}
const fakeGTest = `#!/bin/sh
if [[ "$1" == --gtest_output=xml:* ]]; then
output="${1#--gtest_output=xml:}"
echo "<testsuites></testsuites>" > "${output}"
fi
echo "test log"
exit 0
`
// Under some busy situation, launching and executing subprocess takes very long time.
// Set 1 min for stabilization of the test.
const fakeGTestTimeout = time.Minute
func setUpTest() (td, gtest string, retErr error) {
td, err := ioutil.TempDir("", "gtest")
if err != nil {
return "", "", errors.Wrap(err, "failed to create temp dir")
}
defer func() {
if retErr != nil {
os.RemoveAll(td)
}
}()
gtest = filepath.Join(td, "gtest")
if err := ioutil.WriteFile(gtest, []byte(fakeGTest), 0755); err != nil {
return "", "", errors.Wrap(err, "failed to create an executable script")
}
return td, gtest, nil
}
func TestRun(t *testing.T) {
td, gtest, err := setUpTest()
if err != nil {
t.Fatal("Failed to set up test: ", err)
}
defer os.RemoveAll(td)
ctx, cancel := context.WithTimeout(context.Background(), fakeGTestTimeout)
defer cancel()
if report, err := New(gtest).Run(ctx); err != nil {
t.Fatal("Unexpected execution error: ", err)
} else if report == nil {
t.Fatal("Report is unexpectedly nil")
}
}
func TestStart(t *testing.T) {
td, gtest, err := setUpTest()
if err != nil {
t.Fatal("Failed to set up test: ", err)
}
defer os.RemoveAll(td)
ctx, cancel := context.WithTimeout(context.Background(), fakeGTestTimeout)
defer cancel()
cmd, err := New(gtest).Start(ctx)
if err != nil {
t.Fatal("Unexpected execution error: ", err)
}
// The command is expected to be successfully terminated quickly.
if err := cmd.Wait(); err != nil {
t.Fatal("Unexpected wait error: ", err)
}
}
func TestLogfile(t *testing.T) {
td, gtest, err := setUpTest()
if err != nil {
t.Fatal("Failed to set up test: ", err)
}
defer os.RemoveAll(td)
ctx, cancel := context.WithTimeout(context.Background(), fakeGTestTimeout)
defer cancel()
logpath := filepath.Join(td, "log.txt")
if _, err := New(gtest, Logfile(logpath)).Run(ctx); err != nil {
t.Fatal("Unexpected execution error: ", err)
}
out, err := ioutil.ReadFile(logpath)
if err != nil {
t.Fatal("Failed to read log file: ", err)
}
expect := regexp.MustCompile(`^Running .*/gtest --gtest_output=xml:.*\n\ntest log\n$`)
if !expect.Match(out) {
t.Fatalf("Unexpected log file: got %q", out)
}
}
func TestTempLogfile(t *testing.T) {
td, gtest, err := setUpTest()
if err != nil {
t.Fatal("Failed to set up test: ", err)
}
defer os.RemoveAll(td)
ctx, cancel := context.WithTimeout(context.Background(), fakeGTestTimeout)
defer cancel()
logpath := filepath.Join(td, "log_*.txt")
if _, err := New(gtest, TempLogfile(logpath)).Run(ctx); err != nil {
t.Fatal("Unexpected execution error: ", err)
}
matches, err := filepath.Glob(logpath)
if err != nil {
t.Fatal("Unexpected glob pattern: ", err)
}
if len(matches) != 1 {
t.Fatal("Unexpected number of log files: got ", len(matches))
}
out, err := ioutil.ReadFile(matches[0])
if err != nil {
t.Fatal("Failed to read log file: ", err)
}
expect := regexp.MustCompile(`^Running .*/gtest --gtest_output=xml:.*\n\ntest log\n$`)
if !expect.Match(out) {
t.Fatalf("Unexpected log file: got %q", out)
}
// Run the test again, which should create a new logfile.
if _, err := New(gtest, TempLogfile(logpath)).Run(ctx); err != nil {
t.Fatal("Unexpected execution error: ", err)
}
if matches, err := filepath.Glob(logpath); err != nil {
t.Fatal("Unexpected glob pattern: ", err)
} else if len(matches) != 2 {
t.Fatal("Unexpected number of log files: got ", len(matches))
}
}