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-lsp: See server's STDERR in pytest output #143

Closed
tobb10001 opened this issue Feb 4, 2024 · 7 comments · Fixed by #147
Closed

pytest-lsp: See server's STDERR in pytest output #143

tobb10001 opened this issue Feb 4, 2024 · 7 comments · Fixed by #147
Labels
enhancement New feature or request pytest-lsp Issues affecting the pytest-lsp package

Comments

@tobb10001
Copy link
Contributor

Or: How to debug the server behind pytest?

For debugging, I usually

  • set up a test to reproduce the behaviour
  • run the test case
  • use the logging from my system to trace what's happening

Unfortunately I haven't found a way to access the logs of my server with pytest-lsp in a nice way. I think it would be great to see the server's STDERR output in the console right next to the test results (or have an option for this behaviour), just as pytest does by default when working with pure Pyhon systems. I think this could work by just forwarding the server subprocess' STDERR to the test process STDERR.

My current workaround is to have my server log to a file and check that in another terminal, but that's kind of tedious.

@tobb10001
Copy link
Contributor Author

tobb10001 commented Feb 4, 2024

Tried to make this work, seems harder then I'd hoped.

I took the capturing that happens in LanguageClient.server_exit(), stored it into an instance variable, and output it after the yield in the fixture.

It seems like pytest only captures during the execution of the test case, not during a fixture.

Another option would be to not use stderr=subprocess.PIPE, but that's impractical because (a) that's done in pygls and can't be done here and (b) it would interfere with existing functionality.

@alcarney
Copy link
Member

alcarney commented Feb 5, 2024

How to debug the server behind pytest?

I tend to forward the server's log output via window/logMessage notifications, pytest-lsp is usually able to attach those to failure reports.

But I agree, having pytest-lsp also expose the server's stderr would be useful 🤔
One approach that might work, would be to spawn an async task that continually calls stderr.readline() and prints the result to stderr...

@alcarney alcarney added enhancement New feature or request pytest-lsp Issues affecting the pytest-lsp package labels Feb 5, 2024
@alcarney
Copy link
Member

alcarney commented Feb 5, 2024

One approach that might work, would be to spawn an async task that continually calls stderr.readline() and prints the result to stderr...

Just tried it out, looks like it should work! I'll try and get something out to play with soon.

@tobb10001
Copy link
Contributor Author

tobb10001 commented Feb 6, 2024

Looks interesting, but unfortunately I can't get it to work properly on my end.

The test works, and if I run from the examples directory (manually renaming t_server.py to test_server.py), everything works as desired. However, on other examples it seems doesn't run as smoothly.

I created a test file for myself, which was based on the Getting started, where I just added

for _ in range(10):
    print("Hello stderr.\n", file=sys.stdout)

- with low numbers, I don't see anything in the output
- with high numbers (I tried 1000), the test blocks indefinetely

Forget that, I typoded stderr as stdout, that explains why that didn't work...

However, for my actual project, I also don't see anything. (Should log about 20 lines in debug mode.)

I feel like something in this piping setup causes a deadlock, but unfortunately I'm way to unexperienced with asyncio to debug this.

I could find out that I didn't actually log to stderr here either, because my logging setup was incorrect.

I want to try out what happens when the coroutine is replaced by a thread. Don't know if it would be a good solution, but I wanna see what happens.

UPDATE: The thread solution doesn't seem to be so promising either. Since the subprocess is started by the asyncio machinery, the interface can't be easily accessed from another thread. At least not with my knowledge at least...

TL:DR: Sorry for this mess of a comment. I've tested the code in your PR and it works as desired.

@alcarney
Copy link
Member

alcarney commented Feb 6, 2024

TL:DR: Sorry for this mess of a comment. I've tested the code in your PR and it works as desired.

No worries! It's exciting to see someone interested enough in this that they're willing to get hands on with it!

@alcarney
Copy link
Member

alcarney commented Feb 7, 2024

v0.4.1 is out containing this functionality, let me know if you run into any issues

@windelbouwman
Copy link

This works like a charm. Configure your server logger with logging.basicConfig. This will setup a logger writing to stderr, which is captured by pytest-lsp, which in turn is captured by pytest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request pytest-lsp Issues affecting the pytest-lsp package
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants