mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-12 17:19:05 -05:00
Merge topic 'labels-for-subprojects'
376dc3ebHelp: Add notes for topic 'labels_for_subprojects'a70d8e93Add tests for new directory labels and labels-for-subprojects features47b3a57cDisplay subproject timing summaryd3859624Add directory property 'LABELS' and CMAKE_DIRECTORY_LABELS variabled08ec4d2Add CTEST_LABELS_FOR_SUBPROJECTS as a CTest module and script variable Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1004
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -74,6 +74,7 @@ Properties on Directories
|
||||
/prop_dir/INCLUDE_REGULAR_EXPRESSION
|
||||
/prop_dir/INTERPROCEDURAL_OPTIMIZATION_CONFIG
|
||||
/prop_dir/INTERPROCEDURAL_OPTIMIZATION
|
||||
/prop_dir/LABELS
|
||||
/prop_dir/LINK_DIRECTORIES
|
||||
/prop_dir/LISTFILE_STACK
|
||||
/prop_dir/MACROS
|
||||
|
||||
@@ -32,6 +32,7 @@ Variables that Provide Information
|
||||
/variable/CMAKE_CURRENT_LIST_FILE
|
||||
/variable/CMAKE_CURRENT_LIST_LINE
|
||||
/variable/CMAKE_CURRENT_SOURCE_DIR
|
||||
/variable/CMAKE_DIRECTORY_LABELS
|
||||
/variable/CMAKE_DL_LIBS
|
||||
/variable/CMAKE_EDIT_COMMAND
|
||||
/variable/CMAKE_EXECUTABLE_SUFFIX
|
||||
@@ -482,6 +483,7 @@ Variables for CTest
|
||||
/variable/CTEST_GIT_UPDATE_OPTIONS
|
||||
/variable/CTEST_HG_COMMAND
|
||||
/variable/CTEST_HG_UPDATE_OPTIONS
|
||||
/variable/CTEST_LABELS_FOR_SUBPROJECTS
|
||||
/variable/CTEST_MEMORYCHECK_COMMAND
|
||||
/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS
|
||||
/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS
|
||||
|
||||
@@ -250,6 +250,13 @@ Options
|
||||
label associated with the tests run. If there are no labels on the
|
||||
tests, nothing extra is printed.
|
||||
|
||||
``--no-subproject-summary``
|
||||
Disable timing summary information for subprojects.
|
||||
|
||||
This option tells ctest not to print summary information for each
|
||||
subproject associated with the tests run. If there are no subprojects on the
|
||||
tests, nothing extra is printed.
|
||||
|
||||
``--build-and-test <path-to-source> <path-to-build>``
|
||||
Configure, build and run a test.
|
||||
|
||||
@@ -758,6 +765,15 @@ Configuration settings include:
|
||||
* :module:`CTest` module variable: :variable:`CMAKE_COMMAND`
|
||||
followed by :variable:`PROJECT_SOURCE_DIR`
|
||||
|
||||
``LabelsForSubprojects``
|
||||
Specify a semicolon-separated list of labels that will be treated as
|
||||
subprojects. This mapping will be passed on to CDash when configure, test or
|
||||
build results are submitted.
|
||||
|
||||
* `CTest Script`_ variable: :variable:`CTEST_LABELS_FOR_SUBPROJECTS`
|
||||
* :module:`CTest` module variable: ``CTEST_LABELS_FOR_SUBPROJECTS``
|
||||
|
||||
|
||||
.. _`CTest Build Step`:
|
||||
|
||||
CTest Build Step
|
||||
@@ -780,6 +796,14 @@ Configuration settings include:
|
||||
* :module:`CTest` module variable: ``DEFAULT_CTEST_CONFIGURATION_TYPE``,
|
||||
initialized by the ``CMAKE_CONFIG_TYPE`` environment variable
|
||||
|
||||
``LabelsForSubprojects``
|
||||
Specify a semicolon-separated list of labels that will be treated as
|
||||
subprojects. This mapping will be passed on to CDash when configure, test or
|
||||
build results are submitted.
|
||||
|
||||
* `CTest Script`_ variable: :variable:`CTEST_LABELS_FOR_SUBPROJECTS`
|
||||
* :module:`CTest` module variable: ``CTEST_LABELS_FOR_SUBPROJECTS``
|
||||
|
||||
``MakeCommand``
|
||||
Command-line to launch the software build process.
|
||||
It will be executed in the location specified by the
|
||||
@@ -815,6 +839,15 @@ Arguments to the command may specify some of the step settings.
|
||||
|
||||
Configuration settings include:
|
||||
|
||||
``LabelsForSubprojects``
|
||||
Specify a semicolon-separated list of labels that will be treated as
|
||||
subprojects. This mapping will be passed on to CDash when configure, test or
|
||||
build results are submitted.
|
||||
|
||||
* `CTest Script`_ variable: :variable:`CTEST_LABELS_FOR_SUBPROJECTS`
|
||||
* :module:`CTest` module variable: ``CTEST_LABELS_FOR_SUBPROJECTS``
|
||||
|
||||
|
||||
``TestLoad``
|
||||
While running tests in parallel (e.g. with ``-j``), try not to start
|
||||
tests when they may cause the CPU load to pass above a given threshold.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
LABELS
|
||||
------
|
||||
|
||||
Specify a list of text labels associated with a directory and all of its
|
||||
subdirectories. This is equivalent to setting the :prop_tgt:`LABELS` target
|
||||
property and the :prop_test:`LABELS` test property on all targets and tests in
|
||||
the current directory and subdirectories. Note: Launchers must enabled to
|
||||
propagate labels to targets.
|
||||
|
||||
The :variable:`CMAKE_DIRECTORY_LABELS` variable can be used to initialize this
|
||||
property.
|
||||
|
||||
The list is reported in dashboard submissions.
|
||||
@@ -0,0 +1,14 @@
|
||||
labels_for_subprojects
|
||||
----------------------
|
||||
|
||||
* A :variable:`CTEST_LABELS_FOR_SUBPROJECTS` CTest module variable and CTest
|
||||
script variable was added to specify a list of labels that should be treated
|
||||
as subprojects by CDash. To use this value in both the CTest module and the
|
||||
ctest command line `Dashboard Client` mode (e.g. ctest -S) set it in the
|
||||
CTestConfig.cmake config file.
|
||||
|
||||
* A :prop_dir:`LABELS` directory property was added to specify labels
|
||||
for all targets and tests in a directory.
|
||||
|
||||
* A :variable:`CMAKE_DIRECTORY_LABELS` variable was added to specify
|
||||
labels for all tests in a directory.
|
||||
@@ -0,0 +1,6 @@
|
||||
CMAKE_DIRECTORY_LABELS
|
||||
-----------------------
|
||||
|
||||
Specify labels for the current directory.
|
||||
|
||||
This is used to initialize the :prop_dir:`LABELS` directory property.
|
||||
@@ -0,0 +1,5 @@
|
||||
CTEST_LABELS_FOR_SUBPROJECTS
|
||||
----------------------------
|
||||
|
||||
Specify the CTest ``LabelsForSubprojects`` setting
|
||||
in a :manual:`ctest(1)` dashboard client script.
|
||||
@@ -16,6 +16,9 @@ Site: @SITE@
|
||||
# Build name is osname-revision-compiler, i.e. Linux-2.4.2-2smp-c++
|
||||
BuildName: @BUILDNAME@
|
||||
|
||||
# Subprojects
|
||||
LabelsForSubprojects: @CTEST_LABELS_FOR_SUBPROJECTS@
|
||||
|
||||
# Submission information
|
||||
IsCDash: @CTEST_DROP_SITE_CDASH@
|
||||
CDashVersion: @CTEST_CDASH_VERSION@
|
||||
|
||||
@@ -153,6 +153,12 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
|
||||
this->Quiet);
|
||||
}
|
||||
|
||||
if (const char* labelsForSubprojects =
|
||||
this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
|
||||
this->CTest->SetCTestConfiguration("LabelsForSubprojects",
|
||||
labelsForSubprojects, this->Quiet);
|
||||
}
|
||||
|
||||
handler->SetQuiet(this->Quiet);
|
||||
return handler;
|
||||
}
|
||||
|
||||
@@ -488,6 +488,7 @@ int cmCTestBuildHandler::ProcessHandler()
|
||||
void cmCTestBuildHandler::GenerateXMLHeader(cmXMLWriter& xml)
|
||||
{
|
||||
this->CTest->StartXML(xml, this->AppendXML);
|
||||
this->CTest->GenerateSubprojectsOutput(xml);
|
||||
xml.StartElement("Build");
|
||||
xml.Element("StartDateTime", this->StartBuild);
|
||||
xml.Element("StartBuildTime",
|
||||
|
||||
@@ -141,6 +141,12 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
|
||||
}
|
||||
}
|
||||
|
||||
if (const char* labelsForSubprojects =
|
||||
this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
|
||||
this->CTest->SetCTestConfiguration("LabelsForSubprojects",
|
||||
labelsForSubprojects, this->Quiet);
|
||||
}
|
||||
|
||||
cmCTestGenericHandler* handler =
|
||||
this->CTest->GetInitializedHandler("configure");
|
||||
if (!handler) {
|
||||
|
||||
@@ -73,6 +73,7 @@ int cmCTestConfigureHandler::ProcessHandler()
|
||||
if (os) {
|
||||
cmXMLWriter xml(os);
|
||||
this->CTest->StartXML(xml, this->AppendXML);
|
||||
this->CTest->GenerateSubprojectsOutput(xml);
|
||||
xml.StartElement("Configure");
|
||||
xml.Element("StartDateTime", start_time);
|
||||
xml.Element("StartConfigureTime", start_time_time);
|
||||
|
||||
@@ -291,6 +291,7 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
|
||||
return;
|
||||
}
|
||||
this->CTest->StartXML(xml, this->AppendXML);
|
||||
this->CTest->GenerateSubprojectsOutput(xml);
|
||||
xml.StartElement("DynamicAnalysis");
|
||||
switch (this->MemoryTesterStyle) {
|
||||
case cmCTestMemCheckHandler::VALGRIND:
|
||||
|
||||
@@ -394,7 +394,7 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// extract variabels from the script to set ivars
|
||||
// extract variables from the script to set ivars
|
||||
int cmCTestScriptHandler::ExtractVariables()
|
||||
{
|
||||
// Temporary variables
|
||||
|
||||
@@ -124,6 +124,12 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
|
||||
}
|
||||
handler->SetTestLoad(testLoad);
|
||||
|
||||
if (const char* labelsForSubprojects =
|
||||
this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
|
||||
this->CTest->SetCTestConfiguration("LabelsForSubprojects",
|
||||
labelsForSubprojects, this->Quiet);
|
||||
}
|
||||
|
||||
handler->SetQuiet(this->Quiet);
|
||||
return handler;
|
||||
}
|
||||
|
||||
@@ -238,6 +238,36 @@ bool cmCTestSetTestsPropertiesCommand::InitialPass(
|
||||
return this->TestHandler->SetTestsProperties(args);
|
||||
}
|
||||
|
||||
class cmCTestSetDirectoryPropertiesCommand : public cmCommand
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
cmCommand* Clone() CM_OVERRIDE
|
||||
{
|
||||
cmCTestSetDirectoryPropertiesCommand* c =
|
||||
new cmCTestSetDirectoryPropertiesCommand;
|
||||
c->TestHandler = this->TestHandler;
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
bool InitialPass(std::vector<std::string> const& /*unused*/,
|
||||
cmExecutionStatus& /*unused*/) CM_OVERRIDE;
|
||||
|
||||
cmCTestTestHandler* TestHandler;
|
||||
};
|
||||
|
||||
bool cmCTestSetDirectoryPropertiesCommand::InitialPass(
|
||||
std::vector<std::string> const& args, cmExecutionStatus&)
|
||||
{
|
||||
return this->TestHandler->SetDirectoryProperties(args);
|
||||
}
|
||||
|
||||
// get the next number in a string with numbers separated by ,
|
||||
// pos is the start of the search and pos2 is the end of the search
|
||||
// pos becomes pos2 after a call to GetNextNumber.
|
||||
@@ -506,9 +536,14 @@ int cmCTestTestHandler::ProcessHandler()
|
||||
<< static_cast<int>(percent + .5f) << "% tests passed, "
|
||||
<< failed.size() << " tests failed out of " << total
|
||||
<< std::endl);
|
||||
if (this->CTest->GetLabelSummary()) {
|
||||
|
||||
if (!this->CTest->GetLabelsForSubprojects().empty() &&
|
||||
this->CTest->GetSubprojectSummary()) {
|
||||
this->PrintSubprojectSummary();
|
||||
} else if (this->CTest->GetLabelSummary()) {
|
||||
this->PrintLabelSummary();
|
||||
}
|
||||
|
||||
char realBuf[1024];
|
||||
sprintf(realBuf, "%6.2f sec", (double)(clock_finish - clock_start));
|
||||
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
|
||||
@@ -658,6 +693,84 @@ void cmCTestTestHandler::PrintLabelSummary()
|
||||
}
|
||||
}
|
||||
|
||||
void cmCTestTestHandler::PrintSubprojectSummary()
|
||||
{
|
||||
std::vector<std::string> subprojects =
|
||||
this->CTest->GetLabelsForSubprojects();
|
||||
|
||||
cmCTestTestHandler::ListOfTests::iterator it = this->TestList.begin();
|
||||
std::map<std::string, double> labelTimes;
|
||||
std::map<std::string, int> labelCounts;
|
||||
std::set<std::string> labels;
|
||||
// initialize maps
|
||||
std::string::size_type maxlen = 0;
|
||||
for (; it != this->TestList.end(); ++it) {
|
||||
cmCTestTestProperties& p = *it;
|
||||
for (std::vector<std::string>::iterator l = p.Labels.begin();
|
||||
l != p.Labels.end(); ++l) {
|
||||
std::vector<std::string>::iterator subproject =
|
||||
std::find(subprojects.begin(), subprojects.end(), *l);
|
||||
if (subproject != subprojects.end()) {
|
||||
if ((*l).size() > maxlen) {
|
||||
maxlen = (*l).size();
|
||||
}
|
||||
labels.insert(*l);
|
||||
labelTimes[*l] = 0;
|
||||
labelCounts[*l] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
cmCTestTestHandler::TestResultsVector::iterator ri =
|
||||
this->TestResults.begin();
|
||||
// fill maps
|
||||
for (; ri != this->TestResults.end(); ++ri) {
|
||||
cmCTestTestResult& result = *ri;
|
||||
cmCTestTestProperties& p = *result.Properties;
|
||||
for (std::vector<std::string>::iterator l = p.Labels.begin();
|
||||
l != p.Labels.end(); ++l) {
|
||||
std::vector<std::string>::iterator subproject =
|
||||
std::find(subprojects.begin(), subprojects.end(), *l);
|
||||
if (subproject != subprojects.end()) {
|
||||
labelTimes[*l] += result.ExecutionTime;
|
||||
++labelCounts[*l];
|
||||
}
|
||||
}
|
||||
}
|
||||
// now print times
|
||||
if (!labels.empty()) {
|
||||
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
|
||||
"\nSubproject Time Summary:", this->Quiet);
|
||||
}
|
||||
for (std::set<std::string>::const_iterator i = labels.begin();
|
||||
i != labels.end(); ++i) {
|
||||
std::string label = *i;
|
||||
label.resize(maxlen + 3, ' ');
|
||||
|
||||
char buf[1024];
|
||||
sprintf(buf, "%6.2f sec", labelTimes[*i]);
|
||||
|
||||
std::ostringstream labelCountStr;
|
||||
labelCountStr << "(" << labelCounts[*i] << " test";
|
||||
if (labelCounts[*i] > 1) {
|
||||
labelCountStr << "s";
|
||||
}
|
||||
labelCountStr << ")";
|
||||
|
||||
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n"
|
||||
<< label << " = " << buf << " "
|
||||
<< labelCountStr.str(),
|
||||
this->Quiet);
|
||||
if (this->LogFile) {
|
||||
*this->LogFile << "\n" << *i << " = " << buf << "\n";
|
||||
}
|
||||
}
|
||||
if (!labels.empty()) {
|
||||
if (this->LogFile) {
|
||||
*this->LogFile << "\n";
|
||||
}
|
||||
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n", this->Quiet);
|
||||
}
|
||||
}
|
||||
void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
|
||||
{
|
||||
// if not using Labels to filter then return
|
||||
@@ -1277,6 +1390,7 @@ void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
|
||||
}
|
||||
|
||||
this->CTest->StartXML(xml, this->AppendXML);
|
||||
this->CTest->GenerateSubprojectsOutput(xml);
|
||||
xml.StartElement("Testing");
|
||||
xml.Element("StartDateTime", this->StartTest);
|
||||
xml.Element("StartTestTime", this->StartTestTime);
|
||||
@@ -1660,6 +1774,12 @@ void cmCTestTestHandler::GetListOfTests()
|
||||
newCom4->TestHandler = this;
|
||||
cm.GetState()->AddBuiltinCommand("set_tests_properties", newCom4);
|
||||
|
||||
// Add handler for SET_DIRECTORY_PROPERTIES
|
||||
cmCTestSetDirectoryPropertiesCommand* newCom5 =
|
||||
new cmCTestSetDirectoryPropertiesCommand;
|
||||
newCom5->TestHandler = this;
|
||||
cm.GetState()->AddBuiltinCommand("set_directory_properties", newCom5);
|
||||
|
||||
const char* testFilename;
|
||||
if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
|
||||
// does the CTestTestfile.cmake exist ?
|
||||
@@ -2171,7 +2291,16 @@ bool cmCTestTestHandler::SetTestsProperties(
|
||||
cmSystemTools::ExpandListArgument(val, rtit->Environment);
|
||||
}
|
||||
if (key == "LABELS") {
|
||||
cmSystemTools::ExpandListArgument(val, rtit->Labels);
|
||||
std::vector<std::string> Labels;
|
||||
cmSystemTools::ExpandListArgument(val, Labels);
|
||||
rtit->Labels.insert(rtit->Labels.end(), Labels.begin(),
|
||||
Labels.end());
|
||||
// sort the array
|
||||
std::sort(rtit->Labels.begin(), rtit->Labels.end());
|
||||
// remove duplicates
|
||||
std::vector<std::string>::iterator new_end =
|
||||
std::unique(rtit->Labels.begin(), rtit->Labels.end());
|
||||
rtit->Labels.erase(new_end, rtit->Labels.end());
|
||||
}
|
||||
if (key == "MEASUREMENT") {
|
||||
size_t pos = val.find_first_of('=');
|
||||
@@ -2224,6 +2353,54 @@ bool cmCTestTestHandler::SetTestsProperties(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmCTestTestHandler::SetDirectoryProperties(
|
||||
const std::vector<std::string>& args)
|
||||
{
|
||||
std::vector<std::string>::const_iterator it;
|
||||
std::vector<std::string> tests;
|
||||
bool found = false;
|
||||
for (it = args.begin(); it != args.end(); ++it) {
|
||||
if (*it == "PROPERTIES") {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
tests.push_back(*it);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
++it; // skip PROPERTIES
|
||||
for (; it != args.end(); ++it) {
|
||||
std::string key = *it;
|
||||
++it;
|
||||
if (it == args.end()) {
|
||||
break;
|
||||
}
|
||||
std::string val = *it;
|
||||
cmCTestTestHandler::ListOfTests::iterator rtit;
|
||||
for (rtit = this->TestList.begin(); rtit != this->TestList.end(); ++rtit) {
|
||||
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
|
||||
if (cwd == rtit->Directory) {
|
||||
if (key == "LABELS") {
|
||||
std::vector<std::string> DirectoryLabels;
|
||||
cmSystemTools::ExpandListArgument(val, DirectoryLabels);
|
||||
rtit->Labels.insert(rtit->Labels.end(), DirectoryLabels.begin(),
|
||||
DirectoryLabels.end());
|
||||
|
||||
// sort the array
|
||||
std::sort(rtit->Labels.begin(), rtit->Labels.end());
|
||||
// remove duplicates
|
||||
std::vector<std::string>::iterator new_end =
|
||||
std::unique(rtit->Labels.begin(), rtit->Labels.end());
|
||||
rtit->Labels.erase(new_end, rtit->Labels.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
|
||||
{
|
||||
const std::string& testname = args[0];
|
||||
|
||||
@@ -90,6 +90,11 @@ public:
|
||||
*/
|
||||
bool SetTestsProperties(const std::vector<std::string>& args);
|
||||
|
||||
/**
|
||||
* Set directory properties
|
||||
*/
|
||||
bool SetDirectoryProperties(const std::vector<std::string>& args);
|
||||
|
||||
void Initialize() CM_OVERRIDE;
|
||||
|
||||
// NOTE: This struct is Saved/Restored
|
||||
@@ -227,6 +232,8 @@ private:
|
||||
virtual void GenerateDartOutput(cmXMLWriter& xml);
|
||||
|
||||
void PrintLabelSummary();
|
||||
void PrintSubprojectSummary();
|
||||
|
||||
/**
|
||||
* Run the tests for a directory and any subdirectories
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "cmsys/Process.h"
|
||||
#include "cmsys/String.hxx"
|
||||
#include "cmsys/SystemInformation.hxx"
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
@@ -253,6 +254,7 @@ std::string cmCTest::DecodeURL(const std::string& in)
|
||||
cmCTest::cmCTest()
|
||||
{
|
||||
this->LabelSummary = true;
|
||||
this->SubprojectSummary = true;
|
||||
this->ParallelLevel = 1;
|
||||
this->ParallelLevelSetInCli = false;
|
||||
this->TestLoad = 0;
|
||||
@@ -1364,6 +1366,35 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
|
||||
}
|
||||
}
|
||||
|
||||
void cmCTest::GenerateSubprojectsOutput(cmXMLWriter& xml)
|
||||
{
|
||||
std::vector<std::string> subprojects = this->GetLabelsForSubprojects();
|
||||
std::vector<std::string>::const_iterator i;
|
||||
for (i = subprojects.begin(); i != subprojects.end(); ++i) {
|
||||
xml.StartElement("Subproject");
|
||||
xml.Attribute("name", *i);
|
||||
xml.Element("Label", *i);
|
||||
xml.EndElement(); // Subproject
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> cmCTest::GetLabelsForSubprojects()
|
||||
{
|
||||
std::string labelsForSubprojects =
|
||||
this->GetCTestConfiguration("LabelsForSubprojects");
|
||||
std::vector<std::string> subprojects;
|
||||
cmSystemTools::ExpandListArgument(labelsForSubprojects, subprojects);
|
||||
|
||||
// sort the array
|
||||
std::sort(subprojects.begin(), subprojects.end());
|
||||
// remove duplicates
|
||||
std::vector<std::string>::iterator new_end =
|
||||
std::unique(subprojects.begin(), subprojects.end());
|
||||
subprojects.erase(new_end, subprojects.end());
|
||||
|
||||
return subprojects;
|
||||
}
|
||||
|
||||
void cmCTest::EndXML(cmXMLWriter& xml)
|
||||
{
|
||||
xml.EndElement(); // Site
|
||||
@@ -1765,6 +1796,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
|
||||
if (this->CheckArgument(arg, "--no-label-summary")) {
|
||||
this->LabelSummary = false;
|
||||
}
|
||||
if (this->CheckArgument(arg, "--no-subproject-summary")) {
|
||||
this->SubprojectSummary = false;
|
||||
}
|
||||
if (this->CheckArgument(arg, "-Q", "--quiet")) {
|
||||
this->Quiet = true;
|
||||
}
|
||||
|
||||
@@ -438,7 +438,9 @@ public:
|
||||
this->StreamErr = err;
|
||||
}
|
||||
void AddSiteProperties(cmXMLWriter& xml);
|
||||
|
||||
bool GetLabelSummary() { return this->LabelSummary; }
|
||||
bool GetSubprojectSummary() { return this->SubprojectSummary; }
|
||||
|
||||
std::string GetCostDataFile();
|
||||
|
||||
@@ -453,6 +455,9 @@ public:
|
||||
/** Return true if test should run until fail */
|
||||
bool GetRepeatUntilFail() { return this->RepeatUntilFail; }
|
||||
|
||||
void GenerateSubprojectsOutput(cmXMLWriter& xml);
|
||||
std::vector<std::string> GetLabelsForSubprojects();
|
||||
|
||||
private:
|
||||
int RepeatTests;
|
||||
bool RepeatUntilFail;
|
||||
@@ -464,6 +469,7 @@ private:
|
||||
bool ExtraVerbose;
|
||||
bool ProduceXML;
|
||||
bool LabelSummary;
|
||||
bool SubprojectSummary;
|
||||
bool UseHTTP10;
|
||||
bool PrintLabels;
|
||||
bool Failover;
|
||||
|
||||
@@ -147,8 +147,6 @@ void GetScriptingCommands(cmState* state)
|
||||
state->AddBuiltinCommand("separate_arguments",
|
||||
new cmSeparateArgumentsCommand);
|
||||
state->AddBuiltinCommand("set", new cmSetCommand);
|
||||
state->AddBuiltinCommand("set_directory_properties",
|
||||
new cmSetDirectoryPropertiesCommand);
|
||||
state->AddBuiltinCommand("set_property", new cmSetPropertyCommand);
|
||||
state->AddBuiltinCommand("site_name", new cmSiteNameCommand);
|
||||
state->AddBuiltinCommand("string", new cmStringCommand);
|
||||
@@ -231,6 +229,8 @@ void GetProjectCommands(cmState* state)
|
||||
state->AddBuiltinCommand("install_targets", new cmInstallTargetsCommand);
|
||||
state->AddBuiltinCommand("link_directories", new cmLinkDirectoriesCommand);
|
||||
state->AddBuiltinCommand("project", new cmProjectCommand);
|
||||
state->AddBuiltinCommand("set_directory_properties",
|
||||
new cmSetDirectoryPropertiesCommand);
|
||||
state->AddBuiltinCommand("set_source_files_properties",
|
||||
new cmSetSourceFilesPropertiesCommand);
|
||||
state->AddBuiltinCommand("set_target_properties",
|
||||
|
||||
@@ -2811,7 +2811,12 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
|
||||
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
// Check whether labels are enabled for this target.
|
||||
if (const char* value = target->GetProperty("LABELS")) {
|
||||
const char* targetLabels = target->GetProperty("LABELS");
|
||||
const char* directoryLabels =
|
||||
target->Target->GetMakefile()->GetProperty("LABELS");
|
||||
const char* cmakeDirectoryLabels =
|
||||
target->Target->GetMakefile()->GetDefinition("CMAKE_DIRECTORY_LABELS");
|
||||
if (targetLabels || directoryLabels || cmakeDirectoryLabels) {
|
||||
Json::Value lj_root(Json::objectValue);
|
||||
Json::Value& lj_target = lj_root["target"] = Json::objectValue;
|
||||
lj_target["name"] = target->GetName();
|
||||
@@ -2821,19 +2826,53 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
|
||||
cmSystemTools::MakeDirectory(dir.c_str());
|
||||
cmGeneratedFileStream fout(file.c_str());
|
||||
|
||||
std::vector<std::string> labels;
|
||||
|
||||
// List the target-wide labels. All sources in the target get
|
||||
// these labels.
|
||||
std::vector<std::string> labels;
|
||||
cmSystemTools::ExpandListArgument(value, labels);
|
||||
if (!labels.empty()) {
|
||||
fout << "# Target labels\n";
|
||||
for (std::vector<std::string>::const_iterator li = labels.begin();
|
||||
li != labels.end(); ++li) {
|
||||
fout << " " << *li << "\n";
|
||||
lj_target_labels.append(*li);
|
||||
if (targetLabels) {
|
||||
cmSystemTools::ExpandListArgument(targetLabels, labels);
|
||||
if (!labels.empty()) {
|
||||
fout << "# Target labels\n";
|
||||
for (std::vector<std::string>::const_iterator li = labels.begin();
|
||||
li != labels.end(); ++li) {
|
||||
fout << " " << *li << "\n";
|
||||
lj_target_labels.append(*li);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// List directory labels
|
||||
std::vector<std::string> directoryLabelsList;
|
||||
std::vector<std::string> cmakeDirectoryLabelsList;
|
||||
|
||||
if (directoryLabels) {
|
||||
cmSystemTools::ExpandListArgument(directoryLabels, directoryLabelsList);
|
||||
}
|
||||
|
||||
if (cmakeDirectoryLabels) {
|
||||
cmSystemTools::ExpandListArgument(cmakeDirectoryLabels,
|
||||
cmakeDirectoryLabelsList);
|
||||
}
|
||||
|
||||
if (!directoryLabelsList.empty() || !cmakeDirectoryLabelsList.empty()) {
|
||||
fout << "# Directory labels\n";
|
||||
}
|
||||
|
||||
for (std::vector<std::string>::const_iterator li =
|
||||
directoryLabelsList.begin();
|
||||
li != directoryLabelsList.end(); ++li) {
|
||||
fout << " " << *li << "\n";
|
||||
lj_target_labels.append(*li);
|
||||
}
|
||||
|
||||
for (std::vector<std::string>::const_iterator li =
|
||||
cmakeDirectoryLabelsList.begin();
|
||||
li != cmakeDirectoryLabelsList.end(); ++li) {
|
||||
fout << " " << *li << "\n";
|
||||
lj_target_labels.append(*li);
|
||||
}
|
||||
|
||||
// List the source files with any per-source labels.
|
||||
fout << "# Source files and their labels\n";
|
||||
std::vector<cmSourceFile*> sources;
|
||||
|
||||
@@ -277,6 +277,25 @@ void cmLocalGenerator::GenerateTestFiles()
|
||||
outP = cmOutputConverter::EscapeForCMake(outP);
|
||||
fout << "subdirs(" << outP << ")" << std::endl;
|
||||
}
|
||||
|
||||
// Add directory labels property
|
||||
const char* directoryLabels =
|
||||
this->Makefile->GetDefinition("CMAKE_DIRECTORY_LABELS");
|
||||
const char* labels = this->Makefile->GetProperty("LABELS");
|
||||
|
||||
if (labels || directoryLabels) {
|
||||
fout << "set_directory_properties(PROPERTIES LABELS ";
|
||||
if (labels) {
|
||||
fout << cmOutputConverter::EscapeForCMake(labels);
|
||||
}
|
||||
if (labels && directoryLabels) {
|
||||
fout << ";";
|
||||
}
|
||||
if (directoryLabels) {
|
||||
fout << cmOutputConverter::EscapeForCMake(directoryLabels);
|
||||
}
|
||||
fout << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
|
||||
@@ -327,6 +346,7 @@ void cmLocalGenerator::GenerateInstallRules()
|
||||
{
|
||||
// Compute the install prefix.
|
||||
const char* prefix = this->Makefile->GetDefinition("CMAKE_INSTALL_PREFIX");
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
std::string prefix_win32;
|
||||
if (!prefix) {
|
||||
|
||||
@@ -1235,6 +1235,9 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
|
||||
}
|
||||
}
|
||||
|
||||
// labels
|
||||
this->SetProperty("LABELS", parent->GetProperty("LABELS"));
|
||||
|
||||
// link libraries
|
||||
this->SetProperty("LINK_LIBRARIES", parent->GetProperty("LINK_LIBRARIES"));
|
||||
|
||||
|
||||
@@ -83,6 +83,8 @@ static const char* cmDocumentationOptions[][2] = {
|
||||
{ "--max-width <width>", "Set the max width for a test name to output" },
|
||||
{ "--interactive-debug-mode [0|1]", "Set the interactive mode to 0 or 1." },
|
||||
{ "--no-label-summary", "Disable timing summary information for labels." },
|
||||
{ "--no-subproject-summary", "Disable timing summary information for "
|
||||
"subprojects." },
|
||||
{ "--build-and-test", "Configure, build and run a test." },
|
||||
{ "--build-target", "Specify a specific target to build." },
|
||||
{ "--build-nocmake", "Run the build without running cmake first." },
|
||||
|
||||
@@ -348,6 +348,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
|
||||
list(APPEND CompilerLauncher_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
|
||||
endif()
|
||||
add_RunCMake_test(CompilerLauncher)
|
||||
add_RunCMake_test(ctest_labels_for_subprojects)
|
||||
endif()
|
||||
|
||||
add_RunCMake_test_group(CPack "DEB;RPM;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ")
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.9)
|
||||
@CASE_CMAKELISTS_PREFIX_CODE@
|
||||
project(CTestLabelsForSubprojects@CASE_NAME@ NONE)
|
||||
include(CTest)
|
||||
@CASE_CMAKELISTS_SUFFIX_CODE@
|
||||
@@ -0,0 +1,2 @@
|
||||
set(CTEST_PROJECT_NAME "CTestLabelsForSubprojects@CASE_NAME@")
|
||||
@CTEST_EXTRA_CONFIG@
|
||||
@@ -0,0 +1,36 @@
|
||||
set(EXPERIMENTAL_FEATURE_REGEX "<Subproject name=\"MyExperimentalFeature\">.*<Label>MyExperimentalFeature</Label>.*</Subproject>")
|
||||
set(PRODUCTION_CODE_REGEX "<Subproject name=\"MyProductionCode\">.*<Label>MyProductionCode</Label>.*</Subproject>")
|
||||
set(SUBPROJECTS_REGEX "${EXPERIMENTAL_FEATURE_REGEX}.*${PRODUCTION_CODE_REGEX}")
|
||||
|
||||
file(GLOB configure_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Configure.xml")
|
||||
if(configure_xml_file)
|
||||
file(READ "${configure_xml_file}" configure_xml)
|
||||
if(NOT configure_xml MATCHES "${SUBPROJECTS_REGEX}.*<Configure>")
|
||||
set(RunCMake_TEST_FAILED "Configure.xml does not contain the expected list of subprojects")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Configure.xml not found")
|
||||
endif()
|
||||
|
||||
file(GLOB build_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Build.xml")
|
||||
if(build_xml_file)
|
||||
file(READ "${build_xml_file}" build_xml)
|
||||
set(BUILD_WARNING_REGEX "<Failure type=\"Warning\">.*<Labels>.*<Label>MyExperimentalFeature</Label>.*</Labels>")
|
||||
if(NOT build_xml MATCHES "${SUBPROJECTS_REGEX}.*<Build>.*${BUILD_ERROR_REGEX}.*</Build>")
|
||||
set(RunCMake_TEST_FAILED "Build.xml does not contain the expected list of subprojects and labels")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Build.xml not found")
|
||||
endif()
|
||||
|
||||
file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
|
||||
if(test_xml_file)
|
||||
file(READ "${test_xml_file}" test_xml)
|
||||
set(TEST_FAILED_REGEX "<Test Status=\"failed\">.*<Labels>.*<Label>MyExperimentalFeature</Label>.*<Label>NotASubproject</Label>.*</Labels>")
|
||||
set(TEST_PASSED_REGEX "<Test Status=\"passed\">.*<Labels>.*<Label>MyProductionCode</Label>.*</Labels>")
|
||||
if(NOT test_xml MATCHES "${SUBPROJECTS_REGEX}.*<Testing>.*${TEST_FAILED_REGEX}.*${TEST_PASSED_REGEX}.*${TEST_NOTRUN_REGEX}.*</Testing>")
|
||||
set(RunCMake_TEST_FAILED "Test.xml does not contain the expected list of subprojects and labels")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "${CTEST_BINARY_DIRECTORY}/Testing/*/Test.xml not found")
|
||||
endif()
|
||||
@@ -0,0 +1,7 @@
|
||||
17% tests passed, 5 tests failed out of 6
|
||||
+
|
||||
Subproject Time Summary:
|
||||
MyExperimentalFeature += +[0-9.]+ sec \(5 tests\)
|
||||
MyProductionCode += +[0-9.]+ sec \(1 test\)
|
||||
+
|
||||
Total Test time \(real\) = +[0-9.]+ sec
|
||||
@@ -0,0 +1,36 @@
|
||||
set(EXPERIMENTAL_FEATURE_REGEX "<Subproject name=\"MyExperimentalFeature\">.*<Label>MyExperimentalFeature</Label>.*</Subproject>")
|
||||
set(PRODUCTION_CODE_REGEX "<Subproject name=\"MyProductionCode\">.*<Label>MyProductionCode</Label>.*</Subproject>")
|
||||
set(SUBPROJECTS_REGEX "${EXPERIMENTAL_FEATURE_REGEX}.*${PRODUCTION_CODE_REGEX}")
|
||||
|
||||
file(GLOB configure_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Configure.xml")
|
||||
if(configure_xml_file)
|
||||
file(READ "${configure_xml_file}" configure_xml)
|
||||
if(NOT configure_xml MATCHES "${SUBPROJECTS_REGEX}.*<Configure>")
|
||||
set(RunCMake_TEST_FAILED "Configure.xml does not contain the expected list of subprojects")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Configure.xml not found")
|
||||
endif()
|
||||
|
||||
file(GLOB build_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Build.xml")
|
||||
if(build_xml_file)
|
||||
file(READ "${build_xml_file}" build_xml)
|
||||
set(BUILD_WARNING_REGEX "<Failure type=\"Warning\">.*<Labels>.*<Label>MyExperimentalFeature</Label>.*</Labels>")
|
||||
if(NOT build_xml MATCHES "${SUBPROJECTS_REGEX}.*<Build>.*${BUILD_ERROR_REGEX}.*</Build>")
|
||||
set(RunCMake_TEST_FAILED "Build.xml does not contain the expected list of subprojects and labels")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Build.xml not found")
|
||||
endif()
|
||||
|
||||
file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
|
||||
if(test_xml_file)
|
||||
file(READ "${test_xml_file}" test_xml)
|
||||
set(TEST_FAILED_REGEX "<Test Status=\"failed\">.*<Labels>.*<Label>MyExperimentalFeature</Label>.*<Label>NotASubproject</Label>.*</Labels>")
|
||||
set(TEST_PASSED_REGEX "<Test Status=\"passed\">.*<Labels>.*<Label>MyProductionCode</Label>.*</Labels>")
|
||||
if(NOT test_xml MATCHES "${SUBPROJECTS_REGEX}.*<Testing>.*${TEST_FAILED_REGEX}.*${TEST_PASSED_REGEX}.*${TEST_NOTRUN_REGEX}.*</Testing>")
|
||||
set(RunCMake_TEST_FAILED "Test.xml does not contain the expected list of subprojects and labels")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "${CTEST_BINARY_DIRECTORY}/Testing/*/Test.xml not found")
|
||||
endif()
|
||||
@@ -0,0 +1,7 @@
|
||||
17% tests passed, 5 tests failed out of 6
|
||||
+
|
||||
Subproject Time Summary:
|
||||
MyExperimentalFeature += +[0-9.]+ sec \(5 tests\)
|
||||
MyProductionCode += +[0-9.]+ sec \(1 test\)
|
||||
+
|
||||
Total Test time \(real\) = +[0-9.]+ sec
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
set(THIRD_PARTY_REGEX "<Subproject name=\"MyThirdPartyDependency\">.*<Label>MyThirdPartyDependency</Label>.*</Subproject>")
|
||||
set(SUBPROJECTS_REGEX "${THIRD_PARTY_REGEX}")
|
||||
|
||||
file(GLOB configure_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Configure.xml")
|
||||
if(configure_xml_file)
|
||||
file(READ "${configure_xml_file}" configure_xml)
|
||||
if(NOT configure_xml MATCHES "${SUBPROJECTS_REGEX}.*<Configure>")
|
||||
set(RunCMake_TEST_FAILED "Configure.xml does not contain the expected list of subprojects")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Configure.xml not found")
|
||||
endif()
|
||||
|
||||
file(GLOB build_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Build.xml")
|
||||
if(build_xml_file)
|
||||
file(READ "${build_xml_file}" build_xml)
|
||||
set(BUILD_ERROR_REGEX "<Failure type=\"Error\">.*<Labels>.*<Label>MyThirdPartyDependency</Label>.*<Label>NotASubproject</Label>.*</Labels>")
|
||||
if(NOT build_xml MATCHES "${SUBPROJECTS_REGEX}.*<Build>.*${BUILD_ERROR_REGEX}.*</Build>")
|
||||
set(RunCMake_TEST_FAILED "Build.xml does not contain the expected list of subprojects and labels")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "Build.xml not found")
|
||||
endif()
|
||||
|
||||
file(GLOB test_xml_file "${RunCMake_TEST_BINARY_DIR}/Testing/*/Test.xml")
|
||||
if(test_xml_file)
|
||||
file(READ "${test_xml_file}" test_xml)
|
||||
set(TEST_NOTRUN_REGEX "<Test Status=\"notrun\">.*<Labels>.*<Label>MyThirdPartyDependency</Label>.*<Label>NotASubproject</Label>.*</Labels>")
|
||||
if(NOT test_xml MATCHES "${SUBPROJECTS_REGEX}.*<Testing>.*${TEST_FAILED_REGEX}.*${TEST_PASSED_REGEX}.*${TEST_NOTRUN_REGEX}.*</Testing>")
|
||||
set(RunCMake_TEST_FAILED "Test.xml does not contain the expected list of subprojects and labels")
|
||||
endif()
|
||||
else()
|
||||
set(RunCMake_TEST_FAILED "${CTEST_BINARY_DIRECTORY}/Testing/*/Test.xml not found")
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
(-1|255)
|
||||
@@ -0,0 +1 @@
|
||||
Unable to find executable:.*MyThirdPartyDependency/src/thirdparty
|
||||
@@ -0,0 +1,6 @@
|
||||
0% tests passed, 1 tests failed out of 1
|
||||
+
|
||||
Subproject Time Summary:
|
||||
MyThirdPartyDependency += +[0-9.]+ sec \(1 test\)
|
||||
+
|
||||
Total Test time \(real\) = +[0-9.]+ sec
|
||||
@@ -0,0 +1 @@
|
||||
8
|
||||
@@ -0,0 +1 @@
|
||||
Errors while running CTest
|
||||
@@ -0,0 +1,6 @@
|
||||
50% tests passed, 1 tests failed out of 2
|
||||
+
|
||||
Subproject Time Summary:
|
||||
MySubproject += +[0-9.]+ sec \(2 tests\)
|
||||
+
|
||||
Total Test time \(real\) = +[0-9.]+ sec
|
||||
@@ -0,0 +1 @@
|
||||
8
|
||||
@@ -0,0 +1 @@
|
||||
Errors while running CTest
|
||||
@@ -0,0 +1,6 @@
|
||||
67% tests passed, 1 tests failed out of 3
|
||||
+
|
||||
Subproject Time Summary:
|
||||
MySubproject += +[0-9.]+ sec \(2 tests\)
|
||||
+
|
||||
Total Test time \(real\) = +[0-9.]+ sec
|
||||
+1
@@ -0,0 +1 @@
|
||||
8
|
||||
+1
@@ -0,0 +1 @@
|
||||
Errors while running CTest
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
67% tests passed, 1 tests failed out of 3
|
||||
+
|
||||
Label Time Summary:
|
||||
MySubproject += +[0-9.]+ sec \(2 tests\)
|
||||
NotASubproject += +[0-9.]+ sec \(1 test\)
|
||||
+
|
||||
Total Test time \(real\) = +[0-9.]+ sec
|
||||
@@ -0,0 +1 @@
|
||||
8
|
||||
@@ -0,0 +1 @@
|
||||
Errors while running CTest
|
||||
@@ -0,0 +1,6 @@
|
||||
50% tests passed, 1 tests failed out of 2
|
||||
+
|
||||
Subproject Time Summary:
|
||||
MySubproject += +[0-9.]+ sec \(2 tests\)
|
||||
+
|
||||
Total Test time \(real\) = +[0-9.]+ sec
|
||||
@@ -0,0 +1,33 @@
|
||||
project(MyExperimentalFeature)
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
include(CTest)
|
||||
|
||||
set(CMAKE_DIRECTORY_LABELS "MyExperimentalFeature;NotASubproject")
|
||||
|
||||
add_executable(testapp experimental.c)
|
||||
|
||||
add_test(experimentalFail1 testapp 5)
|
||||
set_tests_properties (experimentalFail1
|
||||
PROPERTIES PASS_REGULAR_EXPRESSION "Test!"
|
||||
)
|
||||
|
||||
add_test(experimentalFail2 testapp -5)
|
||||
set_tests_properties (experimentalFail2
|
||||
PROPERTIES PASS_REGULAR_EXPRESSION "Test!"
|
||||
)
|
||||
|
||||
add_test(experimentalFail3 testapp -5)
|
||||
set_tests_properties (experimentalFail3
|
||||
PROPERTIES PASS_REGULAR_EXPRESSION "Test!"
|
||||
)
|
||||
|
||||
add_test(experimentalFail4 testapp -5)
|
||||
set_tests_properties (experimentalFail4
|
||||
PROPERTIES PASS_REGULAR_EXPRESSION "Test!"
|
||||
)
|
||||
|
||||
add_test(experimentalFail5 testapp -5)
|
||||
set_tests_properties (experimentalFail5
|
||||
PROPERTIES PASS_REGULAR_EXPRESSION "Test!"
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = 0;
|
||||
if (i > 0) {
|
||||
printf("This doesn't happen.\n");
|
||||
printf("Neither does this.\n");
|
||||
}
|
||||
i = i + 1;
|
||||
if (i > 0) {
|
||||
printf("This does happen.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
project(MyProductionCode)
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
include(CTest)
|
||||
|
||||
add_executable(production production.c)
|
||||
add_test(NAME production COMMAND production)
|
||||
|
||||
set_property(TARGET production PROPERTY LABELS MyProductionCode)
|
||||
set_property(TEST production PROPERTY LABELS MyProductionCode)
|
||||
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY LABELS "NotASubproject")
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int j = 0;
|
||||
if (j > 0) {
|
||||
printf("This doesn't happen.\n");
|
||||
printf("Neither does this.\n");
|
||||
}
|
||||
j = j + 1;
|
||||
if (j > 0) {
|
||||
printf("This does happen.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
project(MyThirdPartyDependency)
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
include(CTest)
|
||||
|
||||
set_directory_properties(PROPERTIES LABELS "NotASubproject;MyThirdPartyDependency")
|
||||
add_subdirectory(src)
|
||||
@@ -0,0 +1,10 @@
|
||||
project(MyThirdPartyDependency)
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
include(CTest)
|
||||
|
||||
add_executable(thirdparty thirdparty.c)
|
||||
add_test(NAME thirdparty COMMAND thirdparty)
|
||||
|
||||
set_property(TARGET thirdparty PROPERTY LABELS NotASubproject)
|
||||
set_property(TEST thirdparty PROPERTY LABELS NotASubproject)
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf(This function has an error!\n");
|
||||
n = 5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int notcalled()
|
||||
{
|
||||
printf(This function doesn't get called.\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
include(RunCTest)
|
||||
|
||||
|
||||
# 1. Specify subprojects in the CTest script
|
||||
function(run_CTestScriptVariable)
|
||||
set(CTEST_EXTRA_CONFIG "set(CTEST_USE_LAUNCHERS 1)")
|
||||
set(CASE_TEST_PREFIX_CODE [[
|
||||
file(COPY "${CTEST_RUNCMAKE_SOURCE_DIRECTORY}/MyProductionCode"
|
||||
DESTINATION ${CTEST_SOURCE_DIRECTORY})
|
||||
file(COPY "${CTEST_RUNCMAKE_SOURCE_DIRECTORY}/MyExperimentalFeature"
|
||||
DESTINATION ${CTEST_SOURCE_DIRECTORY})
|
||||
|
||||
set(CTEST_LABELS_FOR_SUBPROJECTS "MyProductionCode;MyExperimentalFeature")
|
||||
]])
|
||||
set(CASE_CMAKELISTS_SUFFIX_CODE [[
|
||||
add_subdirectory(MyExperimentalFeature)
|
||||
add_subdirectory(MyProductionCode)
|
||||
]])
|
||||
|
||||
run_ctest(CTestScriptVariable)
|
||||
|
||||
unset(CTEST_EXTRA_CONFIG)
|
||||
unset(CASE_TEST_PREFIX_CODE)
|
||||
unset(CASE_CMAKELISTS_SUFFIX_CODE)
|
||||
endfunction()
|
||||
run_CTestScriptVariable()
|
||||
|
||||
# 2. Specify subprojects via a CTest script variable on the command line e.g.
|
||||
# ctest -S test.cmake -DCTEST_LABELS_FOR_SUBPROJECTS:STRING="MySubproject"
|
||||
# Note: This test includes a failing build
|
||||
function(run_CTestScriptVariableCommandLine)
|
||||
set(CTEST_EXTRA_CONFIG "set(CTEST_USE_LAUNCHERS 1)")
|
||||
set(CASE_TEST_PREFIX_CODE [[
|
||||
file(COPY "${CTEST_RUNCMAKE_SOURCE_DIRECTORY}/MyThirdPartyDependency"
|
||||
DESTINATION ${CTEST_SOURCE_DIRECTORY})
|
||||
]])
|
||||
set(CASE_CMAKELISTS_SUFFIX_CODE [[
|
||||
add_subdirectory(MyThirdPartyDependency)
|
||||
]])
|
||||
|
||||
run_ctest(CTestScriptVariableCommandLine "-DCTEST_LABELS_FOR_SUBPROJECTS:STRING=MyThirdPartyDependency")
|
||||
|
||||
unset(CTEST_EXTRA_CONFIG)
|
||||
unset(CASE_TEST_PREFIX_CODE)
|
||||
unset(CASE_CMAKELISTS_SUFFIX_CODE)
|
||||
endfunction()
|
||||
run_CTestScriptVariableCommandLine()
|
||||
|
||||
# 3. Set subprojects via a CTest module variable on the command line
|
||||
# (will populate DartConfiguration.tcl)
|
||||
function(run_ModuleVariableCommandLine)
|
||||
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/ModuleVariableCommandLine")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ModuleVariableCommandLine-build")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
|
||||
set(CASE_CMAKELISTS_SUFFIX_CODE [[
|
||||
set(someFile "${CMAKE_CURRENT_SOURCE_DIR}/test.cmake")
|
||||
add_test(NAME SuccessfulTest COMMAND "${CMAKE_COMMAND}" --version)
|
||||
set_property(TEST SuccessfulTest PROPERTY LABELS MySubproject)
|
||||
add_test(NAME FailingTest
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files "${someFile}" "${someFile}xxx")
|
||||
set_property(TEST FailingTest PROPERTY LABELS MySubproject)
|
||||
]])
|
||||
configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in
|
||||
${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt @ONLY)
|
||||
|
||||
set(RunCMake_TEST_OPTIONS "-DCTEST_LABELS_FOR_SUBPROJECTS:STRING=MySubproject")
|
||||
run_cmake(ModuleVariableCommandLine-cmake)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
run_cmake_command(ModuleVariableCommandLine ${CMAKE_CTEST_COMMAND} -C Debug -V)
|
||||
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_NO_CLEAN)
|
||||
unset(CASE_CMAKELISTS_SUFFIX_CODE)
|
||||
endfunction()
|
||||
run_ModuleVariableCommandLine()
|
||||
|
||||
# 4. Set subprojects via a CTest module variable in CMakeLists.txt
|
||||
# (will populate DartConfiguration.tcl)
|
||||
function(run_ModuleVariableCMakeLists)
|
||||
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/ModuleVariableCMakeLists")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ModuleVariableCMakeLists-build")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
|
||||
set(CASE_CMAKELISTS_PREFIX_CODE [[
|
||||
set(CTEST_LABELS_FOR_SUBPROJECTS MySubproject)
|
||||
]])
|
||||
|
||||
set(CASE_CMAKELISTS_SUFFIX_CODE [[
|
||||
set(someFile "${CMAKE_CURRENT_SOURCE_DIR}/test.cmake")
|
||||
add_test(NAME SuccessfulTest COMMAND "${CMAKE_COMMAND}" --version)
|
||||
set_property(TEST SuccessfulTest PROPERTY LABELS MySubproject)
|
||||
add_test(NAME FailingTest
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files "${someFile}" "${someFile}xxx")
|
||||
set_property(TEST FailingTest PROPERTY LABELS MySubproject)
|
||||
]])
|
||||
configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in
|
||||
${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt @ONLY)
|
||||
|
||||
run_cmake(ModuleVariableCMakeLists-cmake)
|
||||
run_cmake_command(ModuleVariableCMakeLists ${CMAKE_CTEST_COMMAND} -C Debug -V)
|
||||
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_NO_CLEAN)
|
||||
unset(CASE_CMAKELISTS_SUFFIX_CODE)
|
||||
unset(CASE_CMAKELISTS_SUFFIX_CODE)
|
||||
endfunction()
|
||||
run_ModuleVariableCMakeLists()
|
||||
|
||||
# The remaining tests set subprojects in CTestConfig.cmake. Settings in this
|
||||
# config file are shared by both the CTest module and the ctest command line
|
||||
# `Dashboard Client` mode (e.g. ctest -S).
|
||||
|
||||
function(run_ModuleVariableCTestConfig CASE_NAME)
|
||||
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${CASE_NAME}")
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${CASE_NAME}-build")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
|
||||
set(CTEST_EXTRA_CONFIG "set(CTEST_LABELS_FOR_SUBPROJECTS \"MySubproject\")")
|
||||
configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in
|
||||
${RunCMake_TEST_SOURCE_DIR}/CTestConfig.cmake @ONLY)
|
||||
|
||||
set(CASE_CMAKELISTS_SUFFIX_CODE [[
|
||||
set(someFile "${CMAKE_CURRENT_SOURCE_DIR}/test.cmake")
|
||||
add_test(NAME SuccessfulTest COMMAND "${CMAKE_COMMAND}" --version)
|
||||
set_property(TEST SuccessfulTest PROPERTY LABELS MySubproject)
|
||||
add_test(NAME FailingTest
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files "${someFile}" "${someFile}xxx")
|
||||
set_property(TEST FailingTest PROPERTY LABELS MySubproject)
|
||||
add_test(NAME AnotherSuccessfulTest COMMAND "${CMAKE_COMMAND}" --version)
|
||||
set_property(TEST AnotherSuccessfulTest PROPERTY LABELS NotASubproject)
|
||||
]])
|
||||
configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in
|
||||
${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt @ONLY)
|
||||
|
||||
run_cmake(${CASE_NAME}-cmake)
|
||||
run_cmake_command(${CASE_NAME} ${CMAKE_CTEST_COMMAND} -C Debug -V ${ARGN})
|
||||
|
||||
unset(RunCMake_TEST_SOURCE_DIR)
|
||||
unset(RunCMake_TEST_BINARY_DIR)
|
||||
unset(RunCMake_TEST_NO_CLEAN)
|
||||
unset(CTEST_EXTRA_CONFIG)
|
||||
unset(CASE_CMAKELISTS_SUFFIX_CODE)
|
||||
endfunction()
|
||||
|
||||
# 5. Check that the Subproject timing Summary is printed
|
||||
run_ModuleVariableCTestConfig(ModuleVariableCTestConfig)
|
||||
|
||||
# 6. Use --no-subproject-summary to disable the Subproject timing summary.
|
||||
run_ModuleVariableCTestConfig(ModuleVariableCTestConfigNoSummary --no-subproject-summary)
|
||||
|
||||
# 7. Verify that subprojects are sent to CDash when running a CTest script
|
||||
function(run_CTestConfigCTestScript)
|
||||
set(CTEST_EXTRA_CONFIG [[
|
||||
set(CTEST_USE_LAUNCHERS 1)
|
||||
set(CTEST_LABELS_FOR_SUBPROJECTS "MyProductionCode;MyExperimentalFeature")
|
||||
]])
|
||||
set(CASE_TEST_PREFIX_CODE [[
|
||||
file(COPY "${CTEST_RUNCMAKE_SOURCE_DIRECTORY}/MyProductionCode"
|
||||
DESTINATION ${CTEST_SOURCE_DIRECTORY})
|
||||
file(COPY "${CTEST_RUNCMAKE_SOURCE_DIRECTORY}/MyExperimentalFeature"
|
||||
DESTINATION ${CTEST_SOURCE_DIRECTORY})
|
||||
]])
|
||||
set(CASE_CMAKELISTS_SUFFIX_CODE [[
|
||||
add_subdirectory(MyExperimentalFeature)
|
||||
add_subdirectory(MyProductionCode)
|
||||
]])
|
||||
run_ctest(CTestConfigCTestScript)
|
||||
|
||||
unset(CTEST_EXTRA_CONFIG)
|
||||
unset(CASE_TEST_PREFIX_CODE)
|
||||
unset(CASE_CMAKELISTS_SUFFIX_CODE)
|
||||
endfunction()
|
||||
run_CTestConfigCTestScript()
|
||||
@@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
|
||||
# Settings:
|
||||
|
||||
set(CTEST_SITE "test-site")
|
||||
set(CTEST_BUILD_NAME "test-build-name")
|
||||
set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
|
||||
set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
|
||||
set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
|
||||
set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
|
||||
set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
|
||||
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
|
||||
set(CTEST_RUNCMAKE_SOURCE_DIRECTORY "@RunCMake_SOURCE_DIR@")
|
||||
|
||||
@CASE_TEST_PREFIX_CODE@
|
||||
|
||||
set(ctest_test_args "@CASE_CTEST_TEST_ARGS@")
|
||||
ctest_start(Experimental)
|
||||
ctest_configure()
|
||||
ctest_build()
|
||||
ctest_test(${ctest_test_args})
|
||||
Reference in New Issue
Block a user