cmake/Source/CTest/cmCTestMultiProcessHandler.h

234 lines
6.4 KiB
C
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2021-09-14 00:13:48 +02:00
#pragma once
2009-10-04 10:30:41 +03:00
2017-07-20 19:35:53 +02:00
#include "cmConfigure.h" // IWYU pragma: keep
2016-10-30 18:24:19 +01:00
2022-03-29 21:10:50 +02:00
#include <cstddef>
2024-04-14 22:45:38 +02:00
#include <list>
2016-10-30 18:24:19 +01:00
#include <map>
2020-08-30 11:54:41 +02:00
#include <memory>
2016-10-30 18:24:19 +01:00
#include <set>
#include <string>
#include <vector>
2016-07-09 11:21:54 +02:00
2023-12-07 09:12:54 +01:00
#include <cm/optional>
2020-08-30 11:54:41 +02:00
#include "cmCTest.h"
2020-02-01 23:06:01 +01:00
#include "cmCTestResourceAllocator.h"
2023-12-07 09:12:54 +01:00
#include "cmCTestResourceSpec.h"
2020-02-01 23:06:01 +01:00
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"
2024-04-14 22:45:38 +02:00
#include "cmUVJobServerClient.h"
2020-02-01 23:06:01 +01:00
struct cmCTestBinPackerAllocation;
2016-10-30 18:24:19 +01:00
class cmCTestRunTest;
2009-10-04 10:30:41 +03:00
/** \class cmCTestMultiProcessHandler
* \brief run parallel ctest
*
2013-03-16 19:13:01 +02:00
* cmCTestMultiProcessHandler
2009-10-04 10:30:41 +03:00
*/
2013-03-16 19:13:01 +02:00
class cmCTestMultiProcessHandler
2009-10-04 10:30:41 +03:00
{
2010-11-13 01:00:53 +02:00
friend class TestComparator;
2018-04-23 21:13:27 +02:00
friend class cmCTestRunTest;
2016-07-09 11:21:54 +02:00
2009-10-04 10:30:41 +03:00
public:
2016-07-09 11:21:54 +02:00
struct TestSet : public std::set<int>
{
};
2024-04-14 22:45:38 +02:00
struct TestInfo
{
TestSet Depends;
};
struct TestMap : public std::map<int, TestInfo>
2016-07-09 11:21:54 +02:00
{
};
struct TestList : public std::vector<int>
{
};
struct PropertiesMap
: public std::map<int, cmCTestTestHandler::cmCTestTestProperties*>
{
};
2020-02-01 23:06:01 +01:00
struct ResourceAllocation
{
std::string Id;
unsigned int Slots;
};
2009-10-04 10:30:41 +03:00
2024-04-14 22:45:38 +02:00
cmCTestMultiProcessHandler(cmCTest* ctest, cmCTestTestHandler* handler);
2009-10-04 10:30:41 +03:00
virtual ~cmCTestMultiProcessHandler();
// Set the tests
2024-04-14 22:45:38 +02:00
void SetTests(TestMap tests, PropertiesMap properties);
2009-10-04 10:30:41 +03:00
// Set the max number of tests that can be run at the same time.
2024-04-14 22:45:38 +02:00
void SetParallelLevel(cm::optional<size_t> level);
2015-11-17 17:22:37 +01:00
void SetTestLoad(unsigned long load);
2009-10-04 10:30:41 +03:00
virtual void RunTests();
2019-11-11 23:01:05 +01:00
void PrintOutputAsJson();
2009-10-04 10:30:41 +03:00
void PrintTestList();
2010-11-13 01:00:53 +02:00
void PrintLabels();
2009-10-04 10:30:41 +03:00
2015-04-27 22:25:09 +02:00
void SetPassFailVectors(std::vector<std::string>* passed,
std::vector<std::string>* failed)
2016-07-09 11:21:54 +02:00
{
2009-10-04 10:30:41 +03:00
this->Passed = passed;
this->Failed = failed;
2016-07-09 11:21:54 +02:00
}
2009-10-04 10:30:41 +03:00
void SetTestResults(std::vector<cmCTestTestHandler::cmCTestTestResult>* r)
2016-07-09 11:21:54 +02:00
{
this->TestResults = r;
}
2009-10-04 10:30:41 +03:00
2016-07-09 11:21:54 +02:00
cmCTestTestHandler* GetTestHandler() { return this->TestHandler; }
2015-08-17 11:37:30 +02:00
2020-08-30 11:54:41 +02:00
void SetRepeatMode(cmCTest::Repeat mode, int count)
{
this->RepeatMode = mode;
this->RepeatCount = count;
}
2023-12-07 09:12:54 +01:00
void SetResourceSpecFile(const std::string& resourceSpecFile)
2020-02-01 23:06:01 +01:00
{
2023-12-07 09:12:54 +01:00
this->ResourceSpecFile = resourceSpecFile;
2020-02-01 23:06:01 +01:00
}
2023-12-07 09:12:54 +01:00
void SetQuiet(bool b) { this->Quiet = b; }
2024-04-14 22:45:38 +02:00
void CheckResourceAvailability();
2020-02-01 23:06:01 +01:00
2010-06-23 01:18:35 +03:00
protected:
2009-10-04 10:30:41 +03:00
// Start the next test or tests as many as are allowed by
// ParallelLevel
void StartNextTests();
2024-04-14 22:45:38 +02:00
void StartTestProcess(int test);
void StartTest(int test);
2009-10-04 10:30:41 +03:00
// Mark the checkpoint for the given test
void WriteCheckpoint(int index);
2010-06-23 01:18:35 +03:00
void UpdateCostData();
2009-10-04 10:30:41 +03:00
void ReadCostData();
2010-06-23 01:18:35 +03:00
// Return index of a test based on its name
2016-07-09 11:21:54 +02:00
int SearchByName(std::string const& name);
2010-06-23 01:18:35 +03:00
2009-10-04 10:30:41 +03:00
void CreateTestCostList();
2014-08-03 19:52:23 +02:00
void GetAllTestDependencies(int test, TestList& dependencies);
void CreateSerialTestCostList();
void CreateParallelTestCostList();
2009-10-04 10:30:41 +03:00
// Removes the checkpoint file
void MarkFinished();
2020-08-30 11:54:41 +02:00
void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
2018-04-23 21:13:27 +02:00
2024-04-14 22:45:38 +02:00
void StartNextTestsOnIdle();
void StartNextTestsOnTimer();
2018-10-07 12:27:06 +02:00
2009-10-04 10:30:41 +03:00
void RemoveTest(int index);
2016-07-09 11:21:54 +02:00
// Check if we need to resume an interrupted test set
2009-10-04 10:30:41 +03:00
void CheckResume();
2016-07-09 11:21:54 +02:00
// Check if there are any circular dependencies
2009-11-06 22:07:41 +02:00
bool CheckCycles();
2009-10-04 10:30:41 +03:00
int FindMaxIndex();
inline size_t GetProcessorsUsed(int index);
2015-11-17 17:22:37 +01:00
std::string GetName(int index);
2010-06-23 01:18:35 +03:00
2020-08-30 11:54:41 +02:00
bool CheckStopOnFailure();
2018-10-28 12:09:07 +01:00
bool CheckStopTimePassed();
void SetStopTimePassed();
2024-04-14 22:45:38 +02:00
void InitializeLoop();
void FinalizeLoop();
bool ResourceLocksAvailable(int test);
2010-06-23 01:18:35 +03:00
void LockResources(int index);
void UnlockResources(int index);
2020-02-01 23:06:01 +01:00
2024-04-14 22:45:38 +02:00
enum class ResourceAvailabilityError
2020-08-30 11:54:41 +02:00
{
NoResourceType,
InsufficientResources,
};
2024-04-14 22:45:38 +02:00
bool Complete();
2020-02-01 23:06:01 +01:00
bool AllocateResources(int index);
bool TryAllocateResources(
int index,
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
2020-08-30 11:54:41 +02:00
allocations,
2024-04-14 22:45:38 +02:00
std::map<std::string, ResourceAvailabilityError>* errors = nullptr);
2020-02-01 23:06:01 +01:00
void DeallocateResources(int index);
bool AllResourcesAvailable();
2023-12-07 09:12:54 +01:00
bool InitResourceAllocator(std::string& error);
bool CheckGeneratedResourceSpec();
2024-04-14 22:45:38 +02:00
private:
cmCTest* CTest;
cmCTestTestHandler* TestHandler;
2023-12-07 09:12:54 +01:00
bool UseResourceSpec = false;
cmCTestResourceSpec ResourceSpec;
std::string ResourceSpecFile;
std::string ResourceSpecSetupFixture;
cm::optional<std::size_t> ResourceSpecSetupTest;
2024-04-14 22:45:38 +02:00
bool HasInvalidGeneratedResourceSpec = false;
2020-02-01 23:06:01 +01:00
2024-04-14 22:45:38 +02:00
// Tests pending selection to start. They may have dependencies.
TestMap PendingTests;
// List of pending test indexes, ordered by cost.
std::list<int> OrderedTests;
2016-07-09 11:21:54 +02:00
// Total number of tests we'll be running
2024-04-14 22:45:38 +02:00
size_t Total = 0;
2016-07-09 11:21:54 +02:00
// Number of tests that are complete
2024-04-14 22:45:38 +02:00
size_t Completed = 0;
size_t RunningCount = 0;
2018-08-09 18:06:22 +02:00
std::set<size_t> ProcessorsAvailable;
size_t HaveAffinity;
2018-10-28 12:09:07 +01:00
bool StopTimePassed = false;
2016-07-09 11:21:54 +02:00
// list of test properties (indices concurrent to the test map)
2009-10-04 10:30:41 +03:00
PropertiesMap Properties;
2015-04-27 22:25:09 +02:00
std::map<int, std::string> TestOutput;
std::vector<std::string>* Passed;
std::vector<std::string>* Failed;
2010-06-23 01:18:35 +03:00
std::vector<std::string> LastTestsFailed;
2024-04-14 22:45:38 +02:00
std::set<std::string> ProjectResourcesLocked;
2020-02-01 23:06:01 +01:00
std::map<int,
std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
AllocatedResources;
2024-04-14 22:45:38 +02:00
std::map<int, std::map<std::string, ResourceAvailabilityError>>
ResourceAvailabilityErrors;
2020-02-01 23:06:01 +01:00
cmCTestResourceAllocator ResourceAllocator;
2009-10-04 10:30:41 +03:00
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
2024-04-14 22:45:38 +02:00
// Get the maximum number of processors that may be used at once.
size_t GetParallelLevel() const;
// With no '-j' option, default to serial testing.
cm::optional<size_t> ParallelLevel = 1;
// Fallback parallelism limit when '-j' is given with no value.
size_t ParallelLevelDefault;
// 'make' jobserver client. If connected, we acquire a token
// for each test before running its process.
cm::optional<cmUVJobServerClient> JobServerClient;
// List of tests that are queued to run when a token is available.
std::list<int> JobServerQueuedTests;
// Callback invoked when a token is received.
void JobServerReceivedToken();
unsigned long TestLoad = 0;
unsigned long FakeLoadForTesting = 0;
cm::uv_loop_ptr Loop;
cm::uv_idle_ptr StartNextTestsOnIdle_;
cm::uv_timer_ptr StartNextTestsOnTimer_;
bool HasCycles = false;
2020-08-30 11:54:41 +02:00
cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
int RepeatCount = 1;
2024-04-14 22:45:38 +02:00
bool Quiet = false;
bool SerialTestRunning = false;
2009-10-04 10:30:41 +03:00
};