This is an automated email from the ASF dual-hosted git repository.
fgerlits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
The following commit(s) were added to refs/heads/main by this push:
new 28f5b35 MINIFI-1354: Memory leaks in nanofi and its unittests
28f5b35 is described below
commit 28f5b351ceb7af9932890c7ee1f1f4a86f74f12b
Author: Martin Zink <[email protected]>
AuthorDate: Thu Feb 18 14:22:58 2021 +0100
MINIFI-1354: Memory leaks in nanofi and its unittests
Signed-off-by: Ferenc Gerlits <[email protected]>
This closes #1035
---
nanofi/src/api/nanofi.cpp | 19 ++++++++++++-------
nanofi/src/cxx/Plan.cpp | 2 +-
nanofi/tests/CAPITests.cpp | 8 +++++++-
nanofi/tests/CLogAggregatorTests.cpp | 25 +++++++++++++++----------
nanofi/tests/CSite2SiteTests.cpp | 1 +
5 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/nanofi/src/api/nanofi.cpp b/nanofi/src/api/nanofi.cpp
index 1ba73af..b339a28 100644
--- a/nanofi/src/api/nanofi.cpp
+++ b/nanofi/src/api/nanofi.cpp
@@ -131,20 +131,25 @@ nifi_instance *create_instance_repo(const char *url,
nifi_port *port, const char
return instance;
}
+nifi_instance * acquire_standalone_instance () {
+ if (standalone_instance == nullptr) {
+ auto port_str =
utils::IdGenerator::getIdGenerator()->generate().to_string();
+ nifi_port port{const_cast<char *>(port_str.c_str())};
+ standalone_instance = create_instance("internal_standalone", &port);
+ }
+ return standalone_instance;
+}
+
standalone_processor * create_processor(const char *name, nifi_instance *
instance) {
NULL_CHECK(nullptr, name);
auto ptr = ExecutionPlan::createProcessor(name, name);
if (!ptr) {
return nullptr;
}
- if (instance == NULL) {
- nifi_port port;
- auto port_str =
utils::IdGenerator::getIdGenerator()->generate().to_string();
- port.port_id = const_cast<char*>(port_str.c_str());
- instance = create_instance("internal_standalone", &port);
- }
+ if (instance == nullptr)
+ instance = acquire_standalone_instance();
auto flow = create_new_flow(instance);
- std::shared_ptr<ExecutionPlan> plan(flow);
+ std::shared_ptr<ExecutionPlan> plan(flow, free_flow);
plan->addProcessor(ptr, name);
ExecutionPlan::addProcessorWithPlan(ptr->getUUID(), plan);
return static_cast<standalone_processor*>(ptr.get());
diff --git a/nanofi/src/cxx/Plan.cpp b/nanofi/src/cxx/Plan.cpp
index 4c52e67..d0f8395 100644
--- a/nanofi/src/cxx/Plan.cpp
+++ b/nanofi/src/cxx/Plan.cpp
@@ -135,7 +135,7 @@ void ExecutionPlan::reset() {
process_sessions_.clear();
factories_.clear();
location = -1;
- for (auto proc : processor_queue_) {
+ for (auto& proc : processor_queue_) {
while (proc->getActiveTasks() > 0) {
proc->decrementActiveTask();
}
diff --git a/nanofi/tests/CAPITests.cpp b/nanofi/tests/CAPITests.cpp
index c425703..bf6cfdb 100644
--- a/nanofi/tests/CAPITests.cpp
+++ b/nanofi/tests/CAPITests.cpp
@@ -254,6 +254,7 @@ TEST_CASE("Test manipulation of attributes",
"[testAttributes]") {
free_flow(test_flow);
free_nanofi_instance(instance);
+ free(attr_set.attributes);
}
TEST_CASE("Test error handling callback", "[errorHandling]") {
@@ -346,6 +347,7 @@ TEST_CASE("Test standalone processors", "[testStandalone]")
{
free_flowfile(ffr2);
free_standalone_processor(getfile_proc);
+ free_standalone_processor(extract_test);
}
TEST_CASE("Test interaction of flow and standlone processors",
"[testStandaloneWithFlow]") {
@@ -449,6 +451,10 @@ TEST_CASE("Test custom processor", "[TestCutomProcessor]")
{
REQUIRE(custom_onschedule_count > 0);
REQUIRE(record != nullptr);
+
+ free_nanofi_instance(instance);
+ free_flow(test_flow);
+ free_flowfile(record);
}
TEST_CASE("C API robustness test", "[TestRobustness]") {
@@ -535,6 +541,6 @@ TEST_CASE("C API robustness test", "[TestRobustness]") {
REQUIRE(add_processor(test_flow, nullptr) == nullptr);
free_flow(test_flow);
-
free_nanofi_instance(instance);
+ free_flowfile(ffr);
}
diff --git a/nanofi/tests/CLogAggregatorTests.cpp
b/nanofi/tests/CLogAggregatorTests.cpp
index 31a9007..a6cee9e 100644
--- a/nanofi/tests/CLogAggregatorTests.cpp
+++ b/nanofi/tests/CLogAggregatorTests.cpp
@@ -31,20 +31,16 @@
#include "CTestsBase.h"
-void test_lists_equal(token_list * tknlist, const std::vector<std::string>&
sv) {
+void test_lists_equal(const token_list * tknlist, const
std::vector<std::string>& sv) {
REQUIRE(tknlist != NULL);
- if (sv.empty()) {
- REQUIRE(tknlist->head == NULL);
- REQUIRE(tknlist->size == 0);
- return;
- }
REQUIRE(tknlist->size == sv.size());
+ token_node *node = tknlist->head;
for (const auto& s : sv) {
- if (tknlist->head) {
- REQUIRE(strcmp(s.c_str(), tknlist->head->data) == 0);
- tknlist->head = tknlist->head->next;
- }
+ REQUIRE(node);
+ REQUIRE(strcmp(s.c_str(), node->data) == 0);
+ node = node->next;
}
+ REQUIRE(node == nullptr);
}
std::string join_strings(const std::vector<std::string>& strings, const
std::string& token) {
@@ -83,6 +79,7 @@ TEST_CASE("Test string tokenizer normal delimited string",
"[stringTokenizerDeli
REQUIRE(tokens.size == 4);
REQUIRE(validate_list(&tokens) == 1);
test_lists_equal(&tokens, slist);
+ free_all_tokens(&tokens);
}
TEST_CASE("Test string tokenizer delimiter started string",
"[stringTokenizerDelimiterStartedString]") {
@@ -94,6 +91,7 @@ TEST_CASE("Test string tokenizer delimiter started string",
"[stringTokenizerDel
REQUIRE(validate_list(&tokens) == 1);
slist.erase(std::remove(slist.begin(), slist.end(), ""), slist.end());
test_lists_equal(&tokens, slist);
+ free_all_tokens(&tokens);
}
TEST_CASE("Test string tokenizer only delimiter character string",
"[stringTokenizerDelimiterOnlyString]") {
@@ -101,6 +99,7 @@ TEST_CASE("Test string tokenizer only delimiter character
string", "[stringToken
char delim = '-';
struct token_list tokens = tokenize_string(delimitedString.c_str(), delim);
REQUIRE(tokens.size == 0);
+ free_all_tokens(&tokens);
}
/****
@@ -121,6 +120,7 @@ TEST_CASE("Test string tokenizer for a delimited string
less than 4096 bytes", "
REQUIRE(validate_list(&tokens) == 1);
slist.pop_back();
test_lists_equal(&tokens, slist);
+ free_all_tokens(&tokens);
}
TEST_CASE("Test string tokenizer for a non-delimited string less than 4096
bytes", "[testNonDelimitedStringTokenizer]") {
@@ -130,6 +130,7 @@ TEST_CASE("Test string tokenizer for a non-delimited string
less than 4096 bytes
REQUIRE(tokens.has_non_delimited_token == 0);
REQUIRE(tokens.size == 0);
test_lists_equal(&tokens, {});
+ free_all_tokens(&tokens);
}
TEST_CASE("Test string tokenizer for empty string",
"[testEmptyStringTokenizer]") {
@@ -139,6 +140,7 @@ TEST_CASE("Test string tokenizer for empty string",
"[testEmptyStringTokenizer]"
REQUIRE(tokens.has_non_delimited_token == 0);
REQUIRE(tokens.size == 0);
test_lists_equal(&tokens, {});
+ free_all_tokens(&tokens);
}
TEST_CASE("Test string tokenizer for string containing only delimited
characters", "[testDelimiterCharOnlyStringTokenizer]") {
@@ -148,6 +150,7 @@ TEST_CASE("Test string tokenizer for string containing only
delimited characters
REQUIRE(tokens.has_non_delimited_token == 0);
REQUIRE(tokens.size == 0);
test_lists_equal(&tokens, {});
+ free_all_tokens(&tokens);
}
TEST_CASE("Test string tokenizer for string starting with delimited
characters", "[testDelimitedStartingStringTokenizer]") {
@@ -157,6 +160,7 @@ TEST_CASE("Test string tokenizer for string starting with
delimited characters",
REQUIRE(tokens.has_non_delimited_token == 0);
REQUIRE(tokens.size == 0);
test_lists_equal(&tokens, {});
+ free_all_tokens(&tokens);
}
TEST_CASE("Test string tokenizer for string starting and ending with delimited
characters", "[testDelimitedStartingEndingStringTokenizer]") {
@@ -166,6 +170,7 @@ TEST_CASE("Test string tokenizer for string starting and
ending with delimited c
REQUIRE(tokens.has_non_delimited_token == 0);
REQUIRE(tokens.size == 2);
test_lists_equal(&tokens, std::vector<std::string>{"token1", "token2"});
+ free_all_tokens(&tokens);
}
/****
diff --git a/nanofi/tests/CSite2SiteTests.cpp b/nanofi/tests/CSite2SiteTests.cpp
index ebbb449..a1f8a08 100644
--- a/nanofi/tests/CSite2SiteTests.cpp
+++ b/nanofi/tests/CSite2SiteTests.cpp
@@ -221,6 +221,7 @@ TEST_CASE("TestSiteToBootStrap", "[S2S3]") {
transfer_state.transer_completed = true;
destroyClient(&cprotocol);
+ freePeer(&cpeer);
};
std::thread c_thread(c_client_thread);