From d078f6dc10eb265a5d88cd96adf86173d6d3ba2e Mon Sep 17 00:00:00 2001 From: Flu0r1ne Date: Thu, 2 Sep 2021 03:14:47 -0500 Subject: Make adapters and internals complient with new directory structure --- adapters/gtest/adapter.go | 77 +++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 30 deletions(-) (limited to 'adapters/gtest/adapter.go') diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index f4fde27..9331cf7 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -11,55 +11,38 @@ import ( "path" "sync" "time" - "golang.flu0r1ne.net/planr" ) const GTEST_CMAKE = "CMakeLists.txt" -func mkUnit(tc *planr.TestCase) cmakeUnit { +func makeUnit(tc *planr.TestCase, dirs planr.DirConfig) cmakeUnit { cfg := tc.AdapterConfig().(*GtestConfig) + testpath := path.Join(dirs.TestsDir(), *cfg.Testfile) + srclist := cfg.srcList(dirs.SrcDir()) + return cmakeUnit { tc.Cname, - cfg.joinTests(*cfg.Testfile), - cfg.srcList(), + testpath, + srclist, }; } +func safeWd() string{ + wd, err := os.Getwd() -type GtestAdapter struct {} - -func (a *GtestAdapter) Config() planr.AdapterConfig { - return planr.AdapterConfig { - Name: "gtest", - ParseConfig: ParseConfig, - ParseDefaultConfig: ParseDefaultConfig, - } -} - -func (adapter *GtestAdapter) Build(tcs []*planr.TestCase) { - buildDir := adapter.Config().Dir() - cmakeFile := path.Join(buildDir, GTEST_CMAKE) - - units := make([]cmakeUnit, 0) - for _, tc := range tcs { - - cfg := tc.AdapterConfig().(*GtestConfig) - cfg.ensureSatisfied(tc.Path) - - units = append(units, mkUnit(tc)) + if err != nil { + log.Fatalf("Could not get GtestBuildDir %s %v\n", wd, err) } - genCmake(cmakeFile, units) - - planr.RunCmd("cmake", "-S", ".", "-B", ".") + return wd } type ResultFromId map[string] Result func (adapter *GtestAdapter) execTests(cnames []string) ResultFromId { - buildDir := adapter.Config().Dir() + buildDir := safeWd() lut := make(ResultFromId, 0) for _, exe := range cnames { @@ -154,6 +137,40 @@ func compile(wg * sync.WaitGroup, tc *planr.TestCase) { tc.Result.DebugOutput = string(out) } +type GtestAdapter struct { + dirs planr.DirConfig +} + +func (a *GtestAdapter) Config() planr.AdapterConfig { + return planr.AdapterConfig { + Name: "gtest", + ParseConfig: ParseConfig, + ParseDefaultConfig: ParseDefaultConfig, + } +} + +func (a *GtestAdapter) Init(dirs planr.DirConfig) { + a.dirs = dirs +} + +func (adapter *GtestAdapter) Build(tcs []*planr.TestCase) { + buildDir := safeWd() + cmakeFile := path.Join(buildDir, GTEST_CMAKE) + + units := make([]cmakeUnit, 0) + for _, tc := range tcs { + + cfg := tc.AdapterConfig().(*GtestConfig) + cfg.ensureSatisfied(tc.Path) + + units = append(units, makeUnit(tc, adapter.dirs)) + } + + genCmake(cmakeFile, units) + + planr.RunCmd("cmake", "-S", ".", "-B", ".") +} + // ./planr eval 0.93s user 0.16s system 100% cpu 1.089 total func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { var wg sync.WaitGroup @@ -169,7 +186,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { for _, tc := range tcs { result, ok := resultById[id(tc)] - // compilation failure + // compilation failure if !ok { fmt.Printf("CAN'T FIND %s: status %d\n", tc.Cname, tc.Result.Status) -- cgit v1.2.3 From 287d029975b7718109f81b480079f375f7d8700a Mon Sep 17 00:00:00 2001 From: Flu0r1ne Date: Fri, 3 Sep 2021 00:02:31 -0500 Subject: Add clean option and fix issue with dir propegation --- adapters/gtest/adapter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'adapters/gtest/adapter.go') diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index 9331cf7..415d823 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -19,8 +19,8 @@ const GTEST_CMAKE = "CMakeLists.txt" func makeUnit(tc *planr.TestCase, dirs planr.DirConfig) cmakeUnit { cfg := tc.AdapterConfig().(*GtestConfig) - testpath := path.Join(dirs.TestsDir(), *cfg.Testfile) - srclist := cfg.srcList(dirs.SrcDir()) + testpath := path.Join(dirs.Tests(), *cfg.Testfile) + srclist := cfg.srcList(dirs.Src()) return cmakeUnit { tc.Cname, -- cgit v1.2.3 From 2d197f1ce3eac8cecb5a655fcb5343cbe562ab1a Mon Sep 17 00:00:00 2001 From: Flu0r1ne Date: Fri, 3 Sep 2021 21:14:28 -0500 Subject: Add new test runner API --- adapters/gtest/adapter.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'adapters/gtest/adapter.go') diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index 415d823..0a955ef 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -188,8 +188,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { // compilation failure if !ok { - fmt.Printf("CAN'T FIND %s: status %d\n", tc.Cname, tc.Result.Status) - + if tc.Result.Status == planr.PASSING { cfg := tc.AdapterConfig().(*GtestConfig) @@ -214,3 +213,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { tc.Result.TestOutput = result.testOutput } } + +func New() *GtestAdapter { + return new(GtestAdapter) +} -- cgit v1.2.3 From cc7ba659adbc5ad55e1ce67f76952f2b8392c9c9 Mon Sep 17 00:00:00 2001 From: Flu0r1ne Date: Sat, 4 Sep 2021 15:38:30 -0500 Subject: Refactor build/eval pipeline to use clearer IO model and adapter segmentation methods --- adapters/gtest/adapter.go | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'adapters/gtest/adapter.go') diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index 0a955ef..7033c7f 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -16,8 +16,8 @@ import ( const GTEST_CMAKE = "CMakeLists.txt" -func makeUnit(tc *planr.TestCase, dirs planr.DirConfig) cmakeUnit { - cfg := tc.AdapterConfig().(*GtestConfig) +func makeUnit(tc planr.TestCase, dirs planr.DirConfig) cmakeUnit { + cfg := tc.AdapterConfig().(*Config) testpath := path.Join(dirs.Tests(), *cfg.Testfile) srclist := cfg.srcList(dirs.Src()) @@ -41,7 +41,7 @@ func safeWd() string{ type ResultFromId map[string] Result -func (adapter *GtestAdapter) execTests(cnames []string) ResultFromId { +func (adapter *Adapter) execTests(cnames []string) ResultFromId { buildDir := safeWd() lut := make(ResultFromId, 0) @@ -89,7 +89,7 @@ func (adapter *GtestAdapter) execTests(cnames []string) ResultFromId { // An executable may contain more than one test // Gather all executables and deduplicate them -func exes(tcs []*planr.TestCase) []string { +func exes(tcs []planr.TestCase) []string { set := make(map[string] bool, 0) for _, tc := range tcs { @@ -112,12 +112,12 @@ func exes(tcs []*planr.TestCase) []string { return exes } -func id(tc *planr.TestCase) string { - cfg := tc.AdapterConfig().(*GtestConfig) +func id(tc planr.TestCase) string { + cfg := tc.AdapterConfig().(*Config) return tc.Cname + "." + *cfg.Suite + "." + *cfg.Name } -func compile(wg * sync.WaitGroup, tc *planr.TestCase) { +func compile(wg * sync.WaitGroup, tc * planr.TestCase) { defer wg.Done() cmd := exec.Command("make", tc.Cname) @@ -137,11 +137,11 @@ func compile(wg * sync.WaitGroup, tc *planr.TestCase) { tc.Result.DebugOutput = string(out) } -type GtestAdapter struct { +type Adapter struct { dirs planr.DirConfig } -func (a *GtestAdapter) Config() planr.AdapterConfig { +func (a *Adapter) Config() planr.AdapterConfig { return planr.AdapterConfig { Name: "gtest", ParseConfig: ParseConfig, @@ -149,18 +149,18 @@ func (a *GtestAdapter) Config() planr.AdapterConfig { } } -func (a *GtestAdapter) Init(dirs planr.DirConfig) { +func (a *Adapter) Init(dirs planr.DirConfig) { a.dirs = dirs } -func (adapter *GtestAdapter) Build(tcs []*planr.TestCase) { +func (adapter Adapter) Build(tcs []planr.TestCase) { buildDir := safeWd() cmakeFile := path.Join(buildDir, GTEST_CMAKE) units := make([]cmakeUnit, 0) for _, tc := range tcs { - cfg := tc.AdapterConfig().(*GtestConfig) + cfg := tc.AdapterConfig().(*Config) cfg.ensureSatisfied(tc.Path) units = append(units, makeUnit(tc, adapter.dirs)) @@ -172,9 +172,10 @@ func (adapter *GtestAdapter) Build(tcs []*planr.TestCase) { } // ./planr eval 0.93s user 0.16s system 100% cpu 1.089 total -func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { +func (adapter *Adapter) Evaluate(tcs []planr.TestCase) [] planr.TestCase { var wg sync.WaitGroup - for _, tc := range tcs { + for i := range tcs { + tc := &tcs[i] wg.Add(1) go compile(&wg, tc) } @@ -183,14 +184,15 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { files := exes(tcs) resultById := adapter.execTests(files) - for _, tc := range tcs { - result, ok := resultById[id(tc)] + for i := range tcs { + tc := &tcs[i] + result, ok := resultById[id(*tc)] // compilation failure if !ok { if tc.Result.Status == planr.PASSING { - cfg := tc.AdapterConfig().(*GtestConfig) + cfg := tc.AdapterConfig().(*Config) log.Printf( "Could not find testcase %s with name=\"%s\" and suite=\"%s\". Does such a test exist in the test source?", @@ -200,7 +202,7 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { ) tc.Result.Status = planr.COMPILATION_FAILURE - tc.Result.DebugOutput += fmt.Sprintf("planr: Did not find testcase %s in any test executable\n", id(tc)) + tc.Result.DebugOutput += fmt.Sprintf("planr: Did not find testcase %s in any test executable\n", id(*tc)) } continue @@ -212,8 +214,10 @@ func (adapter *GtestAdapter) Evaluate(tcs []*planr.TestCase) { tc.Result.TestOutput = result.testOutput } + + return tcs } -func New() *GtestAdapter { - return new(GtestAdapter) +func NewAdapter() *Adapter { + return new(Adapter) } -- cgit v1.2.3 From 151d516e68f5d43aa2d0c5ff462752d640b6a614 Mon Sep 17 00:00:00 2001 From: Flu0r1ne Date: Sun, 5 Sep 2021 00:37:23 -0500 Subject: Refactor gtest adapter to fit new pipeline --- adapters/gtest/adapter.go | 187 ++++++---------------------------------------- 1 file changed, 22 insertions(+), 165 deletions(-) (limited to 'adapters/gtest/adapter.go') diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index 7033c7f..ec11748 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -1,34 +1,14 @@ package gtest import ( - "context" - "errors" - "fmt" - "io/ioutil" "log" "os" - "os/exec" "path" - "sync" - "time" "golang.flu0r1ne.net/planr" ) const GTEST_CMAKE = "CMakeLists.txt" -func makeUnit(tc planr.TestCase, dirs planr.DirConfig) cmakeUnit { - cfg := tc.AdapterConfig().(*Config) - - testpath := path.Join(dirs.Tests(), *cfg.Testfile) - srclist := cfg.srcList(dirs.Src()) - - return cmakeUnit { - tc.Cname, - testpath, - srclist, - }; -} - func safeWd() string{ wd, err := os.Getwd() @@ -39,104 +19,6 @@ func safeWd() string{ return wd } -type ResultFromId map[string] Result - -func (adapter *Adapter) execTests(cnames []string) ResultFromId { - buildDir := safeWd() - - lut := make(ResultFromId, 0) - for _, exe := range cnames { - - exePath := path.Join(buildDir, exe) - - f, err := ioutil.TempFile(buildDir, "gtest_adapter_*.json") - - if err != nil { - log.Fatal(err) - } - - ctx, cancel := context.WithTimeout(context.Background(), 9999*time.Millisecond) - cmd := exec.CommandContext(ctx, exePath, "--gtest_output=json:" + f.Name()) - - defer cancel() - defer os.Remove(f.Name()) - - out, err := cmd.CombinedOutput() - if err != nil { - var exiterr *exec.ExitError - - if !errors.As(err, &exiterr) { - log.Printf("%v\n", err) - os.Exit(exiterr.ExitCode()) - } - } - - results, err := decodeResults(f) - - if err != nil { - log.Printf("Could not collect results from %s: %v", exe, err) - continue - } - - for _, r := range results { - r.testOutput = string(out) - lut[exe + "." + r.id] = r - } - } - - return lut -} - -// An executable may contain more than one test -// Gather all executables and deduplicate them -func exes(tcs []planr.TestCase) []string { - set := make(map[string] bool, 0) - - for _, tc := range tcs { - // Tests which have encountered a failure - // may not have an executable - if tc.Result.Status != planr.PASSING { - continue - } - - if(!set[tc.Cname]) { - set[tc.Cname] = true - } - } - - exes := make([]string, 0) - for k := range set { - exes = append(exes, k) - } - - return exes -} - -func id(tc planr.TestCase) string { - cfg := tc.AdapterConfig().(*Config) - return tc.Cname + "." + *cfg.Suite + "." + *cfg.Name -} - -func compile(wg * sync.WaitGroup, tc * planr.TestCase) { - defer wg.Done() - - cmd := exec.Command("make", tc.Cname) - out, err := cmd.CombinedOutput() - tc.Result = new(planr.TestResult) - - // Don't treat command failure as anything but a build failure - if err != nil{ - var exiterr *exec.ExitError - if errors.As(err, &exiterr) && exiterr.ExitCode() == 0 { - log.Fatal(err) - } - - tc.Result.Status = planr.COMPILATION_FAILURE - } - - tc.Result.DebugOutput = string(out) -} - type Adapter struct { dirs planr.DirConfig } @@ -155,67 +37,42 @@ func (a *Adapter) Init(dirs planr.DirConfig) { func (adapter Adapter) Build(tcs []planr.TestCase) { buildDir := safeWd() - cmakeFile := path.Join(buildDir, GTEST_CMAKE) - units := make([]cmakeUnit, 0) - for _, tc := range tcs { - - cfg := tc.AdapterConfig().(*Config) - cfg.ensureSatisfied(tc.Path) + finalizeConfigs(tcs) - units = append(units, makeUnit(tc, adapter.dirs)) - } + exes := createExecutables(tcs) - genCmake(cmakeFile, units) + cmakeFile := path.Join(buildDir, GTEST_CMAKE) + cmakeUnits := cmakeUnits(exes, adapter.dirs) + + generateCmakeScript(cmakeFile, cmakeUnits) planr.RunCmd("cmake", "-S", ".", "-B", ".") } -// ./planr eval 0.93s user 0.16s system 100% cpu 1.089 total -func (adapter *Adapter) Evaluate(tcs []planr.TestCase) [] planr.TestCase { - var wg sync.WaitGroup - for i := range tcs { - tc := &tcs[i] - wg.Add(1) - go compile(&wg, tc) - } - wg.Wait() - - files := exes(tcs) - resultById := adapter.execTests(files) - - for i := range tcs { - tc := &tcs[i] - result, ok := resultById[id(*tc)] - - // compilation failure - if !ok { - - if tc.Result.Status == planr.PASSING { - cfg := tc.AdapterConfig().(*Config) +func (adapter *Adapter) Evaluate(tcs []planr.TestCase) [] planr.TestResult { + buildDir := safeWd() - log.Printf( - "Could not find testcase %s with name=\"%s\" and suite=\"%s\". Does such a test exist in the test source?", - tc.Cname, - *cfg.Name, - *cfg.Suite, - ) + finalizeConfigs(tcs) + + results := make([]planr.TestResult, 0) + + exes := createExecutables(tcs) - tc.Result.Status = planr.COMPILATION_FAILURE - tc.Result.DebugOutput += fmt.Sprintf("planr: Did not find testcase %s in any test executable\n", id(*tc)) - } + for i := range exes { + succeed, buildFailures := exes[i].compile(buildDir) + if ! succeed { + results = append(results, buildFailures...) continue } - - if !result.pass { - tc.Result.Status = planr.RUNTIME_FAILURE - } - tc.Result.TestOutput = result.testOutput - } + runtimeResults := exes[i].execute(buildDir) - return tcs + results = append(results, runtimeResults...) + } + + return results } func NewAdapter() *Adapter { -- cgit v1.2.3 From e120a9f5955551fcf314543c8889e58277aefb20 Mon Sep 17 00:00:00 2001 From: Flu0r1ne Date: Sun, 5 Sep 2021 01:29:24 -0500 Subject: Add concurrency to evaluate --- adapters/gtest/adapter.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'adapters/gtest/adapter.go') diff --git a/adapters/gtest/adapter.go b/adapters/gtest/adapter.go index ec11748..2961f29 100644 --- a/adapters/gtest/adapter.go +++ b/adapters/gtest/adapter.go @@ -59,17 +59,24 @@ func (adapter *Adapter) Evaluate(tcs []planr.TestCase) [] planr.TestResult { exes := createExecutables(tcs) + c := make(chan []planr.TestResult, len(exes)) for i := range exes { - succeed, buildFailures := exes[i].compile(buildDir) + go func(exe *executable) { + succeed, buildFailures := exe.compile(buildDir) - if ! succeed { - results = append(results, buildFailures...) - continue - } + if ! succeed { + c <- buildFailures + return + } - runtimeResults := exes[i].execute(buildDir) + runtimeResults := exe.execute(buildDir) - results = append(results, runtimeResults...) + c <- runtimeResults + }(&exes[i]) + } + + for range exes { + results = append(results, (<-c)...) } return results -- cgit v1.2.3