mirror of
https://github.com/espressif/openthread.git
synced 2026-08-24 19:29:52 +00:00
[nexus] add support for CLI testing (#13110)
This commit adds support for interacting with nodes via the CLI in the Nexus simulation framework. This enables writing higher-level integration tests that verify stack behavior and state through standard CLI commands. Key changes: - Integrated `Cli::Interpreter` into the `Nexus::Node` class. - Added `Node::InputCli()` to allow sending commands to a node with `printf`-style formatting. - Implemented output capturing logic in `Node::HandleCliOutput()` to buffer and parse CLI responses into individual lines, stored in a `CliOutputArray`. - Added helper methods to `CliOutputLine` for matching and validating the captured output. - Added a new `cli_basic` Nexus test to demonstrate and validate the CLI interaction functionality.
This commit is contained in:
@@ -37,10 +37,12 @@ namespace Nexus {
|
||||
|
||||
Node::Node(void)
|
||||
: Platform(static_cast<Instance &>(*this))
|
||||
, mCliInterpreter(static_cast<Instance *>(this), HandleCliOutput, this)
|
||||
, mX(0.0f)
|
||||
, mY(0.0f)
|
||||
, mLastParentId(0xffff)
|
||||
{
|
||||
mCliInterpreter.SetPromptConfig(false);
|
||||
}
|
||||
|
||||
void Node::Reset(void)
|
||||
@@ -298,6 +300,109 @@ const char *Node::GetExtendedRoleString(void) const
|
||||
return roleStr;
|
||||
}
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Cli
|
||||
|
||||
Node::CliOutputLine &Node::CliOutputLine::operator=(const CliOutputLine &aOther)
|
||||
{
|
||||
SuccessOrQuit(mLine.Set(aOther.mLine));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node::CliOutputLine &Node::CliOutputLine::operator=(CliOutputLine &&aOther)
|
||||
{
|
||||
mLine.TakeFrom(aOther.mLine.Move());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Node::InputCli(const char *aFormat, ...)
|
||||
{
|
||||
static constexpr uint16_t kMaxCommandSize = 256;
|
||||
|
||||
va_list args;
|
||||
char command[kMaxCommandSize];
|
||||
StringWriter writer(command, kMaxCommandSize);
|
||||
|
||||
va_start(args, aFormat);
|
||||
writer.AppendVarArgs(aFormat, args);
|
||||
VerifyOrExit(!writer.IsTruncated());
|
||||
|
||||
ClearCliOutput();
|
||||
mCliInterpreter.ProcessLine(command);
|
||||
|
||||
exit:
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
int Node::HandleCliOutput(void *aContext, const char *aFormat, va_list aArguments)
|
||||
{
|
||||
return static_cast<Node *>(aContext)->HandleCliOutput(aFormat, aArguments);
|
||||
}
|
||||
|
||||
int Node::HandleCliOutput(const char *aFormat, va_list aArguments)
|
||||
{
|
||||
uint16_t length;
|
||||
|
||||
// Generate output - determine number of chars written
|
||||
length = mCliCurOutputLine.GetLength();
|
||||
|
||||
mCliCurOutputLine.AppendVarArgs(aFormat, aArguments);
|
||||
VerifyOrQuit(!mCliCurOutputLine.IsTruncated());
|
||||
|
||||
length = mCliCurOutputLine.GetLength() - length;
|
||||
|
||||
// Search for `\n` and parse lines one by one
|
||||
|
||||
while (true)
|
||||
{
|
||||
char lineString[CliOutputLine::kMaxLineSize];
|
||||
char *end;
|
||||
CliOutputLine *lineEnrry;
|
||||
|
||||
SuccessOrQuit(StringCopy(lineString, mCliCurOutputLine.AsCString()));
|
||||
|
||||
end = AsNonConst(StringFind(lineString, '\n'));
|
||||
VerifyOrExit(end != nullptr);
|
||||
|
||||
mCliCurOutputLine.Clear();
|
||||
mCliCurOutputLine.Append("%s", end + 1);
|
||||
|
||||
*end = kNullChar;
|
||||
|
||||
if (end > &lineString[0])
|
||||
{
|
||||
end--;
|
||||
|
||||
if (*end == '\r')
|
||||
{
|
||||
*end = kNullChar;
|
||||
}
|
||||
}
|
||||
|
||||
// Push the full line into the `mCliOutputLines` array
|
||||
|
||||
lineEnrry = mCliOutputLines.PushBack();
|
||||
VerifyOrQuit(lineEnrry != nullptr);
|
||||
|
||||
SuccessOrQuit(lineEnrry->mLine.Set(lineString));
|
||||
}
|
||||
|
||||
exit:
|
||||
return static_cast<int>(length);
|
||||
}
|
||||
|
||||
bool Node::IsCliOutputSuccess(void)
|
||||
{
|
||||
bool isSuccess = false;
|
||||
|
||||
VerifyOrExit(mCliOutputLines.GetLength() > 0);
|
||||
VerifyOrExit(mCliOutputLines.Back()->IsDone());
|
||||
isSuccess = true;
|
||||
|
||||
exit:
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void AllowLinkBetween(Node &aFirstNode, Node &aSecondNode)
|
||||
|
||||
Reference in New Issue
Block a user