summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJustin Goshi <jgoshi@microsoft.com>2018-10-18 11:33:01 -0700
committerBrad King <brad.king@kitware.com>2019-01-08 11:22:11 -0500
commit7b81d8c21e0a0d8756f0afdc0530c2d06ee3bcd4 (patch)
tree0848b0d979656afe9b796ecbd6b5241df8a3bb8a /Source
parent00530d74d5d07a320c998d6caccc00cf4e59b06d (diff)
downloadcmake-7b81d8c21e0a0d8756f0afdc0530c2d06ee3bcd4.tar.gz
TestGenerator: Record support file and line where test was added
Add internal test properties that ctest can use to report where the test was added in CMake code.
Diffstat (limited to 'Source')
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx26
-rw-r--r--Source/CTest/cmCTestTestHandler.h3
-rw-r--r--Source/cmTestGenerator.cxx59
-rw-r--r--Source/cmTestGenerator.h3
4 files changed, 74 insertions, 17 deletions
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 2e1bb0aab7..9fd22991be 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -2147,6 +2147,32 @@ bool cmCTestTestHandler::SetTestsProperties(
for (std::string const& t : tests) {
for (cmCTestTestProperties& rt : this->TestList) {
if (t == rt.Name) {
+ if (key == "_BACKTRACE_TRIPLES") {
+ std::vector<std::string> triples;
+ // allow empty args in the triples
+ cmSystemTools::ExpandListArgument(val, triples, true);
+
+ // Ensure we have complete triples otherwise the data is corrupt.
+ if (triples.size() % 3 == 0) {
+ cmState state;
+ rt.Backtrace = cmListFileBacktrace(state.CreateBaseSnapshot());
+
+ // the first entry represents the top of the trace so we need to
+ // reconstruct the backtrace in reverse
+ for (size_t i = triples.size(); i >= 3; i -= 3) {
+ cmListFileContext fc;
+ fc.FilePath = triples[i - 3];
+ long line = 0;
+ if (!cmSystemTools::StringToLong(triples[i - 2].c_str(),
+ &line)) {
+ line = 0;
+ }
+ fc.Line = line;
+ fc.Name = triples[i - 1];
+ rt.Backtrace = rt.Backtrace.Push(fc);
+ }
+ }
+ }
if (key == "WILL_FAIL") {
rt.WillFail = cmSystemTools::IsOn(val);
}
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index bcacf23af4..0b557dbcbd 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -7,6 +7,7 @@
#include "cmCTestGenericHandler.h"
#include "cmDuration.h"
+#include "cmListFileCache.h"
#include "cmsys/RegularExpression.hxx"
#include <chrono>
@@ -141,6 +142,8 @@ public:
std::set<std::string> FixturesCleanup;
std::set<std::string> FixturesRequired;
std::set<std::string> RequireSuccessDepends;
+ // Private test generator properties used to track backtraces
+ cmListFileBacktrace Backtrace;
};
struct cmCTestTestResult
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 796d2df64d..e4ced6e3a8 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -7,14 +7,16 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmOutputConverter.h"
#include "cmProperty.h"
-#include "cmPropertyMap.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTest.h"
+class cmPropertyMap;
+
cmTestGenerator::cmTestGenerator(
cmTest* test, std::vector<std::string> const& configurations)
: cmScriptGenerator("CTEST_CONFIGURATION_TYPE", configurations)
@@ -121,16 +123,15 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Output properties for the test.
cmPropertyMap& pm = this->Test->GetProperties();
- if (!pm.empty()) {
- os << indent << "set_tests_properties(" << this->Test->GetName()
- << " PROPERTIES ";
- for (auto const& i : pm) {
- os << " " << i.first << " "
- << cmOutputConverter::EscapeForCMake(
- ge.Parse(i.second.GetValue())->Evaluate(this->LG, config));
- }
- os << ")" << std::endl;
+ os << indent << "set_tests_properties(" << this->Test->GetName()
+ << " PROPERTIES ";
+ for (auto const& i : pm) {
+ os << " " << i.first << " "
+ << cmOutputConverter::EscapeForCMake(
+ ge.Parse(i.second.GetValue())->Evaluate(this->LG, config));
}
+ this->GenerateInternalProperties(os);
+ os << ")" << std::endl;
}
void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
@@ -179,13 +180,37 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
// Output properties for the test.
cmPropertyMap& pm = this->Test->GetProperties();
- if (!pm.empty()) {
- fout << indent << "set_tests_properties(" << this->Test->GetName()
- << " PROPERTIES ";
- for (auto const& i : pm) {
- fout << " " << i.first << " "
- << cmOutputConverter::EscapeForCMake(i.second.GetValue());
+ fout << indent << "set_tests_properties(" << this->Test->GetName()
+ << " PROPERTIES ";
+ for (auto const& i : pm) {
+ fout << " " << i.first << " "
+ << cmOutputConverter::EscapeForCMake(i.second.GetValue());
+ }
+ this->GenerateInternalProperties(fout);
+ fout << ")" << std::endl;
+}
+
+void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
+{
+ cmListFileBacktrace bt = this->Test->GetBacktrace();
+ if (bt.Empty()) {
+ return;
+ }
+
+ os << " "
+ << "_BACKTRACE_TRIPLES"
+ << " \"";
+
+ bool prependTripleSeparator = false;
+ while (!bt.Empty()) {
+ const auto& entry = bt.Top();
+ if (prependTripleSeparator) {
+ os << ";";
}
- fout << ")" << std::endl;
+ os << entry.FilePath << ";" << entry.Line << ";" << entry.Name;
+ bt = bt.Pop();
+ prependTripleSeparator = true;
}
+
+ os << "\"";
}
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
index 73d05a3bb4..f26d2ffb8a 100644
--- a/Source/cmTestGenerator.h
+++ b/Source/cmTestGenerator.h
@@ -35,6 +35,9 @@ public:
cmTest* GetTest() const;
+private:
+ void GenerateInternalProperties(std::ostream& os);
+
protected:
void GenerateScriptConfigs(std::ostream& os, Indent indent) override;
void GenerateScriptActions(std::ostream& os, Indent indent) override;