mirror of
https://github.com/reactos/CMake.git
synced 2025-02-13 16:10:57 +00:00
![Andy Cedilnik](/assets/img/avatar_default.png)
1. Support for showing line numbers when debugging ctest --show-line-numbers 2. Modify the ctest initialization code, so that it can be delayed 3. Handlers now have corresponding command if they were invoked from the command (so far only update actually use that) 4. Start command is simplified and the functionality is moved to CTest 5. Update can perform initial checkout if CTEST_CHECKOUT_COMMAND is set 6. Add test that checks out kwsys and perform tests on the fresh checkout
374 lines
9.8 KiB
C++
374 lines
9.8 KiB
C++
/*=========================================================================
|
|
|
|
Program: CMake - Cross-Platform Makefile Generator
|
|
Module: $RCSfile$
|
|
Language: C++
|
|
Date: $Date$
|
|
Version: $Revision$
|
|
|
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notices for more information.
|
|
|
|
=========================================================================*/
|
|
|
|
#ifndef cmCTest_h
|
|
#define cmCTest_h
|
|
|
|
#include "cmStandardIncludes.h"
|
|
#include "cmListFileCache.h"
|
|
#include <time.h>
|
|
|
|
class cmake;
|
|
class cmMakefile;
|
|
class cmCTestGenericHandler;
|
|
class cmGeneratedFileStream;
|
|
class cmCTestCommand;
|
|
|
|
#define cmCTestLog(ctSelf, logType, msg) \
|
|
do { \
|
|
cmOStringStream cmCTestLog_msg; \
|
|
cmCTestLog_msg << msg; \
|
|
(ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__, cmCTestLog_msg.str().c_str());\
|
|
} while ( 0 )
|
|
|
|
#ifdef cerr
|
|
# undef cerr
|
|
#endif
|
|
#define cerr no_cerr_use_cmCTestLog
|
|
|
|
#ifdef cout
|
|
# undef cout
|
|
#endif
|
|
#define cout no_cout_use_cmCTestLog
|
|
|
|
class cmCTest
|
|
{
|
|
public:
|
|
typedef std::vector<cmStdString> tm_VectorOfStrings;
|
|
|
|
///! Process Command line arguments
|
|
int Run(std::vector<std::string>const&, std::string* output = 0);
|
|
|
|
/**
|
|
* Initialize and finalize testing
|
|
*/
|
|
int Initialize(const char* binary_dir, bool new_tag = false, bool verbose_tag = true);
|
|
bool InitializeFromCommand(cmCTestCommand* command, bool first = false);
|
|
void Finalize();
|
|
|
|
/**
|
|
* Process the tests. This is the main routine. The execution of the
|
|
* tests should look like this:
|
|
*
|
|
* ctest foo;
|
|
* foo.Initialize();
|
|
* // Set some things on foo
|
|
* foo.ProcessTests();
|
|
* foo.Finalize();
|
|
*/
|
|
int ProcessTests();
|
|
|
|
/*
|
|
* A utility function that returns the nightly time
|
|
*/
|
|
struct tm* GetNightlyTime(std::string str,
|
|
bool tomorrowtag);
|
|
|
|
/*
|
|
* Is the tomorrow tag set?
|
|
*/
|
|
bool GetTomorrowTag() { return m_TomorrowTag; };
|
|
|
|
/**
|
|
* Try to run tests of the project
|
|
*/
|
|
int TestDirectory(bool memcheck);
|
|
|
|
///! what is the configuraiton type, e.g. Debug, Release etc.
|
|
std::string GetConfigType();
|
|
double GetTimeOut() { return m_TimeOut; }
|
|
|
|
/**
|
|
* Check if CTest file exists
|
|
*/
|
|
bool CTestFileExists(const std::string& filename);
|
|
bool AddIfExists(tm_VectorOfStrings& files, const char* file);
|
|
|
|
/**
|
|
* Set the cmake test
|
|
*/
|
|
bool SetTest(const char*, bool report = true);
|
|
|
|
/**
|
|
* Set the cmake test mode (experimental, nightly, continuous).
|
|
*/
|
|
void SetTestModel(int mode);
|
|
int GetTestModel() { return m_TestModel; };
|
|
|
|
std::string GetTestModelString();
|
|
static int GetTestModelFromString(const char* str);
|
|
static std::string CleanString(const std::string& str);
|
|
std::string GetCTestConfiguration(const char *name);
|
|
void SetCTestConfiguration(const char *name, const char* value);
|
|
|
|
/**
|
|
* constructor and destructor
|
|
*/
|
|
cmCTest();
|
|
~cmCTest();
|
|
|
|
//! Set the notes files to be created.
|
|
void SetNotesFiles(const char* notes);
|
|
|
|
static void PopulateCustomVector(cmMakefile* mf, const char* definition,
|
|
tm_VectorOfStrings& vec);
|
|
static void PopulateCustomInteger(cmMakefile* mf, const char* def, int& val);
|
|
|
|
///! Get the current time as string
|
|
std::string CurrentTime();
|
|
|
|
///! Open file in the output directory and set the stream
|
|
bool OpenOutputFile(const std::string& path,
|
|
const std::string& name,
|
|
cmGeneratedFileStream& stream,
|
|
bool compress = false);
|
|
|
|
///! Convert string to something that is XML safe
|
|
static std::string MakeXMLSafe(const std::string&);
|
|
|
|
///! Should we only show what we would do?
|
|
bool GetShowOnly();
|
|
|
|
/**
|
|
* Run a single executable command and put the stdout and stderr
|
|
* in output.
|
|
*
|
|
* If verbose is false, no user-viewable output from the program
|
|
* being run will be generated.
|
|
*
|
|
* If timeout is specified, the command will be terminated after
|
|
* timeout expires. Timeout is specified in seconds.
|
|
*
|
|
* Argument retVal should be a pointer to the location where the
|
|
* exit code will be stored. If the retVal is not specified and
|
|
* the program exits with a code other than 0, then the this
|
|
* function will return false.
|
|
*
|
|
* If the command has spaces in the path the caller MUST call
|
|
* cmSystemTools::ConvertToRunCommandPath on the command before passing
|
|
* it into this function or it will not work. The command must be correctly
|
|
* escaped for this to with spaces.
|
|
*/
|
|
bool RunCommand(const char* command,
|
|
std::string* stdOut, std::string* stdErr,
|
|
int* retVal = 0, const char* dir = 0, double timeout = 0.0);
|
|
|
|
//! Start CTest XML output file
|
|
void StartXML(std::ostream& ostr);
|
|
|
|
//! End CTest XML output file
|
|
void EndXML(std::ostream& ostr);
|
|
|
|
//! Run command specialized for make and configure. Returns process status
|
|
// and retVal is return value or exception.
|
|
int RunMakeCommand(const char* command, std::string* output,
|
|
int* retVal, const char* dir, int timeout,
|
|
std::ofstream& ofs);
|
|
|
|
/*
|
|
* return the current tag
|
|
*/
|
|
std::string GetCurrentTag();
|
|
|
|
//! Get the path to the build tree
|
|
std::string GetBinaryDir();
|
|
|
|
//! Get the short path to the file. This means if the file is in binary or
|
|
//source directory, it will become /.../relative/path/to/file
|
|
std::string GetShortPathToFile(const char* fname);
|
|
|
|
//! Get the path to CTest
|
|
const char* GetCTestExecutable() { return m_CTestSelf.c_str(); }
|
|
const char* GetCMakeExecutable() { return m_CMakeSelf.c_str(); }
|
|
|
|
enum {
|
|
EXPERIMENTAL,
|
|
NIGHTLY,
|
|
CONTINUOUS
|
|
};
|
|
|
|
// provide some more detailed info on the return code for ctest
|
|
enum {
|
|
UPDATE_ERRORS = 0x01,
|
|
CONFIGURE_ERRORS = 0x02,
|
|
BUILD_ERRORS = 0x04,
|
|
TEST_ERRORS = 0x08,
|
|
MEMORY_ERRORS = 0x10,
|
|
COVERAGE_ERRORS = 0x20,
|
|
SUBMIT_ERRORS = 0x40
|
|
};
|
|
|
|
///! Are we producing XML
|
|
bool GetProduceXML();
|
|
void SetProduceXML(bool v);
|
|
|
|
//! Run command specialized for tests. Returns process status and retVal is
|
|
// return value or exception.
|
|
int RunTest(std::vector<const char*> args, std::string* output, int *retVal,
|
|
std::ostream* logfile);
|
|
|
|
/**
|
|
* Execute handler and return its result. If the handler fails, it returns negative value.
|
|
*/
|
|
int ExecuteHandler(const char* handler);
|
|
|
|
/*
|
|
* Get the handler object
|
|
*/
|
|
cmCTestGenericHandler* GetHandler(const char* handler);
|
|
|
|
/*
|
|
* Set the CTest variable from CMake variable
|
|
*/
|
|
bool SetCTestConfigurationFromCMakeVariable(cmMakefile* mf, const char* dconfig, const char* cmake_var);
|
|
|
|
//! Make string safe to be send as an URL
|
|
static std::string MakeURLSafe(const std::string&);
|
|
|
|
//! Should ctect configuration be updated. When using new style ctest script,
|
|
// this should be true.
|
|
void SetSuppressUpdatingCTestConfiguration(bool val)
|
|
{
|
|
m_SuppressUpdatingCTestConfiguration = val;
|
|
}
|
|
|
|
//! Create XML file that contains all the notes specified
|
|
int GenerateNotesFile(const std::vector<cmStdString> &files);
|
|
|
|
//! Set the output log file name
|
|
void SetOutputLogFileName(const char* name);
|
|
|
|
//! Various log types
|
|
enum {
|
|
DEBUG = 0,
|
|
OUTPUT,
|
|
HANDLER_OUTPUT,
|
|
HANDLER_VERBOSE_OUTPUT,
|
|
WARNING,
|
|
ERROR_MESSAGE,
|
|
OTHER
|
|
};
|
|
|
|
//! Add log to the output
|
|
void Log(int logType, const char* file, int line, const char* msg);
|
|
|
|
private:
|
|
std::string m_ConfigType;
|
|
bool m_Verbose;
|
|
bool m_ExtraVerbose;
|
|
bool m_ProduceXML;
|
|
|
|
bool m_ForceNewCTestProcess;
|
|
|
|
bool m_RunConfigurationScript;
|
|
|
|
int GenerateNotesFile(const char* files);
|
|
|
|
// these are helper classes
|
|
typedef std::map<cmStdString,cmCTestGenericHandler*> t_TestingHandlers;
|
|
t_TestingHandlers m_TestingHandlers;
|
|
|
|
bool m_ShowOnly;
|
|
|
|
enum {
|
|
FIRST_TEST = 0,
|
|
UPDATE_TEST = 1,
|
|
START_TEST = 2,
|
|
CONFIGURE_TEST = 3,
|
|
BUILD_TEST = 4,
|
|
TEST_TEST = 5,
|
|
COVERAGE_TEST = 6,
|
|
MEMCHECK_TEST = 7,
|
|
SUBMIT_TEST = 8,
|
|
NOTES_TEST = 9,
|
|
ALL_TEST = 10,
|
|
LAST_TEST = 11
|
|
};
|
|
|
|
//! Map of configuration properties
|
|
typedef std::map<cmStdString, cmStdString> tm_CTestConfigurationMap;
|
|
|
|
std::string m_CTestConfigFile;
|
|
tm_CTestConfigurationMap m_CTestConfiguration;
|
|
int m_Tests[LAST_TEST];
|
|
|
|
std::string m_CurrentTag;
|
|
bool m_TomorrowTag;
|
|
|
|
int m_TestModel;
|
|
|
|
double m_TimeOut;
|
|
|
|
int m_CompatibilityMode;
|
|
|
|
// information for the --build-and-test options
|
|
std::string m_CMakeSelf;
|
|
std::string m_CTestSelf;
|
|
std::string m_BinaryDir;
|
|
|
|
std::string m_NotesFiles;
|
|
|
|
|
|
int ReadCustomConfigurationFileTree(const char* dir);
|
|
|
|
bool m_InteractiveDebugMode;
|
|
|
|
bool m_ShortDateFormat;
|
|
|
|
bool m_CompressXMLFiles;
|
|
|
|
void BlockTestErrorDiagnostics();
|
|
|
|
|
|
//! Reread the configuration file
|
|
bool UpdateCTestConfiguration();
|
|
|
|
//! Create not from files.
|
|
int GenerateCTestNotesOutput(std::ostream& os, const tm_VectorOfStrings& files);
|
|
|
|
///! Find the running cmake
|
|
void FindRunningCMake(const char* arg0);
|
|
|
|
bool m_SuppressUpdatingCTestConfiguration;
|
|
|
|
bool m_Debug;
|
|
bool m_ShowLineNumbers;
|
|
bool m_Quiet;
|
|
|
|
|
|
cmGeneratedFileStream* m_OutputLogFile;
|
|
int m_OutputLogFileLastTag;
|
|
};
|
|
|
|
class cmCTestLogWrite
|
|
{
|
|
public:
|
|
cmCTestLogWrite(const char* data, size_t length) : Data(data), Length(length) {}
|
|
|
|
const char* Data;
|
|
size_t Length;
|
|
};
|
|
|
|
inline std::ostream& operator<< (std::ostream& os, const cmCTestLogWrite& c)
|
|
{
|
|
os.write(c.Data, c.Length);
|
|
os.flush();
|
|
return os;
|
|
}
|
|
|
|
#endif
|