summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Altmanninger <aclopte@gmail.com>2024-12-13 08:24:22 +0100
committerMaxime Coste <mawww@kakoune.org>2025-06-26 11:34:17 +1000
commitcff5f12a852a34a548aabfb6166c86fa35466a83 (patch)
tree99ab74642a06182f74db10305512b227d3625429
parent096d72bbb11e3a2ec227de9eda4dfac02ed970aa (diff)
Fix flaky blame-in-diff test and "edit -fifo" in BufCloseFifo
This test uses ui_out and ui_in to coordinate events. This is brittle[1] because ui_out behavior depends on timing. Since this test doesn't really care about intermediate UI state, express the sequence using BufCloseFifo instead. This hits another issue: inside git blame-jump's BufCloseFifo, we run git blame, which runs another "edit -fifo .. *git*". A special aspect of fifo buffers is that any existing *git* buffer will be reused instead of being recreated[2]. After BufCloseFifo, the fifo watcher destructor will reset the fifo flag, even if BufCloseFifo has recreated the fifo buffer. This breaks invariants and causes the next fifo watcher destructor do fail its assertion. Let's not reset fifo flags in this case. This should be safe because it's the very last thing the fifo watcher does, so it's okay if another one is active now. Alternatively we could reject this kind of recursion, or implement it in a different way (using ScopedSetBool for the flags). Reported-by: Nico Sonack <nsonack@herrhotzenplotz.de> [1]: https://lists.sr.ht/~mawww/kakoune/%3C20241210100417.1150697-1-aclopte@gmail.com%3E [2]: This removes the need to use delete-buffer which also ensures that the buffer remains visible in any client it's already shown.
-rw-r--r--src/buffer_utils.cc3
-rwxr-xr-xtest/run4
-rw-r--r--test/tools/git/blame-in-diff/rc15
-rw-r--r--test/tools/git/blame-in-diff/script11
4 files changed, 21 insertions, 12 deletions
diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc
index a2d2e709..bb64e9c1 100644
--- a/src/buffer_utils.cc
+++ b/src/buffer_utils.cc
@@ -290,7 +290,8 @@ Buffer* create_fifo_buffer(String name, int fd, Buffer::Flags flags, AutoScroll
kak_assert(m_buffer.flags() & Buffer::Flags::Fifo);
close_fd();
m_buffer.run_hook_in_own_context(Hook::BufCloseFifo, "");
- m_buffer.flags() &= ~(Buffer::Flags::Fifo | Buffer::Flags::NoUndo);
+ if (not m_buffer.values().contains(fifo_watcher_id))
+ m_buffer.flags() &= ~(Buffer::Flags::Fifo | Buffer::Flags::NoUndo);
}
void read_fifo()
diff --git a/test/run b/test/run
index d48a1a43..670f6858 100755
--- a/test/run
+++ b/test/run
@@ -204,11 +204,11 @@ ui_out() {
[ "$event" = "$expected" ] && break
done
;;
- -until-eval | -until-grep)
+ -until-grep)
pattern=$1
shift
while read -r event <&4; do
- if printf %s "$event" | "${arg#-until-}" "$pattern" >/dev/null; then
+ if printf %s "$event" | grep "$pattern" >/dev/null; then
if [ $# -ne 0 ]; then
assert_eq "$1" "$event"
shift
diff --git a/test/tools/git/blame-in-diff/rc b/test/tools/git/blame-in-diff/rc
index eba02270..1fc54f3f 100644
--- a/test/tools/git/blame-in-diff/rc
+++ b/test/tools/git/blame-in-diff/rc
@@ -11,4 +11,19 @@ define-command run %{
git commit --all --message 'changed line 2'
# Show the commit, jumping to the new version of line 2.
git blame-jump
+ hook -once buffer BufCloseFifo .* %{
+ evaluate-commands -client client0 %{
+ # We've jumped to the new version of line 2. Move to the old
+ # version so we can annotate the old version of the file.
+ execute-keys k
+ git blame
+ hook -once buffer BufCloseFifo .* %{
+ execute-keys -client client0 x
+ # Wait for a redraw before reporting completion.
+ hook -once buffer NormalIdle .* %{
+ echo -to-file fifo
+ }
+ }
+ }
+ }
}
diff --git a/test/tools/git/blame-in-diff/script b/test/tools/git/blame-in-diff/script
index 0cee0ca7..4c371348 100644
--- a/test/tools/git/blame-in-diff/script
+++ b/test/tools/git/blame-in-diff/script
@@ -1,10 +1,3 @@
-ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }'
-
-# We've jumped to the new version of line 2. Move to the old version so we
-# can annotate the old file.
-ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "k:git blame<ret>" ] }'
-ui_out -until-eval 'grep "draw_status" | grep -v "\[fifo\]"'
-
+mkfifo fifo 2>/dev/null
+cat fifo
# We should have jumped to the old version of line 2, assert on kak_selection.
-ui_in '{ "jsonrpc": "2.0", "method": "keys", "params": [ "x" ] }'
-ui_out -until '{ "jsonrpc": "2.0", "method": "refresh", "params": [false] }'