Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Source/CTest/cmCTestMultiProcessHandler.h
4998 views
1
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2
file LICENSE.rst or https://cmake.org/licensing for details. */
3
#pragma once
4
5
#include "cmConfigure.h" // IWYU pragma: keep
6
7
#include <cstddef>
8
#include <list>
9
#include <map>
10
#include <memory>
11
#include <set>
12
#include <string>
13
#include <vector>
14
15
#include <cm/optional>
16
#include <cm/string_view>
17
18
#include "cmCTest.h"
19
#include "cmCTestResourceAllocator.h"
20
#include "cmCTestResourceSpec.h"
21
#include "cmCTestTestHandler.h"
22
#include "cmUVHandlePtr.h"
23
#include "cmUVJobServerClient.h"
24
25
struct cmCTestBinPackerAllocation;
26
class cmCTestRunTest;
27
28
/** \class cmCTestMultiProcessHandler
29
* \brief run parallel ctest
30
*
31
* cmCTestMultiProcessHandler
32
*/
33
class cmCTestMultiProcessHandler
34
{
35
friend class TestComparator;
36
friend class cmCTestRunTest;
37
38
public:
39
struct TestSet : public std::set<int>
40
{
41
};
42
struct TestInfo
43
{
44
TestSet Depends;
45
};
46
struct TestMap : public std::map<int, TestInfo>
47
{
48
};
49
struct TestList : public std::vector<int>
50
{
51
};
52
struct PropertiesMap
53
: public std::map<int, cmCTestTestHandler::cmCTestTestProperties*>
54
{
55
};
56
struct ResourceAllocation
57
{
58
std::string Id;
59
unsigned int Slots;
60
};
61
62
cmCTestMultiProcessHandler(cmCTest* ctest, cmCTestTestHandler* handler);
63
virtual ~cmCTestMultiProcessHandler();
64
// Set the tests
65
bool SetTests(TestMap tests, PropertiesMap properties);
66
// Set the max number of tests that can be run at the same time.
67
void SetParallelLevel(cm::optional<size_t> level);
68
void SetTestLoad(unsigned long load);
69
virtual void RunTests();
70
void PrintOutputAsJson();
71
void PrintTestList();
72
void PrintLabels();
73
74
void SetPassFailVectors(std::vector<std::string>* passed,
75
std::vector<std::string>* failed)
76
{
77
this->Passed = passed;
78
this->Failed = failed;
79
}
80
void SetTestResults(std::vector<cmCTestTestHandler::cmCTestTestResult>* r)
81
{
82
this->TestResults = r;
83
}
84
85
cmCTestTestHandler* GetTestHandler() { return this->TestHandler; }
86
87
void SetRepeatMode(cmCTest::Repeat mode, int count)
88
{
89
this->RepeatMode = mode;
90
this->RepeatCount = count;
91
}
92
93
void SetResourceSpecFile(std::string const& resourceSpecFile)
94
{
95
this->ResourceSpecFile = resourceSpecFile;
96
}
97
98
void SetQuiet(bool b) { this->Quiet = b; }
99
100
void CheckResourceAvailability();
101
102
protected:
103
// Start the next test or tests as many as are allowed by
104
// ParallelLevel
105
void StartNextTests();
106
void StartTestProcess(int test);
107
void StartTest(int test);
108
// Mark the checkpoint for the given test
109
void WriteCheckpoint(int index);
110
111
void UpdateCostData();
112
void ReadCostData();
113
// Return index of a test based on its name
114
int SearchByName(cm::string_view name);
115
116
void CreateTestCostList();
117
118
void GetAllTestDependencies(int test, TestList& dependencies);
119
void CreateSerialTestCostList();
120
121
void CreateParallelTestCostList();
122
123
// Removes the checkpoint file
124
void MarkFinished();
125
void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
126
127
void StartNextTestsOnIdle();
128
void StartNextTestsOnTimer();
129
130
void RemoveTest(int index);
131
// Check if we need to resume an interrupted test set
132
void CheckResume();
133
// Check if there are any circular dependencies
134
bool CheckCycles();
135
int FindMaxIndex();
136
inline size_t GetProcessorsUsed(int index);
137
std::string GetName(int index);
138
139
bool CheckStopOnFailure();
140
141
bool CheckStopTimePassed();
142
void SetStopTimePassed();
143
144
void InitializeLoop();
145
void FinalizeLoop();
146
147
bool ResourceLocksAvailable(int test);
148
void LockResources(int index);
149
void UnlockResources(int index);
150
151
enum class ResourceAvailabilityError
152
{
153
NoResourceType,
154
InsufficientResources,
155
};
156
157
bool Complete();
158
bool AllocateResources(int index);
159
bool TryAllocateResources(
160
int index,
161
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
162
allocations,
163
std::map<std::string, ResourceAvailabilityError>* errors = nullptr);
164
void DeallocateResources(int index);
165
bool AllResourcesAvailable();
166
bool InitResourceAllocator(std::string& error);
167
bool CheckGeneratedResourceSpec();
168
169
private:
170
cmCTest* CTest;
171
cmCTestTestHandler* TestHandler;
172
173
bool UseResourceSpec = false;
174
cmCTestResourceSpec ResourceSpec;
175
std::string ResourceSpecFile;
176
std::string ResourceSpecSetupFixture;
177
cm::optional<std::size_t> ResourceSpecSetupTest;
178
bool HasInvalidGeneratedResourceSpec = false;
179
180
// Tests pending selection to start. They may have dependencies.
181
TestMap PendingTests;
182
// List of pending test indexes, ordered by cost.
183
std::list<int> OrderedTests;
184
// Total number of tests we'll be running
185
size_t Total = 0;
186
// Number of tests that are complete
187
size_t Completed = 0;
188
size_t RunningCount = 0;
189
std::set<size_t> ProcessorsAvailable;
190
size_t HaveAffinity;
191
bool StopTimePassed = false;
192
// list of test properties (indices concurrent to the test map)
193
PropertiesMap Properties;
194
std::map<int, std::string> TestOutput;
195
std::vector<std::string>* Passed;
196
std::vector<std::string>* Failed;
197
std::vector<std::string> LastTestsFailed;
198
std::set<std::string> ProjectResourcesLocked;
199
std::map<int,
200
std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
201
AllocatedResources;
202
std::map<int, std::map<std::string, ResourceAvailabilityError>>
203
ResourceAvailabilityErrors;
204
cmCTestResourceAllocator ResourceAllocator;
205
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
206
207
// Get the maximum number of processors that may be used at once.
208
size_t GetParallelLevel() const;
209
210
// With no '-j' option, default to serial testing.
211
cm::optional<size_t> ParallelLevel = 1;
212
213
// Fallback parallelism limit when '-j' is given with no value.
214
size_t ParallelLevelDefault;
215
216
// 'make' jobserver client. If connected, we acquire a token
217
// for each test before running its process.
218
cm::optional<cmUVJobServerClient> JobServerClient;
219
// List of tests that are queued to run when a token is available.
220
std::list<int> JobServerQueuedTests;
221
// Callback invoked when a token is received.
222
void JobServerReceivedToken();
223
224
unsigned long TestLoad = 0;
225
unsigned long FakeLoadForTesting = 0;
226
cm::uv_loop_ptr Loop;
227
cm::uv_idle_ptr StartNextTestsOnIdle_;
228
cm::uv_timer_ptr StartNextTestsOnTimer_;
229
bool HasCycles = false;
230
cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
231
int RepeatCount = 1;
232
bool Quiet = false;
233
bool SerialTestRunning = false;
234
};
235
236