From 62e85f40923b3485ba60766052de7150acf039c5 Mon Sep 17 00:00:00 2001
From: Flu0r1ne <flur01ne@flu0r1ne.net>
Date: Sun, 5 Sep 2021 04:30:33 -0500
Subject: Add bash adapter

---
 adapters/bash/adapter.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++++
 adapters/bash/config.go  | 64 ++++++++++++++++++++++++++++++++
 2 files changed, 160 insertions(+)
 create mode 100644 adapters/bash/adapter.go
 create mode 100644 adapters/bash/config.go

(limited to 'adapters/bash')

diff --git a/adapters/bash/adapter.go b/adapters/bash/adapter.go
new file mode 100644
index 0000000..b98523e
--- /dev/null
+++ b/adapters/bash/adapter.go
@@ -0,0 +1,96 @@
+package bash
+
+import (
+	"context"
+	"errors"
+	"log"
+	"os"
+	"os/exec"
+	"path"
+	"strings"
+	"time"
+        "fmt"
+
+	"golang.flu0r1ne.net/planr"
+)
+
+type Adapter struct {
+  dirs planr.DirConfig
+}
+
+func (a *Adapter) Config() planr.AdapterConfig {
+  return planr.AdapterConfig {
+    Name: "bash",
+    ParseConfig: ParseConfig,
+    ParseDefaultConfig: ParseDefaultConfig,
+  }
+}
+
+func safeWd() string{
+  wd, err := os.Getwd()
+
+  if err != nil {
+    log.Fatalf("Could not get GtestBuildDir %s %v\n", wd, err)
+  }
+
+  return wd
+}
+
+func (a *Adapter) Init(dirs planr.DirConfig) {
+  a.dirs = dirs
+}
+
+func (adapter Adapter) Build(tcs []planr.TestCase) { }
+
+func executeScriptedTest(testdir string, tc planr.TestCase) planr.TestResult {
+  cfg := tc.AdapterConfig().(*Config)
+
+  timeout := time.Duration(cfg.Timeout) * time.Millisecond
+
+  ctx, cancel := context.WithTimeout(context.Background(), timeout)
+
+  defer cancel()
+
+  path := path.Join(testdir, cfg.Testfile)
+
+  result := planr.TestResult {}
+  result.Tc = tc
+
+  cmd := exec.CommandContext(ctx, "bash", path)
+    
+  if out, err := cmd.CombinedOutput(); err != nil {
+    result.Status = planr.RUNTIME_FAILURE  
+    result.TestOutput = string(out)
+
+    var exiterr *exec.ExitError
+    if !errors.As(err, &exiterr) {
+      log.Fatalf("Test script %s failed with unknown error %v\n", path, err)
+    } else {
+      if strings.Contains(exiterr.String(), "killed") {
+        result.TestOutput += fmt.Sprintf("TEST TERMINATED (Timeout=%d)\n", cfg.Timeout)
+      }
+    }
+
+    return result
+  }
+
+  result.Status = planr.PASSING
+
+
+  return result
+}
+
+func (adapter Adapter) Evaluate(tcs []planr.TestCase) [] planr.TestResult {
+  finalizeConfigs(tcs)
+ 
+  trs := make([]planr.TestResult, len(tcs))
+  for i, tc := range tcs {
+    trs[i] = executeScriptedTest(adapter.dirs.Tests(), tc)
+  }
+
+  return trs
+}
+
+func NewAdapter() *Adapter {
+  return new(Adapter)
+}
diff --git a/adapters/bash/config.go b/adapters/bash/config.go
new file mode 100644
index 0000000..aaa405a
--- /dev/null
+++ b/adapters/bash/config.go
@@ -0,0 +1,64 @@
+package bash
+
+import (
+  "log"
+  "golang.flu0r1ne.net/planr"
+  "github.com/BurntSushi/toml"
+)
+
+const (
+  DEFAULT_TIMEOUT=1000
+)
+
+type Defaults struct {
+  Testfile  string
+  Timeout   uint 
+}
+
+func (child *Defaults) Inherit(p interface{}) {
+  parent := p.(*Defaults)
+
+  if(child.Timeout == 0) { child.Timeout = parent.Timeout }
+}
+
+type Config struct {
+  Defaults
+}
+
+func (c *Config) finalize(path string) {
+  if c.Testfile == "" {
+    log.Fatalf("\"Testfile\" is not defined for unit %s\n", path)
+  }
+
+  if c.Timeout == 0 {
+    c.Timeout = DEFAULT_TIMEOUT;
+  }
+}
+
+func finalizeConfigs(tcs []planr.TestCase) {
+  for i := range tcs {
+    cfg := tcs[i].AdapterConfig().(*Config)
+
+    cfg.finalize(tcs[i].Path)
+  }
+}
+
+func ParseConfig(prim toml.Primitive) (planr.InheritableConfig, error) {
+  config := Config {}
+
+  if err := toml.PrimitiveDecode(prim, &config); err != nil {
+    return nil, err
+  }
+
+  return &config, nil
+}
+
+func ParseDefaultConfig(prim toml.Primitive) (planr.InheritableConfig, error) {
+  config := Defaults{}
+
+  if err := toml.PrimitiveDecode(prim, &config); err != nil {
+    return nil, err
+  }
+
+  return &config, nil
+}
-- 
cgit v1.2.3