diff --git a/tests/nexus/platform/nexus_core.cpp b/tests/nexus/platform/nexus_core.cpp index 71f7450cb..5bdc8b5fa 100644 --- a/tests/nexus/platform/nexus_core.cpp +++ b/tests/nexus/platform/nexus_core.cpp @@ -29,6 +29,7 @@ #include "nexus_core.hpp" #include +#include #include "nexus_node.hpp" @@ -59,6 +60,153 @@ Core::Core(void) } } +void Core::SaveTestInfo(const char *aFilename) +{ + FILE *file = fopen(aFilename, "w"); + Node *tail = mNodes.GetTail(); + const char *testcase; + const char *slash; + const char *dot; + const char *version; + int testcaseLen; + + VerifyOrExit(file != nullptr); + + testcase = aFilename; + slash = strrchr(aFilename, '/'); + + if (slash != nullptr) + { + testcase = slash + 1; + } + + dot = strrchr(testcase, '.'); + testcaseLen = (dot != nullptr) ? static_cast(dot - testcase) : static_cast(strlen(testcase)); + + switch (otThreadGetVersion()) + { + case OT_THREAD_VERSION_1_1: + version = "1.1"; + break; + case OT_THREAD_VERSION_1_2: + version = "1.2"; + break; + case OT_THREAD_VERSION_1_3: + version = "1.3"; + break; + case OT_THREAD_VERSION_1_4: + version = "1.4"; + break; + default: + version = "unknown"; + break; + } + + fprintf(file, "{\n"); + fprintf(file, " \"testcase\": \"%.*s\",\n", testcaseLen, testcase); + fprintf(file, " \"pcap\": \"%s\",\n", getenv("OT_NEXUS_PCAP_FILE") ? getenv("OT_NEXUS_PCAP_FILE") : ""); + + if (!mNodes.IsEmpty()) + { + NetworkKey networkKey; + Node &node = *mNodes.GetHead(); + String keyString; + + node.Get().GetNetworkKey(networkKey); + keyString.AppendHexBytes(networkKey.m8, OT_NETWORK_KEY_SIZE); + fprintf(file, " \"network_key\": \"%s\",\n", keyString.AsCString()); + + for (Node &leaderNode : mNodes) + { + if (leaderNode.Get().IsLeader()) + { + Ip6::Address aloc; + leaderNode.Get().GetLeaderAloc(aloc); + fprintf(file, " \"leader_aloc\": \"%s\",\n", aloc.ToString().AsCString()); + break; + } + } + } + + fprintf(file, " \"topology\": {\n"); + for (Node &node : mNodes) + { + fprintf(file, " \"%u\": {\"name\": \"%s\", \"version\": \"%s\"}%s\n", node.GetInstance().GetId(), + node.GetName() ? node.GetName() : "", version, (&node == tail) ? "" : ","); + } + fprintf(file, " },\n"); + + fprintf(file, " \"extaddrs\": {\n"); + for (Node &node : mNodes) + { + fprintf(file, " \"%u\": \"%s\"%s\n", node.GetInstance().GetId(), + node.Get().GetExtAddress().ToString().AsCString(), (&node == tail) ? "" : ","); + } + fprintf(file, " },\n"); + + fprintf(file, " \"rloc16s\": {\n"); + for (Node &node : mNodes) + { + fprintf(file, " \"%u\": \"0x%04x\"%s\n", node.GetInstance().GetId(), node.Get().GetRloc16(), + (&node == tail) ? "" : ","); + } + fprintf(file, " },\n"); + + fprintf(file, " \"mleids\": {\n"); + for (Node &node : mNodes) + { + fprintf(file, " \"%u\": \"%s\"%s\n", node.GetInstance().GetId(), + node.Get().GetMeshLocalEid().ToString().AsCString(), (&node == tail) ? "" : ","); + } + fprintf(file, " },\n"); + + fprintf(file, " \"rlocs\": {\n"); + for (Node &node : mNodes) + { + fprintf(file, " \"%u\": \"%s\"%s\n", node.GetInstance().GetId(), + node.Get().GetMeshLocalRloc().ToString().AsCString(), (&node == tail) ? "" : ","); + } + fprintf(file, " },\n"); + + fprintf(file, " \"ipaddrs\": {\n"); + for (Node &node : mNodes) + { + bool first = true; + + fprintf(file, " \"%u\": [\n", node.GetInstance().GetId()); + for (const Ip6::Netif::UnicastAddress &addr : node.Get().GetUnicastAddresses()) + { + if (!first) + { + fprintf(file, ",\n"); + } + fprintf(file, " \"%s\"", addr.GetAddress().ToString().AsCString()); + first = false; + } + fprintf(file, "\n ]%s\n", (&node == tail) ? "" : ","); + } + fprintf(file, " },\n"); + + fprintf(file, " \"extra_vars\": {\n"); + if (!mNodes.IsEmpty()) + { + Node &node = *mNodes.GetHead(); + Ip6::Prefix prefix; + + prefix.Set(node.Get().GetMeshLocalPrefix()); + fprintf(file, " \"mesh_local_prefix\": \"%s\"\n", prefix.ToString().AsCString()); + } + fprintf(file, " }\n"); + + fprintf(file, "}\n"); + +exit: + if (file != nullptr) + { + fclose(file); + } +} + Core::~Core(void) { sInUse = false; } Node &Core::CreateNode(void) diff --git a/tests/nexus/platform/nexus_core.hpp b/tests/nexus/platform/nexus_core.hpp index 11ed2c36a..4aad4a0cb 100644 --- a/tests/nexus/platform/nexus_core.hpp +++ b/tests/nexus/platform/nexus_core.hpp @@ -56,6 +56,8 @@ public: TimeMilli GetNow(void) { return mNow; } void AdvanceTime(uint32_t aDuration); + void SaveTestInfo(const char *aFilename); + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Used by platform implementation diff --git a/tests/nexus/platform/nexus_node.hpp b/tests/nexus/platform/nexus_node.hpp index ca254635c..6cdec99d1 100644 --- a/tests/nexus/platform/nexus_node.hpp +++ b/tests/nexus/platform/nexus_node.hpp @@ -83,6 +83,9 @@ public: void GetTrelSockAddr(Ip6::SockAddr &aSockAddr) const; #endif + void SetName(const char *aName) { IgnoreError(StringCopy(mName, aName)); } + const char *GetName(void) const { return mName; } + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template Type &Get(void) @@ -113,7 +116,9 @@ public: Node *mNext; private: - Node(void) = default; + Node(void) {} + + char mName[32]; }; inline Node &AsNode(otInstance *aInstance) { return Node::From(aInstance); } diff --git a/tests/nexus/test_5_1_1.cpp b/tests/nexus/test_5_1_1.cpp index 8a60bdec1..c7c4d5be4 100644 --- a/tests/nexus/test_5_1_1.cpp +++ b/tests/nexus/test_5_1_1.cpp @@ -106,6 +106,9 @@ void Test5_1_1(void) Node &leader = nexus.CreateNode(); Node &router = nexus.CreateNode(); + leader.SetName("LEADER"); + router.SetName("ROUTER"); + nexus.AdvanceTime(0); Instance::SetLogLevel(kLogLevelInfo); @@ -194,6 +197,8 @@ void Test5_1_1(void) router.Get().GetLinkLocalAddress().ToString().AsCString()); SendAndVerifyEchoRequest(nexus, leader, router, leaderReceivedEchoReply); Log("Router (as DUT) responded with Echo Reply successfully"); + + nexus.SaveTestInfo("test_5_1_1.json"); } } // namespace Nexus