blob: 3d38a0b1e09de476657d5b1f1cd62a191a183bb4 [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 testsharder
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"sort"
"testing"
"go.fuchsia.dev/tools/build/api"
)
var qemuPlatform = DimensionSet{
DeviceType: "QEMU",
}
var nucPlatform = DimensionSet{
DeviceType: "NUC",
}
var linuxPlatform = DimensionSet{
OS: "Linux",
}
var macPlatform = DimensionSet{
OS: "Mac",
}
var qemuEnv = Environment{
Dimensions: qemuPlatform,
}
var nucEnv = Environment{
Dimensions: nucPlatform,
}
var linuxEnv = Environment{
Dimensions: linuxPlatform,
}
var macEnv = Environment{
Dimensions: macPlatform,
}
var specFoo1 = TestSpec{
Test: Test{
Name: "//obsidian/bin/foo:foo_unittests",
Path: "/system/test/foo_unittests",
OS: Fuchsia,
Command: []string{"/system/test/foo_unittests", "bar", "baz"},
},
Envs: []Environment{qemuEnv},
}
var specFoo2 = TestSpec{
Test: Test{
Name: "//obsidian/bin/foo:foo_integration_tests",
Path: "/system/test/foo_integration_tests",
OS: Fuchsia,
},
Envs: []Environment{qemuEnv, nucEnv},
}
var specBar = TestSpec{
Test: Test{
Name: "//obsidian/lib/bar:bar_tests",
Path: "/system/test/bar_tests",
OS: Fuchsia,
},
Envs: []Environment{qemuEnv},
}
var specBaz = TestSpec{
Test: Test{
Name: "//obsidian/public/lib/baz:baz_host_tests",
Path: "/$root_build_dir/baz_host_tests",
OS: Linux,
},
Envs: []Environment{linuxEnv, macEnv},
}
func TestLoadTestSpecs(t *testing.T) {
areEqual := func(a, b []TestSpec) bool {
stringify := func(spec TestSpec) string {
return fmt.Sprintf("%#v", spec)
}
sort := func(list []TestSpec) {
sort.Slice(list[:], func(i, j int) bool {
return stringify(list[i]) < stringify(list[j])
})
}
sort(a)
sort(b)
return reflect.DeepEqual(a, b)
}
tmpDir, err := ioutil.TempDir("", "test-spec")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer os.RemoveAll(tmpDir)
deps := []string{"path/to/first/dep", "path/to/second"}
depsFilepath := filepath.Join(tmpDir, "deps.json")
df, err := os.Create(depsFilepath)
if err != nil {
t.Fatal(err)
}
defer df.Close()
if err := json.NewEncoder(df).Encode(&deps); err != nil {
t.Fatalf("failed to create JSON encoder: %v", err)
}
specBazIn := specBaz
specBazIn.DepsFile = "deps.json"
initial := []TestSpec{specBar, specBazIn}
manifest := filepath.Join(tmpDir, build.TestSpecManifestName)
m, err := os.Create(manifest)
if err != nil {
t.Fatal(err)
}
defer m.Close()
if err := json.NewEncoder(m).Encode(&initial); err != nil {
t.Fatal(err)
}
actual, err := LoadTestSpecs(tmpDir)
if err != nil {
t.Fatalf("failed to load test specs: %v", err)
}
specBazOut := specBaz
specBazOut.Deps = deps
expected := []TestSpec{specBar, specBazOut}
if !areEqual(expected, actual) {
t.Fatalf("test specs not properly loaded:\nexpected:\n%+v\nactual:\n%+v", expected, actual)
}
}
func TestValidateTestSpecs(t *testing.T) {
noTestNameSpec := TestSpec{
Test: Test{
Path: "/system/test/baz_tests",
OS: Linux,
},
Envs: []Environment{qemuEnv},
}
noTestPathSpec := TestSpec{
Test: Test{
Name: "//obsidian/public/lib/baz:baz_tests",
OS: Linux,
},
Envs: []Environment{qemuEnv},
}
noOSSpec := TestSpec{
Test: Test{
Name: "//obsidian/bin/foo:foo_unittests",
Path: "/system/test/foo_unittests",
},
}
badEnvSpec := TestSpec{
Test: Test{
Name: "//obsidian/public/lib/baz:baz_tests",
Path: "/system/test/baz_tests",
OS: Linux,
},
Envs: []Environment{
Environment{
Dimensions: DimensionSet{
DeviceType: "NON-EXISTENT-DEVICE",
},
},
},
}
platforms := []DimensionSet{qemuPlatform, nucPlatform}
t.Run("valid specs are validated", func(t *testing.T) {
validSpecLists := [][]TestSpec{
{specFoo1}, {specFoo2}, {specBar},
{specFoo1, specFoo2}, {specFoo1, specBar}, {specFoo2, specBar},
{specFoo1, specFoo2, specBar},
}
for _, list := range validSpecLists {
if err := ValidateTestSpecs(list, platforms); err != nil {
t.Fatalf("valid specs marked as invalid: %+v: %v", list, err)
}
}
})
t.Run("invalid specs are invalidated", func(t *testing.T) {
invalidSpecLists := [][]TestSpec{
{noOSSpec}, {noTestNameSpec}, {noTestPathSpec}, {badEnvSpec},
{noTestNameSpec, noTestPathSpec}, {noTestNameSpec, badEnvSpec},
{noTestPathSpec, badEnvSpec},
{noTestNameSpec, noTestPathSpec, badEnvSpec},
}
for _, list := range invalidSpecLists {
if err := ValidateTestSpecs(list, platforms); err == nil {
t.Fatalf("invalid specs marked as valid: %+v", list)
}
}
})
}