Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pytest-xdist issues when libtmux > v0.16.1 #468

Closed
cidrblock opened this issue Jan 10, 2023 · 14 comments · Fixed by #523
Closed

pytest-xdist issues when libtmux > v0.16.1 #468

cidrblock opened this issue Jan 10, 2023 · 14 comments · Fixed by #523

Comments

@cidrblock
Copy link

cidrblock commented Jan 10, 2023

We use libtmux for testing ansible-navigator and have the version pinned at 0.16.1.

I've installed the latest version v0.19.1 and if the tests are run with pytest-xdist and the number of CPUs > 1 the following errors are generated:

E           libtmux._internal.query_list.ObjectDoesNotExist: Could not find pane_id=%204 for list-panes

I'm still digging into it, but wanted to get an issue logged early.

What more information can I provide? How can I help?

Thanks, brad

(TY for libtmux BTW, I'm not sure what we would do without it)

@tony
Copy link
Member

tony commented Jan 10, 2023

@cidrblock Thank you! If you could provide more of the traceback, I can give my full attention to it this weekend

  • tmux version
  • full traceback (to see where in libtmux it's tripping up)
  • a snippet of libtmux code where the error is happening (or perhaps linking to the code in the repo)
  • steps to reproduce in ansible navigator (I assume its happening there)
  • If time isn't a problem: Enough to reproduce it reliably and independent of ansible-navigator, if possible (if that's too intensive I can clone the repo and try to reproduce locally)

(TY for libtmux BTW, I'm not sure what we would do without it)

Thank you!

@cidrblock
Copy link
Author

I'm trying to create a repro, will be in touch.

thanks, Brad

@tony
Copy link
Member

tony commented Jan 12, 2023

Sounds good!

@tony
Copy link
Member

tony commented Jan 28, 2023

@cidrblock This doesn't necessarily need a full reproduction (that may be prohibitively difficult)

If there's a more fuller traceback / etc. I can look at that as well.

@tony
Copy link
Member

tony commented Jan 29, 2023

@cidrblock If you try v0.21.0 (which includes #475), is anything different?

@cidrblock
Copy link
Author

I need to get back to this.... Will try next week. I few other things popped up that needed attention.

talk soon

@tony
Copy link
Member

tony commented Apr 14, 2023

@cidrblock Sounds good. This is a priority since we definitely want libtmux to be xdist compatible

@sgherdao
Copy link

Hi, I think I am facing the same issue.

To reproduce the problem:

  1. Attach a tmux session
tmux new -A -s main
  1. run the following code repro.py
import libtmux
tmux_server = libtmux.Server()
session = tmux_server.new_session(session_name="repro-bug", kill_session=True)
window = session.windows[0]
window.rename_window("BOOM")

The traceback

Traceback (most recent call last):
  File "bug-repro-libtmux.py", line 6, in <module>
    window.rename_window("BOOM")
  File "/...site-packages/libtmux/window.py", line 480, in rename_window
    self.refresh()
  File "/...site-packages/libtmux/window.py", line 84, in refresh
    return super()._refresh(
           ^^^^^^^^^^^^^^^^^
  File "/...site-packages/libtmux/neo.py", line 175, in _refresh
    obj = fetch_obj(
          ^^^^^^^^^^
  File "/...site-packages/libtmux/neo.py", line 244, in fetch_obj
    raise ObjectDoesNotExist(
libtmux._internal.query_list.ObjectDoesNotExist: Could not find window_id=@2 for list-windows

Done some digging

❯ export PYTHONBREAKPOINT=ipdb.set_trace

❯ python bug-repro-libtmux.py

Some debugging with comments

ipdb> bt
bug-repro-libtmux.py(6)<module>()
4 session = tmux_server.new_session(session_name="repro-bug", kill_session=True)
5 window = session.windows[0]
----> 6 window.rename_window("BOOM")

.../libtmux/window.py(480)rename_window()
479
--> 480 self.refresh()
481

.../libtmux/window.py(84)refresh()
83 assert isinstance(self.window_id, str)
---> 84 return super().\_refresh(
85 obj_key="window_id",

.../libtmux/neo.py(175)\_refresh()
174 assert isinstance(obj_id, str)
--> 175 obj = fetch_obj(
176 obj_key=obj_key, obj_id=obj_id, list_cmd=list_cmd, server=self.server

> .../libtmux/neo.py(243)fetch_obj()

    242     breakpoint()

--> 243 if obj is None:
244 raise ObjectDoesNotExist(
#
# We can see that only the window for the current session is returned 
# and not the one we are looking for so ObjectDoesNotExist will raise
#
ipdb> obj_id
'@17'
ipdb> obj_key
'window_id'
ipdb> pp [(x["window_name"], x["window_id"]) for x in obj_formatters_filtered]
[('python3.11', '@16')]
#
# Re-run fetch_obj but we will modify list_extra_args from None to ["-a"]
#
ipdb> jump 234

> .../libtmux/neo.py(234)fetch_obj()

    233 ) -> OutputRaw:

--> 234 obj_formatters_filtered = fetch_objs(
235 server=server, list_cmd=list_cmd, list_extra_args=list_extra_args
# 
# HACK make libtmux run tmux list-windows -a (list all windows of all sessions)
# 
ipdb> list_extra_args = ["-a"] 
ipdb> pp [(x["window_name"], x["window_id"]) for x in obj_formatters_filtered]
[('python3.11', '@16')]
ipdb> until 238

> .../libtmux/neo.py(238)fetch_obj()

    237

--> 238 obj = None
239 for \_obj in obj_formatters_filtered:

# You can see now that the window from the new session is returned

ipdb> pp [(x["window_name"], x["window_id"]) for x in obj_formatters_filtered]
[('python3.11', '@16'), ('BOOM', '@17')]
ipdb> obj_id
'@17'
ipdb> obj_key
'window_id'

# 
# and the script exits gracefully 
# 
ipdb> c

hope this gives some pointers and thx for the lib :)

@sgherdao
Copy link

A workaround that seems to work for me is to use .cmd() to bypass the code.

import libtmux
import os
tmux_server = libtmux.Server()
session = tmux_server.new_session(session_name="repro-bug", kill_session=True)
window = session.windows[0]
window.cmd("rename-window", "BOOM")

@tony tony added the pinned label May 27, 2023
@tony tony pinned this issue May 27, 2023
@tony
Copy link
Member

tony commented May 27, 2023

@cidrblock Pinning this, in re: ansible/ansible-navigator#1380

Thank you as well for the additional info @sgherdao

@ssbarnea
Copy link
Contributor

ssbarnea commented Feb 13, 2024

@tony Any chance we could get a fix on this bug. Being forced to use an ancient version of libtmux is more like a playing with a grenade. I tried latest release and i still not working, so we are stuck with 0.16.1 for now.

Usually I would have tried to make a fix it myself but sadly my tmux knowledge is not up for that.

@tony
Copy link
Member

tony commented Feb 13, 2024

@ssbarnea Yes, happy to escalate this.

@tony
Copy link
Member

tony commented Feb 15, 2024

@cidrblock @ssbarnea @sgherdao The above issue will be resolved by #523.

TLDR: It was caused by refreshing not passing -a to list-windows / list-panes.

@tony tony closed this as completed in #523 Feb 15, 2024
tony added a commit that referenced this issue Feb 15, 2024
Resolves #468.

# Changes

## Breaking changes

- `Session.new_window()` + `Window.split_window()`: No longer `attach` by default. Pass `attach=True` for the old behavior.
- `Pane.resize_pane` renamed to `Pane.resize()`

## `Window.resize_window()`: Added

If `Pane.resize_pane()` didn't work before, try resizing the window.

## `Pane.resize()`: Arguments added

## `Server.panes`: Fix listing of panes

Would list only panes in attached session, rather than all in a server.

## `Window.refresh()` and `Pane.refresh()`: Refresh more underlying state

## `Obj._refresh`: Allow passing args

e.g. `-a` (all) to `list-panes` and `list-windows`
@tony
Copy link
Member

tony commented Feb 15, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants