This is an automated email from the ASF dual-hosted git repository.
pengzheng pushed a commit to branch feature/error_injector
in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to refs/heads/feature/error_injector by this
push:
new f9b8fee5 Add documentation for error injector.
f9b8fee5 is described below
commit f9b8fee56c2026886f0b3049382c3b960fd0039d
Author: PengZheng <[email protected]>
AuthorDate: Tue Jan 24 17:46:17 2023 +0800
Add documentation for error injector.
---
libs/error_injector/README.md | 81 ++++++++++++++++++++++++++
libs/error_injector/api/celix_error_injector.h | 5 ++
2 files changed, 86 insertions(+)
diff --git a/libs/error_injector/README.md b/libs/error_injector/README.md
new file mode 100644
index 00000000..7b65b6ef
--- /dev/null
+++ b/libs/error_injector/README.md
@@ -0,0 +1,81 @@
+---
+title: Error Injector
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Celix Error Injector
+
+Error handling path is infamously difficult to test.
+To achieve high testing coverage, some extra mechanism is generally needed to
emulate various error conditions in the testing environment.
+Such mechanism, as [SQLite's test
VFS](https://www.sqlite.org/src/doc/trunk/src/test_vfs.c), tends to be
heavy-weight and requires a lot of efforts to implement.
+
+Celix Error Injector provides a lightweight alternative way.
+As its name suggests, Celix Error Injector enables you to inject arbitrary
errors into target function call very easily.
+You only have to:
+
+1. Implement a simple stub module for your target API under this folder.
+2. Link it into your test executable.
+3. Specify the target function call you want to injector specific error into
with a single function call before the code under test runs.
+4. Disable error injector during the TearDown phase of the test. Forgetting
this step may interrupt other tests.
+
+## Example Usage
+
+```c++
+#include <gtest/gtest.h>
+#include <iostream>
+#include <cstring>
+#include "malloc_ei.h"
+
+#include "pubsub_wire_protocol_common.h"
+
+class WireProtocolCommonEiTest : public ::testing::Test {
+public:
+ WireProtocolCommonEiTest() = default;
+ ~WireProtocolCommonEiTest() override {
+ celix_ei_expect_calloc(nullptr, 0, nullptr);
+ };
+};
+
+TEST_F(WireProtocolCommonEiTest,
WireProtocolCommonTest_NotEnoughMemoryForMultipleEntries) {
+ pubsub_protocol_message_t message;
+ message.header.convertEndianess = 1;
+ message.metadata.metadata = nullptr;
+
+ char* data =
strdup("ABCD4:key1,6:value1,4:key2,6:value2,6:key111,8:value111,"); //note 3
entries
+ auto len = strlen(data);
+ pubsubProtocol_writeInt((unsigned char*)data, 0,
message.header.convertEndianess, 3);
+ for (int i = 0; i < 6; ++i) {
+ celix_ei_expect_calloc((void *)pubsubProtocol_decodeMetadata/* caller
*/, 0, nullptr, i+1/* ordinal */);
+ auto status = pubsubProtocol_decodeMetadata((void*)data, len,
&message);
+
+ EXPECT_EQ(status, CELIX_ENOMEM);
+ EXPECT_EQ(nullptr, message.metadata.metadata);
+ }
+ free(data);
+}
+```
+
+In the above test, `pubsubProtocol_decodeMetadata` makes six calls to `calloc`.
+Failure in any of the six calls should return `CELIX_ENOMEM`.
+`celix_ei_expect_calloc((void *)pubsubProtocol_decodeMetadata, 0, nullptr,
i+1)` specifies only the (i+1)-th call made by `pubsubProtocol_decodeMetadata`
should fail.
+
+
+Note that `caller` does not always work, especially if the caller is a static
function (not visible outside the translation unit).
+In this case, you should specify `CELIX_EI_UNKNOWN_CALLER` for `caller`, and
rely solely on the `ordinal` parameter to specify which call to injector error
into.
+Note also that `celix_ei_expect_calloc(nullptr, 0, nullptr)` is called to
disable error injector for `calloc` in the destructor.
\ No newline at end of file
diff --git a/libs/error_injector/api/celix_error_injector.h
b/libs/error_injector/api/celix_error_injector.h
index 440ce757..75e717d5 100644
--- a/libs/error_injector/api/celix_error_injector.h
+++ b/libs/error_injector/api/celix_error_injector.h
@@ -27,6 +27,11 @@ extern "C" {
#include <dlfcn.h>
#include <stddef.h>
+/**
+ * @brief This macro find the address of target function's caller, or caller's
caller.
+ * The level argument is number of frames to scan up the call stack: 0 means
caller, 1 means caller's caller.
+ * The result is stored in the addr argument.
+ */
#define CELIX_EI_GET_CALLER(addr, level) \
do { \
Dl_info dlinfo; \