feat: enable interactive debugging via breakpoint in testing#2363
Conversation
This breaks lots of tests because we drop into an interactive debug session on any charm exception!
This reverts commit aa54ebe.
tonyandrewmeyer
left a comment
There was a problem hiding this comment.
This solution works for me.
I wonder if it would be cleaner if framework.set_breakpointhook had the logic to check the environment variable, but that is more of an invasive change, and maybe the hook breakpoint wouldn't work with that? I haven't looked at the Ops code in detail.
I'm not sure I understand how that approach would work. Do you mean if |
Yes. But like I said I hadn't looked into it to see if it would work or not, it just seemed like maybe the framework approach wasn't the right one given how this is used. But your explanation makes sense, and I'm still good with doing this specifically in Scenario. |
This PR enables interactive debugging via
breakpointcalls in charm code in state-transition tests, by preventing Ops from redefiningsys.breakpointhookwhen charm code is executed withtesting.Context.run.Resolves #2166.
Issue
In
main, Ops unconditionally overridessys.breakpointhookwith theops.Framework.breakpointmethod. This happens whenops._main._Manager._make_frameworkcallsops.Framework.set_breakpointhook.Framework.breakpointdoes nothing unlessJUJU_DEBUG_ATis set. This means you can deploy a charm that callsbreakpoint(orself.framework.breakpoint), and those breakpoints will be a no-op until you usejuju debug-code.A consequence of this is that
breakpointcalls in charm code that are being driven byops.testing.Context.runare no-ops, as reported in #2166.Fix
This PR updates the
CapturingFrameworkofops.testingto override theset_breakpointhookmethod with an implementation that does nothing. This means that in tests usingContext.run, breakpoints in charm code will work the same as breakpoints in the test code itself -- dropping the user into an interactive debugger session (or not, ifPYTHONBREAKPOINT=0; or raising an error if running tests across multiple processes withpytest-xdist).Implications
Searching for
breakpointin our known charms shows that it is common to setPYTHONBREAKPOINTtopdb.set_traceoripdb.set_trace, but thatbreakpointcalls in Python code are not checked in.To set breakpoints in charm code that are not triggered during state-transition tests, but will be active when running
juju debug-code, users can either setPYTHONBREAKPOINT=0when running state-transition tests, or useself.framework.breakpointinstead.Documentation
I will be improving the docs for debugging a charm in a separate PR. Unless there's a great place to fit this in right now, I think we can defer documenting this change to that PR.