server: add "ctestInfo" request to get test info
This commit is contained in:
parent
206354ac4c
commit
35a52bd1b4
@ -628,6 +628,79 @@ CMake will reply::
|
|||||||
]== "CMake Server" ==]
|
]== "CMake Server" ==]
|
||||||
|
|
||||||
|
|
||||||
|
Type "ctestInfo"
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The "ctestInfo" request can be used after a project was "compute"d successfully.
|
||||||
|
|
||||||
|
It will list the complete project test structure as it is known to cmake.
|
||||||
|
|
||||||
|
The reply will contain a key "configurations", which will contain a list of
|
||||||
|
configuration objects. Configuration objects are used to destinquish between
|
||||||
|
different configurations the build directory might have enabled. While most
|
||||||
|
generators only support one configuration, others might support several.
|
||||||
|
|
||||||
|
Each configuration object can have the following keys:
|
||||||
|
|
||||||
|
"name"
|
||||||
|
contains the name of the configuration. The name may be empty.
|
||||||
|
"projects"
|
||||||
|
contains a list of project objects, one for each build project.
|
||||||
|
|
||||||
|
Project objects define one (sub-)project defined in the cmake build system.
|
||||||
|
|
||||||
|
Each project object can have the following keys:
|
||||||
|
|
||||||
|
"name"
|
||||||
|
contains the (sub-)projects name.
|
||||||
|
"targets"
|
||||||
|
contains a list of build system target objects.
|
||||||
|
|
||||||
|
Target objects define individual build targets for a certain configuration.
|
||||||
|
|
||||||
|
Each target object can have the following keys:
|
||||||
|
|
||||||
|
"name"
|
||||||
|
contains the name of the target.
|
||||||
|
"type"
|
||||||
|
defines the type of build of the target. Possible values are
|
||||||
|
"STATIC_LIBRARY", "MODULE_LIBRARY", "SHARED_LIBRARY", "OBJECT_LIBRARY",
|
||||||
|
"EXECUTABLE", "UTILITY" and "INTERFACE_LIBRARY".
|
||||||
|
"fullName"
|
||||||
|
contains the full name of the build result (incl. extensions, etc.).
|
||||||
|
"hasEnabledTests"
|
||||||
|
true if testing is enabled for this target.
|
||||||
|
"ctestInfo"
|
||||||
|
contains a list of test objects for this target.
|
||||||
|
|
||||||
|
Each test object can have the following keys:
|
||||||
|
|
||||||
|
"ctestName"
|
||||||
|
contains the name of the test.
|
||||||
|
"ctestCommand"
|
||||||
|
contains the test command.
|
||||||
|
"properties"
|
||||||
|
contains a list of test property objects.
|
||||||
|
"backtrace"
|
||||||
|
contains a list of backtrace objects that specify where the test was defined.
|
||||||
|
|
||||||
|
Each backtrace object can have the following keys:
|
||||||
|
|
||||||
|
"path"
|
||||||
|
contains the full path to the file containing the statement.
|
||||||
|
"line"
|
||||||
|
contains the line number in the file where the statement was defined.
|
||||||
|
"name"
|
||||||
|
contains the name of the statement that added the test.
|
||||||
|
|
||||||
|
Each test property object can have the following keys:
|
||||||
|
|
||||||
|
"key"
|
||||||
|
contains the test property key.
|
||||||
|
"value"
|
||||||
|
contains the test property value.
|
||||||
|
|
||||||
|
|
||||||
Type "cmakeInputs"
|
Type "cmakeInputs"
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -222,7 +222,14 @@ void cmLocalGenerator::TraceDependencies()
|
|||||||
|
|
||||||
void cmLocalGenerator::GenerateTestFiles()
|
void cmLocalGenerator::GenerateTestFiles()
|
||||||
{
|
{
|
||||||
|
std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary();
|
||||||
|
file += "/";
|
||||||
|
file += "CTestTestfile.cmake";
|
||||||
|
|
||||||
if (!this->Makefile->IsOn("CMAKE_TESTING_ENABLED")) {
|
if (!this->Makefile->IsOn("CMAKE_TESTING_ENABLED")) {
|
||||||
|
if (cmSystemTools::FileExists(file)) {
|
||||||
|
cmSystemTools::RemoveFile(file);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,10 +238,6 @@ void cmLocalGenerator::GenerateTestFiles()
|
|||||||
const std::string& config =
|
const std::string& config =
|
||||||
this->Makefile->GetConfigurations(configurationTypes, false);
|
this->Makefile->GetConfigurations(configurationTypes, false);
|
||||||
|
|
||||||
std::string file = this->StateSnapshot.GetDirectory().GetCurrentBinary();
|
|
||||||
file += "/";
|
|
||||||
file += "CTestTestfile.cmake";
|
|
||||||
|
|
||||||
cmGeneratedFileStream fout(file.c_str());
|
cmGeneratedFileStream fout(file.c_str());
|
||||||
fout.SetCopyIfDifferent(true);
|
fout.SetCopyIfDifferent(true);
|
||||||
|
|
||||||
|
@ -3282,6 +3282,13 @@ cmGlobalGenerator* cmMakefile::GetGlobalGenerator() const
|
|||||||
return this->GlobalGenerator;
|
return this->GlobalGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmMakefile::GetTestNames(std::vector<std::string>& testNames)
|
||||||
|
{
|
||||||
|
for (const auto& iter : Tests) {
|
||||||
|
testNames.push_back(iter.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||||
cmVariableWatch* cmMakefile::GetVariableWatch() const
|
cmVariableWatch* cmMakefile::GetVariableWatch() const
|
||||||
{
|
{
|
||||||
|
@ -616,6 +616,11 @@ public:
|
|||||||
cmMessenger* GetMessenger() const;
|
cmMessenger* GetMessenger() const;
|
||||||
cmGlobalGenerator* GetGlobalGenerator() const;
|
cmGlobalGenerator* GetGlobalGenerator() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the test names this makefile knows about
|
||||||
|
*/
|
||||||
|
void GetTestNames(std::vector<std::string>& testNames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the source files this makefile knows about
|
* Get all the source files this makefile knows about
|
||||||
*/
|
*/
|
||||||
|
@ -23,6 +23,7 @@ static const std::string kPROGRESS_TYPE = "progress";
|
|||||||
static const std::string kREPLY_TYPE = "reply";
|
static const std::string kREPLY_TYPE = "reply";
|
||||||
static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings";
|
static const std::string kSET_GLOBAL_SETTINGS_TYPE = "setGlobalSettings";
|
||||||
static const std::string kSIGNAL_TYPE = "signal";
|
static const std::string kSIGNAL_TYPE = "signal";
|
||||||
|
static const std::string kCTEST_INFO_TYPE = "ctestInfo";
|
||||||
|
|
||||||
static const std::string kARTIFACTS_KEY = "artifacts";
|
static const std::string kARTIFACTS_KEY = "artifacts";
|
||||||
static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
|
static const std::string kBUILD_DIRECTORY_KEY = "buildDirectory";
|
||||||
@ -90,6 +91,10 @@ static const std::string kWATCHED_DIRECTORIES_KEY = "watchedDirectories";
|
|||||||
static const std::string kWATCHED_FILES_KEY = "watchedFiles";
|
static const std::string kWATCHED_FILES_KEY = "watchedFiles";
|
||||||
static const std::string kHAS_INSTALL_RULE = "hasInstallRule";
|
static const std::string kHAS_INSTALL_RULE = "hasInstallRule";
|
||||||
static const std::string kINSTALL_PATHS = "installPaths";
|
static const std::string kINSTALL_PATHS = "installPaths";
|
||||||
|
static const std::string kHAS_ENABLED_TESTS = "hasEnabledTests";
|
||||||
|
static const std::string kCTEST_NAME = "ctestName";
|
||||||
|
static const std::string kCTEST_COMMAND = "ctestCommand";
|
||||||
|
static const std::string kCTEST_INFO = "ctestInfo";
|
||||||
|
|
||||||
static const std::string kTARGET_CROSS_REFERENCES_KEY = "crossReferences";
|
static const std::string kTARGET_CROSS_REFERENCES_KEY = "crossReferences";
|
||||||
static const std::string kLINE_NUMBER_KEY = "line";
|
static const std::string kLINE_NUMBER_KEY = "line";
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "cmListFileCache.h"
|
#include "cmListFileCache.h"
|
||||||
#include "cmLocalGenerator.h"
|
#include "cmLocalGenerator.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
#include "cmProperty.h"
|
||||||
#include "cmServer.h"
|
#include "cmServer.h"
|
||||||
#include "cmServerDictionary.h"
|
#include "cmServerDictionary.h"
|
||||||
#include "cmSourceFile.h"
|
#include "cmSourceFile.h"
|
||||||
@ -23,6 +24,7 @@
|
|||||||
#include "cmStateTypes.h"
|
#include "cmStateTypes.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmTarget.h"
|
#include "cmTarget.h"
|
||||||
|
#include "cmTest.h"
|
||||||
#include "cm_uv.h"
|
#include "cm_uv.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
|
||||||
@ -479,6 +481,9 @@ const cmServerResponse cmServerProtocol1::Process(
|
|||||||
if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) {
|
if (request.Type == kSET_GLOBAL_SETTINGS_TYPE) {
|
||||||
return this->ProcessSetGlobalSettings(request);
|
return this->ProcessSetGlobalSettings(request);
|
||||||
}
|
}
|
||||||
|
if (request.Type == kCTEST_INFO_TYPE) {
|
||||||
|
return this->ProcessCTests(request);
|
||||||
|
}
|
||||||
|
|
||||||
return request.ReportError("Unknown command!");
|
return request.ReportError("Unknown command!");
|
||||||
}
|
}
|
||||||
@ -766,6 +771,153 @@ static void DumpBacktraceRange(Json::Value& result, const std::string& type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Json::Value DumpCTestInfo(const std::string& name, cmTest* testInfo)
|
||||||
|
{
|
||||||
|
Json::Value result = Json::objectValue;
|
||||||
|
result[kCTEST_NAME] = name;
|
||||||
|
|
||||||
|
// Concat command entries together. After the first should be the arguments
|
||||||
|
// for the command
|
||||||
|
std::string command;
|
||||||
|
for (auto const& cmd : testInfo->GetCommand()) {
|
||||||
|
command.append(cmd);
|
||||||
|
command.append(" ");
|
||||||
|
}
|
||||||
|
result[kCTEST_COMMAND] = command;
|
||||||
|
|
||||||
|
// Build up the list of properties that may have been specified
|
||||||
|
Json::Value properties = Json::arrayValue;
|
||||||
|
for (auto& prop : testInfo->GetProperties()) {
|
||||||
|
Json::Value entry = Json::objectValue;
|
||||||
|
entry[kKEY_KEY] = prop.first;
|
||||||
|
entry[kVALUE_KEY] = prop.second.GetValue();
|
||||||
|
properties.append(entry);
|
||||||
|
}
|
||||||
|
result[kPROPERTIES_KEY] = properties;
|
||||||
|
|
||||||
|
// Need backtrace to figure out where this test was originally added
|
||||||
|
result[kBACKTRACE_KEY] = DumpBacktrace(testInfo->GetBacktrace());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Json::Value DumpCTestTarget(cmGeneratorTarget* target,
|
||||||
|
const std::string& config)
|
||||||
|
{
|
||||||
|
cmLocalGenerator* lg = target->GetLocalGenerator();
|
||||||
|
const cmState* state = lg->GetState();
|
||||||
|
|
||||||
|
const cmStateEnums::TargetType type = target->GetType();
|
||||||
|
const std::string typeName = state->GetTargetTypeName(type);
|
||||||
|
|
||||||
|
Json::Value ttl = Json::arrayValue;
|
||||||
|
ttl.append("EXECUTABLE");
|
||||||
|
ttl.append("STATIC_LIBRARY");
|
||||||
|
ttl.append("SHARED_LIBRARY");
|
||||||
|
ttl.append("MODULE_LIBRARY");
|
||||||
|
ttl.append("OBJECT_LIBRARY");
|
||||||
|
ttl.append("UTILITY");
|
||||||
|
ttl.append("INTERFACE_LIBRARY");
|
||||||
|
|
||||||
|
if (!hasString(ttl, typeName) || target->IsImported()) {
|
||||||
|
return Json::Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value result = Json::objectValue;
|
||||||
|
result[kNAME_KEY] = target->GetName();
|
||||||
|
result[kTYPE_KEY] = typeName;
|
||||||
|
|
||||||
|
if (type == cmStateEnums::INTERFACE_LIBRARY) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result[kFULL_NAME_KEY] = target->GetFullName(config);
|
||||||
|
|
||||||
|
if (target->Makefile->IsOn("CMAKE_TESTING_ENABLED")) {
|
||||||
|
result[kHAS_ENABLED_TESTS] = true;
|
||||||
|
std::vector<std::string> CTestNames;
|
||||||
|
|
||||||
|
Json::Value testInfo = Json::arrayValue;
|
||||||
|
std::vector<std::string> testNames;
|
||||||
|
target->Makefile->GetTestNames(testNames);
|
||||||
|
for (auto& name : testNames) {
|
||||||
|
auto test = target->Makefile->GetTest(name);
|
||||||
|
if (test != nullptr) {
|
||||||
|
testInfo.append(DumpCTestInfo(name, test));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result[kCTEST_INFO] = testInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Json::Value DumpCTestTargetsList(
|
||||||
|
const std::vector<cmLocalGenerator*>& generators, const std::string& config)
|
||||||
|
{
|
||||||
|
Json::Value result = Json::arrayValue;
|
||||||
|
|
||||||
|
std::vector<cmGeneratorTarget*> targetList;
|
||||||
|
for (const auto& lgIt : generators) {
|
||||||
|
auto list = lgIt->GetGeneratorTargets();
|
||||||
|
targetList.insert(targetList.end(), list.begin(), list.end());
|
||||||
|
}
|
||||||
|
std::sort(targetList.begin(), targetList.end());
|
||||||
|
|
||||||
|
for (cmGeneratorTarget* target : targetList) {
|
||||||
|
Json::Value tmp = DumpCTestTarget(target, config);
|
||||||
|
if (!tmp.isNull()) {
|
||||||
|
result.append(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Json::Value DumpCTestProjectList(const cmake* cm,
|
||||||
|
std::string const& config)
|
||||||
|
{
|
||||||
|
Json::Value result = Json::arrayValue;
|
||||||
|
|
||||||
|
auto globalGen = cm->GetGlobalGenerator();
|
||||||
|
|
||||||
|
for (const auto& projectIt : globalGen->GetProjectMap()) {
|
||||||
|
Json::Value pObj = Json::objectValue;
|
||||||
|
pObj[kNAME_KEY] = projectIt.first;
|
||||||
|
|
||||||
|
// All Projects must have at least one local generator
|
||||||
|
assert(!projectIt.second.empty());
|
||||||
|
|
||||||
|
// Project structure information:
|
||||||
|
pObj[kTARGETS_KEY] = DumpCTestTargetsList(projectIt.second, config);
|
||||||
|
|
||||||
|
result.append(pObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Json::Value DumpCTestConfiguration(const cmake* cm,
|
||||||
|
const std::string& config)
|
||||||
|
{
|
||||||
|
Json::Value result = Json::objectValue;
|
||||||
|
result[kNAME_KEY] = config;
|
||||||
|
|
||||||
|
result[kPROJECTS_KEY] = DumpCTestProjectList(cm, config);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Json::Value DumpCTestConfigurationsList(const cmake* cm)
|
||||||
|
{
|
||||||
|
Json::Value result = Json::arrayValue;
|
||||||
|
|
||||||
|
for (const std::string& c : getConfigurations(cm)) {
|
||||||
|
result.append(DumpCTestConfiguration(cm, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static Json::Value DumpTarget(cmGeneratorTarget* target,
|
static Json::Value DumpTarget(cmGeneratorTarget* target,
|
||||||
const std::string& config)
|
const std::string& config)
|
||||||
{
|
{
|
||||||
@ -1222,6 +1374,19 @@ cmServerResponse cmServerProtocol1::ProcessFileSystemWatchers(
|
|||||||
return request.Reply(result);
|
return request.Reply(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmServerResponse cmServerProtocol1::ProcessCTests(
|
||||||
|
const cmServerRequest& request)
|
||||||
|
{
|
||||||
|
if (this->m_State < STATE_COMPUTED) {
|
||||||
|
return request.ReportError("This instance was not yet computed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value result = Json::objectValue;
|
||||||
|
result[kCONFIGURATIONS_KEY] =
|
||||||
|
DumpCTestConfigurationsList(this->CMakeInstance());
|
||||||
|
return request.Reply(result);
|
||||||
|
}
|
||||||
|
|
||||||
cmServerProtocol1::GeneratorInformation::GeneratorInformation(
|
cmServerProtocol1::GeneratorInformation::GeneratorInformation(
|
||||||
const std::string& generatorName, const std::string& extraGeneratorName,
|
const std::string& generatorName, const std::string& extraGeneratorName,
|
||||||
const std::string& toolset, const std::string& platform,
|
const std::string& toolset, const std::string& platform,
|
||||||
|
@ -123,6 +123,7 @@ private:
|
|||||||
cmServerResponse ProcessGlobalSettings(const cmServerRequest& request);
|
cmServerResponse ProcessGlobalSettings(const cmServerRequest& request);
|
||||||
cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request);
|
cmServerResponse ProcessSetGlobalSettings(const cmServerRequest& request);
|
||||||
cmServerResponse ProcessFileSystemWatchers(const cmServerRequest& request);
|
cmServerResponse ProcessFileSystemWatchers(const cmServerRequest& request);
|
||||||
|
cmServerResponse ProcessCTests(const cmServerRequest& request);
|
||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user