mirror of
https://github.com/ddworken/hishtory.git
synced 2025-01-11 16:58:47 +01:00
Move testutils to a separate package so as to move test-only code out of the main binary
This commit is contained in:
parent
bed19f5316
commit
cdc5421a7b
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/ddworken/hishtory/client/data"
|
||||
"github.com/ddworken/hishtory/shared"
|
||||
"github.com/ddworken/hishtory/shared/testutils"
|
||||
"github.com/go-test/deep"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@ -34,11 +35,11 @@ func TestESubmitThenQuery(t *testing.T) {
|
||||
apiRegisterHandler(nil, deviceReq)
|
||||
|
||||
// Submit a few entries for different devices
|
||||
entry := data.MakeFakeHistoryEntry("ls ~/")
|
||||
entry := testutils.MakeFakeHistoryEntry("ls ~/")
|
||||
encEntry, err := data.EncryptHistoryEntry("key", entry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
reqBody, err := json.Marshal([]shared.EncHistoryEntry{encEntry})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
submitReq := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(reqBody))
|
||||
apiSubmitHandler(nil, submitReq)
|
||||
|
||||
@ -49,9 +50,9 @@ func TestESubmitThenQuery(t *testing.T) {
|
||||
res := w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err := ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
var retrievedEntries []*shared.EncHistoryEntry
|
||||
shared.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
testutils.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
if len(retrievedEntries) != 1 {
|
||||
t.Fatalf("Expected to retrieve 1 entry, found %d", len(retrievedEntries))
|
||||
}
|
||||
@ -66,7 +67,7 @@ func TestESubmitThenQuery(t *testing.T) {
|
||||
t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount)
|
||||
}
|
||||
decEntry, err := data.DecryptHistoryEntry("key", *dbEntry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !data.EntryEquals(decEntry, entry) {
|
||||
t.Fatalf("DB data is different than input! \ndb =%#v\ninput=%#v", *dbEntry, entry)
|
||||
}
|
||||
@ -78,8 +79,8 @@ func TestESubmitThenQuery(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
shared.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
testutils.Check(t, err)
|
||||
testutils.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
if len(retrievedEntries) != 1 {
|
||||
t.Fatalf("Expected to retrieve 1 entry, found %d", len(retrievedEntries))
|
||||
}
|
||||
@ -94,7 +95,7 @@ func TestESubmitThenQuery(t *testing.T) {
|
||||
t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount)
|
||||
}
|
||||
decEntry, err = data.DecryptHistoryEntry("key", *dbEntry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !data.EntryEquals(decEntry, entry) {
|
||||
t.Fatalf("DB data is different than input! \ndb =%#v\ninput=%#v", *dbEntry, entry)
|
||||
}
|
||||
@ -106,8 +107,8 @@ func TestESubmitThenQuery(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
shared.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
testutils.Check(t, err)
|
||||
testutils.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
if len(retrievedEntries) != 2 {
|
||||
t.Fatalf("Expected to retrieve 2 entries, found %d", len(retrievedEntries))
|
||||
}
|
||||
@ -139,9 +140,9 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res := w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err := ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
var dumpRequests []*shared.DumpRequest
|
||||
shared.Check(t, json.Unmarshal(respBody, &dumpRequests))
|
||||
testutils.Check(t, json.Unmarshal(respBody, &dumpRequests))
|
||||
if len(dumpRequests) != 1 {
|
||||
t.Fatalf("expected one pending dump request, got %#v", dumpRequests)
|
||||
}
|
||||
@ -159,9 +160,9 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
dumpRequests = make([]*shared.DumpRequest, 0)
|
||||
shared.Check(t, json.Unmarshal(respBody, &dumpRequests))
|
||||
testutils.Check(t, json.Unmarshal(respBody, &dumpRequests))
|
||||
if len(dumpRequests) != 1 {
|
||||
t.Fatalf("expected one pending dump request, got %#v", dumpRequests)
|
||||
}
|
||||
@ -179,7 +180,7 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if string(respBody) != "[]" {
|
||||
t.Fatalf("got unexpected respBody: %#v", string(respBody))
|
||||
}
|
||||
@ -190,20 +191,20 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if string(respBody) != "[]" {
|
||||
t.Fatalf("got unexpected respBody: %#v", string(respBody))
|
||||
}
|
||||
|
||||
// Now submit a dump for userId
|
||||
entry1Dec := data.MakeFakeHistoryEntry("ls ~/")
|
||||
entry1Dec := testutils.MakeFakeHistoryEntry("ls ~/")
|
||||
entry1, err := data.EncryptHistoryEntry("dkey", entry1Dec)
|
||||
shared.Check(t, err)
|
||||
entry2Dec := data.MakeFakeHistoryEntry("aaaaaaáaaa")
|
||||
testutils.Check(t, err)
|
||||
entry2Dec := testutils.MakeFakeHistoryEntry("aaaaaaáaaa")
|
||||
entry2, err := data.EncryptHistoryEntry("dkey", entry1Dec)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
reqBody, err := json.Marshal([]shared.EncHistoryEntry{entry1, entry2})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
submitReq := httptest.NewRequest(http.MethodPost, "/?user_id="+userId+"&requesting_device_id="+devId2+"&source_device_id="+devId1, bytes.NewReader(reqBody))
|
||||
apiSubmitDumpHandler(nil, submitReq)
|
||||
|
||||
@ -213,7 +214,7 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if string(respBody) != "[]" {
|
||||
t.Fatalf("got unexpected respBody: %#v", string(respBody))
|
||||
}
|
||||
@ -223,7 +224,7 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if string(respBody) != "[]" {
|
||||
t.Fatalf("got unexpected respBody: %#v", string(respBody))
|
||||
}
|
||||
@ -234,9 +235,9 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
dumpRequests = make([]*shared.DumpRequest, 0)
|
||||
shared.Check(t, json.Unmarshal(respBody, &dumpRequests))
|
||||
testutils.Check(t, json.Unmarshal(respBody, &dumpRequests))
|
||||
if len(dumpRequests) != 1 {
|
||||
t.Fatalf("expected one pending dump request, got %#v", dumpRequests)
|
||||
}
|
||||
@ -255,9 +256,9 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
var retrievedEntries []*shared.EncHistoryEntry
|
||||
shared.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
testutils.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
if len(retrievedEntries) != 2 {
|
||||
t.Fatalf("Expected to retrieve 2 entries, found %d", len(retrievedEntries))
|
||||
}
|
||||
@ -272,7 +273,7 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount)
|
||||
}
|
||||
decEntry, err := data.DecryptHistoryEntry("dkey", *dbEntry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !data.EntryEquals(decEntry, entry1Dec) && !data.EntryEquals(decEntry, entry2Dec) {
|
||||
t.Fatalf("DB data is different than input! \ndb =%#v\nentry1=%#v\nentry2=%#v", *dbEntry, entry1Dec, entry2Dec)
|
||||
}
|
||||
@ -280,7 +281,7 @@ func TestDumpRequestAndResponse(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUpdateReleaseVersion(t *testing.T) {
|
||||
if !shared.IsOnline() {
|
||||
if !testutils.IsOnline() {
|
||||
t.Skip("skipping because we're currently offline")
|
||||
}
|
||||
|
||||
@ -329,33 +330,33 @@ func TestDeletionRequests(t *testing.T) {
|
||||
apiRegisterHandler(nil, deviceReq)
|
||||
|
||||
// Add an entry for user1
|
||||
entry1 := data.MakeFakeHistoryEntry("ls ~/")
|
||||
entry1 := testutils.MakeFakeHistoryEntry("ls ~/")
|
||||
entry1.DeviceId = devId1
|
||||
encEntry, err := data.EncryptHistoryEntry("dkey", entry1)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
reqBody, err := json.Marshal([]shared.EncHistoryEntry{encEntry})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
submitReq := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(reqBody))
|
||||
apiSubmitHandler(nil, submitReq)
|
||||
|
||||
// And another entry for user1
|
||||
entry2 := data.MakeFakeHistoryEntry("ls /foo/bar")
|
||||
entry2 := testutils.MakeFakeHistoryEntry("ls /foo/bar")
|
||||
entry2.DeviceId = devId2
|
||||
encEntry, err = data.EncryptHistoryEntry("dkey", entry2)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
reqBody, err = json.Marshal([]shared.EncHistoryEntry{encEntry})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
submitReq = httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(reqBody))
|
||||
apiSubmitHandler(nil, submitReq)
|
||||
|
||||
// And an entry for user2 that has the same timestamp as the previous entry
|
||||
entry3 := data.MakeFakeHistoryEntry("ls /foo/bar")
|
||||
entry3 := testutils.MakeFakeHistoryEntry("ls /foo/bar")
|
||||
entry3.StartTime = entry1.StartTime
|
||||
entry3.EndTime = entry1.EndTime
|
||||
encEntry, err = data.EncryptHistoryEntry("dOtherkey", entry3)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
reqBody, err = json.Marshal([]shared.EncHistoryEntry{encEntry})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
submitReq = httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(reqBody))
|
||||
apiSubmitHandler(nil, submitReq)
|
||||
|
||||
@ -366,9 +367,9 @@ func TestDeletionRequests(t *testing.T) {
|
||||
res := w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err := ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
var retrievedEntries []*shared.EncHistoryEntry
|
||||
shared.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
testutils.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
if len(retrievedEntries) != 2 {
|
||||
t.Fatalf("Expected to retrieve 1 entry, found %d", len(retrievedEntries))
|
||||
}
|
||||
@ -383,7 +384,7 @@ func TestDeletionRequests(t *testing.T) {
|
||||
t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount)
|
||||
}
|
||||
decEntry, err := data.DecryptHistoryEntry("dkey", *dbEntry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !data.EntryEquals(decEntry, entry1) && !data.EntryEquals(decEntry, entry2) {
|
||||
t.Fatalf("DB data is different than input! \ndb =%#v\nentry1=%#v\nentry2=%#v", *dbEntry, entry1, entry2)
|
||||
}
|
||||
@ -399,7 +400,7 @@ func TestDeletionRequests(t *testing.T) {
|
||||
}},
|
||||
}
|
||||
reqBody, err = json.Marshal(delReq)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader(reqBody))
|
||||
addDeletionRequestHandler(nil, req)
|
||||
|
||||
@ -410,8 +411,8 @@ func TestDeletionRequests(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
shared.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
testutils.Check(t, err)
|
||||
testutils.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
if len(retrievedEntries) != 1 {
|
||||
t.Fatalf("Expected to retrieve 1 entry, found %d", len(retrievedEntries))
|
||||
}
|
||||
@ -426,7 +427,7 @@ func TestDeletionRequests(t *testing.T) {
|
||||
t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount)
|
||||
}
|
||||
decEntry, err := data.DecryptHistoryEntry("dkey", *dbEntry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !data.EntryEquals(decEntry, entry2) {
|
||||
t.Fatalf("DB data is different than input! \ndb =%#v\nentry=%#v", *dbEntry, entry2)
|
||||
}
|
||||
@ -438,8 +439,8 @@ func TestDeletionRequests(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
shared.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
testutils.Check(t, err)
|
||||
testutils.Check(t, json.Unmarshal(respBody, &retrievedEntries))
|
||||
if len(retrievedEntries) != 1 {
|
||||
t.Fatalf("Expected to retrieve 1 entry, found %d", len(retrievedEntries))
|
||||
}
|
||||
@ -454,7 +455,7 @@ func TestDeletionRequests(t *testing.T) {
|
||||
t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount)
|
||||
}
|
||||
decEntry, err = data.DecryptHistoryEntry("dOtherkey", *dbEntry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !data.EntryEquals(decEntry, entry3) {
|
||||
t.Fatalf("DB data is different than input! \ndb =%#v\nentry=%#v", *dbEntry, entry3)
|
||||
}
|
||||
@ -466,9 +467,9 @@ func TestDeletionRequests(t *testing.T) {
|
||||
res = w.Result()
|
||||
defer res.Body.Close()
|
||||
respBody, err = ioutil.ReadAll(res.Body)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
var deletionRequests []*shared.DeletionRequest
|
||||
shared.Check(t, json.Unmarshal(respBody, &deletionRequests))
|
||||
testutils.Check(t, json.Unmarshal(respBody, &deletionRequests))
|
||||
if len(deletionRequests) != 1 {
|
||||
t.Fatalf("received %d deletion requests, expected only one", len(deletionRequests))
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/ddworken/hishtory/client/hctx"
|
||||
"github.com/ddworken/hishtory/client/lib"
|
||||
"github.com/ddworken/hishtory/shared"
|
||||
"github.com/ddworken/hishtory/shared/testutils"
|
||||
)
|
||||
|
||||
func skipSlowTests() bool {
|
||||
@ -29,7 +30,7 @@ func skipSlowTests() bool {
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
defer shared.RunTestServer()()
|
||||
defer testutils.RunTestServer()()
|
||||
cmd := exec.Command("go", "build", "-o", "/tmp/client")
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
|
||||
@ -154,7 +155,7 @@ func TestParameterized(t *testing.T) {
|
||||
|
||||
func testIntegration(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Run the test
|
||||
testBasicUserFlow(t, tester)
|
||||
@ -162,13 +163,13 @@ func testIntegration(t *testing.T, tester shellTester) {
|
||||
|
||||
func testIntegrationWithNewDevice(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Run the test
|
||||
userSecret := testBasicUserFlow(t, tester)
|
||||
|
||||
// Clear all local state
|
||||
shared.ResetLocalState(t)
|
||||
testutils.ResetLocalState(t)
|
||||
|
||||
// Install it again
|
||||
installHishtory(t, tester, userSecret)
|
||||
@ -195,7 +196,7 @@ func testIntegrationWithNewDevice(t *testing.T, tester shellTester) {
|
||||
}
|
||||
|
||||
// Clear local state again
|
||||
shared.ResetLocalState(t)
|
||||
testutils.ResetLocalState(t)
|
||||
|
||||
// Install it a 3rd time
|
||||
installHishtory(t, tester, "adifferentsecret")
|
||||
@ -209,7 +210,7 @@ func testIntegrationWithNewDevice(t *testing.T, tester shellTester) {
|
||||
|
||||
// Set the secret key to the previous secret key
|
||||
out, err := tester.RunInteractiveShellRelaxed(t, `yes | hishtory init `+userSecret)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !strings.Contains(out, "Setting secret hishtory key to "+userSecret) {
|
||||
t.Fatalf("Failed to re-init with the user secret: %v", out)
|
||||
}
|
||||
@ -241,7 +242,7 @@ func testIntegrationWithNewDevice(t *testing.T, tester shellTester) {
|
||||
|
||||
// Manually submit an event that isn't in the local DB, and then we'll
|
||||
// check if we see it when we do a query without ever having done an init
|
||||
newEntry := data.MakeFakeHistoryEntry("othercomputer")
|
||||
newEntry := testutils.MakeFakeHistoryEntry("othercomputer")
|
||||
newEntry.StartTime = time.Now()
|
||||
newEntry.EndTime = time.Now()
|
||||
manuallySubmitHistoryEntry(t, userSecret, newEntry)
|
||||
@ -292,7 +293,7 @@ func testBasicUserFlow(t *testing.T, tester shellTester) string {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get homedir: %v", err)
|
||||
}
|
||||
dat, err := os.ReadFile(path.Join(homedir, shared.HISHTORY_PATH, "config.sh"))
|
||||
dat, err := os.ReadFile(path.Join(homedir, data.HISHTORY_PATH, "config.sh"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read config.sh: %v", err)
|
||||
}
|
||||
@ -348,22 +349,22 @@ echo thisisrecorded`)
|
||||
line2Matcher := hostnameMatcher + tableDividerMatcher + pathMatcher + tableDividerMatcher + datetimeMatcher + tableDividerMatcher + runtimeMatcher + tableDividerMatcher + exitCodeMatcher + tableDividerMatcher + pipefailMatcher + tableDividerMatcher + `\n`
|
||||
line3Matcher := hostnameMatcher + tableDividerMatcher + pathMatcher + tableDividerMatcher + datetimeMatcher + tableDividerMatcher + runtimeMatcher + tableDividerMatcher + exitCodeMatcher + tableDividerMatcher + `echo thisisrecorded` + tableDividerMatcher + `\n`
|
||||
match, err := regexp.MatchString(line3Matcher, out)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !match {
|
||||
t.Fatalf("output is missing the row for `echo thisisrecorded`: %v", out)
|
||||
}
|
||||
match, err = regexp.MatchString(line1Matcher, out)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !match {
|
||||
t.Fatalf("output is missing the headings: %v", out)
|
||||
}
|
||||
match, err = regexp.MatchString(line2Matcher, out)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !match {
|
||||
t.Fatalf("output is missing the pipefail: %v", out)
|
||||
}
|
||||
match, err = regexp.MatchString(line1Matcher+line2Matcher+line3Matcher, out)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if !match {
|
||||
t.Fatalf("output doesn't match the expected table: %v", out)
|
||||
}
|
||||
@ -404,7 +405,7 @@ echo thisisrecorded`)
|
||||
|
||||
func testAdvancedQuery(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Install hishtory
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
@ -514,7 +515,7 @@ hishtory disable`)
|
||||
}
|
||||
|
||||
// Manually submit an entry with a different hostname and username so we can test those atoms
|
||||
entry := data.MakeFakeHistoryEntry("cmd_with_diff_hostname_and_username")
|
||||
entry := testutils.MakeFakeHistoryEntry("cmd_with_diff_hostname_and_username")
|
||||
entry.LocalUsername = "otheruser"
|
||||
entry.Hostname = "otherhostname"
|
||||
manuallySubmitHistoryEntry(t, userSecret, entry)
|
||||
@ -575,7 +576,7 @@ hishtory disable`)
|
||||
}
|
||||
|
||||
// Test filtering out a search item that also looks like it could be a search for a flag
|
||||
entry = data.MakeFakeHistoryEntry("foo -echo")
|
||||
entry = testutils.MakeFakeHistoryEntry("foo -echo")
|
||||
manuallySubmitHistoryEntry(t, userSecret, entry)
|
||||
out = hishtoryQuery(t, tester, `-echo -install`)
|
||||
if strings.Contains(out, "echo") {
|
||||
@ -586,7 +587,7 @@ hishtory disable`)
|
||||
}
|
||||
|
||||
// Search for a cwd based on the home directory
|
||||
entry = data.MakeFakeHistoryEntry("foobar")
|
||||
entry = testutils.MakeFakeHistoryEntry("foobar")
|
||||
entry.HomeDirectory = "/home/david/"
|
||||
entry.CurrentWorkingDirectory = "~/dir/"
|
||||
manuallySubmitHistoryEntry(t, userSecret, entry)
|
||||
@ -605,7 +606,7 @@ hishtory disable`)
|
||||
}
|
||||
|
||||
func testUpdate(t *testing.T, tester shellTester) {
|
||||
if !shared.IsOnline() {
|
||||
if !testutils.IsOnline() {
|
||||
t.Skip("skipping because we're currently offline")
|
||||
}
|
||||
if runtime.GOOS == "linux" && runtime.GOARCH == "arm64" {
|
||||
@ -615,7 +616,7 @@ func testUpdate(t *testing.T, tester shellTester) {
|
||||
t.Skip("skipping slow tests")
|
||||
}
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
|
||||
// Record a command before the update
|
||||
@ -662,7 +663,7 @@ func testUpdate(t *testing.T, tester shellTester) {
|
||||
|
||||
func testRepeatedCommandThenQuery(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
|
||||
// Check the status command
|
||||
@ -701,7 +702,7 @@ echo mycommand-3`)
|
||||
|
||||
func testRepeatedCommandAndQuery(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
|
||||
// Check the status command
|
||||
@ -726,7 +727,7 @@ func testRepeatedCommandAndQuery(t *testing.T, tester shellTester) {
|
||||
|
||||
func testRepeatedEnableDisable(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Run a command many times
|
||||
@ -758,7 +759,7 @@ hishtory enable`, i))
|
||||
|
||||
func testExcludeHiddenCommand(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
tester.RunInteractiveShell(t, `echo hello1
|
||||
@ -829,14 +830,14 @@ func hishtoryQuery(t *testing.T, tester shellTester, query string) string {
|
||||
|
||||
func manuallySubmitHistoryEntry(t *testing.T, userSecret string, entry data.HistoryEntry) {
|
||||
encEntry, err := data.EncryptHistoryEntry(userSecret, entry)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if encEntry.Date != entry.EndTime {
|
||||
t.Fatalf("encEntry.Date does not match the entry")
|
||||
}
|
||||
jsonValue, err := json.Marshal([]shared.EncHistoryEntry{encEntry})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
resp, err := http.Post("http://localhost:8080/api/v1/submit", "application/json", bytes.NewBuffer(jsonValue))
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if resp.StatusCode != 200 {
|
||||
t.Fatalf("failed to submit result to backend, status_code=%d", resp.StatusCode)
|
||||
}
|
||||
@ -844,7 +845,7 @@ func manuallySubmitHistoryEntry(t *testing.T, userSecret string, entry data.Hist
|
||||
|
||||
func testTimestampsAreReasonablyCorrect(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Record a command
|
||||
@ -866,7 +867,7 @@ func testTimestampsAreReasonablyCorrect(t *testing.T, tester shellTester) {
|
||||
|
||||
func testTableDisplayCwd(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Record a command
|
||||
@ -901,11 +902,11 @@ func testHishtoryBackgroundSaving(t *testing.T, tester shellTester) {
|
||||
}
|
||||
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Check that we can find the go binary
|
||||
_, err := exec.LookPath("go")
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
|
||||
// Test install with an unset HISHTORY_TEST var so that we save in the background (this is likely to be flakey!)
|
||||
out := tester.RunInteractiveShell(t, `unset HISHTORY_TEST
|
||||
@ -923,7 +924,7 @@ CGO_ENABLED=0 go build -o /tmp/client
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get homedir: %v", err)
|
||||
}
|
||||
dat, err := os.ReadFile(path.Join(homedir, shared.HISHTORY_PATH, "config.sh"))
|
||||
dat, err := os.ReadFile(path.Join(homedir, data.HISHTORY_PATH, "config.sh"))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read config.sh: %v", err)
|
||||
}
|
||||
@ -971,7 +972,7 @@ echo foo`)
|
||||
|
||||
func testDisplayTable(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
|
||||
// Submit two fake entries
|
||||
@ -979,11 +980,11 @@ func testDisplayTable(t *testing.T, tester shellTester) {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to load timezone: %v", err)
|
||||
}
|
||||
entry1 := data.MakeFakeHistoryEntry("table_cmd1")
|
||||
entry1 := testutils.MakeFakeHistoryEntry("table_cmd1")
|
||||
entry1.StartTime = time.Unix(1650096186, 0).In(tmz)
|
||||
entry1.EndTime = time.Unix(1650096190, 0).In(tmz)
|
||||
manuallySubmitHistoryEntry(t, userSecret, entry1)
|
||||
entry2 := data.MakeFakeHistoryEntry("table_cmd2")
|
||||
entry2 := testutils.MakeFakeHistoryEntry("table_cmd2")
|
||||
entry2.StartTime = time.Unix(1650096196, 0).In(tmz)
|
||||
entry2.EndTime = time.Unix(1650096220, 0).In(tmz)
|
||||
entry2.CurrentWorkingDirectory = "~/foo/"
|
||||
@ -1005,7 +1006,7 @@ func testDisplayTable(t *testing.T, tester shellTester) {
|
||||
|
||||
func testRequestAndReceiveDbDump(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
secretKey := installHishtory(t, tester, "")
|
||||
|
||||
// Confirm there are no pending dump requests
|
||||
@ -1039,7 +1040,7 @@ echo other`)
|
||||
}
|
||||
|
||||
// Back up this copy
|
||||
restoreFirstInstallation := shared.BackupAndRestoreWithId(t, "-install1")
|
||||
restoreFirstInstallation := testutils.BackupAndRestoreWithId(t, "-install1")
|
||||
|
||||
// Wipe the DB to simulate entries getting deleted because they've already been read and expired
|
||||
_, err = lib.ApiGet("/api/v1/wipe-db")
|
||||
@ -1073,7 +1074,7 @@ echo other`)
|
||||
}
|
||||
|
||||
// Restore the first copy
|
||||
restoreSecondInstallation := shared.BackupAndRestoreWithId(t, "-install2")
|
||||
restoreSecondInstallation := testutils.BackupAndRestoreWithId(t, "-install2")
|
||||
restoreFirstInstallation()
|
||||
|
||||
// Confirm it still has the correct entries via hishtory export (and this runs a command to trigger it to dump the DB)
|
||||
@ -1118,8 +1119,8 @@ echo other`)
|
||||
|
||||
func testInstallViaPythonScript(t *testing.T, tester shellTester) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer shared.BackupAndRestoreEnv("HISHTORY_TEST")()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestoreEnv("HISHTORY_TEST")()
|
||||
|
||||
// Install via the python script
|
||||
out := tester.RunInteractiveShell(t, `curl https://hishtory.dev/install.py | python3 -`)
|
||||
@ -1154,7 +1155,7 @@ func testInstallViaPythonScript(t *testing.T, tester shellTester) {
|
||||
|
||||
func testExportWithQuery(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Test recording commands
|
||||
@ -1220,7 +1221,7 @@ sleep 1`)
|
||||
|
||||
func testHelpCommand(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Test the help command
|
||||
@ -1240,7 +1241,7 @@ func testStripBashTimePrefix(t *testing.T, tester shellTester) {
|
||||
}
|
||||
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Add a HISTTIMEFORMAT to the bashrc
|
||||
@ -1296,13 +1297,13 @@ func testStripBashTimePrefix(t *testing.T, tester shellTester) {
|
||||
|
||||
func testReuploadHistoryEntries(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Init an initial device
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
|
||||
// Set up a second device
|
||||
restoreFirstProfile := shared.BackupAndRestoreWithId(t, "-install1")
|
||||
restoreFirstProfile := testutils.BackupAndRestoreWithId(t, "-install1")
|
||||
installHishtory(t, tester, userSecret)
|
||||
|
||||
// Device 2: Record a command
|
||||
@ -1312,7 +1313,7 @@ func testReuploadHistoryEntries(t *testing.T, tester shellTester) {
|
||||
tester.RunInteractiveShell(t, `echo 2; export HISHTORY_SIMULATE_NETWORK_ERROR=1; echo 3`)
|
||||
|
||||
// Device 1: Run an export and confirm that the network only contains the first command
|
||||
restoreSecondProfile := shared.BackupAndRestoreWithId(t, "-install2")
|
||||
restoreSecondProfile := testutils.BackupAndRestoreWithId(t, "-install2")
|
||||
restoreFirstProfile()
|
||||
out := tester.RunInteractiveShell(t, "hishtory export | grep -v pipefail")
|
||||
expectedOutput := "echo 1\n"
|
||||
@ -1321,7 +1322,7 @@ func testReuploadHistoryEntries(t *testing.T, tester shellTester) {
|
||||
}
|
||||
|
||||
// Device 2: Run another command but with the network re-enabled
|
||||
restoreFirstProfile = shared.BackupAndRestoreWithId(t, "-install1")
|
||||
restoreFirstProfile = testutils.BackupAndRestoreWithId(t, "-install1")
|
||||
restoreSecondProfile()
|
||||
tester.RunInteractiveShell(t, `unset HISHTORY_SIMULATE_NETWORK_ERROR; echo 4`)
|
||||
|
||||
@ -1343,20 +1344,20 @@ func testReuploadHistoryEntries(t *testing.T, tester shellTester) {
|
||||
|
||||
func testHishtoryOffline(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Init an initial device
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
|
||||
// Set up a second device
|
||||
restoreFirstProfile := shared.BackupAndRestoreWithId(t, "-install1")
|
||||
restoreFirstProfile := testutils.BackupAndRestoreWithId(t, "-install1")
|
||||
installHishtory(t, tester, userSecret)
|
||||
|
||||
// Device 2: Record a command
|
||||
tester.RunInteractiveShell(t, `echo dev2`)
|
||||
|
||||
// Device 1: Run a command
|
||||
restoreSecondProfile := shared.BackupAndRestoreWithId(t, "-install2")
|
||||
restoreSecondProfile := testutils.BackupAndRestoreWithId(t, "-install2")
|
||||
restoreFirstProfile()
|
||||
tester.RunInteractiveShell(t, `echo dev1-a`)
|
||||
|
||||
@ -1368,7 +1369,7 @@ func testHishtoryOffline(t *testing.T, tester shellTester) {
|
||||
}
|
||||
|
||||
// Device 2: Record another command
|
||||
restoreFirstProfile = shared.BackupAndRestoreWithId(t, "-install1")
|
||||
restoreFirstProfile = testutils.BackupAndRestoreWithId(t, "-install1")
|
||||
restoreSecondProfile()
|
||||
tester.RunInteractiveShell(t, `echo dev2-b`)
|
||||
|
||||
@ -1390,7 +1391,7 @@ func testHishtoryOffline(t *testing.T, tester shellTester) {
|
||||
|
||||
func testInitialHistoryImport(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Record some commands before installing hishtory
|
||||
randomCmdUuid := uuid.Must(uuid.NewRandom()).String()
|
||||
@ -1440,7 +1441,7 @@ echo %v-bar`, randomCmdUuid, randomCmdUuid)
|
||||
|
||||
func testLocalRedaction(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Install hishtory
|
||||
installHishtory(t, tester, "")
|
||||
@ -1496,7 +1497,7 @@ ls /tmp`, randomCmdUuid, randomCmdUuid)
|
||||
|
||||
// Redact it without --force
|
||||
out, err := tester.RunInteractiveShellRelaxed(t, `yes | hishtory redact hello`)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if out != "This will permanently delete 1 entries, are you sure? [y/N]" {
|
||||
t.Fatalf("hishtory redact gave unexpected output=%#v", out)
|
||||
}
|
||||
@ -1511,7 +1512,7 @@ ls /tmp`, randomCmdUuid, randomCmdUuid)
|
||||
|
||||
func testRemoteRedaction(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Install hishtory client 1
|
||||
userSecret := installHishtory(t, tester, "")
|
||||
@ -1532,7 +1533,7 @@ ls /tmp`, randomCmdUuid, randomCmdUuid)
|
||||
}
|
||||
|
||||
// Install hishtory client 2
|
||||
restoreInstall1 := shared.BackupAndRestoreWithId(t, "-1")
|
||||
restoreInstall1 := testutils.BackupAndRestoreWithId(t, "-1")
|
||||
installHishtory(t, tester, userSecret)
|
||||
|
||||
// And confirm that it has the commands too
|
||||
@ -1542,7 +1543,7 @@ ls /tmp`, randomCmdUuid, randomCmdUuid)
|
||||
}
|
||||
|
||||
// Restore the first client, and redact some commands
|
||||
restoreInstall2 := shared.BackupAndRestoreWithId(t, "-2")
|
||||
restoreInstall2 := testutils.BackupAndRestoreWithId(t, "-2")
|
||||
restoreInstall1()
|
||||
out = tester.RunInteractiveShell(t, `hishtory redact --force `+randomCmdUuid)
|
||||
if out != "Permanently deleting 2 entries\n" {
|
||||
@ -1566,7 +1567,7 @@ ls /tmp`, randomCmdUuid, randomCmdUuid)
|
||||
|
||||
func testConfigGetSet(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Initially is true
|
||||
@ -1592,24 +1593,24 @@ func testConfigGetSet(t *testing.T, tester shellTester) {
|
||||
|
||||
func clearControlRSearchFromConfig(t *testing.T) {
|
||||
configContents, err := hctx.GetConfigContents()
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
configContents = []byte(strings.ReplaceAll(string(configContents), "enable_control_r_search", "something-else"))
|
||||
homedir, err := os.UserHomeDir()
|
||||
shared.Check(t, err)
|
||||
err = os.WriteFile(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH), configContents, 0o644)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
err = os.WriteFile(path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH), configContents, 0o644)
|
||||
testutils.Check(t, err)
|
||||
}
|
||||
|
||||
func testHandleUpgradedFeatures(t *testing.T, tester shellTester) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Install, and there is no prompt since the config already mentions control-r
|
||||
_, err := tester.RunInteractiveShellRelaxed(t, `/tmp/client install`)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
_, err = tester.RunInteractiveShellRelaxed(t, `hishtory disable`)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
|
||||
// Ensure that the config doesn't mention control-r
|
||||
clearControlRSearchFromConfig(t)
|
||||
@ -1633,7 +1634,7 @@ func testHandleUpgradedFeatures(t *testing.T, tester shellTester) {
|
||||
|
||||
func TestFish(t *testing.T) {
|
||||
// Setup
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
tester := bashTester{}
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
@ -1680,7 +1681,7 @@ func compareGoldens(t *testing.T, out, goldenName string) {
|
||||
if os.IsNotExist(err) {
|
||||
expected = []byte{}
|
||||
} else {
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
}
|
||||
}
|
||||
if diff := cmp.Diff(string(expected), out); diff != "" {
|
||||
@ -1688,15 +1689,14 @@ func compareGoldens(t *testing.T, out, goldenName string) {
|
||||
_, filename, line, _ := runtime.Caller(1)
|
||||
t.Fatalf("hishtory golden mismatch at %s:%d (-expected +got):\n%s", filename, line, diff)
|
||||
} else {
|
||||
shared.Check(t, os.WriteFile(goldenPath, []byte(out), 0644))
|
||||
testutils.Check(t, os.WriteFile(goldenPath, []byte(out), 0644))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTui(t *testing.T) {
|
||||
// Setup
|
||||
data.ResetFakeHistoryTimestamp() // TODO: move this to backupandrestore
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
tester := zshTester{}
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
@ -1705,8 +1705,8 @@ func TestTui(t *testing.T) {
|
||||
|
||||
// Insert a couple hishtory entries
|
||||
db := hctx.GetDb(hctx.MakeContext())
|
||||
db.Create(data.MakeFakeHistoryEntry("ls ~/"))
|
||||
db.Create(data.MakeFakeHistoryEntry("echo 'aaaaaa bbbb'"))
|
||||
db.Create(testutils.MakeFakeHistoryEntry("ls ~/"))
|
||||
db.Create(testutils.MakeFakeHistoryEntry("echo 'aaaaaa bbbb'"))
|
||||
|
||||
// Check the initial output when there is no search
|
||||
out := captureTerminalOutput(t, tester, []string{"hishtory SPACE tquery ENTER"})
|
||||
@ -1775,8 +1775,7 @@ func testControlR(t *testing.T, tester shellTester, shellName string) {
|
||||
}
|
||||
|
||||
// Setup
|
||||
data.ResetFakeHistoryTimestamp() // TODO: move this to backupandrestore
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
installHishtory(t, tester, "")
|
||||
|
||||
// Disable recording so that all our testing commands don't get recorded
|
||||
@ -1785,15 +1784,15 @@ func testControlR(t *testing.T, tester shellTester, shellName string) {
|
||||
|
||||
// Insert a few hishtory entries
|
||||
db := hctx.GetDb(hctx.MakeContext())
|
||||
e1 := data.MakeFakeHistoryEntry("ls ~/")
|
||||
e1 := testutils.MakeFakeHistoryEntry("ls ~/")
|
||||
e1.CurrentWorkingDirectory = "/etc/"
|
||||
e1.Hostname = "server"
|
||||
e1.ExitCode = 127
|
||||
db.Create(e1)
|
||||
db.Create(data.MakeFakeHistoryEntry("ls ~/foo/"))
|
||||
db.Create(data.MakeFakeHistoryEntry("ls ~/bar/"))
|
||||
db.Create(data.MakeFakeHistoryEntry("echo 'aaaaaa bbbb'"))
|
||||
db.Create(data.MakeFakeHistoryEntry("echo 'bar' &"))
|
||||
db.Create(testutils.MakeFakeHistoryEntry("ls ~/foo/"))
|
||||
db.Create(testutils.MakeFakeHistoryEntry("ls ~/bar/"))
|
||||
db.Create(testutils.MakeFakeHistoryEntry("echo 'aaaaaa bbbb'"))
|
||||
db.Create(testutils.MakeFakeHistoryEntry("echo 'bar' &"))
|
||||
|
||||
// And check that the control-r binding brings up the search
|
||||
out := captureTerminalOutputWithShellName(t, tester, shellName, []string{"C-R"})
|
||||
@ -1878,8 +1877,8 @@ func createDevice(t *testing.T, tester shellTester, devices *deviceSet, key, dev
|
||||
}
|
||||
installHishtory(t, tester, key)
|
||||
(*devices.deviceMap)[d] = deviceOp{
|
||||
backup: func() { shared.BackupAndRestoreWithId(t, key+deviceId) },
|
||||
restore: shared.BackupAndRestoreWithId(t, key+deviceId),
|
||||
backup: func() { testutils.BackupAndRestoreWithId(t, key+deviceId) },
|
||||
restore: testutils.BackupAndRestoreWithId(t, key+deviceId),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1895,7 +1894,7 @@ func switchToDevice(devices *deviceSet, d device) {
|
||||
}
|
||||
|
||||
func testMultipleUsers(t *testing.T, tester shellTester) {
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
|
||||
// Create all our devices
|
||||
var deviceMap map[device]deviceOp = make(map[device]deviceOp)
|
||||
@ -1939,7 +1938,7 @@ func testMultipleUsers(t *testing.T, tester shellTester) {
|
||||
for i, d := range []device{u1d1, u1d2} {
|
||||
switchToDevice(&devices, d)
|
||||
out, err := tester.RunInteractiveShellRelaxed(t, `hishtory export`)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
expectedOutput := "echo u1d1\necho u1d2\necho u1d1-b\necho u1d1-c\necho u1d2-b\necho u1d2-c\n"
|
||||
for j := 0; j < i; j++ {
|
||||
expectedOutput += "hishtory export\n"
|
||||
@ -1961,7 +1960,7 @@ func testMultipleUsers(t *testing.T, tester shellTester) {
|
||||
for i, d := range []device{u2d1, u2d2, u2d3} {
|
||||
switchToDevice(&devices, d)
|
||||
out, err := tester.RunInteractiveShellRelaxed(t, `hishtory export`)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
expectedOutput := "echo u2d1\necho u2d2\necho u2d3\necho u1d1-b\necho u1d1-c\necho u2d3-b\necho u2d3-c\n"
|
||||
for j := 0; j < i; j++ {
|
||||
expectedOutput += "hishtory export\n"
|
||||
@ -2019,7 +2018,7 @@ func fuzzTest(t *testing.T, tester shellTester, input string) {
|
||||
}
|
||||
|
||||
// Set up and create the devices
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
var deviceMap map[device]deviceOp = make(map[device]deviceOp)
|
||||
var devices deviceSet = deviceSet{}
|
||||
devices.deviceMap = &deviceMap
|
||||
@ -2041,11 +2040,11 @@ func fuzzTest(t *testing.T, tester shellTester, input string) {
|
||||
switchToDevice(&devices, op.device)
|
||||
if op.cmd != "" {
|
||||
_, err := tester.RunInteractiveShellRelaxed(t, op.cmd)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
}
|
||||
if op.redactQuery != "" {
|
||||
_, err := tester.RunInteractiveShellRelaxed(t, `hishtory redact --force `+op.redactQuery)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
}
|
||||
|
||||
// Calculate the expected output of hishtory export
|
||||
@ -2073,7 +2072,7 @@ func fuzzTest(t *testing.T, tester shellTester, input string) {
|
||||
|
||||
// Run hishtory export and check the output
|
||||
out, err := tester.RunInteractiveShellRelaxed(t, `hishtory export | grep -v export`)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
expectedOutput := keyToCommands[op.device.key]
|
||||
if diff := cmp.Diff(expectedOutput, out); diff != "" {
|
||||
t.Fatalf("hishtory export mismatch for input=%#v key=%s (-expected +got):\n%s\nout=%#v", input, op.device.key, diff, out)
|
||||
@ -2084,7 +2083,7 @@ func fuzzTest(t *testing.T, tester shellTester, input string) {
|
||||
for _, op := range ops {
|
||||
switchToDevice(&devices, op.device)
|
||||
out, err := tester.RunInteractiveShellRelaxed(t, `hishtory export | grep -v export`)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
expectedOutput := keyToCommands[op.device.key]
|
||||
if diff := cmp.Diff(expectedOutput, out); diff != "" {
|
||||
t.Fatalf("hishtory export mismatch for key=%s (-expected +got):\n%s\nout=%#v", op.device.key, diff, out)
|
||||
|
@ -268,24 +268,8 @@ func EntryEquals(entry1, entry2 HistoryEntry) bool {
|
||||
entry1.EndTime.Format(time.RFC3339) == entry2.EndTime.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
// TODO: move this code to testutils
|
||||
|
||||
var fakeHistoryTimestamp int64 = 1666068191
|
||||
|
||||
func ResetFakeHistoryTimestamp() {
|
||||
fakeHistoryTimestamp = 1666068191
|
||||
}
|
||||
|
||||
func MakeFakeHistoryEntry(command string) HistoryEntry {
|
||||
fakeHistoryTimestamp += 5
|
||||
return HistoryEntry{
|
||||
LocalUsername: "david",
|
||||
Hostname: "localhost",
|
||||
Command: command,
|
||||
CurrentWorkingDirectory: "/tmp/",
|
||||
HomeDirectory: "/home/david/",
|
||||
ExitCode: 2,
|
||||
StartTime: time.Unix(fakeHistoryTimestamp, 0),
|
||||
EndTime: time.Unix(fakeHistoryTimestamp+3, 0),
|
||||
}
|
||||
}
|
||||
const (
|
||||
CONFIG_PATH = ".hishtory.config"
|
||||
HISHTORY_PATH = ".hishtory"
|
||||
DB_PATH = ".hishtory.db"
|
||||
)
|
||||
|
@ -3,8 +3,6 @@ package data
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ddworken/hishtory/shared"
|
||||
)
|
||||
|
||||
func TestEncryptDecrypt(t *testing.T) {
|
||||
@ -15,9 +13,9 @@ func TestEncryptDecrypt(t *testing.T) {
|
||||
}
|
||||
|
||||
ciphertext, nonce, err := Encrypt("key", []byte("hello world!"), []byte("extra"))
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
plaintext, err := Decrypt("key", ciphertext, []byte("extra"), nonce)
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if string(plaintext) != "hello world!" {
|
||||
t.Fatalf("Expected decrypt(encrypt(x)) to work, but it didn't!")
|
||||
}
|
||||
@ -25,62 +23,70 @@ func TestEncryptDecrypt(t *testing.T) {
|
||||
|
||||
func TestParseTimeGenerously(t *testing.T) {
|
||||
ts, err := parseTimeGenerously("2006-01-02T15:04:00-08:00")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Unix() != 1136243040 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02 T15:04:00 -08:00")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Unix() != 1136243040 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02_T15:04:00_-08:00")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Unix() != 1136243040 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02T15:04:00")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Year() != 2006 || ts.Month() != time.January || ts.Day() != 2 || ts.Hour() != 15 || ts.Minute() != 4 || ts.Second() != 0 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02_T15:04:00")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Year() != 2006 || ts.Month() != time.January || ts.Day() != 2 || ts.Hour() != 15 || ts.Minute() != 4 || ts.Second() != 0 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02_15:04:00")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Year() != 2006 || ts.Month() != time.January || ts.Day() != 2 || ts.Hour() != 15 || ts.Minute() != 4 || ts.Second() != 0 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02T15:04")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Year() != 2006 || ts.Month() != time.January || ts.Day() != 2 || ts.Hour() != 15 || ts.Minute() != 4 || ts.Second() != 0 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02_15:04")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Year() != 2006 || ts.Month() != time.January || ts.Day() != 2 || ts.Hour() != 15 || ts.Minute() != 4 || ts.Second() != 0 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
ts, err = parseTimeGenerously("2006-01-02")
|
||||
shared.Check(t, err)
|
||||
checkError(t, err)
|
||||
if ts.Year() != 2006 || ts.Month() != time.January || ts.Day() != 2 || ts.Hour() != 0 || ts.Minute() != 0 || ts.Second() != 0 {
|
||||
t.Fatalf("parsed time incorrectly: %d", ts.Unix())
|
||||
}
|
||||
}
|
||||
|
||||
func checkError(t *testing.T, err error) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomColumnSerialization(t *testing.T) {
|
||||
// cc1 := CustomColumn{
|
||||
// Name: "name1",
|
||||
// Val: "val1",
|
||||
// }
|
||||
// cc2 := CustomColumn{
|
||||
// Name: "name2",
|
||||
// Val: "val2",
|
||||
// }
|
||||
cc1 := CustomColumn{
|
||||
Name: "name1",
|
||||
Val: "val1",
|
||||
}
|
||||
cc2 := CustomColumn{
|
||||
Name: "name2",
|
||||
Val: "val2",
|
||||
}
|
||||
var ccs CustomColumns = make(CustomColumns, 0)
|
||||
|
||||
// Empty array
|
||||
v, err := ccs.Value()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
@ -89,4 +95,16 @@ func TestCustomColumnSerialization(t *testing.T) {
|
||||
if val != "[]" {
|
||||
t.Fatalf("unexpected val for empty CustomColumns: %#v", val)
|
||||
}
|
||||
|
||||
// Non-empty array
|
||||
ccs = append(ccs, cc1, cc2)
|
||||
v, err = ccs.Value()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err: %v", err)
|
||||
}
|
||||
val = string(v.([]uint8))
|
||||
if val != "[{\"name\":\"name1\",\"value\":\"val1\"},{\"name\":\"name2\",\"value\":\"val2\"}]" {
|
||||
t.Fatalf("unexpected val for empty CustomColumns: %#v", val)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ddworken/hishtory/client/data"
|
||||
"github.com/ddworken/hishtory/shared"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
|
||||
@ -38,7 +37,7 @@ func GetLogger() *log.Logger {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f, err := os.OpenFile(path.Join(homedir, shared.HISHTORY_PATH, "hishtory.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o660)
|
||||
f, err := os.OpenFile(path.Join(homedir, data.HISHTORY_PATH, "hishtory.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o660)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to open hishtory.log: %v", err))
|
||||
}
|
||||
@ -53,7 +52,7 @@ func MakeHishtoryDir() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get user's home directory: %v", err)
|
||||
}
|
||||
err = os.MkdirAll(path.Join(homedir, shared.HISHTORY_PATH), 0o744)
|
||||
err = os.MkdirAll(path.Join(homedir, data.HISHTORY_PATH), 0o744)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create ~/.hishtory dir: %v", err)
|
||||
}
|
||||
@ -79,7 +78,7 @@ func OpenLocalSqliteDb() (*gorm.DB, error) {
|
||||
Colorful: false,
|
||||
},
|
||||
)
|
||||
db, err := gorm.Open(sqlite.Open(path.Join(homedir, shared.HISHTORY_PATH, shared.DB_PATH)), &gorm.Config{SkipDefaultTransaction: true, Logger: newLogger})
|
||||
db, err := gorm.Open(sqlite.Open(path.Join(homedir, data.HISHTORY_PATH, data.DB_PATH)), &gorm.Config{SkipDefaultTransaction: true, Logger: newLogger})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to the DB: %v", err)
|
||||
}
|
||||
@ -174,9 +173,9 @@ func GetConfigContents() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve homedir: %v", err)
|
||||
}
|
||||
data, err := os.ReadFile(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH))
|
||||
dat, err := os.ReadFile(path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH))
|
||||
if err != nil {
|
||||
files, err := ioutil.ReadDir(path.Join(homedir, shared.HISHTORY_PATH))
|
||||
files, err := ioutil.ReadDir(path.Join(homedir, data.HISHTORY_PATH))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read config file (and failed to list too): %v", err)
|
||||
}
|
||||
@ -187,7 +186,7 @@ func GetConfigContents() ([]byte, error) {
|
||||
}
|
||||
return nil, fmt.Errorf("failed to read config file (files in ~/.hishtory/: %s): %v", filenames, err)
|
||||
}
|
||||
return data, nil
|
||||
return dat, nil
|
||||
}
|
||||
|
||||
func GetConfig() (ClientConfig, error) {
|
||||
@ -219,7 +218,7 @@ func SetConfig(config ClientConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configPath := path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH)
|
||||
configPath := path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH)
|
||||
stagedConfigPath := configPath + ".tmp"
|
||||
err = os.WriteFile(stagedConfigPath, serializedConfig, 0o644)
|
||||
if err != nil {
|
||||
@ -237,7 +236,7 @@ func InitConfig() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = os.Stat(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH))
|
||||
_, err = os.Stat(path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH))
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return SetConfig(ClientConfig{})
|
||||
}
|
||||
|
@ -677,7 +677,7 @@ func configureFish(homedir, binaryPath string) error {
|
||||
return nil
|
||||
}
|
||||
// Create the file we're going to source. Do this no matter what in case there are updates to it.
|
||||
fishConfigPath := path.Join(homedir, shared.HISHTORY_PATH, "config.fish")
|
||||
fishConfigPath := path.Join(homedir, data.HISHTORY_PATH, "config.fish")
|
||||
configContents := ConfigFishContents
|
||||
if os.Getenv("HISHTORY_TEST") != "" {
|
||||
testConfig, err := tweakConfigForTests(ConfigFishContents)
|
||||
@ -708,7 +708,7 @@ func configureFish(homedir, binaryPath string) error {
|
||||
return fmt.Errorf("failed to append to ~/.config/fish/config.fish: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString("\n# Hishtory Config:\nexport PATH=\"$PATH:" + path.Join(homedir, shared.HISHTORY_PATH) + "\"\nsource " + fishConfigPath + "\n")
|
||||
_, err = f.WriteString("\n# Hishtory Config:\nexport PATH=\"$PATH:" + path.Join(homedir, data.HISHTORY_PATH) + "\"\nsource " + fishConfigPath + "\n")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to append to zshrc: %v", err)
|
||||
}
|
||||
@ -729,7 +729,7 @@ func isFishConfigured(homedir string) (bool, error) {
|
||||
|
||||
func configureZshrc(homedir, binaryPath string) error {
|
||||
// Create the file we're going to source in our zshrc. Do this no matter what in case there are updates to it.
|
||||
zshConfigPath := path.Join(homedir, shared.HISHTORY_PATH, "config.zsh")
|
||||
zshConfigPath := path.Join(homedir, data.HISHTORY_PATH, "config.zsh")
|
||||
configContents := ConfigZshContents
|
||||
if os.Getenv("HISHTORY_TEST") != "" {
|
||||
testConfig, err := tweakConfigForTests(configContents)
|
||||
@ -756,7 +756,7 @@ func configureZshrc(homedir, binaryPath string) error {
|
||||
return fmt.Errorf("failed to append to zshrc: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString("\n# Hishtory Config:\nexport PATH=\"$PATH:" + path.Join(homedir, shared.HISHTORY_PATH) + "\"\nsource " + zshConfigPath + "\n")
|
||||
_, err = f.WriteString("\n# Hishtory Config:\nexport PATH=\"$PATH:" + path.Join(homedir, data.HISHTORY_PATH) + "\"\nsource " + zshConfigPath + "\n")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to append to zshrc: %v", err)
|
||||
}
|
||||
@ -777,7 +777,7 @@ func isZshConfigured(homedir string) (bool, error) {
|
||||
|
||||
func configureBashrc(homedir, binaryPath string) error {
|
||||
// Create the file we're going to source in our bashrc. Do this no matter what in case there are updates to it.
|
||||
bashConfigPath := path.Join(homedir, shared.HISHTORY_PATH, "config.sh")
|
||||
bashConfigPath := path.Join(homedir, data.HISHTORY_PATH, "config.sh")
|
||||
configContents := ConfigShContents
|
||||
if os.Getenv("HISHTORY_TEST") != "" {
|
||||
testConfig, err := tweakConfigForTests(ConfigShContents)
|
||||
@ -804,7 +804,7 @@ func configureBashrc(homedir, binaryPath string) error {
|
||||
return fmt.Errorf("failed to append to bashrc: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.WriteString("\n# Hishtory Config:\nexport PATH=\"$PATH:" + path.Join(homedir, shared.HISHTORY_PATH) + "\"\nsource " + bashConfigPath + "\n")
|
||||
_, err = f.WriteString("\n# Hishtory Config:\nexport PATH=\"$PATH:" + path.Join(homedir, data.HISHTORY_PATH) + "\"\nsource " + bashConfigPath + "\n")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to append to bashrc: %v", err)
|
||||
}
|
||||
@ -826,7 +826,7 @@ func isBashConfigured(homedir string) (bool, error) {
|
||||
func installBinary(homedir string) (string, error) {
|
||||
clientPath, err := exec.LookPath("hishtory")
|
||||
if err != nil {
|
||||
clientPath = path.Join(homedir, shared.HISHTORY_PATH, "hishtory")
|
||||
clientPath = path.Join(homedir, data.HISHTORY_PATH, "hishtory")
|
||||
}
|
||||
if _, err := os.Stat(clientPath); err == nil {
|
||||
err = syscall.Unlink(clientPath)
|
||||
@ -919,9 +919,9 @@ func Update(ctx *context.Context) error {
|
||||
// Unlink the existing binary so we can overwrite it even though it is still running
|
||||
if runtime.GOOS == "linux" {
|
||||
homedir := hctx.GetHome(ctx)
|
||||
err = syscall.Unlink(path.Join(homedir, shared.HISHTORY_PATH, "hishtory"))
|
||||
err = syscall.Unlink(path.Join(homedir, data.HISHTORY_PATH, "hishtory"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unlink %s for update: %v", path.Join(homedir, shared.HISHTORY_PATH, "hishtory"), err)
|
||||
return fmt.Errorf("failed to unlink %s for update: %v", path.Join(homedir, data.HISHTORY_PATH, "hishtory"), err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,37 +11,37 @@ import (
|
||||
|
||||
"github.com/ddworken/hishtory/client/data"
|
||||
"github.com/ddworken/hishtory/client/hctx"
|
||||
"github.com/ddworken/hishtory/shared"
|
||||
"github.com/ddworken/hishtory/shared/testutils"
|
||||
)
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer shared.RunTestServer()()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
defer testutils.RunTestServer()()
|
||||
|
||||
homedir, err := os.UserHomeDir()
|
||||
shared.Check(t, err)
|
||||
if _, err := os.Stat(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH)); err == nil {
|
||||
testutils.Check(t, err)
|
||||
if _, err := os.Stat(path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH)); err == nil {
|
||||
t.Fatalf("hishtory secret file already exists!")
|
||||
}
|
||||
shared.Check(t, Setup([]string{}))
|
||||
if _, err := os.Stat(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH)); err != nil {
|
||||
testutils.Check(t, Setup([]string{}))
|
||||
if _, err := os.Stat(path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH)); err != nil {
|
||||
t.Fatalf("hishtory secret file does not exist after Setup()!")
|
||||
}
|
||||
data, err := os.ReadFile(path.Join(homedir, shared.HISHTORY_PATH, shared.CONFIG_PATH))
|
||||
shared.Check(t, err)
|
||||
data, err := os.ReadFile(path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH))
|
||||
testutils.Check(t, err)
|
||||
if len(data) < 10 {
|
||||
t.Fatalf("hishtory secret has unexpected length: %d", len(data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildHistoryEntry(t *testing.T) {
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer shared.RunTestServer()()
|
||||
shared.Check(t, Setup([]string{}))
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
defer testutils.RunTestServer()()
|
||||
testutils.Check(t, Setup([]string{}))
|
||||
|
||||
// Test building an actual entry for bash
|
||||
entry, err := BuildHistoryEntry(hctx.MakeContext(), []string{"unused", "saveHistoryEntry", "bash", "120", " 123 ls /foo ", "1641774958"})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if entry.ExitCode != 120 {
|
||||
t.Fatalf("history entry has unexpected exit code: %v", entry.ExitCode)
|
||||
}
|
||||
@ -70,7 +70,7 @@ func TestBuildHistoryEntry(t *testing.T) {
|
||||
|
||||
// Test building an entry for zsh
|
||||
entry, err = BuildHistoryEntry(hctx.MakeContext(), []string{"unused", "saveHistoryEntry", "zsh", "120", "ls /foo\n", "1641774958"})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if entry.ExitCode != 120 {
|
||||
t.Fatalf("history entry has unexpected exit code: %v", entry.ExitCode)
|
||||
}
|
||||
@ -95,7 +95,7 @@ func TestBuildHistoryEntry(t *testing.T) {
|
||||
|
||||
// Test building an entry for fish
|
||||
entry, err = BuildHistoryEntry(hctx.MakeContext(), []string{"unused", "saveHistoryEntry", "fish", "120", "ls /foo\n", "1641774958"})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if entry.ExitCode != 120 {
|
||||
t.Fatalf("history entry has unexpected exit code: %v", entry.ExitCode)
|
||||
}
|
||||
@ -120,17 +120,17 @@ func TestBuildHistoryEntry(t *testing.T) {
|
||||
|
||||
// Test building an entry that is empty, and thus not saved
|
||||
entry, err = BuildHistoryEntry(hctx.MakeContext(), []string{"unused", "saveHistoryEntry", "zsh", "120", " \n", "1641774958"})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if entry != nil {
|
||||
t.Fatalf("expected history entry to be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildHistoryEntryWithTimestampStripping(t *testing.T) {
|
||||
defer shared.BackupAndRestoreEnv("HISTTIMEFORMAT")()
|
||||
defer shared.BackupAndRestore(t)()
|
||||
defer shared.RunTestServer()()
|
||||
shared.Check(t, Setup([]string{}))
|
||||
defer testutils.BackupAndRestoreEnv("HISTTIMEFORMAT")()
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
defer testutils.RunTestServer()()
|
||||
testutils.Check(t, Setup([]string{}))
|
||||
|
||||
testcases := []struct {
|
||||
input, histtimeformat, expectedCommand string
|
||||
@ -142,11 +142,11 @@ func TestBuildHistoryEntryWithTimestampStripping(t *testing.T) {
|
||||
for _, tc := range testcases {
|
||||
conf := hctx.GetConf(hctx.MakeContext())
|
||||
conf.LastSavedHistoryLine = ""
|
||||
shared.Check(t, hctx.SetConfig(conf))
|
||||
testutils.Check(t, hctx.SetConfig(conf))
|
||||
|
||||
os.Setenv("HISTTIMEFORMAT", tc.histtimeformat)
|
||||
entry, err := BuildHistoryEntry(hctx.MakeContext(), []string{"unused", "saveHistoryEntry", "bash", "120", tc.input, "1641774958"})
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if entry == nil {
|
||||
t.Fatalf("entry is unexpectedly nil")
|
||||
}
|
||||
@ -157,15 +157,15 @@ func TestBuildHistoryEntryWithTimestampStripping(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPersist(t *testing.T) {
|
||||
defer shared.BackupAndRestore(t)()
|
||||
shared.Check(t, hctx.InitConfig())
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
testutils.Check(t, hctx.InitConfig())
|
||||
db := hctx.GetDb(hctx.MakeContext())
|
||||
|
||||
entry := data.MakeFakeHistoryEntry("ls ~/")
|
||||
entry := testutils.MakeFakeHistoryEntry("ls ~/")
|
||||
db.Create(entry)
|
||||
var historyEntries []*data.HistoryEntry
|
||||
result := db.Find(&historyEntries)
|
||||
shared.Check(t, result.Error)
|
||||
testutils.Check(t, result.Error)
|
||||
if len(historyEntries) != 1 {
|
||||
t.Fatalf("DB has %d entries, expected 1!", len(historyEntries))
|
||||
}
|
||||
@ -176,19 +176,19 @@ func TestPersist(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSearch(t *testing.T) {
|
||||
defer shared.BackupAndRestore(t)()
|
||||
shared.Check(t, hctx.InitConfig())
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
testutils.Check(t, hctx.InitConfig())
|
||||
db := hctx.GetDb(hctx.MakeContext())
|
||||
|
||||
// Insert data
|
||||
entry1 := data.MakeFakeHistoryEntry("ls /foo")
|
||||
entry1 := testutils.MakeFakeHistoryEntry("ls /foo")
|
||||
db.Create(entry1)
|
||||
entry2 := data.MakeFakeHistoryEntry("ls /bar")
|
||||
entry2 := testutils.MakeFakeHistoryEntry("ls /bar")
|
||||
db.Create(entry2)
|
||||
|
||||
// Search for data
|
||||
results, err := data.Search(db, "ls", 5)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if len(results) != 2 {
|
||||
t.Fatalf("Search() returned %d results, expected 2!", len(results))
|
||||
}
|
||||
@ -202,15 +202,15 @@ func TestSearch(t *testing.T) {
|
||||
|
||||
func TestAddToDbIfNew(t *testing.T) {
|
||||
// Set up
|
||||
defer shared.BackupAndRestore(t)()
|
||||
shared.Check(t, hctx.InitConfig())
|
||||
defer testutils.BackupAndRestore(t)()
|
||||
testutils.Check(t, hctx.InitConfig())
|
||||
db := hctx.GetDb(hctx.MakeContext())
|
||||
|
||||
// Add duplicate entries
|
||||
entry1 := data.MakeFakeHistoryEntry("ls /foo")
|
||||
entry1 := testutils.MakeFakeHistoryEntry("ls /foo")
|
||||
AddToDbIfNew(db, entry1)
|
||||
AddToDbIfNew(db, entry1)
|
||||
entry2 := data.MakeFakeHistoryEntry("ls /foo")
|
||||
entry2 := testutils.MakeFakeHistoryEntry("ls /foo")
|
||||
AddToDbIfNew(db, entry2)
|
||||
AddToDbIfNew(db, entry2)
|
||||
AddToDbIfNew(db, entry1)
|
||||
@ -228,12 +228,12 @@ func TestAddToDbIfNew(t *testing.T) {
|
||||
|
||||
func TestParseCrossPlatformInt(t *testing.T) {
|
||||
res, err := parseCrossPlatformInt("123")
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if res != 123 {
|
||||
t.Fatalf("failed to parse cross platform int %d", res)
|
||||
}
|
||||
res, err = parseCrossPlatformInt("123N")
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if res != 123 {
|
||||
t.Fatalf("failed to parse cross platform int %d", res)
|
||||
}
|
||||
@ -270,7 +270,7 @@ func TestGetLastCommand(t *testing.T) {
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
actualOutput, err := getLastCommand(tc.input)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if actualOutput != tc.expectedOutput {
|
||||
t.Fatalf("getLastCommand(%#v) returned %#v (expected=%#v)", tc.input, actualOutput, tc.expectedOutput)
|
||||
}
|
||||
@ -278,7 +278,7 @@ func TestGetLastCommand(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMaybeSkipBashHistTimePrefix(t *testing.T) {
|
||||
defer shared.BackupAndRestoreEnv("HISTTIMEFORMAT")()
|
||||
defer testutils.BackupAndRestoreEnv("HISTTIMEFORMAT")()
|
||||
|
||||
testcases := []struct {
|
||||
env, cmdLine, expected string
|
||||
@ -312,7 +312,7 @@ func TestMaybeSkipBashHistTimePrefix(t *testing.T) {
|
||||
for _, tc := range testcases {
|
||||
os.Setenv("HISTTIMEFORMAT", tc.env)
|
||||
stripped, err := maybeSkipBashHistTimePrefix(tc.cmdLine)
|
||||
shared.Check(t, err)
|
||||
testutils.Check(t, err)
|
||||
if stripped != tc.expected {
|
||||
t.Fatalf("skipping the time prefix returned %#v (expected=%#v for %#v)", stripped, tc.expected, tc.cmdLine)
|
||||
}
|
||||
|
@ -85,9 +85,3 @@ func (m *MessageIdentifiers) Scan(value interface{}) error {
|
||||
func (m MessageIdentifiers) Value() (driver.Value, error) {
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
const (
|
||||
CONFIG_PATH = ".hishtory.config"
|
||||
HISHTORY_PATH = ".hishtory"
|
||||
DB_PATH = ".hishtory.db"
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package shared
|
||||
package testutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -15,11 +15,13 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ddworken/hishtory/client/data"
|
||||
)
|
||||
|
||||
const (
|
||||
DB_WAL_PATH = DB_PATH + "-wal"
|
||||
DB_SHM_PATH = DB_PATH + "-shm"
|
||||
DB_WAL_PATH = data.DB_PATH + "-wal"
|
||||
DB_SHM_PATH = data.DB_PATH + "-shm"
|
||||
)
|
||||
|
||||
func ResetLocalState(t *testing.T) {
|
||||
@ -28,13 +30,13 @@ func ResetLocalState(t *testing.T) {
|
||||
t.Fatalf("failed to retrieve homedir: %v", err)
|
||||
}
|
||||
|
||||
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, DB_PATH))
|
||||
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, DB_WAL_PATH))
|
||||
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, CONFIG_PATH))
|
||||
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "hishtory"))
|
||||
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "config.sh"))
|
||||
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "config.zsh"))
|
||||
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "config.fish"))
|
||||
_ = os.Remove(path.Join(homedir, data.HISHTORY_PATH, data.DB_PATH))
|
||||
_ = os.Remove(path.Join(homedir, data.HISHTORY_PATH, DB_WAL_PATH))
|
||||
_ = os.Remove(path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH))
|
||||
_ = os.Remove(path.Join(homedir, data.HISHTORY_PATH, "hishtory"))
|
||||
_ = os.Remove(path.Join(homedir, data.HISHTORY_PATH, "config.sh"))
|
||||
_ = os.Remove(path.Join(homedir, data.HISHTORY_PATH, "config.zsh"))
|
||||
_ = os.Remove(path.Join(homedir, data.HISHTORY_PATH, "config.fish"))
|
||||
}
|
||||
|
||||
func BackupAndRestore(t *testing.T) func() {
|
||||
@ -44,31 +46,32 @@ func BackupAndRestore(t *testing.T) func() {
|
||||
func DeleteBakFiles(t *testing.T) {
|
||||
homedir, err := os.UserHomeDir()
|
||||
checkError(err)
|
||||
entries, err := ioutil.ReadDir(path.Join(homedir, HISHTORY_PATH))
|
||||
entries, err := ioutil.ReadDir(path.Join(homedir, data.HISHTORY_PATH))
|
||||
checkError(err)
|
||||
for _, entry := range entries {
|
||||
fmt.Println(entry.Name())
|
||||
if strings.HasSuffix(entry.Name(), ".bak") {
|
||||
checkError(os.Remove(path.Join(homedir, HISHTORY_PATH, entry.Name())))
|
||||
checkError(os.Remove(path.Join(homedir, data.HISHTORY_PATH, entry.Name())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BackupAndRestoreWithId(t *testing.T, id string) func() {
|
||||
ResetFakeHistoryTimestamp()
|
||||
homedir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to retrieve homedir: %v", err)
|
||||
}
|
||||
|
||||
renameFiles := []string{
|
||||
path.Join(homedir, HISHTORY_PATH, DB_PATH),
|
||||
path.Join(homedir, HISHTORY_PATH, DB_WAL_PATH),
|
||||
path.Join(homedir, HISHTORY_PATH, DB_SHM_PATH),
|
||||
path.Join(homedir, HISHTORY_PATH, CONFIG_PATH),
|
||||
path.Join(homedir, HISHTORY_PATH, "hishtory"),
|
||||
path.Join(homedir, HISHTORY_PATH, "config.sh"),
|
||||
path.Join(homedir, HISHTORY_PATH, "config.zsh"),
|
||||
path.Join(homedir, HISHTORY_PATH, "config.fish"),
|
||||
path.Join(homedir, data.HISHTORY_PATH, data.DB_PATH),
|
||||
path.Join(homedir, data.HISHTORY_PATH, DB_WAL_PATH),
|
||||
path.Join(homedir, data.HISHTORY_PATH, DB_SHM_PATH),
|
||||
path.Join(homedir, data.HISHTORY_PATH, data.CONFIG_PATH),
|
||||
path.Join(homedir, data.HISHTORY_PATH, "hishtory"),
|
||||
path.Join(homedir, data.HISHTORY_PATH, "config.sh"),
|
||||
path.Join(homedir, data.HISHTORY_PATH, "config.zsh"),
|
||||
path.Join(homedir, data.HISHTORY_PATH, "config.fish"),
|
||||
path.Join(homedir, ".bash_history"),
|
||||
path.Join(homedir, ".zsh_history"),
|
||||
}
|
||||
@ -249,3 +252,23 @@ func IsOnline() bool {
|
||||
_, err := http.Get("https://hishtory.dev")
|
||||
return err == nil
|
||||
}
|
||||
|
||||
var fakeHistoryTimestamp int64 = 1666068191
|
||||
|
||||
func ResetFakeHistoryTimestamp() {
|
||||
fakeHistoryTimestamp = 1666068191
|
||||
}
|
||||
|
||||
func MakeFakeHistoryEntry(command string) data.HistoryEntry {
|
||||
fakeHistoryTimestamp += 5
|
||||
return data.HistoryEntry{
|
||||
LocalUsername: "david",
|
||||
Hostname: "localhost",
|
||||
Command: command,
|
||||
CurrentWorkingDirectory: "/tmp/",
|
||||
HomeDirectory: "/home/david/",
|
||||
ExitCode: 2,
|
||||
StartTime: time.Unix(fakeHistoryTimestamp, 0),
|
||||
EndTime: time.Unix(fakeHistoryTimestamp+3, 0),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user