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);

Reply via email to