mirror of
https://github.com/ddworken/hishtory.git
synced 2025-02-13 09:01:23 +01:00
* Implement restrictions on default column searching for #268 * Add better docs for config-set excluded-default-search-columns * Enable debugging * Clean up server binaries to avoid wasting disk space * Add tests * Swap from configuring excluded columns to configuring included columns, to prep for future changes where we may add support for other default columns * Reduce gotestsum re-runs since tests are less flaky nowadays * Fix bug in lib.where(...) function that failed to trim the args list and caused DB query correctness issues * Disable tmate debugging * Update goldens
This commit is contained in:
parent
23ed840aa3
commit
65d1ebfd07
2
Makefile
2
Makefile
@ -15,7 +15,7 @@ forcetest: ## Force running all tests without a test cache
|
|||||||
make test
|
make test
|
||||||
|
|
||||||
test: ## Run all tests
|
test: ## Run all tests
|
||||||
TZ='America/Los_Angeles' HISHTORY_TEST=1 HISHTORY_SKIP_INIT_IMPORT=1 gotestsum --packages ./... --rerun-fails=10 --rerun-fails-max-failures=30 --format testname --jsonfile /tmp/testrun.json --post-run-command "go run client/posttest/main.go export" -- -p 1 -timeout 90m
|
TZ='America/Los_Angeles' HISHTORY_TEST=1 HISHTORY_SKIP_INIT_IMPORT=1 gotestsum --packages ./... --rerun-fails=5 --rerun-fails-max-failures=15 --format testname --jsonfile /tmp/testrun.json --post-run-command "go run client/posttest/main.go export" -- -p 1 -timeout 90m
|
||||||
|
|
||||||
ftest: ## Run a specific test specified via `make ftest FILTER=TestParam/testTui/color` or `make ftest FILTER=TestImportJson`
|
ftest: ## Run a specific test specified via `make ftest FILTER=TestParam/testTui/color` or `make ftest FILTER=TestImportJson`
|
||||||
go clean -testcache
|
go clean -testcache
|
||||||
|
@ -168,6 +168,19 @@ var getAiCompletionEndpoint = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var getDefaultSearchColumns = &cobra.Command{
|
||||||
|
Use: "default-search-columns",
|
||||||
|
Short: "Get the list of columns that are used for \"default\" search queries that don't use any search atoms",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
ctx := hctx.MakeContext()
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
for _, col := range config.DefaultSearchColumns {
|
||||||
|
fmt.Print(col + " ")
|
||||||
|
}
|
||||||
|
fmt.Print("\n")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(configGetCmd)
|
rootCmd.AddCommand(configGetCmd)
|
||||||
configGetCmd.AddCommand(getEnableControlRCmd)
|
configGetCmd.AddCommand(getEnableControlRCmd)
|
||||||
@ -185,6 +198,7 @@ func init() {
|
|||||||
configGetCmd.AddCommand(getCompactMode)
|
configGetCmd.AddCommand(getCompactMode)
|
||||||
configGetCmd.AddCommand(getLogLevelCmd)
|
configGetCmd.AddCommand(getLogLevelCmd)
|
||||||
configGetCmd.AddCommand(getFullScreenCmd)
|
configGetCmd.AddCommand(getFullScreenCmd)
|
||||||
|
configGetCmd.AddCommand(getDefaultSearchColumns)
|
||||||
}
|
}
|
||||||
|
|
||||||
var getLogLevelCmd = &cobra.Command{
|
var getLogLevelCmd = &cobra.Command{
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ddworken/hishtory/client/hctx"
|
"github.com/ddworken/hishtory/client/hctx"
|
||||||
@ -275,6 +276,24 @@ var setFullScreenCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var setDefaultSearchColumns = &cobra.Command{
|
||||||
|
Use: "default-search-columns",
|
||||||
|
Short: "Get the list of columns that are used for \"default\" search queries that don't use any search atoms",
|
||||||
|
Long: "By default hishtory queries are checked against `command`, `current_working_directory`, and `hostname`. This option can be used to exclude `current_working_directory` and/or `hostname` from default search queries. E.g. `hishtory config-set default-search-columns hostname command` would exclude `current_working_directory` from default searches.",
|
||||||
|
Args: cobra.OnlyValidArgs,
|
||||||
|
// Note: If we are ever adding new arguments to this list, we should consider adding support for this config option in configAdd.go and configDelete.go.
|
||||||
|
ValidArgs: []string{"current_working_directory", "hostname", "command"},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
ctx := hctx.MakeContext()
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
if !slices.Contains(args, "command") {
|
||||||
|
lib.CheckFatalError(fmt.Errorf("command is a required default search column"))
|
||||||
|
}
|
||||||
|
config.DefaultSearchColumns = args
|
||||||
|
lib.CheckFatalError(hctx.SetConfig(config))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(configSetCmd)
|
rootCmd.AddCommand(configSetCmd)
|
||||||
configSetCmd.AddCommand(setEnableControlRCmd)
|
configSetCmd.AddCommand(setEnableControlRCmd)
|
||||||
@ -291,6 +310,7 @@ func init() {
|
|||||||
configSetCmd.AddCommand(compactMode)
|
configSetCmd.AddCommand(compactMode)
|
||||||
configSetCmd.AddCommand(setLogLevelCmd)
|
configSetCmd.AddCommand(setLogLevelCmd)
|
||||||
configSetCmd.AddCommand(setFullScreenCmd)
|
configSetCmd.AddCommand(setFullScreenCmd)
|
||||||
|
configSetCmd.AddCommand(setDefaultSearchColumns)
|
||||||
setColorSchemeCmd.AddCommand(setColorSchemeSelectedText)
|
setColorSchemeCmd.AddCommand(setColorSchemeSelectedText)
|
||||||
setColorSchemeCmd.AddCommand(setColorSchemeSelectedBackground)
|
setColorSchemeCmd.AddCommand(setColorSchemeSelectedBackground)
|
||||||
setColorSchemeCmd.AddCommand(setColorSchemeBorderColor)
|
setColorSchemeCmd.AddCommand(setColorSchemeBorderColor)
|
||||||
|
@ -223,6 +223,9 @@ type ClientConfig struct {
|
|||||||
LogLevel logrus.Level `json:"log_level"`
|
LogLevel logrus.Level `json:"log_level"`
|
||||||
// Whether the TUI should render in full-screen mode
|
// Whether the TUI should render in full-screen mode
|
||||||
FullScreenRendering bool `json:"full_screen_rendering"`
|
FullScreenRendering bool `json:"full_screen_rendering"`
|
||||||
|
// Columns that are used for default searches.
|
||||||
|
// See https://github.com/ddworken/hishtory/issues/268 for context on this.
|
||||||
|
DefaultSearchColumns []string `json:"default_search_columns"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ColorScheme struct {
|
type ColorScheme struct {
|
||||||
@ -297,6 +300,9 @@ func GetConfig() (ClientConfig, error) {
|
|||||||
if config.LogLevel == logrus.Level(0) {
|
if config.LogLevel == logrus.Level(0) {
|
||||||
config.LogLevel = logrus.InfoLevel
|
config.LogLevel = logrus.InfoLevel
|
||||||
}
|
}
|
||||||
|
if len(config.DefaultSearchColumns) == 0 {
|
||||||
|
config.DefaultSearchColumns = []string{"command", "current_working_directory", "hostname"}
|
||||||
|
}
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3534,4 +3534,58 @@ func TestOfflineClient(t *testing.T) {
|
|||||||
require.Contains(t, err.Error(), "panic: Cannot GetHttpClient() from a hishtory client compiled with the offline tag!")
|
require.Contains(t, err.Error(), "panic: Cannot GetHttpClient() from a hishtory client compiled with the offline tag!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultSearchColumns(t *testing.T) {
|
||||||
|
markTestForSharding(t, 21)
|
||||||
|
defer testutils.BackupAndRestore(t)()
|
||||||
|
tester := zshTester{}
|
||||||
|
installHishtory(t, tester, "")
|
||||||
|
|
||||||
|
// Disable recording so that all our testing commands don't get recorded
|
||||||
|
_, _ = tester.RunInteractiveShellRelaxed(t, ` hishtory disable`)
|
||||||
|
_, _ = tester.RunInteractiveShellRelaxed(t, ` hishtory config-set enable-control-r true`)
|
||||||
|
tester.RunInteractiveShell(t, ` HISHTORY_REDACT_FORCE=true hishtory redact pipefail`)
|
||||||
|
db := hctx.GetDb(hctx.MakeContext())
|
||||||
|
require.NoError(t, db.Where("true").Delete(&data.HistoryEntry{}).Error)
|
||||||
|
|
||||||
|
// Insert a few hishtory entries that we'll use for testing into an empty DB
|
||||||
|
e1 := testutils.MakeFakeHistoryEntry("echo hi")
|
||||||
|
e1.CurrentWorkingDirectory = "/cwd1/"
|
||||||
|
e1.Hostname = "h1"
|
||||||
|
require.NoError(t, db.Create(e1).Error)
|
||||||
|
e2 := testutils.MakeFakeHistoryEntry("ls")
|
||||||
|
e2.CurrentWorkingDirectory = "/echo/"
|
||||||
|
e2.Hostname = "hi"
|
||||||
|
require.NoError(t, db.Create(e2).Error)
|
||||||
|
|
||||||
|
// Check that by default all columns are included
|
||||||
|
out := tester.RunInteractiveShell(t, ` hishtory export echo | grep -v pipefail`)
|
||||||
|
testutils.CompareGoldens(t, out, "TestDefaultSearchColumns-Default-Echo")
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory export hi | grep -v pipefail`)
|
||||||
|
testutils.CompareGoldens(t, out, "TestDefaultSearchColumns-Default-Hi")
|
||||||
|
|
||||||
|
// Update the config value to exclude CWD
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory config-get default-search-columns`)
|
||||||
|
require.Equal(t, out, "command current_working_directory hostname \n")
|
||||||
|
tester.RunInteractiveShell(t, ` hishtory config-set default-search-columns 'hostname' 'command'`)
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory config-get default-search-columns`)
|
||||||
|
require.Equal(t, out, "hostname command \n")
|
||||||
|
|
||||||
|
// Without CWD included
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory export echo | grep -v pipefail`)
|
||||||
|
testutils.CompareGoldens(t, out, "TestDefaultSearchColumns-NoCWD-Echo")
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory export hi | grep -v pipefail`)
|
||||||
|
testutils.CompareGoldens(t, out, "TestDefaultSearchColumns-NoCWD-Hi")
|
||||||
|
|
||||||
|
// Update the config value to exclude hostname
|
||||||
|
tester.RunInteractiveShell(t, ` hishtory config-set default-search-columns command`)
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory config-get default-search-columns`)
|
||||||
|
require.Equal(t, out, "command \n")
|
||||||
|
|
||||||
|
// Without hostname included
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory export echo | grep -v pipefail`)
|
||||||
|
testutils.CompareGoldens(t, out, "TestDefaultSearchColumns-NoCWDHostname-Echo")
|
||||||
|
out = tester.RunInteractiveShell(t, ` hishtory export hi | grep -v pipefail`)
|
||||||
|
testutils.CompareGoldens(t, out, "TestDefaultSearchColumns-NoCWDHostname-Hi")
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: somehow test/confirm that hishtory works even if only bash/only zsh is installed
|
// TODO: somehow test/confirm that hishtory works even if only bash/only zsh is installed
|
||||||
|
@ -750,17 +750,21 @@ func parseTimeGenerously(input string) (time.Time, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A wrapper around tx.Where(...) that filters out nil-values
|
// A wrapper around tx.Where(...) that filters out nil-values
|
||||||
func where(tx *gorm.DB, s string, v1, v2 any) *gorm.DB {
|
func where(tx *gorm.DB, s string, args ...any) *gorm.DB {
|
||||||
if v1 == nil && v2 == nil {
|
trimmedArgs := make([]any, 0)
|
||||||
return tx.Where(s)
|
foundNil := false
|
||||||
|
for _, v := range args {
|
||||||
|
if v == nil {
|
||||||
|
foundNil = true
|
||||||
}
|
}
|
||||||
if v1 != nil && v2 == nil {
|
if foundNil && v != nil {
|
||||||
return tx.Where(s, v1)
|
panic(fmt.Sprintf("Illegal state: args=%#v", args))
|
||||||
}
|
}
|
||||||
if v1 != nil && v2 != nil {
|
if v != nil {
|
||||||
return tx.Where(s, v1, v2)
|
trimmedArgs = append(trimmedArgs, v)
|
||||||
}
|
}
|
||||||
panic(fmt.Sprintf("Impossible state: v1=%#v, v2=%#v", v1, v2))
|
}
|
||||||
|
return tx.Where(s, trimmedArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeWhereQueryFromSearch(ctx context.Context, db *gorm.DB, query string) (*gorm.DB, error) {
|
func MakeWhereQueryFromSearch(ctx context.Context, db *gorm.DB, query string) (*gorm.DB, error) {
|
||||||
@ -780,11 +784,11 @@ func MakeWhereQueryFromSearch(ctx context.Context, db *gorm.DB, query string) (*
|
|||||||
}
|
}
|
||||||
tx = where(tx, "NOT "+query, v1, v2)
|
tx = where(tx, "NOT "+query, v1, v2)
|
||||||
} else {
|
} else {
|
||||||
query, v1, v2, v3, err := parseNonAtomizedToken(token[1:])
|
query, v1, v2, v3, err := parseNonAtomizedToken(ctx, token[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tx = tx.Where("NOT "+query, v1, v2, v3)
|
tx = where(tx, "NOT "+query, v1, v2, v3)
|
||||||
}
|
}
|
||||||
} else if containsUnescaped(token, ":") {
|
} else if containsUnescaped(token, ":") {
|
||||||
query, v1, v2, err := parseAtomizedToken(ctx, token)
|
query, v1, v2, err := parseAtomizedToken(ctx, token)
|
||||||
@ -793,11 +797,11 @@ func MakeWhereQueryFromSearch(ctx context.Context, db *gorm.DB, query string) (*
|
|||||||
}
|
}
|
||||||
tx = where(tx, query, v1, v2)
|
tx = where(tx, query, v1, v2)
|
||||||
} else {
|
} else {
|
||||||
query, v1, v2, v3, err := parseNonAtomizedToken(token)
|
query, v1, v2, v3, err := parseNonAtomizedToken(ctx, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tx = tx.Where(query, v1, v2, v3)
|
tx = where(tx, query, v1, v2, v3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tx, nil
|
return tx, nil
|
||||||
@ -847,9 +851,36 @@ func retryingSearch(ctx context.Context, db *gorm.DB, query string, limit, offse
|
|||||||
return historyEntries, nil
|
return historyEntries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNonAtomizedToken(token string) (string, any, any, any, error) {
|
func parseNonAtomizedToken(ctx context.Context, token string) (string, any, any, any, error) {
|
||||||
wildcardedToken := "%" + unescape(token) + "%"
|
wildcardedToken := "%" + unescape(token) + "%"
|
||||||
return "(command LIKE ? OR hostname LIKE ? OR current_working_directory LIKE ?)", wildcardedToken, wildcardedToken, wildcardedToken, nil
|
query := "(false "
|
||||||
|
numFilters := 0
|
||||||
|
if slices.Contains(hctx.GetConf(ctx).DefaultSearchColumns, "command") {
|
||||||
|
query += "OR command LIKE ? "
|
||||||
|
numFilters += 1
|
||||||
|
}
|
||||||
|
if slices.Contains(hctx.GetConf(ctx).DefaultSearchColumns, "hostname") {
|
||||||
|
query += "OR hostname LIKE ? "
|
||||||
|
numFilters += 1
|
||||||
|
}
|
||||||
|
if slices.Contains(hctx.GetConf(ctx).DefaultSearchColumns, "current_working_directory") {
|
||||||
|
query += "OR current_working_directory LIKE ? "
|
||||||
|
numFilters += 1
|
||||||
|
}
|
||||||
|
query += ")"
|
||||||
|
var t1 any = nil
|
||||||
|
var t2 any = nil
|
||||||
|
var t3 any = nil
|
||||||
|
if numFilters >= 1 {
|
||||||
|
t1 = wildcardedToken
|
||||||
|
}
|
||||||
|
if numFilters >= 2 {
|
||||||
|
t2 = wildcardedToken
|
||||||
|
}
|
||||||
|
if numFilters >= 3 {
|
||||||
|
t3 = wildcardedToken
|
||||||
|
}
|
||||||
|
return query, t1, t2, t3, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAtomizedToken(ctx context.Context, token string) (string, any, any, error) {
|
func parseAtomizedToken(ctx context.Context, token string) (string, any, any, error) {
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/ddworken/hishtory/shared/testutils"
|
"github.com/ddworken/hishtory/shared/testutils"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -345,3 +346,63 @@ func TestSplitEscaped(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseNonAtomizedToken(t *testing.T) {
|
||||||
|
defer testutils.BackupAndRestore(t)()
|
||||||
|
require.NoError(t, hctx.InitConfig())
|
||||||
|
ctx := hctx.MakeContext()
|
||||||
|
|
||||||
|
// Default
|
||||||
|
q, v1, v2, v3, err := parseNonAtomizedToken(ctx, "echo hello")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "(false OR command LIKE ? OR hostname LIKE ? OR current_working_directory LIKE ? )", q)
|
||||||
|
require.Equal(t, v1, "%echo hello%")
|
||||||
|
require.Equal(t, v2, "%echo hello%")
|
||||||
|
require.Equal(t, v3, "%echo hello%")
|
||||||
|
|
||||||
|
// Skipping cwd
|
||||||
|
config := hctx.GetConf(ctx)
|
||||||
|
config.DefaultSearchColumns = []string{"hostname", "command"}
|
||||||
|
q, v1, v2, v3, err = parseNonAtomizedToken(ctx, "echo hello")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "(false OR command LIKE ? OR hostname LIKE ? )", q)
|
||||||
|
require.Equal(t, v1, "%echo hello%")
|
||||||
|
require.Equal(t, v2, "%echo hello%")
|
||||||
|
require.Nil(t, v3)
|
||||||
|
|
||||||
|
// Skipping cwd and hostname
|
||||||
|
config.DefaultSearchColumns = []string{"command"}
|
||||||
|
q, v1, v2, v3, err = parseNonAtomizedToken(ctx, "echo hello")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "(false OR command LIKE ? )", q)
|
||||||
|
require.Equal(t, v1, "%echo hello%")
|
||||||
|
require.Nil(t, v2)
|
||||||
|
require.Nil(t, v3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWhere(t *testing.T) {
|
||||||
|
defer testutils.BackupAndRestore(t)()
|
||||||
|
require.NoError(t, hctx.InitConfig())
|
||||||
|
ctx := hctx.MakeContext()
|
||||||
|
db := hctx.GetDb(ctx)
|
||||||
|
|
||||||
|
testcases := []struct {
|
||||||
|
in_query string
|
||||||
|
in_args []any
|
||||||
|
expected_query string
|
||||||
|
}{
|
||||||
|
{"exit_code = ?", []any{1}, "SELECT * FROM `history_entries` WHERE exit_code = 1"},
|
||||||
|
{"exit_code = ?", []any{1, nil, nil}, "SELECT * FROM `history_entries` WHERE exit_code = 1"},
|
||||||
|
{"exit_code = ? OR exit_code = ?", []any{1, 2, nil}, "SELECT * FROM `history_entries` WHERE exit_code = 1 OR exit_code = 2"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testcases {
|
||||||
|
tx := where(db, tc.in_query, tc.in_args...)
|
||||||
|
queryString := tx.ToSQL(func(tx *gorm.DB) *gorm.DB {
|
||||||
|
var entries []data.HistoryEntry
|
||||||
|
return tx.Find(&entries)
|
||||||
|
})
|
||||||
|
require.Equal(t, tc.expected_query, queryString)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
client/testdata/TestDefaultSearchColumns-Default-Echo
vendored
Normal file
2
client/testdata/TestDefaultSearchColumns-Default-Echo
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
echo hi
|
||||||
|
ls
|
2
client/testdata/TestDefaultSearchColumns-Default-Hi
vendored
Normal file
2
client/testdata/TestDefaultSearchColumns-Default-Hi
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
echo hi
|
||||||
|
ls
|
1
client/testdata/TestDefaultSearchColumns-NoCWD-Echo
vendored
Normal file
1
client/testdata/TestDefaultSearchColumns-NoCWD-Echo
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
echo hi
|
2
client/testdata/TestDefaultSearchColumns-NoCWD-Hi
vendored
Normal file
2
client/testdata/TestDefaultSearchColumns-NoCWD-Hi
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
echo hi
|
||||||
|
ls
|
1
client/testdata/TestDefaultSearchColumns-NoCWDHostname-Echo
vendored
Normal file
1
client/testdata/TestDefaultSearchColumns-NoCWDHostname-Echo
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
echo hi
|
1
client/testdata/TestDefaultSearchColumns-NoCWDHostname-Hi
vendored
Normal file
1
client/testdata/TestDefaultSearchColumns-NoCWDHostname-Hi
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
echo hi
|
4
client/testdata/TestStatusFullConfig
vendored
4
client/testdata/TestStatusFullConfig
vendored
@ -68,4 +68,8 @@ Full Config:
|
|||||||
- ctrl+right
|
- ctrl+right
|
||||||
loglevel: info
|
loglevel: info
|
||||||
fullscreenrendering: false
|
fullscreenrendering: false
|
||||||
|
defaultsearchcolumns:
|
||||||
|
- command
|
||||||
|
- current_working_directory
|
||||||
|
- hostname
|
||||||
|
|
||||||
|
@ -280,10 +280,14 @@ func RunTestServer() func() {
|
|||||||
panic(fmt.Errorf("expected server stdout to end with %#v, but it doesn't: %#v", expectedSuffix, stdout.String()))
|
panic(fmt.Errorf("expected server stdout to end with %#v, but it doesn't: %#v", expectedSuffix, stdout.String()))
|
||||||
}
|
}
|
||||||
return func() {
|
return func() {
|
||||||
|
// Kill the server process to guarantee the next test can run
|
||||||
err := cmd.Process.Kill()
|
err := cmd.Process.Kill()
|
||||||
if err != nil && err.Error() != "os: process already finished" {
|
if err != nil && err.Error() != "os: process already finished" {
|
||||||
panic(fmt.Sprintf("failed to kill server process: %v", err))
|
panic(fmt.Sprintf("failed to kill server process: %v", err))
|
||||||
}
|
}
|
||||||
|
// Delete the built server binary to avoid wasting disk space
|
||||||
|
_ = os.Remove(fn)
|
||||||
|
// Now that we've cleaned up, check the output to see if the server had any errors
|
||||||
allOutput := stdout.String() + stderr.String()
|
allOutput := stdout.String() + stderr.String()
|
||||||
if strings.Contains(allOutput, "failed to") && IsOnline() {
|
if strings.Contains(allOutput, "failed to") && IsOnline() {
|
||||||
panic(fmt.Sprintf("server experienced an error\n\n\nstderr=\n%s\n\n\nstdout=%s", stderr.String(), stdout.String()))
|
panic(fmt.Sprintf("server experienced an error\n\n\nstderr=\n%s\n\n\nstdout=%s", stderr.String(), stdout.String()))
|
||||||
|
Loading…
Reference in New Issue
Block a user