Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions tools/projmgr/include/ProjMgrWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,12 @@ class ProjMgrWorker {
*/
void SetUpCommand(bool isSetup);

/**
* @brief set flag when running in rpc mode
* @param boolean rpcMode
*/
void RpcMode(bool rpcMode);

/**
* @brief set yaml emitter
* @param pointer to yaml emitter
Expand Down Expand Up @@ -961,6 +967,7 @@ class ProjMgrWorker {
bool m_relativePaths;
bool m_cbuild2cmake;
bool m_isSetupCommand;
bool m_rpcMode = false;
std::set<std::string> m_undefLayerVars;
StrMap m_packMetadata;
std::map<std::string, ExecutesItem> m_executes;
Expand Down
1 change: 1 addition & 0 deletions tools/projmgr/src/ProjMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ int ProjMgr::ProcessCommands() {
} else if (m_command == "rpc") {
// Launch 'rpc' server over stdin/stdout
ProjMgrLogger::m_silent = true;
m_worker.RpcMode(true);
if (!m_rpcServer.Run()) {
return ErrorCode::ERROR;
}
Expand Down
5 changes: 3 additions & 2 deletions tools/projmgr/src/ProjMgrRpcServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,10 @@ bool ProjMgrRpcServer::Run(void) {

// Send response
if (m_contextLength) {
cout << CONTENT_LENGTH_HEADER << response.size() << std::endl << std::endl;
cout << CONTENT_LENGTH_HEADER << response.size() << std::endl << std::endl << response << std::flush;
} else {
cout << response << std::endl;
}
cout << response << std::flush;

if (m_debug) {
log << response << std::endl;
Expand Down
9 changes: 9 additions & 0 deletions tools/projmgr/src/ProjMgrWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@ void ProjMgrWorker::SetUpCommand(bool isSetup) {
m_isSetupCommand = isSetup;
}

void ProjMgrWorker::RpcMode(bool rpcMode) {
m_rpcMode = rpcMode;
}

void ProjMgrWorker::SetEmitter(ProjMgrYamlEmitter* emitter) {
m_emitter = emitter;
}
Expand Down Expand Up @@ -1919,6 +1923,11 @@ bool ProjMgrWorker::ProcessComponents(ContextItem& context) {
return false;
}

// tolerate component selection errors when in rpc mode
if (m_rpcMode) {
error = false;
}

return !error;
}

Expand Down
7 changes: 7 additions & 0 deletions tools/projmgr/test/data/TestRpc/minimal.cproject.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json

project:

components:
- component: Startup
- component: CORE
15 changes: 15 additions & 0 deletions tools/projmgr/test/data/TestRpc/minimal.csolution.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json

solution:

compiler: AC6

target-types:
- type: TestHW
device: RteTest_ARMCM4_NOFP

projects:
- project: minimal.cproject.yml

packs:
- pack: ARM::RteTest_DFP
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/cproject.schema.json

project:

components:
- component: Startup
- component: CORE
- component: ARM::UNKNOWN:COMPONENT
15 changes: 15 additions & 0 deletions tools/projmgr/test/data/TestRpc/unknown-component.csolution.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json

solution:

compiler: AC6

target-types:
- type: TestHW
device: RteTest_ARMCM4_NOFP

projects:
- project: unknown-component.cproject.yml

packs:
- pack: ARM::RteTest_DFP
59 changes: 56 additions & 3 deletions tools/projmgr/test/src/ProjMgrRpcTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,76 @@
#include "ProjMgrTestEnv.h"
#include "ProjMgrRpcServer.h"
#include "ProjMgrRpcServerData.h"


#include "ProjMgrLogger.h"

#include "ProductInfo.h"

using namespace std;

class ProjMgrRpcTests : public ProjMgr, public ::testing::Test {
protected:
ProjMgrRpcTests() {}
virtual ~ProjMgrRpcTests() {}
string FormatRequest(const int id, const string& method, const json& params);
vector<json> RunRpcMethods(const string& strIn);
};

TEST_F(ProjMgrRpcTests, Load_Solution) {
string ProjMgrRpcTests::FormatRequest(const int id, const string& method, const json& params = json()) {
json request;
request["jsonrpc"] = "2.0";
request["id"] = id;
request["method"] = method;
if (!params.is_null()) {
request["params"] = params;
}
return request.dump();
}

vector<json> ProjMgrRpcTests::RunRpcMethods(const string& strIn) {
StdStreamRedirect streamRedirect;
streamRedirect.SetInString(strIn);
char* argv[] = { (char*)"csolution", (char*)"rpc" };
EXPECT_EQ(0, RunProjMgr(2, argv, 0));
string line;
vector<json> responses;
istringstream iss(streamRedirect.GetOutString());
while (getline(iss, line)) {
responses.push_back(json::parse(line));
}
return responses;
}

TEST_F(ProjMgrRpcTests, RpcGetVersion) {
const auto& requests = FormatRequest(1, "GetVersion");
const auto& responses = RunRpcMethods(requests);
EXPECT_EQ("2.0", responses[0]["jsonrpc"]);
EXPECT_EQ(1, responses[0]["id"]);
EXPECT_EQ(string(VERSION_STRING), responses[0]["result"]);
}

TEST_F(ProjMgrRpcTests, RpcLoadSolution) {
const string& csolution = testinput_folder + "/TestRpc/minimal.csolution.yml";
const auto& requests =
FormatRequest(1, "LoadPacks") +
FormatRequest(2, "LoadSolution", json({{ "solution", csolution }}));

const auto& responses = RunRpcMethods(requests);
EXPECT_TRUE(responses[0]["result"]);
EXPECT_TRUE(responses[1]["result"]);
}

TEST_F(ProjMgrRpcTests, RpcLoadSolution_UnknownComponent) {
const string& csolution = testinput_folder + "/TestRpc/unknown-component.csolution.yml";
const auto& requests =
FormatRequest(1, "LoadPacks") +
FormatRequest(2, "LoadSolution", json({ { "solution", csolution } })) +
FormatRequest(3, "GetLogMessages");

const auto& responses = RunRpcMethods(requests);
EXPECT_TRUE(responses[0]["result"]);
EXPECT_TRUE(responses[1]["result"]);
EXPECT_EQ("no component was found with identifier 'ARM::UNKNOWN:COMPONENT'",
responses[2]["result"]["errors"][0]);
}

// end of ProjMgrRpcTests.cpp
7 changes: 6 additions & 1 deletion tools/projmgr/test/src/ProjMgrTestEnv.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -44,6 +44,11 @@ void StdStreamRedirect::ClearStringStreams() {
m_cerrbuffer.str(string());
}

void StdStreamRedirect::SetInString(const std::string& inStr) {
m_inputBuffer = std::istringstream(inStr);
std::cin.rdbuf(m_inputBuffer.rdbuf());
}

StdStreamRedirect::~StdStreamRedirect() {
// reverse redirect
std::cout.rdbuf(m_stdoutStreamBuf);
Expand Down
4 changes: 3 additions & 1 deletion tools/projmgr/test/src/ProjMgrTestEnv.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020-2025 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -31,12 +31,14 @@ class StdStreamRedirect {
std::string GetOutString();
std::string GetErrorString();
void ClearStringStreams();
void SetInString(const std::string& inStr);

private:
std::stringstream m_outbuffer;
std::stringstream m_cerrbuffer;
std::streambuf* m_stdoutStreamBuf;
std::streambuf* m_stdcerrStreamBuf;
std::istringstream m_inputBuffer;
};

class TempSwitchCwd {
Expand Down
Loading