|  | # Integration Test utilities | 
|  |  | 
|  | There are several test utilities that can be used to simulate or force behavior | 
|  | on devices for the purposes of testing. | 
|  |  | 
|  | When using any of these utilities it is important to inject the errors at the | 
|  | point where they are running through the MOST code that they can. | 
|  |  | 
|  | If the cluster uses the | 
|  | [ClusterLogic](../cluster_and_device_type_dev/unit_testing_clusters.md) pattern, | 
|  | this means injecting errors as close as possible to the driver layer, rather | 
|  | than catching errors in the server. | 
|  |  | 
|  | ## TestEventTriggers | 
|  |  | 
|  | TestEventTriggers are used to test interactions on the DUT that are difficult to | 
|  | perform during certification testing (ex. triggering a smoke alarm) | 
|  |  | 
|  | **These should be used sparingly!** | 
|  |  | 
|  | TestEventTriggers are started though a command in the General Diagnostics | 
|  | cluster. The command takes a “test key” and a “trigger code” to request that a | 
|  | device to perform a specific action. Currently most devices use a default key, | 
|  | but it can be overridden by a specific device if required. | 
|  |  | 
|  | **TestEventTriggers need to be turned off outside of certification tests** | 
|  |  | 
|  | To use these triggers: | 
|  |  | 
|  | -   Derive from | 
|  | [TestEventTriggerHandler](https://github.com/project-chip/connectedhomeip/blob/master/src/app/TestEventTriggerDelegate.h) | 
|  | -   Implement HandleEventTrigger function | 
|  | -   Register with TestEventTriggerDelegate::AddHandler | 
|  |  | 
|  | Please see | 
|  | [EnergyEvseTestEventTriggerHandler](https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/energy-evse-server/EnergyEvseTestEventTriggerHandler.h) | 
|  | for a good example. | 
|  |  | 
|  | ## NamedPipes | 
|  |  | 
|  | NamedPipes are used to trigger actions on Linux applications. These can be used | 
|  | in the CI, and are normally used to simulate manual actions for CI integration. | 
|  | Any required manual action in a test (ex. push a button) should have a | 
|  | corresponding NamedPipe action to allow the test to run in the CI. | 
|  |  | 
|  | In python tests, the app-pid required to access the named pipe can be passed in | 
|  | as a flag (--app-pid). | 
|  |  | 
|  | NamedPipes are implemented in | 
|  | [NamedPipeCommands.h](https://github.com/project-chip/connectedhomeip/blob/master/examples/platform/linux/NamedPipeCommands.h) | 
|  |  | 
|  | To use NamedPipes | 
|  |  | 
|  | -   Derive from NamedPipeCommandDelegate | 
|  | -   Implement the OnEventCommandReceived(const char \* json) function | 
|  | -   Instantiate and start a NamedPipeCommands object to receive commands and | 
|  | pass in the NamedPipeCommandDelegate and a file path base name | 
|  | -   (while running) Write to the file (baseName_pid) to trigger the actions | 
|  |  | 
|  | For a good example, see Air Quality: | 
|  |  | 
|  | -   [Delegate](https://github.com/project-chip/connectedhomeip/blob/master/examples/air-quality-sensor-app/linux/AirQualitySensorAppAttrUpdateDelegate.cpp) | 
|  | -   [main](https://github.com/project-chip/connectedhomeip/blob/master/examples/air-quality-sensor-app/linux/main.cpp) | 
|  | -   [README](https://github.com/project-chip/connectedhomeip/blob/master/examples/air-quality-sensor-app/linux/README.md) | 
|  |  | 
|  | [RVC Clean Mode](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/TC_RVCCLEANM_2_1.py) | 
|  | gives an example of how to use named pipes in testing. | 
|  |  | 
|  | ## Fault Injection | 
|  |  | 
|  | Fault injection is used to inject conditional code paths at runtime, e.g. | 
|  | errors. This is very useful for things like client testing, to check error | 
|  | handling for paths that are difficult to hit under normal operating conditions. | 
|  |  | 
|  | The fault injection framework we are currently using is nlFaultInjection.The | 
|  | framework uses a macro for injecting the code paths, and the macro is set to a | 
|  | no-op if the option is turned off at compile time. The build option to turn on | 
|  | fault inject is `chip_with_nlfaultinjection`. | 
|  |  | 
|  | Fault injection has been plumbed out through a manufacturer-specific | 
|  | [fault injection cluster](#fault-injection-cluster) that is available in the | 
|  | SDK. This allows fault injection to be turned on and off using standard cluster | 
|  | mechanisms during testing. For certification, operating these using a secondary, | 
|  | non-DUT controller is recommended. For a good example of this, please see | 
|  | [TC-IDM-1.3](https://github.com/CHIP-Specifications/chip-test-plans/blob/master/src/interactiondatamodel.adoc#tc-idm-1-3-batched-commands-invoke-request-action-from-dut-to-th-dut_client). | 
|  |  | 
|  | The nlFaultInjection allows the application to define multiple managers. In the | 
|  | SDK, we have managers for System, inet and CHIP. CHIP should be used for | 
|  | anything above the system layer (basically all new cluster development). The | 
|  | CHIP fault manager is available at | 
|  | [lib/support/CHIPFaultInjection.h](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPFaultInjection.h). | 
|  |  | 
|  | To add new fault injection code paths: | 
|  |  | 
|  | -   Add new IDs (aFaultID) to the enum in | 
|  | [CHIPFaultInjection](https://github.com/project-chip/connectedhomeip/blob/master/src/lib/support/CHIPFaultInjection.h) | 
|  | -   add CHIP_FAULT_INJECT(aFaultID, aStatements) at the point where the fault | 
|  | injection should occur | 
|  |  | 
|  | ### Fault Injection example | 
|  |  | 
|  | ``` | 
|  | CHIP_ERROR CASEServer::OnMessageReceived(Messaging::ExchangeContext * ec, | 
|  | const PayloadHeader & payloadHeader, | 
|  | System::PacketBufferHandle && payload) | 
|  | { | 
|  | MATTER_TRACE_SCOPE("OnMessageReceived", "CASEServer"); | 
|  |  | 
|  | bool busy = GetSession().GetState() != CASESession::State::kInitialized; | 
|  | CHIP_FAULT_INJECT(FaultInjection::kFault_CASEServerBusy, busy = true); | 
|  | if (busy) | 
|  | { | 
|  | … | 
|  | ``` | 
|  |  | 
|  | ### Fault Injection cluster | 
|  |  | 
|  | The Fault injection cluster is a manufacturer-specific cluster, available in the | 
|  | SDK (0xFFF1FC06). | 
|  |  | 
|  | -   [server](https://github.com/project-chip/connectedhomeip/blob/master/src/app/clusters/fault-injection-server/fault-injection-server.cpp) | 
|  | -   [xml](https://github.com/project-chip/connectedhomeip/blob/master/src/app/zap-templates/zcl/data-model/chip/fault-injection-cluster.xml) | 
|  |  | 
|  | Example apps can be compiled with this cluster for client-side certification and | 
|  | integration tests. | 
|  |  | 
|  | To use this cluster to turn on a fault, use the FailAtFault command: | 
|  |  | 
|  | -   Type: FaultType - use FaultType::kChipFault (0x03) | 
|  | -   Id: int32u - match the ID you set up for your fault | 
|  | -   NumCallsToSkip: int32u - number of times to run normally | 
|  | -   NumCallsToFail: int32u - number of times to hit the fault injection | 
|  | condition after NumCallsToSkip | 
|  | -   TakeMutex: bool - controls access to the fault injection manager for | 
|  | multi-threaded systems. False is fine. |