Skip to content

Commit

Permalink
doc: Update developers-guide
Browse files Browse the repository at this point in the history
- communicate regarding YANG
- add StatD with focus on Yanger
- add test dev procedures

[ci skip]

Resolves #934
  • Loading branch information
axkar committed Feb 17, 2025
1 parent 8eaaaa9 commit 8f30f88
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 29 deletions.
58 changes: 58 additions & 0 deletions doc/developers-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,59 @@ Now you can rebuild `confd`, just as described above, and restart Infix:
make confd-rebuild all run


### `statd`

The Infix status daemon, `src/statd`, is responsible for populating the
sysrepo `operational` datastore. Like `confd`, it uses XPath subscriptions,
but unlike `confd`, it relies entirely on `yanger`, a Python script that
gathers data from local linux services and feeds it into sysrepo.

To apply changes, rebuild the image:

make python-statd-rebuild statd-rebuild all

Rebuilding the image and testing on target for every change during
development process can be tedious. Instead, `yanger` allows remote
execution, running the script directly on the host system (test
container):

infamy0:test # ../src/statd/python/yanger/yanger -x "../utils/ixll -A ssh d3a" ieee802-dot1ab-lldp

`ixll` is a utility script that lets you run network commands using an
**interface name** instead of a hostname. It makes operations like
`ssh`, `scp`, and network discovery easier.

Normally, `yanger` runs commands **locally** to retrieve data
(e.g., `lldpcli` when handling `ieee802-dot1ab-lldp`). However, when
executed with `-x "../utils/ixll -A ssh d3a"` it redirects these
commands to a remote system connected to the local `d3a` interface via
SSH. This setup is used for running `yanger` in an
[interactive test environment](testing.md#interactive-usage). The yanger
script runs on the `host` system, but key commands are executed on the
`target` system.

For debugging or testing, you can capture system command output and
replay it later without needing a live system.

To capture:

infamy0:test # ../src/statd/python/yanger/yanger -c /tmp/capture ieee802-dot1ab-lldp

To replay:

infamy0:test # ../src/statd/python/yanger/yanger -r /tmp/capture ieee802-dot1ab-lldp

This is especially useful when working in isolated environments or debugging
issues without direct access to the DUT.

### Agree on YANG Model

When making changes to the `confd` and `statd` services, you will often need to update
the YANG models. If you are adding a new YANG module, it's best to follow the
structure of an existing one. However, before making any changes, **always discuss
them with the Infix core team**. This helps avoid issues later in development and
makes pull request reviews smoother.

Testing
-------

Expand All @@ -175,6 +228,11 @@ The Infix automated test suite is built around Qemu and [Qeneth][2], see:
* [Testing](testing.md)
* [Docker Image](../test/docker/README.md)

With any new feature added to Infix, it is essential to include a
relevant test case. See the
[Test Development](testing.md#test-development) section for guidance
on adding test cases.


Reviewing
---------
Expand Down
26 changes: 9 additions & 17 deletions doc/test-arch.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,23 +243,15 @@ spanning tree matches the expected one.

Integration to Infix
--------------------
To successfully run all Infix tests, the image must be built in
'test-mode'. This can be achieved by setting the DISK_IMAGE_TEST_MODE
parameter to true. Although this is the default setting, it’s advisable
to verify it by running:

$ make menuconfig
(External Options --> -*- Disk image --> [*] Enable Test Mode)

Building an image in 'test-mode' results in the creation of a 'test-mode'
file within the auxiliary (aux) partition of the Infix disk image
(/mnt/aux/test-mode).

During the bootstrap phase, the system checks for the presence of this
test-mode flag (file). If the flag exists, a 'test-config.cfg' file is
generated. In the following step, the system loads the 'test-config'
instead of the standard startup-config (or factory-config). This
configuration is simple and safe, equivalent to the one used in 'Secure Mode'
When the test environment is started with Qeneth, it doesn't use the
base image directly. Instead, it creates a copy and inserts a `test-mode`
flag into it. During the bootstrap phase, the system checks for the
presence of the test-mode flag (file).

If the flag exists, a 'test-config.cfg' file is generated. In the
following step, the system loads the 'test-config' instead of the
standard `startup-config` (or `factory-config`). This configuration
is simple and safe, equivalent to the one used in 'Secure Mode'
(also known as 'failure-config').

Additionally, the configuration enables extra RPCs related to system
Expand Down
63 changes: 51 additions & 12 deletions doc/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,6 @@ for `x86_64`:
$ make
$ make test

It is important to mention that Infix build system by default creates
an image in 'test-mode'. The mode is set by DISK_IMAGE_TEST_MODE
parameter (default=true). To generate a standard image set the
DISK_IMAGE_TEST_MODE to 'false'. However, only the test mode ensures
that all Infix tests are executed properly. Prior to the set of commands
above, it is always good to check that DISK_IMAGE_TEST_MODE is properly
set by running:

$ make menuconfig
(External Options --> -*- Disk image --> [*] Enable Test Mode)

### Physical Devices

To run the tests on a preexisting topology from the host's network
Expand Down Expand Up @@ -99,8 +88,11 @@ arguments:
To run a suite of tests, e.g., only the DHCP client tests, pass the
suite as an argument to [9PM][]:

11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/all.yaml
11:42:53 infamy0:test # ./9pm/9pm.py case/infix_dhcp/infix_dhcp.yaml

To run the suite of all tests:

11:42:53 infamy0:test # ./9pm/9pm.py case/all.yaml

### Connecting to Infamy

Expand Down Expand Up @@ -315,5 +307,52 @@ The test specifaction can be genererated with:

$ make test-spec

### Test Development

For adding a new test to the automated regression test suite, it's best
to start by reviewing an existing test case.

All tests are located in the `infix/test/case` repository and are
grouped by the features they verify. For example,
`infix/test/case/infix_services` contains tests for various Infix
services, such as LLDP and mDNS.

While test grouping is flexible, each test should be placed in a
logically relevant category.

When creating a new test group, add it to `infix/test/case/all.yaml`,
to enable it to run as a
[subset of the test suite](#running-subsets-of-tests):

```
- name: infix-services
suite: infix_services/infix_services.yaml
```

A new test (e.g., lldp_enable_disable) should be added to the
corresponding test group .yaml file, such as
`infix/test/cases/infix_services.yaml`:

```
- name: lldp_enable_disable
case: lldp_enable_disable/test.py
```

It is necessary to include the test in
`infix/test/case/infix_services/Readme.adoc` to ensure proper test
specification generation:

```
include::lldp_enable_disable/Readme.adoc[]
```

Each test case should have its own directory under,
`infix/test/case/infix_services`, containing:
- `test.py` - the test script
- `topology.dot` - the logical topology definition.

When the [test specification](#test-specification) is generated,
`topology.svg` and `Readme.adoc` should also be created.

[9PM]: https://github.com/rical/9pm
[Qeneth]: https://github.com/wkz/qeneth

0 comments on commit 8f30f88

Please sign in to comment.