Re: [Autotest] [KVM-AUTOTEST PATCH 3/7] [RFC] Introduce exception context strings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jan 03, 2011 at 09:48:02PM +0200, Michael Goldish wrote:
> On 01/03/2011 09:26 PM, Eduardo Habkost wrote:
> > On Mon, Jan 03, 2011 at 08:34:07PM +0200, Michael Goldish wrote:
> >> +# Exception context information:
> >> +# ------------------------------
> >> +# Every function can have some context string associated with it.
> >> +# The context string can be changed by calling context(str) and cleared by
> >> +# calling context() with no parameters.
> >> +# get_context() joins the current context strings of all functions in the
> >> +# provided traceback.  The result is a brief description of what the test was
> >> +# doing in the provided traceback (which should be the traceback of a caught
> >> +# exception).
> > 
> > I am sure people will eventually forget to call context() to clear
> > previous context calls, and people won't notice until an actual error is
> > raised on another section.
> > 
> > What about a decorator like:
> > 
> > @context("hello")
> > def a()
> >     ...
> > 
> > That would set/clear the context automatically when the function is
> > called/returns?
> 
> - In most cases it isn't necessary. The context dict maps whole stack
> traces to context strings, which means that if a function is called
> twice from different places in the code, it won't have the same context
> string.  The only problematic case is functions that are called in loops
> and declare context strings.  I suppose those should be rare, and all
> they need to do to prevent the problem is call error.context() at the top.
> - A function can (and should) change its context string at runtime (for
> example: before reboot, after reboot).  If each function could only
> declare a single context, we could just use the function's name and we
> wouldn't need a context.

OK, I am convinced about the general features of the API (one context
per function call).

Now, about the internal implementation: what about something to avoid
using the stack trace tricks on context()? Basically what you need is
something that adds a new "context entry" when a function is called and
clear it once the function returns.

What about a decorator tyat indicates "this function will push/pop a context
when it is called/returns"? It looks much simpler than doing the tricks
involving the stack on every context() call.


e.g. I would find something like the following much easier to understand:

CTX = threading.local()
CTX.contexts = []

def context(s):
    """Change current context"""
    CTX.contexts[-1] = s

def new_context(s):
    """Push new context in the stack"""
    CTX.contexts.append(s)

def clear_context():
    """Remove current context from the stack"""
    CTX.contexts.pop()

def get_context():
    return " --> ".join(CTX.contexts)

def context_aware(fn):
    # quick solution. using decorator util functions to keep function metadata would be better
    def docall(*args, **kwargs):
        new_context("[%s function begin]" % (fn.__name__))
        try:
            return fn(*args, **kwargs)
        finally:
            clear_context()
    return docall


### sample usage:
@context_aware
def a():
    context("hello")
    b()
    context("world")
    print 'b:',get_context() # ----> 'world'

@context_aware
def b():
    context("foo")
    c()

@context_aware
def c():
    context("bar")
    print 'c:',get_context() # ----> 'hello --> foo --> bar'

-- 
Eduardo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux