working integration tests

This commit is contained in:
David Dworken 2022-01-09 14:34:59 -08:00
parent 3d450a1175
commit 9b144e7f31
8 changed files with 150 additions and 23 deletions

View File

@ -1,5 +1,5 @@
Installation: Installation:
``` ```
export PROMPT_COMMAND='~/.hishtory-client upload $? "`history 1`"' export PROMPT_COMMAND='~/.hishtory-client saveHistoryEntry $? "`history 1`"'
``` ```

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"os" "os"
"strings" "strings"
@ -19,6 +20,8 @@ func main() {
shared.CheckFatalError(shared.Enable()) shared.CheckFatalError(shared.Enable())
case "disable": case "disable":
shared.CheckFatalError(shared.Disable()) shared.CheckFatalError(shared.Disable())
default:
shared.CheckFatalError(fmt.Errorf("unknown command: %s", os.Args[1]))
} }
} }
@ -35,9 +38,9 @@ func query() {
db, err := shared.OpenDB() db, err := shared.OpenDB()
shared.CheckFatalError(err) shared.CheckFatalError(err)
query := strings.Join(os.Args[2:], " ") query := strings.Join(os.Args[2:], " ")
data, err := shared.Search(db, query, userSecret, 25) data, err := shared.Search(db, userSecret, query, 25)
shared.CheckFatalError(err) shared.CheckFatalError(err)
shared.DisplayResults(data) shared.DisplayResults(data, false)
} }
func saveHistoryEntry() { func saveHistoryEntry() {

View File

@ -2,23 +2,69 @@ package main
import ( import (
"bytes" "bytes"
"fmt" "io/ioutil"
"os/exec" "os/exec"
"regexp"
"strings"
"testing" "testing"
"github.com/ddworken/hishtory/shared" "github.com/ddworken/hishtory/shared"
) )
func RunInteractiveBashCommands(t *testing.T, script string) string {
shared.Check(t, ioutil.WriteFile("/tmp/hishtory-test-in.sh", []byte(script), 0600))
cmd := exec.Command("bash", "-i")
cmd.Stdin = strings.NewReader(script)
var out bytes.Buffer
cmd.Stdout = &out
var err bytes.Buffer
cmd.Stderr = &err
shared.CheckWithInfo(t, cmd.Run(), out.String()+err.String())
return out.String()
}
const (
PROMPT_COMMAND = "export PROMPT_COMMAND='/tmp/client saveHistoryEntry $? \"`history 1`\"'"
)
func TestIntegration(t *testing.T) { func TestIntegration(t *testing.T) {
// Set up // Set up
defer shared.BackupAndRestore(t) defer shared.BackupAndRestore(t)
// Run the test // Test init
cmd := exec.Command("bash", "--init-file", "test_interaction.sh") out := RunInteractiveBashCommands(t, `
var out bytes.Buffer gvm use go1.17
cmd.Stdout = &out cd ../../
if err := cmd.Run(); err != nil { go build -o /tmp/client clients/local/client.go
t.Fatalf("unexpected error when running test script: %v", err) /tmp/client init`)
match, err := regexp.MatchString(`Setting secret hishtory key to .*`, out)
shared.Check(t, err)
if !match {
t.Fatalf("unexpected output from init: %v", out)
}
// Test recording commands
out = RunInteractiveBashCommands(t, PROMPT_COMMAND+`
ls /a
ls /bar
ls /foo
echo foo
echo bar
/tmp/client disable
echo thisisnotrecorded
/tmp/client enable
echo thisisrecorded
`)
if out != "foo\nbar\nthisisnotrecorded\nthisisrecorded\n" {
t.Fatalf("unexpected output from running commands: %#v", out)
}
// Test querying for all commands
out = RunInteractiveBashCommands(t, "/tmp/client query")
expected := []string{"echo thisisrecorded", "/tmp/client enable", "echo bar", "echo foo", "ls /foo", "ls /bar", "ls /a"}
for _, item := range expected {
if !strings.Contains(out, item) {
t.Fatalf("output is missing expected item %#v: %#v", item, out)
}
} }
fmt.Printf("%q\n", out.String())
} }

View File

@ -1,8 +0,0 @@
go build -o /tmp/client clients/local/client.go
/tmp/client init
export PROMPT_COMMAND='/tmp/client upload $? "`history 1`"'
ls /a
ls /bar
ls /foo
echo foo
/tmp/client query

View File

@ -27,6 +27,8 @@ func main() {
shared.CheckFatalError(shared.Enable()) shared.CheckFatalError(shared.Enable())
case "disable": case "disable":
shared.CheckFatalError(shared.Disable()) shared.CheckFatalError(shared.Disable())
default:
shared.CheckFatalError(fmt.Errorf("unknown command: %s", os.Args[1]))
} }
} }
@ -63,7 +65,7 @@ func query() {
var data []*shared.HistoryEntry var data []*shared.HistoryEntry
err = json.Unmarshal(resp_body, &data) err = json.Unmarshal(resp_body, &data)
shared.CheckFatalError(err) shared.CheckFatalError(err)
shared.DisplayResults(data) shared.DisplayResults(data, true)
} }
func saveHistoryEntry() { func saveHistoryEntry() {

View File

@ -0,0 +1,71 @@
package main
import (
"bytes"
"io/ioutil"
"os/exec"
"regexp"
"strings"
"testing"
"github.com/ddworken/hishtory/shared"
)
func RunInteractiveBashCommands(t *testing.T, script string) string {
shared.Check(t, ioutil.WriteFile("/tmp/hishtory-test-in.sh", []byte(script), 0600))
cmd := exec.Command("bash", "-i")
cmd.Stdin = strings.NewReader(script)
var out bytes.Buffer
cmd.Stdout = &out
var err bytes.Buffer
cmd.Stderr = &err
shared.CheckWithInfo(t, cmd.Run(), out.String()+err.String())
return out.String()
}
const (
PROMPT_COMMAND = "export PROMPT_COMMAND='/tmp/client saveHistoryEntry $? \"`history 1`\"'"
)
func TestIntegration(t *testing.T) {
// Set up
defer shared.BackupAndRestore(t)
// Test init
out := RunInteractiveBashCommands(t, `
gvm use go1.17
cd ../../
go build -o /tmp/client clients/remote/client.go
go build -o /tmp/server server/server.go
/tmp/client init`)
match, err := regexp.MatchString(`Setting secret hishtory key to .*`, out)
shared.Check(t, err)
if !match {
t.Fatalf("unexpected output from init: %v", out)
}
// Test recording commands
out = RunInteractiveBashCommands(t, `/tmp/server &`+PROMPT_COMMAND+`
ls /a
ls /bar
ls /foo
echo foo
echo bar
/tmp/client disable
echo thisisnotrecorded
/tmp/client enable
echo thisisrecorded
`)
if out != "Listening on localhost:8080\nfoo\nbar\nthisisnotrecorded\nthisisrecorded\n" {
t.Fatalf("unexpected output from running commands: %#v", out)
}
// Test querying for all commands
out = RunInteractiveBashCommands(t, `/tmp/server & /tmp/client query`)
expected := []string{"echo thisisrecorded", "/tmp/client enable", "echo bar", "echo foo", "ls /foo", "ls /bar", "ls /a"}
for _, item := range expected {
if !strings.Contains(out, item) {
t.Fatalf("output is missing expected item %#v: %#v", item, out)
}
}
}

View File

@ -113,13 +113,20 @@ func Setup(args []string) error {
return SetConfig(config) return SetConfig(config)
} }
func DisplayResults(results []*HistoryEntry) { func DisplayResults(results []*HistoryEntry, displayHostname bool) {
headerFmt := color.New(color.FgGreen, color.Underline).SprintfFunc() headerFmt := color.New(color.FgGreen, color.Underline).SprintfFunc()
tbl := table.New("Hostname", "CWD", "Timestamp", "Exit Code", "Command") tbl := table.New("CWD", "Timestamp", "Exit Code", "Command")
if displayHostname {
tbl = table.New("Hostname", "CWD", "Timestamp", "Exit Code", "Command")
}
tbl.WithHeaderFormatter(headerFmt) tbl.WithHeaderFormatter(headerFmt)
for _, result := range results { for _, result := range results {
if displayHostname {
tbl.AddRow(result.Hostname, result.CurrentWorkingDirectory, result.EndTime.Format("Jan 2 2006 15:04:05 MST"), result.ExitCode, result.Command) tbl.AddRow(result.Hostname, result.CurrentWorkingDirectory, result.EndTime.Format("Jan 2 2006 15:04:05 MST"), result.ExitCode, result.Command)
} else {
tbl.AddRow(result.CurrentWorkingDirectory, result.EndTime.Format("Jan 2 2006 15:04:05 MST"), result.ExitCode, result.Command)
}
} }
tbl.Print() tbl.Print()

View File

@ -13,6 +13,12 @@ func Check(t *testing.T, err error) {
} }
} }
func CheckWithInfo(t *testing.T, err error, additionalInfo string) {
if err != nil {
t.Fatalf("Unexpected error: %v! Additional info: %v", err, additionalInfo)
}
}
func BackupAndRestore(t *testing.T) func() { func BackupAndRestore(t *testing.T) func() {
homedir, err := os.UserHomeDir() homedir, err := os.UserHomeDir()
if err != nil { if err != nil {