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

Multiple calls of a guarded() function retain output #37

Closed
SwampFalc opened this issue Jan 18, 2022 · 1 comment
Closed

Multiple calls of a guarded() function retain output #37

SwampFalc opened this issue Jan 18, 2022 · 1 comment

Comments

@SwampFalc
Copy link

SwampFalc commented Jan 18, 2022

Let me first start by saying that this is not an issue in production, as I am fully aware there should be only one call of the actual guarded() code.

However, when unittesting the plugin I'm writing, I wanted to ensure the various verbose levels each gave me the right output. So I have one test class, with each verbose level a separate test function in that class and all of them getting run when I do my test.

Because of this approach, I of course need to mock out sys.exit() to allow the tests to finish.

I quickly noticed that the output of verbose level 3 included the one from verbose level 2, although there was no code path that could allow it to be generated.

Debugging the test run revealed that indeed, at the end of the verbose 2 test, something was not getting cleaned up. Further investigation led to the conclusion that the Runtime class has been designed as a singleton, ie. the very same instance is always returned when guarded() asks for a Runtime. Furthermore, Runtime accumulates verbose output and then prints it, but does not afterward empty out that storage. Because the entire test run is a single invocation of the interpreter, this global Runtime instance doesn't get reset between tests and the output just accumulates.

I have implemented a pretty simple workaround, where I set nagiosplugin.runtime.Runtime.instance = None at the start of each test to force it to create a new Runtime each time.

Now I don't really expect this you to solve this for me, but I felt it worth noting in case anyone ever runs into a similar issue.

If you do feel like looking into a solution... I just have to ask, why exactly is Runtime a singleton? I can't see what purpose that serves, nor do I even see where else a Runtime instance is created except in guarded()...

@mpounsett
Copy link
Owner

I can't really speak to the reasoning of the original author and why he chose to implement it that way. If I had to guess I'd say it was done that way in case multiple @guarded() calls were made in the same plugin.. but that would just be a guess. In any case, it shouldn't be implemented that way. Whatever his goals were it's likely there was a better way to get there.

Unfortunately, there's a risk that the behaviour is relied upon by existing plugins, so I'm hesitant to change it now. I've opened #38 as a reminder should I ever get around to do a version 2.x, where it will be possible to change the interface.

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

No branches or pull requests

2 participants