Files
openthread/tests/nexus/test_1_1_5_2_3.cpp
T
Abtin Keshavarzian cb4b28313b [logging] add support for per-instance log levels (#12740)
This commit introduces the ability to set and manage log levels on a
per-instance basis when dynamic logging is enabled, while maintaining
backward compatibility with existing logging behaviors.

The existing `otLoggingGetLevel()` and `otLoggingSetLevel()` APIs are
repurposed to manage the "global" log level. They continue to behave
exactly as before in both single-instance and multi-instance
configurations, ensuring that existing users of these APIs do not need
to change their implementations. To provide more granular control, new
APIs `otGetLogLevel()` and `otSetLogLevel()` are added to handle
per-instance log levels.

Specifically, this commit makes the following changes:
- Adds `mLogLevel` to `Instance` to track the instance-specific log
  level.
- Renames the global log level static variable to `sGlobalLogLevel` and
  introduces `GetGlobalLogLevel()` and `SetGlobalLogLevel()` to manage
  it in a multi-instance configuration.
- Updates `otGetLogLevel()` and `otSetLogLevel()` APIs to handle
  per-instance log level retrieval and configuration. If a specific
  level is not set for an instance, it falls back to the global
  log level.
- Adds `mIsLogLevelSet` to distinguish between an explicitly set
  instance log level and the global fallback in multi-instance builds.
- Introduces `otPlatLogHandleLogLevelChanged()` platform callback to
  notify the platform when an instance-specific log level is updated.
- Updates Nexus tests to use `SetGlobalLogLevel()` instead of the
  deprecated instance `SetLogLevel()` method.
2026-03-27 00:24:49 -05:00

213 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 2026, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdarg.h>
#include <stdio.h>
#include "platform/nexus_core.hpp"
#include "platform/nexus_node.hpp"
namespace ot {
namespace Nexus {
/**
* 5.2.3 Leader rejects CoAP Address Solicit (2-hops from Leader)
*
* 5.2.3.1 Topology
* - Build a topology with the DUT as the Leader and have a total of 32 routers, including the Leader.
* - Attempt to attach a 33rd router, two hops from the leader.
*
* 5.2.3.2 Purpose & Description
* The purpose of this test case is to show that the DUT will only allow 32 active routers on the network and
* reject the Address Solicit Request from a 33rd router - that is 2-hops away - with a No Address Available status.
*
* Spec Reference | V1.1 Section | V1.3.0 Section
* ---------------------------------------------|-----------------|-----------------
* Attaching to a Parent / Router ID Assignment | 4.7.1 / 5.9.10 | 4.5.1 / 5.9.10
*/
/**
* Time to advance for a node to form a network and become leader.
*/
static constexpr uint32_t kFormNetworkTime = 13 * 1000;
/**
* Time to advance for a node to join as a child and upgrade to a router.
* This duration accounts for MLE attach process and ROUTER_SELECTION_JITTER.
*/
static constexpr uint32_t kAttachToRouterTime = 200 * 1000;
/**
* Time to advance for a node to try to become a router.
*/
static constexpr uint32_t kWaitTime = 10 * 1000;
static constexpr uint8_t kMaxRouters = 32;
void Test5_2_3(void)
{
Core nexus;
Node &leader = nexus.CreateNode();
Node *routers[kMaxRouters];
leader.SetName("Leader");
for (uint8_t i = 0; i < kMaxRouters; i++)
{
routers[i] = &nexus.CreateNode();
routers[i]->SetName("Router", i + 1);
}
nexus.AdvanceTime(0);
SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote));
leader.Get<Mle::Mle>().SetRouterUpgradeThreshold(kMaxRouters);
leader.Get<Mle::Mle>().SetRouterDowngradeThreshold(kMaxRouters);
for (uint8_t i = 0; i < kMaxRouters; i++)
{
routers[i]->Get<Mle::Mle>().SetRouterUpgradeThreshold(kMaxRouters);
routers[i]->Get<Mle::Mle>().SetRouterDowngradeThreshold(kMaxRouters);
}
// Topology:
// Leader <-> Router 1..31
// Router 32 <-> Router 1
for (uint8_t i = 0; i < kMaxRouters - 1; i++)
{
leader.AllowList(*routers[i]);
routers[i]->AllowList(leader);
}
routers[kMaxRouters - 1]->AllowList(*routers[0]);
routers[0]->AllowList(*routers[kMaxRouters - 1]);
Log("---------------------------------------------------------------------------------------");
/**
* Step 1: All
* - Description: Begin wireless sniffer and ensure topology is created and connectivity between nodes.
* - Pass Criteria: Topology is created, the DUT is the Leader of the network and there is a total of 32
* active routers, including the Leader.
*/
Log("Step 1: All");
leader.Form();
nexus.AdvanceTime(kFormNetworkTime);
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
for (uint8_t i = 0; i < kMaxRouters - 1; i++)
{
routers[i]->Join(leader);
}
nexus.AdvanceTime(kAttachToRouterTime);
for (uint8_t i = 0; i < kMaxRouters - 1; i++)
{
VerifyOrQuit(routers[i]->Get<Mle::Mle>().IsRouter());
}
Log("---------------------------------------------------------------------------------------");
/**
* Step 2: Router_31
* - Description: The harness causes Router_31 to attach to the network and send an Address Solicit Request to
* become an active router.
* - Pass Criteria: N/A
*/
Log("Step 2: Router_31");
// Handled in Step 1 for simplicity as Router 31 is one of the 31 routers joining the Leader.
Log("---------------------------------------------------------------------------------------");
/**
* Step 3: Leader (DUT)
* - Description: The DUT receives the Address Solicit Request and automatically replies with an Address
* Solicit Response.
* - Pass Criteria:
* - The DUT MUST reply to the Address Solicit Request with an Address Solicit Response containing:
* - CoAP Response Code: 2.04 Changed
* - CoAP Payload:
* - Status TLV (value = Success)
* - RLOC16 TLV
* - Router Mask TLV
*/
Log("Step 3: Leader (DUT)");
// Handled in Step 1.
Log("---------------------------------------------------------------------------------------");
/**
* Step 4: Leader (DUT)
* - Description: Automatically sends MLE Advertisements.
* - Pass Criteria: The DUTs MLE Advertisements MUST contain the Route64 TLV with 32 assigned Router IDs.
*/
Log("Step 4: Leader (DUT)");
// Handled in Step 1.
Log("---------------------------------------------------------------------------------------");
/**
* Step 5: Router_32
* - Description: The harness causes Router_32 to attach to any of the active routers, 2-hops from the leader,
* and to send an Address Solicit Request to become an active router.
* - Pass Criteria: N/A
*/
Log("Step 5: Router_32");
routers[kMaxRouters - 1]->Join(*routers[0]);
nexus.AdvanceTime(kAttachToRouterTime);
VerifyOrQuit(routers[kMaxRouters - 1]->Get<Mle::Mle>().IsChild());
// Force Router 32 to try to become a router
SuccessOrQuit(routers[kMaxRouters - 1]->Get<Mle::Mle>().BecomeRouter(Mle::kReasonTooFewRouters));
Log("---------------------------------------------------------------------------------------");
/**
* Step 6: Leader (DUT)
* - Description: The DUT receives the Address Solicit Request and automatically replies with an Address
* Solicit Response.
* - Pass Criteria:
* - The DUT MUST reply to the Address Solicit Request with an Address Solicit Response containing:
* - CoAP Response Code: 2.04 Changed
* - CoAP Payload:
* - Status TLV (value = No Address Available)
*/
Log("Step 6: Leader (DUT)");
nexus.AdvanceTime(kWaitTime);
VerifyOrQuit(routers[kMaxRouters - 1]->Get<Mle::Mle>().IsChild());
nexus.SaveTestInfo("test_1_1_5_2_3.json");
}
} // namespace Nexus
} // namespace ot
int main(void)
{
ot::Nexus::Test5_2_3();
printf("All tests passed\n");
return 0;
}