Abstract functions and common functions are located in transport.py
Some quirks has been required due to how rousette works,
these functions has been added to the abstract class
Can be removed when rousette behaves as expected.
This is the only way to delete with restconf so it it must also be
implemented in netconf. This replace the put_diff_dict function.
Also: how the xpath looks is different in restconf/netconf therefore
each protocl has a get_xpath() function as well.
This tries to improve on the existing sniffer in a couple of ways:
- In addition to being usable as a context manager, also allow
explicitly starting and stopping the capture.
- Try to synchronize the start of the capture by snooping stderr and
wait for tcpdump to start up. This should eliminate the need for
sleeps before starting to send packets.
- By default, execute a safety sleep when terminating the capture to
ensure that any straggling packets have had time to arrive at their
destination.
By default, ping(1) will use a random ID in the ICMP packet. Allow
setting it to a fixed value instead.
This makes it easy to identify that particular packet in a packet
capture later on.
Very simple tests work (hostname.py), more complex
tests (static_routing.py) failes due to the lack of
model prefix, for example. infix-ip:ipv4 instead of just
ipv4.
We need to fix this before you send your configuration, run
it through libyang for example and get the full model-name.
In test cases, it is common that we want to verify that a certain type
of traffic reaches a namespace. This has, up to this point, been
solved by the generic sniffer.Sniffer.
Try to improve the two most common use-cases...
1. Test if a flow reaches a namespace
2. Ensure that a flow does not reach a namespace
...by always exiting as soon as the first packet is received.
This saves time on positive tests, and the synchronous API allows it
to compose well with infamy.parallel().
Support the familiar subprocess.run API, and runsh from netns.py.
This should only be used for debugging, or in the rare instances when
we want to test functionality that is not available via NETCONF.
QEMU systems seem work fine with the 5s timeout, whereas some physical
devices can't quite keep up with that.
Let the slower systems indicate that they need a bit more time without
punishing faster ones with a longer default.
This will let other Infamy submodules tune their behavior based on the
particular test system they are running on.
Attributes are defined by creating graph-global attributes with an
"ix_" prefix.
Avoid having log messages stuck in a pipe when stdout is not a tty,
e.g. when running a suite of tests using 9pm.
Two benefits:
- Nicer experience when interactively running a suite
- Timestamps inserted by 9pm are more useful
It turns out that the semantics of ping's -c option does not match our
expectations. The manual says:
> Stop after sending count ECHO_REQUEST packets. With deadline option,
> ping waits for count ECHO_REPLY packets, until the timeout expires.
But in fact, something like an ICMP_DEST_UNREACH will also count as a
response, meaning that the process will terminate with non-zero
exitcode even though the deadline has not yet been crossed, rather
than keep waiting for an ECHO_REPLY.
To add some extra flavor: this is only the case for iputils' ping,
Busybox's implementation will hold out for a response until the
deadline expires.
Therefore, wrap the ping in an ugly retry loop.
Also, return the full available context from must{,_not}_reach on
failures, instead of just the output. This allows us to show the exit
code in the top-level exception handler.
It is not uncommon for subprocesses to fail when developing new tests,
but the default representation of CalledProcessError does not print
the stdout of the program, only that it failed.
Catch this common case when a test is about to fail, and make sure to
log any output it produced.
- Present the topologies to networkx as multigraphs, rather than
expaning each port of the record shape as a separate node.
- Create a topology mapping by locating a subgraph monomorphism of the
logical topology in the physical ditto.
This cuts down the time of finding a mapping by several orders of
magnitude. Example:
Before:
time python3 test/infamy/topology.py \
test/virt/quad/topology.dot.in \
test/infamy/topologies/ring-4-duts.dot >/dev/null
real 13m1,213s
user 13m0,112s
sys 0m0,732s
After:
time python3 test/infamy/topology.py \
test/virt/quad/topology.dot.in \
test/infamy/topologies/ring-4-duts.dot >/dev/null
real 0m0,153s
user 0m0,128s
sys 0m0,024s
- New helper class for container testing
- New helper class to urllib, Furl
Due to extremely weak Python-fu in the undersigned, this patch changes
the __init__.py file to add new helper classes for container tests.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Fix most of what pylint complains about
- Simplify constructs and add missing whitespace
- Simplify output of YANG model downloader
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch handles a corner case we for some reason have not run into
yet. With the new container operational data it was triggered almost
immediately, so let's add some basic guards around it and return None
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Add a helper that lets you call a Python function (or lambda) in the
context of a network samespace.
Example:
with infamy.IsolatedMacVlan("eth0") as ns:
res = ns.call(lambda: subprocess.run(["ip", "link"],
capture_output=True))
print(res.stdout, f"\n[exitcode:{res.returncode}]")
The call to subprocess.run will be executed in the context of the
network namespace, and thus only list "lo" and the "iface"
macvlan.
The return value of the function passed to ns.call() is passed back
over a multiprocessing.Pipe, which requires that the object be
"picklable". This is true for most objects (even more complex ones
like the CompletedProcess object seen in the example above). Some
notable exceptions are things like file objects, sockets, etc.
The setns(2) syscall is unfortunately not available in current
versions of Python shipped with neither Ubuntu nor Alpine at the time
of this writing. Therefore, shoot from the hip, assume that we're
running on an x86_64 CPU, and just hotwire the syscall directly with
some constants we found in a dumpster.