+++ /dev/null
-// Copyright (C) 2021 Simon Ruderich
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package sync
-
-import (
- "bytes"
- "fmt"
- "os/exec"
- "reflect"
- "sync"
- "testing"
-
- "github.com/google/go-cmp/cmp"
- "github.com/google/go-cmp/cmp/cmpopts"
-
- "ruderich.org/simon/safcm"
- "ruderich.org/simon/safcm/cmd/safcm-remote/log"
- "ruderich.org/simon/safcm/cmd/safcm-remote/run"
-)
-
-// testRunner implements run.Runner to test commands without actually running
-// them.
-type testRunner struct {
- t *testing.T
- expCmds []*exec.Cmd
- resStdout [][]byte
- resStderr [][]byte
- resError []error
-}
-
-func (r *testRunner) Run(cmd *exec.Cmd) error {
- stdout, stderr, resErr := r.check("run", cmd)
- _, err := cmd.Stdout.Write(stdout)
- if err != nil {
- panic(err)
- }
- _, err = cmd.Stderr.Write(stderr)
- if err != nil {
- panic(err)
- }
- return resErr
-}
-func (r *testRunner) CombinedOutput(cmd *exec.Cmd) ([]byte, error) {
- r.t.Helper()
-
- stdout, stderr, err := r.check("combinedOutput", cmd)
- if stderr != nil {
- // stdout also contains stderr
- r.t.Fatalf("CombinedOutput: stderr != nil, but %v", stderr)
- }
- return stdout, err
-}
-func (r *testRunner) check(method string, cmd *exec.Cmd) (
- []byte, []byte, error) {
- r.t.Helper()
-
- if len(r.expCmds) == 0 {
- r.t.Fatalf("%s: empty expCmds", method)
- }
- if len(r.resStdout) == 0 {
- r.t.Fatalf("%s: empty resStdout", method)
- }
- if len(r.resStderr) == 0 {
- r.t.Fatalf("%s: empty resStderr", method)
- }
- if len(r.resError) == 0 {
- r.t.Fatalf("%s: empty resError", method)
- }
-
- exp := r.expCmds[0]
- r.expCmds = r.expCmds[1:]
- if !reflect.DeepEqual(exp, cmd) {
- opts := cmpopts.IgnoreUnexported(exec.Cmd{}, bytes.Buffer{})
- r.t.Errorf("%s: %s", method, cmp.Diff(exp, cmd, opts))
- }
-
- var stdout, stderr []byte
- var err error
-
- stdout, r.resStdout = r.resStdout[0], r.resStdout[1:]
- stderr, r.resStderr = r.resStderr[0], r.resStderr[1:]
- err, r.resError = r.resError[0], r.resError[1:]
-
- return stdout, stderr, err
-}
-
-type syncTestResult struct {
- ch chan string
- wg sync.WaitGroup
- dbg []string
- runner *testRunner
-}
-
-func prepareSync(req safcm.MsgSyncReq, runner *testRunner) (
- *Sync, *syncTestResult) {
-
- res := &syncTestResult{
- ch: make(chan string),
- runner: runner,
- }
- res.wg.Add(1)
- go func() {
- for {
- x, ok := <-res.ch
- if !ok {
- break
- }
- res.dbg = append(res.dbg, x)
- }
- res.wg.Done()
- }()
-
- logger := log.NewLogger(func(level safcm.LogLevel, msg string) {
- res.ch <- fmt.Sprintf("%d: %s", level, msg)
- })
- return &Sync{
- req: req,
- cmd: run.NewCmd(runner, logger),
- log: logger,
- }, res
-}
-
-func (s *syncTestResult) Wait() []string {
- s.runner.t.Helper()
-
- close(s.ch)
- s.wg.Wait()
-
- // All expected commands must have been executed
- if len(s.runner.expCmds) != 0 {
- s.runner.t.Errorf("expCmds left: %v", s.runner.expCmds)
- }
- if len(s.runner.resStdout) != 0 {
- s.runner.t.Errorf("resStdout left: %v", s.runner.resStdout)
- }
- if len(s.runner.resStderr) != 0 {
- s.runner.t.Errorf("resStderr left: %v", s.runner.resStderr)
- }
- if len(s.runner.resError) != 0 {
- s.runner.t.Errorf("resError left: %v", s.runner.resError)
- }
-
- return s.dbg
-}