这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@rjarry
Copy link
Contributor

@rjarry rjarry commented Jan 13, 2025

Without the recent change of line wrapper implementation, this test is failing with the following error:

=== RUN   TestWriter_afterReading
    writer_test.go:231: reformatted message differs:
        --- /tmp/go-message-orig-2606107600.txt	2025-01-13 21:12:35.433528299 +0100
        +++ /tmp/go-message-after-1462324866.txt	2025-01-13 21:12:35.433528299 +0100
        @@ -83,7 +83,8 @@
          app/compose.go | 24 ++++++++++++++++++------
          1 file changed, 18 insertions(+), 6 deletions(-)

        -diff --git a/app/compose.go b/app/compose.go
        +diff --git a/app/compose.go b/app/co
        +mpose.go
         index 7a6a423c3ea3..e8a672479245 100644
         --- a/app/compose.go
         +++ b/app/compose.go
        @@ -113,7 +114,8 @@
          	c.editor = nil
          	c.focusable = c.focusable[:len(c.focusable)-1]
          	if c.focused >= len(c.focusable) {
        -@@ -1213,8 +1221,10 @@ func (c *Composer) termClosed(err error) {
        +@@ -1213,8 +1221,10 @@ func (c *Composer) termClosed(err err
        +or) {
          	}

          	if editor.cmd.ProcessState.ExitCode() > 0 {
--- FAIL: TestWriter_afterReading (0.00s)
FAIL
exit status 1
FAIL	github.com/emersion/go-message	0.005s

Link: c2ff70fd20da09d40ba
Link: 6a718fa6214f9f35d33

Copy link
Owner

@emersion emersion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the original message be reduced to the minimum reproducer?

writer_test.go Outdated
Comment on lines 218 to 231
orig, _ := os.CreateTemp(os.TempDir(), "go-message-orig-*.txt")
after, _ := os.CreateTemp(os.TempDir(), "go-message-after-*.txt")
defer os.Remove(orig.Name())
defer os.Remove(after.Name())
orig.WriteString(original)
orig.Close()
after.Write(buf.Bytes())
after.Close()

var stdout bytes.Buffer
cmd := exec.Command("diff", "-u", orig.Name(), after.Name())
cmd.Stdout = &stdout
cmd.Run()
t.Fatalf("reformatted message differs:\n%s", stdout.String())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, not a fan of shelling out to diff. Even if that makes reading the difference more difficult, can we just print both strings instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it was to make spotting the differences easier, but I guess you can instrument the test later to debug it more.

@rjarry
Copy link
Contributor Author

rjarry commented Jan 13, 2025

Could the original message be reduced to the minimum reproducer?

The message needs to be sufficiently long to trigger the issue. I'll try to scrape off the excess as much as possible.

@emersion
Copy link
Owner

Probably at least the header could be shortened quite a bit?

Without the recent change of line wrapper implementation, this test is
failing. There seem to be line breaks inserted in the middle of the
body:

```diff
--- /tmp/go-message-orig-194495186.txt
+++ /tmp/go-message-after-83245617.txt
@@ -37,7 +37,8 @@
  	if c.editor == nil {
  		return
  	}
-@@ -1205,7 +1213,7 @@ func (c *Composer) termClosed(err error) {
+@@ -1205,7 +1
+213,7 @@ func (c *Composer) termClosed(err error) {
  		PushError("Failed to reopen email file: " + e.Error())
  	}
  	editor := c.editor
@@ -70,7 +71,8 @@
 +					PushError(err.Error())
 +				})
  			}
- 			return
+ 			return
+
  		}
 --
 2.47.1
```

Link: emersion@c2ff70fd20da09d40ba
Link: emersion@6a718fa6214f9f35d33
Signed-off-by: Robin Jarry <robin@jarry.cc>
@rjarry
Copy link
Contributor Author

rjarry commented Jan 13, 2025

Ooops, forgot to remove the reverts to check that the test was indeed failing:

--- FAIL: TestWriter_afterReading (0.00s)
    writer_test.go:148: reformatted message differs: original="From: Robin Jarry <robin@jarry.cc>\r\nTo: ~rjarry/aerc-devel@lists.sr.ht\r\nSubject: [PATCH aerc] compose: fix deadlock when editor exits with an error\r\nDate: Mon, 13 Jan 2025 14:08:53 +0100\r\nMessage-ID: <20250113130852.47802-2-robin@jarry.cc>\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: 8bit\r\n\r\nWhen exiting vim with :cq, it exits with an error status which is caught\r\nin the termClosed() callback. This causes the composer tab to be closed\r\nand it is a known and expected behaviour.\r\n\r\nSigned-off-by: Robin Jarry <robin@jarry.cc>\r\n---\r\n app/compose.go | 24 ++++++++++++++++++------\r\n 1 file changed, 18 insertions(+), 6 deletions(-)\r\n\r\ndiff --git a/app/compose.go b/app/compose.go\r\nindex 7a6a423c3ea3..e8a672479245 100644\r\n--- a/app/compose.go\r\n+++ b/app/compose.go\r\n@@ -1197,7 +1197,15 @@ func (c *Composer) reopenEmailFile() error {\r\n \r\n func (c *Composer) termClosed(err error) {\r\n \tc.Lock()\r\n-\tdefer c.Unlock()\r\n+\t// RemoveTab() on error must be called *AFTER* c.Unlock() but the defer\r\n+\t// statement does the exact opposite (last defer statement is executed\r\n+\t// first). Use an explicit list that begins with unlocking first.\r\n+\tdeferred := []func(){c.Unlock}\r\n+\tdefer func() {\r\n+\t\tfor _, d := range deferred {\r\n+\t\t\td()\r\n+\t\t}\r\n+\t}()\r\n \tif c.editor == nil {\r\n \t\treturn\r\n \t}\r\n@@ -1205,7 +1213,7 @@ func (c *Composer) termClosed(err error) {\r\n \t\tPushError(\"Failed to reopen email file: \" + e.Error())\r\n \t}\r\n \teditor := c.editor\r\n-\tdefer editor.Destroy()\r\n+\tdeferred = append(deferred, editor.Destroy)\r\n \tc.editor = nil\r\n \tc.focusable = c.focusable[:len(c.focusable)-1]\r\n \tif c.focused >= len(c.focusable) {\r\n@@ -1213,8 +1221,10 @@ func (c *Composer) termClosed(err error) {\r\n \t}\r\n \r\n \tif editor.cmd.ProcessState.ExitCode() > 0 {\r\n-\t\tRemoveTab(c, true)\r\n-\t\tPushError(\"Editor exited with error. Compose aborted!\")\r\n+\t\tdeferred = append(deferred, func() {\r\n+\t\t\tRemoveTab(c, true)\r\n+\t\t\tPushError(\"Editor exited with error. Compose aborted!\")\r\n+\t\t})\r\n \t\treturn\r\n \t}\r\n \r\n@@ -1225,8 +1235,10 @@ func (c *Composer) termClosed(err error) {\r\n \t\t\tPushError(err.Error())\r\n \t\t\terr := c.showTerminal()\r\n \t\t\tif err != nil {\r\n-\t\t\t\tRemoveTab(c, true)\r\n-\t\t\t\tPushError(err.Error())\r\n+\t\t\t\tdeferred = append(deferred, func() {\r\n+\t\t\t\t\tRemoveTab(c, true)\r\n+\t\t\t\t\tPushError(err.Error())\r\n+\t\t\t\t})\r\n \t\t\t}\r\n \t\t\treturn\r\n \t\t}\r\n-- \r\n2.47.1\r\n\r\n\r\n" reformatted="From: Robin Jarry <robin@jarry.cc>\r\nTo: ~rjarry/aerc-devel@lists.sr.ht\r\nSubject: [PATCH aerc] compose: fix deadlock when editor exits with an error\r\nDate: Mon, 13 Jan 2025 14:08:53 +0100\r\nMessage-ID: <20250113130852.47802-2-robin@jarry.cc>\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: 8bit\r\n\r\nWhen exiting vim with :cq, it exits with an error status which is caught\r\nin the termClosed() callback. This causes the composer tab to be closed\r\nand it is a known and expected behaviour.\r\n\r\nSigned-off-by: Robin Jarry <robin@jarry.cc>\r\n---\r\n app/compose.go | 24 ++++++++++++++++++------\r\n 1 file changed, 18 insertions(+), 6 deletions(-)\r\n\r\ndiff --git a/app/compose.go b/app/compose.go\r\nindex 7a6a423c3ea3..e8a672479245 100644\r\n--- a/app/compose.go\r\n+++ b/app/compose.go\r\n@@ -1197,7 +1197,15 @@ func (c *Composer) reopenEmailFile() error {\r\n \r\n func (c *Composer) termClosed(err error) {\r\n \tc.Lock()\r\n-\tdefer c.Unlock()\r\n+\t// RemoveTab() on error must be called *AFTER* c.Unlock() but the defer\r\n+\t// statement does the exact opposite (last defer statement is executed\r\n+\t// first). Use an explicit list that begins with unlocking first.\r\n+\tdeferred := []func(){c.Unlock}\r\n+\tdefer func() {\r\n+\t\tfor _, d := range deferred {\r\n+\t\t\td()\r\n+\t\t}\r\n+\t}()\r\n \tif c.editor == nil {\r\n \t\treturn\r\n \t}\r\n@@ -1205,7 +1\r\n213,7 @@ func (c *Composer) termClosed(err error) {\r\n \t\tPushError(\"Failed to reopen email file: \" + e.Error())\r\n \t}\r\n \teditor := c.editor\r\n-\tdefer editor.Destroy()\r\n+\tdeferred = append(deferred, editor.Destroy)\r\n \tc.editor = nil\r\n \tc.focusable = c.focusable[:len(c.focusable)-1]\r\n \tif c.focused >= len(c.focusable) {\r\n@@ -1213,8 +1221,10 @@ func (c *Composer) termClosed(err error) {\r\n \t}\r\n \r\n \tif editor.cmd.ProcessState.ExitCode() > 0 {\r\n-\t\tRemoveTab(c, true)\r\n-\t\tPushError(\"Editor exited with error. Compose aborted!\")\r\n+\t\tdeferred = append(deferred, func() {\r\n+\t\t\tRemoveTab(c, true)\r\n+\t\t\tPushError(\"Editor exited with error. Compose aborted!\")\r\n+\t\t})\r\n \t\treturn\r\n \t}\r\n \r\n@@ -1225,8 +1235,10 @@ func (c *Composer) termClosed(err error) {\r\n \t\t\tPushError(err.Error())\r\n \t\t\terr := c.showTerminal()\r\n \t\t\tif err != nil {\r\n-\t\t\t\tRemoveTab(c, true)\r\n-\t\t\t\tPushError(err.Error())\r\n+\t\t\t\tdeferred = append(deferred, func() {\r\n+\t\t\t\t\tRemoveTab(c, true)\r\n+\t\t\t\t\tPushError(err.Error())\r\n+\t\t\t\t})\r\n \t\t\t}\r\n \t\t\treturn\r\r\n\n \t\t}\r\n-- \r\n2.47.1\r\n\r\n\r\n"
FAIL

Copy link
Owner

@emersion emersion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@emersion emersion merged commit 162c134 into emersion:master Jan 13, 2025
1 check passed
@rjarry rjarry deleted the rewrite-verbatim branch January 13, 2025 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants