Skip to content

Commit

Permalink
[darwin-framework-tool] Address post-landing comments of project-chip…
Browse files Browse the repository at this point in the history
…#31638

[CI] Add some tests for bdx download with darwin-framework-tool
  • Loading branch information
vivien-apple committed Feb 2, 2024
1 parent 8370212 commit 5ef9cbe
Show file tree
Hide file tree
Showing 10 changed files with 640 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@
}
},

'Bdx': {
'commands': {
'Download': {
'arguments': {
'LogType': 'log-type',
},
'has_endpoint': False,
}
}
},

'DelayCommands': {
'alias': 'delay',
'commands': {
Expand Down
11 changes: 10 additions & 1 deletion examples/darwin-framework-tool/commands/bdx/DownloadLogCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,23 @@ class DownloadLogCommand : public CHIPCommandBridge
"The timeout for getting the log. If the timeout expires, completion will be called with whatever has been "
"retrieved by that point (which might be none or a partial log). If the timeout is set to 0, the request will "
"not expire and completion will not be called until the log is fully retrieved or an error occurs.");
AddArgument("async", 0, 1, &mIsAsyncCommand,
"By default the command waits for the download to finish before returning. If async is true the command will "
"not wait and the download will proceed in the background");
AddArgument("filepath", &mFilePath, "An optional filepath to save the download log content to.");
}

/////////// CHIPCommandBridge Interface /////////
CHIP_ERROR RunCommand() override;
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); }
chip::System::Clock::Timeout GetWaitDuration() const override
{
return chip::System::Clock::Seconds16(mTimeout > 0 ? mTimeout + 1 : 300);
}

private:
chip::NodeId mNodeId;
uint8_t mLogType;
uint16_t mTimeout;
chip::Optional<char *> mFilePath;
chip::Optional<bool> mIsAsyncCommand;
};
41 changes: 32 additions & 9 deletions examples/darwin-framework-tool/commands/bdx/DownloadLogCommand.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import "MTRError_Utils.h"

#include "DownloadLogCommand.h"
#include "RemoteDataModelLogger.h"

CHIP_ERROR DownloadLogCommand::RunCommand()
{
Expand All @@ -32,27 +33,49 @@
auto logType = static_cast<MTRDiagnosticLogType>(mLogType);
auto queue = dispatch_queue_create("com.chip.bdx.downloader", DISPATCH_QUEUE_SERIAL);

bool isAsyncCommand = mIsAsyncCommand.ValueOr(false);

bool dumpToFile = mFilePath.HasValue();
auto * dumpFilePath = dumpToFile ? [NSString stringWithUTF8String:mFilePath.Value()] : nil;

auto * self = this;
auto completion = ^(NSURL * url, NSError * error) {
// A non-nil url indicates the presence of content, which can occur even in error scenarios like timeouts.
NSString * logContent = nil;
if (nil != url) {
NSError * readError = nil;
auto * data = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:&readError];
VerifyOrReturn(nil == readError, self->SetCommandExitStatus(MTRErrorToCHIPErrorCode(readError)));
if (nil != readError) {
VerifyOrReturn(isAsyncCommand, self->SetCommandExitStatus(MTRErrorToCHIPErrorCode(readError)));
return;
}

auto * content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Content: %@", content);
}
logContent = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Content: %@", logContent);

VerifyOrReturn(nil == error, self->SetCommandExitStatus(MTRErrorToCHIPErrorCode(error)));
if (dumpToFile) {
NSError * writeError = nil;
auto * fileManager = [NSFileManager defaultManager];
[fileManager copyItemAtPath:[url path] toPath:dumpFilePath error:&writeError];
if (nil != writeError) {
VerifyOrReturn(isAsyncCommand, self->SetCommandExitStatus(MTRErrorToCHIPErrorCode(readError)));
return;
}
}
}

// The url is nil when there are no logs on the target device.
if (nil == url) {
NSLog(@"No logs has been found onto node 0x" ChipLogFormatX64, ChipLogValueX64(mNodeId));
ChipLogProgress(chipTool, "Diagnostic logs transfer: %s", error ? "Error" : "Success");
auto err = RemoteDataModelLogger::LogBdxDownload(logContent, error);
if (CHIP_NO_ERROR != err) {
VerifyOrDo(isAsyncCommand, self->SetCommandExitStatus(err));
return;
}
self->SetCommandExitStatus(CHIP_NO_ERROR);

VerifyOrDo(isAsyncCommand, self->SetCommandExitStatus(MTRErrorToCHIPErrorCode(error)));
};

[device downloadLogOfType:logType timeout:mTimeout queue:queue completion:completion];

VerifyOrDo(!isAsyncCommand, SetCommandExitStatus(CHIP_NO_ERROR));
return CHIP_NO_ERROR;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ CHIP_ERROR LogCommandAsJSON(NSNumber * endpointId, NSNumber * clusterId, NSNumbe
CHIP_ERROR LogAttributeErrorAsJSON(NSNumber * endpointId, NSNumber * clusterId, NSNumber * attributeId, NSError * error);
CHIP_ERROR LogCommandErrorAsJSON(NSNumber * endpointId, NSNumber * clusterId, NSNumber * commandId, NSError * error);
CHIP_ERROR LogGetCommissionerNodeId(NSNumber * nodeId);
CHIP_ERROR LogBdxDownload(NSString * content, NSError * error);
void SetDelegate(RemoteDataModelLoggerDelegate * delegate);
}; // namespace RemoteDataModelLogger
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
constexpr char kClusterErrorIdKey[] = "clusterError";
constexpr char kValueKey[] = "value";
constexpr char kNodeIdKey[] = "nodeId";
constexpr char kLogContentIdKey[] = "logContent";

constexpr char kBase64Header[] = "base64:";

Expand Down Expand Up @@ -204,5 +205,33 @@ CHIP_ERROR LogGetCommissionerNodeId(NSNumber * value)
return gDelegate->LogJSON(valueStr.c_str());
}

CHIP_ERROR LogBdxDownload(NSString * content, NSError * error)
{
VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);

Json::Value rootValue;
rootValue[kValueKey] = Json::Value();

Json::Value jsonValue;
VerifyOrDie(CHIP_NO_ERROR == AsJsonValue(content, jsonValue));
rootValue[kValueKey][kLogContentIdKey] = jsonValue;

if (error) {
auto err = MTRErrorToCHIPErrorCode(error);
auto status = chip::app::StatusIB(err);

#if CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT
auto statusName = chip::Protocols::InteractionModel::StatusName(status.mStatus);
rootValue[kValueKey][kErrorIdKey] = statusName;
#else
auto statusName = status.mStatus;
rootValue[kValueKey][kErrorIdKey] = chip::to_underlying(statusName);
#endif // CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT
}

auto valueStr = JsonToString(rootValue);
return gDelegate->LogJSON(valueStr.c_str());
}

void SetDelegate(RemoteDataModelLoggerDelegate * delegate) { gDelegate = delegate; }
}; // namespace RemoteDataModelLogger
Loading

0 comments on commit 5ef9cbe

Please sign in to comment.