2022-01-09 06:59:28 +01:00
|
|
|
package shared
|
|
|
|
|
|
|
|
import (
|
2022-04-06 08:31:24 +02:00
|
|
|
"bytes"
|
2022-04-15 20:20:23 +02:00
|
|
|
"fmt"
|
2022-09-18 06:56:39 +02:00
|
|
|
"io"
|
2022-09-23 08:06:28 +02:00
|
|
|
"io/ioutil"
|
2022-05-23 04:45:46 +02:00
|
|
|
"log"
|
2022-04-28 20:26:55 +02:00
|
|
|
"net/http"
|
2022-04-07 03:18:46 +02:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path"
|
2022-09-19 04:20:21 +02:00
|
|
|
"path/filepath"
|
2022-04-12 07:36:52 +02:00
|
|
|
"runtime"
|
2022-04-09 08:47:13 +02:00
|
|
|
"strings"
|
2022-04-07 03:18:46 +02:00
|
|
|
"testing"
|
|
|
|
"time"
|
2022-01-09 06:59:28 +01:00
|
|
|
)
|
|
|
|
|
2022-05-02 04:37:26 +02:00
|
|
|
const (
|
|
|
|
DB_WAL_PATH = DB_PATH + "-wal"
|
|
|
|
DB_SHM_PATH = DB_PATH + "-shm"
|
|
|
|
)
|
|
|
|
|
2022-04-06 08:31:24 +02:00
|
|
|
func ResetLocalState(t *testing.T) {
|
|
|
|
homedir, err := os.UserHomeDir()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to retrieve homedir: %v", err)
|
|
|
|
}
|
2022-04-07 03:18:46 +02:00
|
|
|
|
2022-04-08 06:40:22 +02:00
|
|
|
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, DB_PATH))
|
2022-05-02 04:37:26 +02:00
|
|
|
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, DB_WAL_PATH))
|
2022-04-08 06:40:22 +02:00
|
|
|
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, CONFIG_PATH))
|
2022-04-15 05:18:49 +02:00
|
|
|
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "hishtory"))
|
|
|
|
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "config.sh"))
|
2022-04-18 04:54:17 +02:00
|
|
|
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "config.zsh"))
|
2022-10-19 04:55:41 +02:00
|
|
|
_ = os.Remove(path.Join(homedir, HISHTORY_PATH, "config.fish"))
|
2022-04-06 08:31:24 +02:00
|
|
|
}
|
|
|
|
|
2022-01-09 06:59:28 +01:00
|
|
|
func BackupAndRestore(t *testing.T) func() {
|
2022-05-02 04:37:26 +02:00
|
|
|
return BackupAndRestoreWithId(t, "")
|
|
|
|
}
|
|
|
|
|
2022-09-23 08:06:28 +02:00
|
|
|
func DeleteBakFiles(t *testing.T) {
|
|
|
|
homedir, err := os.UserHomeDir()
|
|
|
|
checkError(err)
|
|
|
|
entries, err := ioutil.ReadDir(path.Join(homedir, 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())))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-02 04:37:26 +02:00
|
|
|
func BackupAndRestoreWithId(t *testing.T, id string) func() {
|
2022-01-09 06:59:28 +01:00
|
|
|
homedir, err := os.UserHomeDir()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to retrieve homedir: %v", err)
|
|
|
|
}
|
|
|
|
|
2022-09-18 08:02:57 +02:00
|
|
|
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"),
|
2022-10-19 04:55:41 +02:00
|
|
|
path.Join(homedir, HISHTORY_PATH, "config.fish"),
|
2022-09-18 08:02:57 +02:00
|
|
|
path.Join(homedir, ".bash_history"),
|
|
|
|
path.Join(homedir, ".zsh_history"),
|
|
|
|
}
|
|
|
|
for _, file := range renameFiles {
|
|
|
|
touchFile(file)
|
|
|
|
_ = os.Rename(file, file+id+".bak")
|
|
|
|
}
|
|
|
|
copyFiles := []string{
|
|
|
|
path.Join(homedir, ".zshrc"),
|
|
|
|
path.Join(homedir, ".bashrc"),
|
|
|
|
}
|
|
|
|
for _, file := range copyFiles {
|
2022-09-18 18:14:34 +02:00
|
|
|
touchFile(file)
|
2022-09-18 08:02:57 +02:00
|
|
|
_ = copy(file, file+id+".bak")
|
|
|
|
}
|
2022-09-18 06:59:13 +02:00
|
|
|
configureZshrc(homedir)
|
|
|
|
touchFile(path.Join(homedir, ".bash_history"))
|
|
|
|
touchFile(path.Join(homedir, ".zsh_history"))
|
2022-01-09 06:59:28 +01:00
|
|
|
return func() {
|
2022-09-18 08:02:57 +02:00
|
|
|
for _, file := range renameFiles {
|
2022-09-18 18:42:24 +02:00
|
|
|
checkError(os.Rename(file+id+".bak", file))
|
2022-09-18 08:02:57 +02:00
|
|
|
}
|
|
|
|
for _, file := range copyFiles {
|
|
|
|
checkError(copy(file+id+".bak", file))
|
|
|
|
}
|
2022-10-23 10:03:16 +02:00
|
|
|
cmd := exec.Command("killall", "hishtory")
|
|
|
|
stdout, err := cmd.Output()
|
|
|
|
if err != nil && err.Error() != "exit status 1" {
|
|
|
|
t.Fatalf("failed to execute killall hishtory, stdout=%#v: %v", string(stdout), err)
|
|
|
|
}
|
2022-09-18 06:56:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-18 06:59:13 +02:00
|
|
|
func touchFile(p string) {
|
2022-09-18 08:02:57 +02:00
|
|
|
_, err := os.Stat(p)
|
|
|
|
if os.IsNotExist(err) {
|
2022-09-19 06:05:51 +02:00
|
|
|
checkError(os.MkdirAll(filepath.Dir(p), os.ModePerm))
|
2022-09-19 03:34:27 +02:00
|
|
|
file, err := os.Create(p)
|
2022-09-18 08:02:57 +02:00
|
|
|
checkError(err)
|
|
|
|
defer file.Close()
|
|
|
|
} else {
|
|
|
|
currentTime := time.Now().Local()
|
|
|
|
err := os.Chtimes(p, currentTime, currentTime)
|
|
|
|
checkError(err)
|
|
|
|
}
|
2022-09-18 06:59:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func configureZshrc(homedir string) {
|
|
|
|
f, err := os.OpenFile(path.Join(homedir, ".zshrc"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
|
|
checkError(err)
|
|
|
|
defer f.Close()
|
|
|
|
_, err = f.WriteString(`export HISTFILE=~/.zsh_history
|
|
|
|
export HISTSIZE=10000
|
|
|
|
export SAVEHIST=1000
|
2022-09-23 03:22:06 +02:00
|
|
|
setopt SHARE_HISTORY
|
|
|
|
`)
|
2022-09-18 06:59:13 +02:00
|
|
|
checkError(err)
|
|
|
|
}
|
|
|
|
|
2022-09-18 06:56:39 +02:00
|
|
|
func copy(src, dst string) error {
|
|
|
|
in, err := os.Open(src)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer in.Close()
|
|
|
|
|
|
|
|
out, err := os.Create(dst)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer out.Close()
|
|
|
|
|
|
|
|
_, err = io.Copy(out, in)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2022-05-23 04:45:46 +02:00
|
|
|
}
|
2022-09-18 06:56:39 +02:00
|
|
|
return out.Close()
|
2022-05-23 04:45:46 +02:00
|
|
|
}
|
|
|
|
|
2022-06-13 06:28:19 +02:00
|
|
|
func BackupAndRestoreEnv(k string) func() {
|
|
|
|
origValue := os.Getenv(k)
|
|
|
|
return func() {
|
|
|
|
os.Setenv(k, origValue)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-23 04:45:46 +02:00
|
|
|
func checkError(err error) {
|
2022-09-18 07:45:07 +02:00
|
|
|
if err != nil {
|
2022-05-23 04:45:46 +02:00
|
|
|
_, filename, line, _ := runtime.Caller(1)
|
2022-05-28 07:06:20 +02:00
|
|
|
_, cf, cl, _ := runtime.Caller(2)
|
2022-05-28 04:00:02 +02:00
|
|
|
log.Fatalf("testutils fatal error at %s:%d (caller: %s:%d): %v", filename, line, cf, cl, err)
|
2022-01-09 06:59:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-15 20:20:23 +02:00
|
|
|
func buildServer() {
|
2022-04-09 20:55:00 +02:00
|
|
|
for {
|
|
|
|
wd, err := os.Getwd()
|
|
|
|
if err != nil {
|
2022-04-15 20:20:23 +02:00
|
|
|
panic(fmt.Sprintf("failed to getwd: %v", err))
|
2022-04-09 20:55:00 +02:00
|
|
|
}
|
|
|
|
if strings.HasSuffix(wd, "/hishtory") {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
err = os.Chdir("../")
|
|
|
|
if err != nil {
|
2022-04-15 20:20:23 +02:00
|
|
|
panic(fmt.Sprintf("failed to chdir: %v", err))
|
2022-04-09 20:55:00 +02:00
|
|
|
}
|
|
|
|
if wd == "/" {
|
2022-04-15 20:20:23 +02:00
|
|
|
panic("failed to cd into hishtory dir!")
|
2022-04-09 20:55:00 +02:00
|
|
|
}
|
2022-04-06 08:31:24 +02:00
|
|
|
}
|
2022-04-20 06:05:54 +02:00
|
|
|
version, err := os.ReadFile("VERSION")
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Sprintf("failed to read VERSION file: %v", err))
|
|
|
|
}
|
|
|
|
cmd := exec.Command("go", "build", "-o", "/tmp/server", "-ldflags", fmt.Sprintf("-X main.ReleaseVersion=v0.%s", version), "backend/server/server.go")
|
2022-04-06 08:31:24 +02:00
|
|
|
var stdout bytes.Buffer
|
|
|
|
cmd.Stdout = &stdout
|
|
|
|
var stderr bytes.Buffer
|
|
|
|
cmd.Stderr = &stderr
|
2022-04-20 06:05:54 +02:00
|
|
|
err = cmd.Start()
|
2022-04-06 08:31:24 +02:00
|
|
|
if err != nil {
|
2022-04-15 20:20:23 +02:00
|
|
|
panic(fmt.Sprintf("failed to start to build server: %v, stderr=%#v, stdout=%#v", err, stderr.String(), stdout.String()))
|
2022-04-06 08:31:24 +02:00
|
|
|
}
|
|
|
|
err = cmd.Wait()
|
|
|
|
if err != nil {
|
2022-04-09 20:55:00 +02:00
|
|
|
wd, _ := os.Getwd()
|
2022-04-15 20:20:23 +02:00
|
|
|
panic(fmt.Sprintf("failed to build server: %v, wd=%#v, stderr=%#v, stdout=%#v", err, wd, stderr.String(), stdout.String()))
|
2022-04-06 08:31:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-15 20:20:23 +02:00
|
|
|
func RunTestServer() func() {
|
2022-04-07 03:18:46 +02:00
|
|
|
os.Setenv("HISHTORY_SERVER", "http://localhost:8080")
|
2022-04-15 20:20:23 +02:00
|
|
|
buildServer()
|
2022-04-07 03:18:46 +02:00
|
|
|
cmd := exec.Command("/tmp/server")
|
|
|
|
var stdout bytes.Buffer
|
2022-04-06 08:31:24 +02:00
|
|
|
cmd.Stdout = &stdout
|
|
|
|
var stderr bytes.Buffer
|
|
|
|
cmd.Stderr = &stderr
|
2022-04-07 03:18:46 +02:00
|
|
|
err := cmd.Start()
|
|
|
|
if err != nil {
|
2022-04-15 20:20:23 +02:00
|
|
|
panic(fmt.Sprintf("failed to start server: %v", err))
|
2022-04-07 03:18:46 +02:00
|
|
|
}
|
2022-04-15 20:20:23 +02:00
|
|
|
time.Sleep(time.Second * 5)
|
2022-04-07 03:18:46 +02:00
|
|
|
go func() {
|
2022-04-08 06:40:22 +02:00
|
|
|
_ = cmd.Wait()
|
2022-04-07 03:18:46 +02:00
|
|
|
}()
|
2022-04-06 08:31:24 +02:00
|
|
|
return func() {
|
|
|
|
err := cmd.Process.Kill()
|
2022-04-15 05:18:49 +02:00
|
|
|
if err != nil && err.Error() != "os: process already finished" {
|
2022-04-15 20:20:23 +02:00
|
|
|
panic(fmt.Sprintf("failed to kill server process: %v", err))
|
2022-04-06 08:31:24 +02:00
|
|
|
}
|
2022-04-28 20:26:55 +02:00
|
|
|
if strings.Contains(stderr.String()+stdout.String(), "failed to") && IsOnline() {
|
2022-04-15 20:20:23 +02:00
|
|
|
panic(fmt.Sprintf("server failed to do something: stderr=%#v, stdout=%#v", stderr.String(), stdout.String()))
|
2022-04-09 08:47:13 +02:00
|
|
|
}
|
2022-04-16 20:37:43 +02:00
|
|
|
if strings.Contains(stderr.String()+stdout.String(), "ERROR:") {
|
|
|
|
panic(fmt.Sprintf("server experienced an error: stderr=%#v, stdout=%#v", stderr.String(), stdout.String()))
|
|
|
|
}
|
2022-04-16 09:44:47 +02:00
|
|
|
// fmt.Printf("stderr=%#v, stdout=%#v\n", stderr.String(), stdout.String())
|
2022-04-06 08:31:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-05 07:07:01 +02:00
|
|
|
func Check(t *testing.T, err error) {
|
|
|
|
if err != nil {
|
2022-04-12 07:36:52 +02:00
|
|
|
_, filename, line, _ := runtime.Caller(1)
|
|
|
|
t.Fatalf("Unexpected error at %s:%d: %v", filename, line, err)
|
2022-04-05 07:07:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func CheckWithInfo(t *testing.T, err error, additionalInfo string) {
|
|
|
|
if err != nil {
|
2022-04-12 07:36:52 +02:00
|
|
|
_, filename, line, _ := runtime.Caller(1)
|
|
|
|
t.Fatalf("Unexpected error: %v at %s:%d! Additional info: %v", err, filename, line, additionalInfo)
|
2022-04-05 07:07:01 +02:00
|
|
|
}
|
|
|
|
}
|
2022-04-28 20:26:55 +02:00
|
|
|
|
|
|
|
func IsOnline() bool {
|
|
|
|
_, err := http.Get("https://hishtory.dev")
|
|
|
|
return err == nil
|
|
|
|
}
|