libperfmgr: Validate on duplicate node index across Actions

Test: libperfmgr_test

(cherry picked from commit 86d3bfd952c6bf191738712d53908dc11bf1d864)

Change-Id: Iec7ad0b9bca9ee0af0bb25f038586ce5c9ec53cd
diff --git a/libperfmgr/HintManager.cc b/libperfmgr/HintManager.cc
index 135e55a..d751032 100644
--- a/libperfmgr/HintManager.cc
+++ b/libperfmgr/HintManager.cc
@@ -297,6 +297,15 @@
                 {node_index, static_cast<std::size_t>(value_index),
                  std::chrono::milliseconds(duration)}};
         } else {
+            for (const auto& action : actions_parsed[hint_type]) {
+                if (action.node_index == node_index) {
+                    LOG(ERROR)
+                        << "Action[" << i
+                        << "]'s NodeIndex is duplicated with another Action";
+                    actions_parsed.clear();
+                    return actions_parsed;
+                }
+            }
             actions_parsed[hint_type].emplace_back(
                 node_index, static_cast<std::size_t>(value_index),
                 std::chrono::milliseconds(duration));
@@ -307,7 +316,7 @@
 
     LOG(INFO) << total_parsed << " Actions parsed successfully";
 
-    for (auto& action : actions_parsed) {
+    for (const auto& action : actions_parsed) {
         LOG(INFO) << "PowerHint " << action.first << " has "
                   << action.second.size() << " actions parsed";
     }
diff --git a/libperfmgr/tests/HintManagerTest.cc b/libperfmgr/tests/HintManagerTest.cc
index ff90128..dc8e330 100644
--- a/libperfmgr/tests/HintManagerTest.cc
+++ b/libperfmgr/tests/HintManagerTest.cc
@@ -286,6 +286,20 @@
               actions["LAUNCH"][1].timeout_ms.count());
 }
 
+// Test parsing actions with duplicate node
+TEST_F(HintManagerTest, ParseActionDuplicateNodeTest) {
+    std::string from = "\"Node\":\"CPUCluster0MinFreq\"";
+    size_t start_pos = json_doc_.find(from);
+    json_doc_.replace(start_pos, from.length(),
+                      "\"Node\": \"CPUCluster1MinFreq\"");
+    std::vector<std::unique_ptr<Node>> nodes =
+        HintManager::ParseNodes(json_doc_);
+    EXPECT_EQ(2u, nodes.size());
+    std::map<std::string, std::vector<NodeAction>> actions =
+        HintManager::ParseActions(json_doc_, nodes);
+    EXPECT_EQ(0u, actions.size());
+}
+
 // Test parsing invalid json for actions
 TEST_F(HintManagerTest, ParseBadActionsTest) {
     std::vector<std::unique_ptr<Node>> nodes =