summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2023-05-27 13:11:25 +1000
committerJesse Duffield <jessedduffield@gmail.com>2023-05-27 13:11:25 +1000
commitb146c055784b5add8dfb748f1b7beb3faa88c293 (patch)
tree4cb2d8e023bdf09a6ff563b816898076fdfd5897
parent6c7f893f7a7848234ba7fd516417c7aebecfeea4 (diff)
-rw-r--r--pkg/commands/oscommands/cmd_obj_runner_win.go40
-rw-r--r--pkg/gui/gui.go1
-rw-r--r--pkg/gui/gui_driver.go1
-rw-r--r--pkg/gui/test_mode.go54
-rw-r--r--pkg/integration/clients/go_test.go4
-rw-r--r--pkg/integration/components/runner.go11
-rw-r--r--pkg/integration/tests/ui/double_popup.go3
-rw-r--r--pkg/integration/types/types.go1
-rw-r--r--pkg/logs/logs.go1
-rwxr-xr-xtest/files/pre-push15
10 files changed, 51 insertions, 80 deletions
diff --git a/pkg/commands/oscommands/cmd_obj_runner_win.go b/pkg/commands/oscommands/cmd_obj_runner_win.go
index 6893a2535..083a035e6 100644
--- a/pkg/commands/oscommands/cmd_obj_runner_win.go
+++ b/pkg/commands/oscommands/cmd_obj_runner_win.go
@@ -4,48 +4,20 @@
package oscommands
import (
- "bytes"
- "io"
"os/exec"
- "github.com/sasha-s/go-deadlock"
+ "github.com/creack/pty"
)
-type Buffer struct {
- b bytes.Buffer
- m deadlock.Mutex
-}
-
-func (b *Buffer) Read(p []byte) (n int, err error) {
- b.m.Lock()
- defer b.m.Unlock()
- return b.b.Read(p)
-}
-
-func (b *Buffer) Write(p []byte) (n int, err error) {
- b.m.Lock()
- defer b.m.Unlock()
- return b.b.Write(p)
-}
-
-// TODO: Remove this hack and replace it with a proper way to run commands live on windows. We still have an issue where if a password is requested, the request for a password is written straight to stdout because we can't control the stdout of a subprocess of a subprocess. Keep an eye on https://github.com/creack/pty/pull/109
func (self *cmdObjRunner) getCmdHandler(cmd *exec.Cmd) (*cmdHandler, error) {
- stdoutReader, stdoutWriter := io.Pipe()
- cmd.Stdout = stdoutWriter
-
- buf := &Buffer{}
- cmd.Stdin = buf
-
- if err := cmd.Start(); err != nil {
+ ptmx, err := pty.Start(cmd)
+ if err != nil {
return nil, err
}
- // because we don't yet have windows support for a pty, we instead just
- // pass our standard stream handlers and because there's no pty to close
- // we pass a no-op function for that.
return &cmdHandler{
- stdoutPipe: stdoutReader,
- stdinPipe: buf,
- close: func() error { return nil },
+ stdoutPipe: ptmx,
+ stdinPipe: ptmx,
+ close: ptmx.Close,
}, nil
}
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 4c69a4e4e..a169373af 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -617,6 +617,7 @@ func (gui *Gui) Run(startArgs appTypes.StartArgs) error {
gui.c.Log.Info("starting main loop")
+ defer gui.handlePanicInTest(startArgs.IntegrationTest)
gui.handleTestMode(startArgs.IntegrationTest)
return gui.g.MainLoop()
diff --git a/pkg/gui/gui_driver.go b/pkg/gui/gui_driver.go
index a90578b65..d4f140b56 100644
--- a/pkg/gui/gui_driver.go
+++ b/pkg/gui/gui_driver.go
@@ -70,6 +70,7 @@ func (self *GuiDriver) Fail(message string) {
self.gui.g.Close()
// need to give the gui time to close
time.Sleep(time.Millisecond * 100)
+ self.Log("test failed")
panic(fullMessage)
}
diff --git a/pkg/gui/test_mode.go b/pkg/gui/test_mode.go
index 5b61f3ccc..ed45542d6 100644
--- a/pkg/gui/test_mode.go
+++ b/pkg/gui/test_mode.go
@@ -19,46 +19,54 @@ type IntegrationTest interface {
}
func (gui *Gui) handleTestMode(test integrationTypes.IntegrationTest) {
- if os.Getenv(components.SANDBOX_ENV_VAR) == "true" {
+ if os.Getenv(components.SANDBOX_ENV_VAR) == "true" || test == nil {
return
}
- if test != nil {
- go func() {
- time.Sleep(time.Millisecond * 100)
+ go func() {
+ defer gui.handlePanicInTest(test)
- defer handlePanic()
+ time.Sleep(time.Millisecond * 100)
- guiDriver := &GuiDriver{gui: gui}
- test.Run(guiDriver)
+ guiDriver := &GuiDriver{gui: gui}
+ test.Run(guiDriver)
- // if we're here then the test must have passed: it panics upon failure
- if err := result.LogSuccess(); err != nil {
- panic(err)
- }
+ // if we're here then the test must have passed: it panics upon failure
+ gui.Log.Warnf("test %s logging success", test.Name())
+ if err := result.LogSuccess(); err != nil {
+ gui.Log.Warnf("test %s failed to log success!", test.Name())
+ panic(err)
+ }
- gui.g.Update(func(*gocui.Gui) error {
- return gocui.ErrQuit
- })
+ gui.g.Update(func(*gocui.Gui) error {
+ return gocui.ErrQuit
+ })
- time.Sleep(time.Second * 1)
+ time.Sleep(time.Second * 1)
- log.Fatal("gocui should have already exited")
- }()
+ log.Fatal("gocui should have already exited")
+ }()
- go utils.Safe(func() {
- time.Sleep(time.Second * 40)
- log.Fatal("40 seconds is up, lazygit recording took too long to complete")
- })
- }
+ go utils.Safe(func() {
+ defer gui.handlePanicInTest(test)
+
+ time.Sleep(time.Second * 40)
+ panic("40 seconds is up, lazygit recording took too long to complete")
+ })
}
-func handlePanic() {
+func (gui *Gui) handlePanicInTest(test integrationTypes.IntegrationTest) {
+ if test == nil {
+ return
+ }
+
if r := recover(); r != nil {
buf := make([]byte, 4096*4) // arbitrarily large buffer size
stackSize := runtime.Stack(buf, false)
stackTrace := string(buf[:stackSize])
+ gui.Log.Warnf("test %s panicked!", test.Name())
+
if err := result.LogFailure(fmt.Sprintf("%v\n%s", r, stackTrace)); err != nil {
panic(err)
}
diff --git a/pkg/integration/clients/go_test.go b/pkg/integration/clients/go_test.go
index cf938ccc8..565569254 100644
--- a/pkg/integration/clients/go_test.go
+++ b/pkg/integration/clients/go_test.go
@@ -82,12 +82,9 @@ func runCmdHeadless(cmd *exec.Cmd) error {
_, err := pty.StartWithSize(cmd, &pty.Winsize{Rows: 300, Cols: 300})
if err != nil {
- panic(err)
return err
}
- fmt.Println("about to wait")
-
_ = cmd.Wait()
time.Sleep(time.Second)
@@ -99,7 +96,6 @@ func runCmdHeadless(cmd *exec.Cmd) error {
if !result.Success {
return errors.New(result.Message)
}
- fmt.Printf("test succeeded")
return nil
}
diff --git a/pkg/integration/components/runner.go b/pkg/integration/components/runner.go
index c6266d397..57e59523e 100644
--- a/pkg/integration/components/runner.go
+++ b/pkg/integration/components/runner.go
@@ -35,14 +35,12 @@ func RunTests(
projectRootDir := utils.GetLazyRootDirectory()
err := os.Chdir(projectRootDir)
if err != nil {
- panic(err)
return err
}
testDir := filepath.Join(projectRootDir, "test", "results")
if err := buildLazygit(); err != nil {
- panic(err)
return err
}
@@ -63,7 +61,6 @@ func RunTests(
err := runTest(test, paths, projectRootDir, logf, runCmd, sandbox, keyPressDelay, gitVersion)
if err != nil {
if i == maxAttempts-1 {
- panic(err)
return err
}
logf("retrying test %s", test.Name())
@@ -100,18 +97,17 @@ func runTest(
}
if err := prepareTestDir(test, paths, projectRootDir); err != nil {
- panic(err)
return err
}
cmd, err := getLazygitCommand(test, paths, projectRootDir, sandbox, keyPressDelay)
if err != nil {
- panic(err)
+ return err
}
err = runCmd(cmd)
if err != nil {
- panic(err)
+ return err
}
return nil
@@ -164,7 +160,6 @@ func getGitVersion() (*git_commands.GitVersion, error) {
cmdObj := osCommand.Cmd.New([]string{"git", "--version"})
versionStr, err := cmdObj.RunWithOutput()
if err != nil {
- panic(err)
return nil, err
}
return git_commands.ParseGitVersion(versionStr)
@@ -175,14 +170,12 @@ func getLazygitCommand(test *IntegrationTest, paths Paths, rootDir string, sandb
err := os.RemoveAll(paths.Config())
if err != nil {
- panic(err)
return nil, err
}
templateConfigDir := filepath.Join(rootDir, "test", "default_test_config")
err = oscommands.CopyDir(templateConfigDir, paths.Config())
if err != nil {
- panic(err)
return nil, err
}
diff --git a/pkg/integration/tests/ui/double_popup.go b/pkg/integration/tests/ui/double_popup.go
index 2d6b7fe20..9843c3e48 100644
--- a/pkg/integration/tests/ui/double_popup.go
+++ b/pkg/integration/tests/ui/double_popup.go
@@ -16,6 +16,9 @@ var DoublePopup = NewIntegrationTest(NewIntegrationTestArgs{
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Branches().
Focus().
+ Lines(
+ Contains("master"),
+ ).
// arbitrarily bringing up a popup
PressPrimaryAction()
diff --git a/pkg/integration/types/types.go b/pkg/integration/types/types.go
index a26ac67af..193d06c86 100644
--- a/pkg/integration/types/types.go
+++ b/pkg/integration/types/types.go
@@ -13,6 +13,7 @@ import (
type IntegrationTest interface {
Run(GuiDriver)
SetupConfig(config *config.AppConfig)
+ Name() string
}
// this is the interface through which our integration tests interact with the lazygit gui
diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go
index 3558e52a6..bc3279c87 100644
--- a/pkg/logs/logs.go
+++ b/pkg/logs/logs.go
@@ -35,6 +35,7 @@ func NewProductionLogger() *logrus.Entry {
}
func NewDevelopmentLogger(logPath string) *logrus.Entry {
+ logPath = `C:\Users\New\AppData\Roaming\jesseduffield\lazygit\development.log`
logger := logrus.New()
logger.SetLevel(getLogLevel())
diff --git a/test/files/pre-push b/test/files/pre-push
index 3b758c1b1..0ec35d20a 100755
--- a/test/files/pre-push
+++ b/test/files/pre-push
@@ -8,20 +8,15 @@
# this will hang if you're using git from the command line, so only enable this
# when you are testing the credentials view in lazygit
-exec < /dev/tty
+read -p "Username for 'github': " username
+read -p "Password for 'github': " password
-echo -n "Username for 'github': "
-read username
+echo
-echo -n "Password for 'github': "
-# this will print the password to the log view but real git won't do that.
-# We could use read -s but that's not POSIX compliant.
-read password
-
-if [ "$username" = "username" -a "$password" = "password" ]; then
+if [[ "$username" == "username" && "$password" == "password" ]]; then
echo "success"
exit 0
fi
->&2 echo "incorrect username/password"
+echo "incorrect username/password" >&2
exit 1