From 44589a2efd1e9317d9249a076f5bc4ea4aa7d6be Mon Sep 17 00:00:00 2001 From: George Dunlap Date: Fri, 19 May 2017 17:05:44 +0100 Subject: [PATCH] Change to in-binary test `go test` apparently has a default 10-minute timeout. This isn't enough for all the tests in the "system test", and there's no way to change the default except to manually add a --timeout parameter to "go test". Instead pull the test out into a special xsatool command. Signed-off-by: George Dunlap --- main.go | 12 ++- system_test.go => systemtest.go | 128 ++++++++++++++++++-------------- 2 files changed, 82 insertions(+), 58 deletions(-) rename system_test.go => systemtest.go (71%) diff --git a/main.go b/main.go index d8d87c9..3bc5167 100644 --- a/main.go +++ b/main.go @@ -66,7 +66,7 @@ func globalReset() { } func XsaMain(args []string) int { - if len(args) < 3 { + if len(args) < 3 && args[1] != "systemtest" { fmt.Printf("Not enough arguments\n") return 1 } @@ -84,8 +84,11 @@ func XsaMain(args []string) int { tgt := args[1] args = args[2:] - cmd := args[0] - args = args[1:] + var cmd string + if len(args) > 0 { + cmd = args[0] + args = args[1:] + } if xsanum, err = strconv.Atoi(tgt); err == nil { switch cmd { @@ -145,6 +148,8 @@ func XsaMain(args []string) int { fmt.Printf("Unknown command: %s\n", cmd) return 1 } + } else if tgt == "systemtest" { + return MainSystemTest() } if loadConfig { @@ -215,6 +220,7 @@ func main() { } func MainHarness(args ...string) int { + Q.real = false x := append([]string{"xsatool"}, args...) return XsaMain(x) } diff --git a/system_test.go b/systemtest.go similarity index 71% rename from system_test.go rename to systemtest.go index 9d1b846..8d1b287 100644 --- a/system_test.go +++ b/systemtest.go @@ -4,22 +4,30 @@ import ( "fmt" "os" "path/filepath" - "testing" ) +type SystemTest struct { + failed bool +} + +func (st *SystemTest) Errorf(s string, args ...interface{}) { + st.failed = true + fmt.Printf(s, args...) +} + // Should we always do a new full clone (slow) or use a previous clone // if it exists (and leave clones for future callers)? var FullClone = false // Set up the repo in a known state. -func InitRepo(t *testing.T) bool { +func InitRepo(st *SystemTest) bool { callRepoInit := true if FullClone { // Make temporary directory and cd to it // rm -rf tmp if err := os.RemoveAll("tmp"); err != nil { - t.Errorf("Removing temporary path: %v", err) + st.Errorf("Removing temporary path: %v", err) return false } } else { @@ -29,7 +37,7 @@ func InitRepo(t *testing.T) bool { callRepoInit = false } else { if !os.IsNotExist(err) { - t.Errorf("Stat'ing temporary directory: %v\n", err) + st.Errorf("Stat'ing temporary directory: %v\n", err) return false } } @@ -38,26 +46,26 @@ func InitRepo(t *testing.T) bool { if callRepoInit { // mkdir tmp if err := os.Mkdir("tmp", 0777); err != nil { - t.Errorf("Making temporary path: %v\n", err) + st.Errorf("Making temporary path: %v\n", err) return false } } if err := os.Chdir("tmp"); err != nil { - t.Errorf("cd tmp: %v\n", err) + st.Errorf("cd tmp: %v\n", err) return false } if callRepoInit { // Initialize a current version of the repo if ret := MainHarness("repo", "init"); ret != 0 { - t.Errorf("repo init failed: %d\n", ret) + st.Errorf("repo init failed: %d\n", ret) return false } } else { // Read existing version of repos if ret := MainHarness("repo", "info"); ret != 0 { - t.Errorf("repo info failed: %d\n", ret) + st.Errorf("repo info failed: %d\n", ret) return false } } @@ -94,7 +102,7 @@ func InitRepo(t *testing.T) bool { } if err := ForEachTree(updateMaster); err != nil { - t.Errorf("Tree update failed: %v\n", err) + st.Errorf("Tree update failed: %v\n", err) return false } @@ -109,7 +117,7 @@ func InitRepo(t *testing.T) bool { r := G.repos.XenRepos[TreeXen] versions, err := r.GetVersions() if err != nil { - t.Errorf("Error getting Xen releases: %v\n", err) + st.Errorf("Error getting Xen releases: %v\n", err) return false } @@ -119,9 +127,9 @@ func InitRepo(t *testing.T) bool { if fv.XenVersion().IsGreaterEqualThan(XenVersion("4.9")) || (prs && fv.Point() > l.Point()) { tag := "RELEASE-" + string(fv) - t.Logf("Deleting tag %s\n", tag) + fmt.Printf("Deleting tag %s\n", tag) if err := r.DeleteTag(tag); err != nil { - t.Errorf("Deleting tag %s: %v\n", tag, err) + st.Errorf("Deleting tag %s: %v\n", tag, err) return false } } @@ -132,15 +140,15 @@ func InitRepo(t *testing.T) bool { // rm xsa.git/*.meta files, err := filepath.Glob("xsa.git/*.meta") if err != nil { - t.Errorf("Finding meta files to remove: %v", err) + st.Errorf("Finding meta files to remove: %v", err) return false } for _, file := range files { - t.Logf("Removing meta file %s\n", file) + fmt.Printf("Removing meta file %s\n", file) err = os.Remove(file) if err != nil { - t.Errorf("Removing meta file %s: %v", file, err) + st.Errorf("Removing meta file %s: %v", file, err) return false } } @@ -151,7 +159,7 @@ func InitRepo(t *testing.T) bool { return true } -func GlobalInit(t *testing.T) (pass bool) { +func GlobalInit(st *SystemTest) (pass bool) { //args := []string{"xsatool", "global", "update"} pass = true @@ -176,12 +184,12 @@ func GlobalInit(t *testing.T) (pass bool) { for v := range G.config.Security.Versions { _, prs := versions[v] if !prs { - t.Errorf("Unexpected version: %v\n", v) + st.Errorf("Unexpected version: %v\n", v) pass = false } else { versions[v].seen = true if versions[v].fv != G.config.Security.Versions[v].Latest { - t.Errorf("Expected fullversion %v, got %v\n", + st.Errorf("Expected fullversion %v, got %v\n", versions[v].fv, G.config.Security.Versions[v].Latest) pass = false @@ -191,17 +199,17 @@ func GlobalInit(t *testing.T) (pass bool) { for v := range versions { if !versions[v].seen { - t.Errorf("Didn't find expected xenversion %v\n", v) + st.Errorf("Didn't find expected xenversion %v\n", v) pass = false } } return pass } -func Story206Init(t *testing.T) (pass bool) { - t.Logf(" xsatool 206 init xen") +func Story206Init(st *SystemTest) (pass bool) { + fmt.Printf(" xsatool 206 init xen") if MainHarness("206", "init", "xen") != 0 { - t.Errorf("xsatool 206 init failed\n") + st.Errorf("xsatool 206 init failed\n") return false } @@ -209,19 +217,19 @@ func Story206Init(t *testing.T) (pass bool) { // - Recipes for appropriate var xsa XSAMeta if err := xsa.Load(206); err != nil { - t.Errorf("Re-loading xsa: %v\n", err) + st.Errorf("Re-loading xsa: %v\n", err) return false } pass = true if xsa.XSA != 206 { - t.Errorf("Unexpected XSA number: %d\n", xsa.XSA) + st.Errorf("Unexpected XSA number: %d\n", xsa.XSA) pass = false } if len(xsa.Trees) != 1 || xsa.Trees[0] != TreeXen { - t.Errorf("Unexpected xsa.Trees state: %v\n", xsa.Trees) + st.Errorf("Unexpected xsa.Trees state: %v\n", xsa.Trees) pass = false } @@ -241,12 +249,12 @@ func Story206Init(t *testing.T) (pass bool) { r := xsa.Recipes[v] _, prs := versions[v] if !prs { - t.Errorf("Unexpected version: %v\n", v) + st.Errorf("Unexpected version: %v\n", v) pass = false } else { versions[v].seen = true if versions[v].fv != r.XenVersionFull { - t.Errorf("Expected fullversion %v, got %v\n", + st.Errorf("Expected fullversion %v, got %v\n", versions[v].fv, r.XenVersionFull) pass = false @@ -255,15 +263,15 @@ func Story206Init(t *testing.T) (pass bool) { tr, prs := r.Recipes[tree] if tree == TreeXen { if !prs { - t.Errorf("Missing expected recipe for Xen\n") + st.Errorf("Missing expected recipe for Xen\n") pass = false } else if len(tr.Prereqs) != 0 || len(tr.Patches) != 0 { - t.Errorf("Unexpected recipe for tree Xen\n") + st.Errorf("Unexpected recipe for tree Xen\n") pass = false } } else { if prs { - t.Errorf("Unexpected tree: %v\n", tree) + st.Errorf("Unexpected tree: %v\n", tree) pass = false } } @@ -274,7 +282,7 @@ func Story206Init(t *testing.T) (pass bool) { for v := range versions { if !versions[v].seen { - t.Errorf("Didn't find expected xenversion %v\n", v) + st.Errorf("Didn't find expected xenversion %v\n", v) pass = false } } @@ -284,7 +292,7 @@ func Story206Init(t *testing.T) (pass bool) { ForEachCodeTree(func(tree Tree) error { xsas, prs := vm.XSAs[tree] if !prs { - t.Errorf("No XSA list for tree %v\n", tree) + st.Errorf("No XSA list for tree %v\n", tree) pass = false } else { expected := 0 @@ -292,7 +300,7 @@ func Story206Init(t *testing.T) (pass bool) { expected = 1 } if len(xsas) != expected { - t.Errorf("Expected %d xsas, got %d!\n", expected, len(xsas)) + st.Errorf("Expected %d xsas, got %d!\n", expected, len(xsas)) pass = false } } @@ -305,24 +313,24 @@ func Story206Init(t *testing.T) (pass bool) { return } -func Story206Implement(t *testing.T) (pass bool) { +func Story206Implement(st *SystemTest) (pass bool) { // [should already be on correct branch] // git am $PATH/xsa206-master/*.patch out, err := G.repos.XenRepos[TreeXen].Am("../testdata/xsa206-unstable/*.patch") if err != nil { - t.Errorf("Error importing example patches: %v %s\n", err, string(out)) + st.Errorf("Error importing example patches: %v %s\n", err, string(out)) return } return true } -func Story206SyncOne(t *testing.T) (pass bool) { - t.Logf(" xsatool 206 sync-patches") +func Story206SyncOne(st *SystemTest) (pass bool) { + fmt.Printf(" xsatool 206 sync-patches") if MainHarness("206", "sync-patches") != 0 { - t.Errorf("xsatool 206 sync-patches failed\n") + st.Errorf("xsatool 206 sync-patches failed\n") return false } @@ -330,7 +338,7 @@ func Story206SyncOne(t *testing.T) (pass bool) { err := xsa.Load(206) if err != nil { - t.Errorf("Error loading updated recipe: %v\n", err) + st.Errorf("Error loading updated recipe: %v\n", err) return false } @@ -345,7 +353,7 @@ func Story206SyncOne(t *testing.T) (pass bool) { expected = 1 } if len(tr.Patches) != expected { - t.Errorf("Version %v tree %v: Wanted %d, got %d\n", + st.Errorf("Version %v tree %v: Wanted %d, got %d\n", v, tree, expected, len(tr.Patches)) pass = false } @@ -355,20 +363,20 @@ func Story206SyncOne(t *testing.T) (pass bool) { return pass } -func Story206(t *testing.T) bool { - t.Logf("Starting XSA-206 'story'") +func Story206(st *SystemTest) bool { + fmt.Printf("Starting XSA-206 'story'") // xsatool 206 init xen - if !Story206Init(t) { + if !Story206Init(st) { return false } // Fake-up xsa/206/master - if !Story206Implement(t) { + if !Story206Implement(st) { return false } // 206 sync-patches - if !Story206SyncOne(t) { + if !Story206SyncOne(st) { return false } @@ -381,32 +389,33 @@ func Story206(t *testing.T) bool { return true } -func TestSystem(t *testing.T) { - if testing.Short() { - t.Skipf("Not running full system tests") - } +func MainSystemTest() (ret int) { + var st SystemTest + // Fail unless we make it through the gauntlet + ret = 1 + // Store the toplevel directory topdir, err := os.Getwd() if err != nil { - t.Errorf("Getwd failed?\n") + st.Errorf("Getwd failed?\n") return } // Init and/or cd into the testing directory - if !InitRepo(t) { - t.Errorf("Could not initialize repo") + if !InitRepo(&st) { + st.Errorf("Could not initialize repo") goto out } // Initialize global state // xsatool global update - if !GlobalInit(t) { + if !GlobalInit(&st) { goto out } //// xsa 206 "story" - if !Story206(t) { + if !Story206(&st) { goto out } @@ -416,15 +425,24 @@ func TestSystem(t *testing.T) { //// xsa 212-215 "story" + ret = 0 out: os.Chdir(topdir) if FullClone { // rm -rf tmp if err := os.RemoveAll("tmp"); err != nil { - t.Errorf("Removing temporary path: %v", err) + st.Errorf("Removing temporary path: %v", err) + ret = 1 return } } + if st.failed { + fmt.Print("System test: FAILED\n") + } else { + fmt.Print("System test: PASSED\n") + } + + return } -- 2.39.5