File: fiu.py

package info (click to toggle)
libfiu 1.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 768 kB
  • sloc: ansic: 2,633; python: 973; makefile: 599; sh: 309
file content (118 lines) | stat: -rw-r--r-- 3,389 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""
libfiu python wrapper

This module is a wrapper for the libfiu, the fault injection C library.

It provides an almost one-to-one mapping of the libfiu functions, although its
primary use is to be able to test C code from within Python.

For fault injection in Python, a native library would be more suitable.

See libfiu's manpage for more detailed documentation.
"""

import fiu_ll as _ll


def fail(name):
    "Returns the failure status of the given point of failure."
    return _ll.fail(name)


def failinfo():
    """Returns the information associated with the last failure. Use with
    care, can be fatal if the point of failure was not enabled via
    Python."""
    return _ll.failinfo()


class Flags:
    """Contains the valid flag constants.

    ONETIME: This point of failure is disabled immediately after failing once.
    """

    ONETIME = _ll.FIU_ONETIME


# To be sure failinfo doesn't dissapear from under our feet, we keep a
# name -> failinfo table. See fiu_ll's comments for more details.
_fi_table = {}


def enable(name, failnum=1, failinfo=None, flags=0):
    "Enables the given point of failure."
    _fi_table[name] = failinfo
    r = _ll.enable(name, failnum, failinfo, flags)
    if r != 0:
        del _fi_table[name]
        raise RuntimeError(r)


def enable_random(name, probability, failnum=1, failinfo=None, flags=0):
    "Enables the given point of failure, with the given probability."
    _fi_table[name] = failinfo
    r = _ll.enable_random(name, failnum, failinfo, flags, probability)
    if r != 0:
        del _fi_table[name]
        raise RuntimeError(r)


def enable_external(name, cb, failnum=1, flags=0):
    """Enables the given point of failure, leaving the decision whether to
    fail or not to the given external function, which should return 0 if
    it is not to fail, or 1 otherwise.

    The cb parameter is a Python function that takes three parameters,
    name, failnum and flags, with the same values that we receive.

    For technical limitations, enable_external() cannot take
    failinfo."""
    # in this case, use the table to prevent the function from
    # dissapearing
    _fi_table[name] = cb
    r = _ll.enable_external(name, failnum, flags, cb)
    if r != 0:
        del _fi_table[name]
        raise RuntimeError(r)


def enable_stack_by_name(
    name, func_name, failnum=1, failinfo=None, flags=0, pos_in_stack=-1
):
    """Enables the given point of failure, but only if 'func_name' is in
    the stack.

    'func_name' is be the name of the C function to look for.
    """
    _fi_table[name] = failinfo
    r = _ll.enable_stack_by_name(
        name, failnum, failinfo, flags, func_name, pos_in_stack
    )
    if r != 0:
        del _fi_table[name]
        raise RuntimeError(r)


def disable(name):
    """Disables the given point of failure, undoing the actions of the
    enable*() functions."""
    if name in _fi_table:
        del _fi_table[name]
    r = _ll.disable(name)
    if r != 0:
        raise RuntimeError(r)


def set_prng_seed(seed):
    """Sets the PRNG seed. Don't use this unless you know what you're
    doing."""
    return _ll.set_prng_seed(seed)


def rc_fifo(basename):
    """Enables remote control over a named pipe that begins with the given
    basename. The final path will be "basename-$PID"."""
    r = _ll.rc_fifo(basename)
    if r != 0:
        raise RuntimeError(r)