From 11ec3fc7199e5e92779ec8bc25bbab6ff80d5ed4 Mon Sep 17 00:00:00 2001 From: Carlos Segarra Date: Fri, 29 Oct 2021 15:09:06 +0000 Subject: [PATCH] add checks for serialisation/deserialisation --- src/util/json.cpp | 97 ++++++++++++++++++++++++++++++++--- tests/test/util/test_json.cpp | 1 + tests/utils/faabric_utils.h | 16 ++++++ tests/utils/message_utils.cpp | 5 ++ 4 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/util/json.cpp b/src/util/json.cpp index 007272c86..bdcb06676 100644 --- a/src/util/json.cpp +++ b/src/util/json.cpp @@ -8,6 +8,8 @@ #include +#include + using namespace rapidjson; namespace faabric::util { @@ -187,24 +189,35 @@ std::string messageToJson(const faabric::Message& msg) d.AddMember("record_exec_graph", msg.recordexecgraph(), a); if (msg.execgraphdetails_size() > 0) { - std::string out = ""; + std::stringstream ss; const auto& map = msg.execgraphdetails(); - for (const auto& it : map) { - out = fmt::format("{},{}:{}", out, it.first, it.second); + auto it = map.begin(); + while (it != map.end()) { + ss << fmt::format("{}:{}", it->first, it->second); + ++it; + if (it != map.end()) { + ss << ","; + } } + std::string out = ss.str(); d.AddMember( "exec_graph_detail", Value(out.c_str(), out.size()).Move(), a); } if (msg.intexecgraphdetails_size() > 0) { - std::string out = ""; + std::stringstream ss; const auto& map = msg.intexecgraphdetails(); - for (const auto& it : map) { - out = fmt::format( - "{},{}:{}", out, it.first, std::to_string(it.second)); + auto it = map.begin(); + while (it != map.end()) { + ss << fmt::format("{}:{}", it->first, it->second); + ++it; + if (it != map.end()) { + ss << ","; + } } + std::string out = ss.str(); d.AddMember("int_exec_graph_detail", Value(out.c_str(), out.size()).Move(), a); @@ -294,6 +307,54 @@ std::string getStringFromJson(Document& doc, return std::string(valuePtr, valuePtr + it->value.GetStringLength()); } +std::map getStringStringMapFromJson( + Document& doc, + const std::string& key) +{ + std::map map; + + Value::MemberIterator it = doc.FindMember(key.c_str()); + if (it == doc.MemberEnd()) { + return map; + } + + const char* valuePtr = it->value.GetString(); + std::stringstream ss( + std::string(valuePtr, valuePtr + it->value.GetStringLength())); + std::string keyVal; + while (std::getline(ss, keyVal, ',')) { + auto pos = keyVal.find(":"); + std::string key = keyVal.substr(0, pos); + map[key] = keyVal.erase(0, pos + sizeof(char)); + } + + return map; +} + +std::map getStringIntMapFromJson(Document& doc, + const std::string& key) +{ + std::map map; + + Value::MemberIterator it = doc.FindMember(key.c_str()); + if (it == doc.MemberEnd()) { + return map; + } + + const char* valuePtr = it->value.GetString(); + std::stringstream ss( + std::string(valuePtr, valuePtr + it->value.GetStringLength())); + std::string keyVal; + while (std::getline(ss, keyVal, ',')) { + auto pos = keyVal.find(":"); + std::string key = keyVal.substr(0, pos); + int val = std::stoi(keyVal.erase(0, pos + sizeof(char))); + map[key] = val; + } + + return map; +} + faabric::Message jsonToMessage(const std::string& jsonIn) { PROF_START(jsonDecode) @@ -352,6 +413,28 @@ faabric::Message jsonToMessage(const std::string& jsonIn) msg.set_sgxpolicy(getStringFromJson(d, "sgxpolicy", "")); msg.set_sgxresult(getStringFromJson(d, "sgxresult", "")); + msg.set_recordexecgraph(getBoolFromJson(d, "record_exec_graph", false)); + + // By default, clear the map + msg.clear_execgraphdetails(); + // Fill keypairs if found + auto& msgStrMap = *msg.mutable_execgraphdetails(); + std::map strMap = + getStringStringMapFromJson(d, "exec_graph_detail"); + for (auto& it : strMap) { + msgStrMap[it.first] = it.second; + } + + // By default, clear the map + msg.clear_intexecgraphdetails(); + // Fill keypairs if found + auto& msgIntMap = *msg.mutable_intexecgraphdetails(); + std::map intMap = + getStringIntMapFromJson(d, "int_exec_graph_detail"); + for (auto& it : intMap) { + msgIntMap[it.first] = it.second; + } + PROF_END(jsonDecode) return msg; diff --git a/tests/test/util/test_json.cpp b/tests/test/util/test_json.cpp index f8ac1766d..df3248ae3 100644 --- a/tests/test/util/test_json.cpp +++ b/tests/test/util/test_json.cpp @@ -61,6 +61,7 @@ TEST_CASE("Test message to JSON round trip", "[util]") REQUIRE(msg.timestamp() > 0); std::string jsonString = faabric::util::messageToJson(msg); + SPDLOG_INFO("{}", jsonString); faabric::Message actual = faabric::util::jsonToMessage(jsonString); diff --git a/tests/utils/faabric_utils.h b/tests/utils/faabric_utils.h index 3a9ea939c..b6c50c5a2 100644 --- a/tests/utils/faabric_utils.h +++ b/tests/utils/faabric_utils.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "fixtures.h" #include @@ -63,6 +65,20 @@ using namespace faabric; namespace tests { void cleanFaabric(); +template +void checkMessageMapEquality(T mapA, T mapB) +{ + REQUIRE(mapA.size() == mapB.size()); + auto itA = mapA.begin(); + auto itB = mapB.begin(); + while (itA != mapA.end() && itB != mapB.end()) { + REQUIRE(itA->first == itB->first); + REQUIRE(itA->second == itB->second); + itA++; + itB++; + } +} + void checkMessageEquality(const faabric::Message& msgA, const faabric::Message& msgB); diff --git a/tests/utils/message_utils.cpp b/tests/utils/message_utils.cpp index d441d26b8..58924958c 100644 --- a/tests/utils/message_utils.cpp +++ b/tests/utils/message_utils.cpp @@ -47,5 +47,10 @@ void checkMessageEquality(const faabric::Message& msgA, REQUIRE(msgA.sgxtag() == msgB.sgxtag()); REQUIRE(msgA.sgxpolicy() == msgB.sgxpolicy()); REQUIRE(msgA.sgxresult() == msgB.sgxresult()); + + REQUIRE(msgA.recordexecgraph() == msgB.recordexecgraph()); + checkMessageMapEquality(msgA.execgraphdetails(), msgB.execgraphdetails()); + checkMessageMapEquality(msgA.intexecgraphdetails(), + msgB.intexecgraphdetails()); } }