[cli] add command to get tcp results (#9142)

This commit updates the cli command of TCP benchmark so that the
result of TCP benchmark could be queried any time. This enables test
scripts to automate TCP benchmark test. Currently the command `tcp
benchmark` is asynchronous and return immediately. If we use `ot-ctl
tcp benchmark` on posix, it's hard to fetch the test results. With the
newly added command, we can write a script to poll and get the result.
This commit is contained in:
Li Cao
2023-06-15 04:31:09 +08:00
committed by GitHub
parent 4b0b93ad00
commit 55e3440ee2
3 changed files with 101 additions and 48 deletions
+18 -3
View File
@@ -60,7 +60,7 @@ For a more in-depth example, see [this video](https://youtu.be/ppZ784YUKlI).
- [bind](#bind-ip-port)
- [connect](#connect-ip-port)
- [send](#send-message)
- [benchmark](#benchmark-size)
- [benchmark](#benchmark-run-size)
- [sendend](#sendend)
- [abort](#abort)
- [listen](#listen-ip-port)
@@ -78,19 +78,34 @@ TCP: Connection reset
Done
```
### benchmark [\<size\>]
### benchmark run [\<size\>]
Transfers the specified number of bytes using the TCP connection currently associated with the example TCP endpoint (this TCP connection must be established before using this command).
- size: the number of bytes to send for the benchmark. If it is left unspecified, the default size is used.
```bash
> tcp benchmark
> tcp benchmark run
Done
TCP Benchmark Complete: Transferred 73728 bytes in 7233 milliseconds
TCP Goodput: 81.546 kb/s
```
### benchmark result
Get the last result of TCP benchmark. If the benchmark is ongoing, it will show that benchmark is ongoing. This command is used for test scripts which automate the tcp benchmark test.
```
> tcp benchmark result
TCP Benchmark Status: Ongoing
Done
> tcp benchmark result
TCP Benchmark Status: Completed
TCP Benchmark Complete: Transferred 73728 bytes in 7056 milliseconds
TCP Goodput: 83.592 kb/s
```
### bind \<ip\> \<port\>
Associates a name (i.e. IPv6 address and port) to the example TCP endpoint.
+79 -44
View File
@@ -70,6 +70,7 @@ TcpExample::TcpExample(otInstance *aInstance, OutputImplementer &aOutputImplemen
, mTlsHandshakeComplete(false)
, mBenchmarkBytesTotal(0)
, mBenchmarkBytesUnsent(0)
, mBenchmarkTimeUsed(0)
{
mEndpointAndCircularSendBuffer.mEndpoint = &mEndpoint;
mEndpointAndCircularSendBuffer.mSendBuffer = &mSendBuffer;
@@ -377,48 +378,73 @@ template <> otError TcpExample::Process<Cmd("benchmark")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
VerifyOrExit(!mSendBusy, error = OT_ERROR_BUSY);
VerifyOrExit(mBenchmarkBytesTotal == 0, error = OT_ERROR_BUSY);
if (aArgs[0].IsEmpty())
if (aArgs[0] == "result")
{
mBenchmarkBytesTotal = OPENTHREAD_CONFIG_CLI_TCP_DEFAULT_BENCHMARK_SIZE;
}
else
{
SuccessOrExit(error = aArgs[0].ParseAsUint32(mBenchmarkBytesTotal));
VerifyOrExit(mBenchmarkBytesTotal != 0, error = OT_ERROR_INVALID_ARGS);
}
VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
mBenchmarkStart = TimerMilli::GetNow();
mBenchmarkBytesUnsent = mBenchmarkBytesTotal;
if (mUseCircularSendBuffer)
{
SuccessOrExit(error = ContinueBenchmarkCircularSend());
}
else
{
uint32_t benchmarkLinksLeft = (mBenchmarkBytesTotal + sizeof(mSendBufferBytes) - 1) / sizeof(mSendBufferBytes);
uint32_t toSendOut = OT_MIN(OT_ARRAY_LENGTH(mBenchmarkLinks), benchmarkLinksLeft);
/* We could also point the linked buffers directly to sBenchmarkData. */
memset(mSendBufferBytes, 'a', sizeof(mSendBufferBytes));
for (uint32_t i = 0; i != toSendOut; i++)
OutputFormat("TCP Benchmark Status: ");
if (mBenchmarkBytesTotal != 0)
{
mBenchmarkLinks[i].mNext = nullptr;
mBenchmarkLinks[i].mData = mSendBufferBytes;
mBenchmarkLinks[i].mLength = sizeof(mSendBufferBytes);
if (i == 0 && mBenchmarkBytesTotal % sizeof(mSendBufferBytes) != 0)
{
mBenchmarkLinks[i].mLength = mBenchmarkBytesTotal % sizeof(mSendBufferBytes);
}
error = otTcpSendByReference(&mEndpoint, &mBenchmarkLinks[i],
i == toSendOut - 1 ? 0 : OT_TCP_SEND_MORE_TO_COME);
VerifyOrExit(error == OT_ERROR_NONE, mBenchmarkBytesTotal = 0);
OutputLine("Ongoing");
}
else if (mBenchmarkTimeUsed != 0)
{
OutputLine("Completed");
OutputBenchmarkResult();
}
else
{
OutputLine("Untested");
}
}
else if (aArgs[0] == "run")
{
VerifyOrExit(!mSendBusy, error = OT_ERROR_BUSY);
VerifyOrExit(mBenchmarkBytesTotal == 0, error = OT_ERROR_BUSY);
if (aArgs[1].IsEmpty())
{
mBenchmarkBytesTotal = OPENTHREAD_CONFIG_CLI_TCP_DEFAULT_BENCHMARK_SIZE;
}
else
{
SuccessOrExit(error = aArgs[1].ParseAsUint32(mBenchmarkBytesTotal));
VerifyOrExit(mBenchmarkBytesTotal != 0, error = OT_ERROR_INVALID_ARGS);
}
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
mBenchmarkStart = TimerMilli::GetNow();
mBenchmarkBytesUnsent = mBenchmarkBytesTotal;
if (mUseCircularSendBuffer)
{
SuccessOrExit(error = ContinueBenchmarkCircularSend());
}
else
{
uint32_t benchmarkLinksLeft =
(mBenchmarkBytesTotal + sizeof(mSendBufferBytes) - 1) / sizeof(mSendBufferBytes);
uint32_t toSendOut = OT_MIN(OT_ARRAY_LENGTH(mBenchmarkLinks), benchmarkLinksLeft);
/* We could also point the linked buffers directly to sBenchmarkData. */
memset(mSendBufferBytes, 'a', sizeof(mSendBufferBytes));
for (uint32_t i = 0; i != toSendOut; i++)
{
mBenchmarkLinks[i].mNext = nullptr;
mBenchmarkLinks[i].mData = mSendBufferBytes;
mBenchmarkLinks[i].mLength = sizeof(mSendBufferBytes);
if (i == 0 && mBenchmarkBytesTotal % sizeof(mSendBufferBytes) != 0)
{
mBenchmarkLinks[i].mLength = mBenchmarkBytesTotal % sizeof(mSendBufferBytes);
}
error = otTcpSendByReference(&mEndpoint, &mBenchmarkLinks[i],
i == toSendOut - 1 ? 0 : OT_TCP_SEND_MORE_TO_COME);
VerifyOrExit(error == OT_ERROR_NONE, mBenchmarkBytesTotal = 0);
}
}
}
else
{
error = OT_ERROR_INVALID_ARGS;
}
exit:
@@ -860,15 +886,24 @@ exit:
return error;
}
void TcpExample::CompleteBenchmark(void)
void TcpExample::OutputBenchmarkResult(void)
{
uint32_t milliseconds = TimerMilli::GetNow() - mBenchmarkStart;
uint32_t thousandTimesGoodput = (1000 * (mBenchmarkBytesTotal << 3) + (milliseconds >> 1)) / milliseconds;
uint32_t thousandTimesGoodput =
(1000 * (mBenchmarkLastBytesTotal << 3) + (mBenchmarkTimeUsed >> 1)) / mBenchmarkTimeUsed;
OutputLine("TCP Benchmark Complete: Transferred %lu bytes in %lu milliseconds", ToUlong(mBenchmarkBytesTotal),
ToUlong(milliseconds));
OutputLine("TCP Benchmark Complete: Transferred %lu bytes in %lu milliseconds", ToUlong(mBenchmarkLastBytesTotal),
ToUlong(mBenchmarkTimeUsed));
OutputLine("TCP Goodput: %lu.%03u kb/s", ToUlong(thousandTimesGoodput / 1000),
static_cast<uint16_t>(thousandTimesGoodput % 1000));
}
void TcpExample::CompleteBenchmark(void)
{
mBenchmarkTimeUsed = TimerMilli::GetNow() - mBenchmarkStart;
mBenchmarkLastBytesTotal = mBenchmarkBytesTotal;
OutputBenchmarkResult();
mBenchmarkBytesTotal = 0;
}
+4 -1
View File
@@ -131,6 +131,8 @@ private:
static void MbedTlsDebugOutput(void *ctx, int level, const char *file, int line, const char *str);
#endif
void OutputBenchmarkResult(void);
otTcpEndpoint mEndpoint;
otTcpListener mListener;
@@ -151,7 +153,8 @@ private:
uint32_t mBenchmarkBytesTotal;
uint32_t mBenchmarkBytesUnsent;
TimeMilli mBenchmarkStart;
uint32_t mBenchmarkTimeUsed;
uint32_t mBenchmarkLastBytesTotal;
otTcpEndpointAndCircularSendBuffer mEndpointAndCircularSendBuffer;
#if OPENTHREAD_CONFIG_TLS_ENABLE