1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-23 00:00:06 +01:00
libwebsockets/READMEs/README.fault-injection.md
2021-02-20 13:54:35 +00:00

92 lines
3.9 KiB
Markdown

# `lws_fi` Fault Injection
To provide better quality there's a need to not just test the code paths for
normal operation, but also that it acts correctly under various fault
conditions that may be difficult to arrange at test-time.
Code handling the failures may be anywhere including during early initialization
or in user code before lws intialization.
To help with this lws has `LWS_WITH_SYS_FAULT_INJECTION` build option that
provides a simple but powerful api for fault injection in any lws or user code.
## Fault contexts and faults
`lws_fi_t` objects represent a named fault injection rules, just in terms of
whether and how often to inject the fault.
`lws_fi_ctx_t` objects are linked-lists of `lws_fi_t` objects. When Fault
Injection is enabled at build-time, the key system objects like the
`lws_context`, `lws_vhost`, `wsi` and Secure Stream handles / SSPC handles
contain their own `lws_fi_ctx_t` lists that may have any number of `lws_fi_t`
added to them.
`lws_fi_ctx_t` objects are hierarchical, if a named rule is not found in, eg,
a wsi Fault injection context, then the vhost and finally the lws_context Fault
Injection contexts are searched for it before giving up. This allows for both
global and individual overridden Fault Injection rules at each level.
## Integrating fault injection conditionals into code
A simple api `lws_fi(fi_ctx, "name")` is provided that returns 0 if no fault to
be injected, or 1 if the fault should be synthesized. If there is no rule
matching "name", the answer is always to not inject a fault, ie, returns 0.
By default then just enabling Fault Injection at build does not have any impact
on code operation since the user must first add the fault injection rules he
wants.
The api keeps track of each time the context was asked and uses this information
to drive the decision about when to say yes, according to the type of rule
|Injection rule type|Description|
|---|---|
|`LWSFI_ALWAYS`|Unconditionally inject the fault|
|`LWSFI_DETERMINISTIC`|after `pre` times without the fault, the next `count` times exhibit the fault`|
|`LWSFI_PROBABILISTIC`|exhibit a fault `pre` percentage of the time|
|`LWSFI_PATTERN`|Reference `pre` bits pointed to by `pattern` and fault if the bit set|
## Addings Fault Injection Rules to `lws_fi_ctx_t`
User code should prepare a `lws_fi_ctx_t` cleared down to zero if necessary,
and one of these, eg on the stack
```
typedef struct lws_fi {
const char *name;
uint8_t *pattern;
uint64_t pre__prob1;
uint64_t count__prob2;
char type; /* LWSFI_* */
} lws_fi_t;
```
and call `lws_fi_add(lws_fi_ctx_t *fic, const lws_fi_t *fi);`, this will
allocate and copy the provided `fi` into the allocation, and attach it to
the `lws_fi_ctx_t` list.
The creation info struct associated with the context, vhost, wsi or Secure
Stream has a `*fi` pointer you can set to your `lws_fi_ctx_t`, when creating
the object it will take ownership of any `lws_fi_t` you attached to it.
So the `lws_fi_ctx_t` and the `lws_fi_t` used as a template for adding the
rules may be on the stack and safely and go out of scope after the object
creation api is called. The `lws_fi_t` `name` is also copied into the
allocation and does not need to continue to exist after it is added to the
`lws_fi_ctx_t`. The only exception is the `pattern` member if used, the
array pointed to is not copied and must exist for the lifetime of the rule.
## Passing in fault injection rules
A key requirement is that Fault Injection rules must be availble to the code
creating an object before the object has been created. This is why the user
code prepares a temporary context listing his rules, and offers it as part of
the creation info struct, rather than waiting for the object to be created and
then attach Fault Injection rules... it's too late to test faults during the
creation by then otherwise.
## Using the namespace to target specific instances
Wsi client connection can directly have fault injection objects attached to it
at client connection creation time.