1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <cm3p/uv.h>
#include <stddef.h>
#include "cmCTest.h"
#include "cmCTestResourceAllocator.h"
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"
struct cmCTestBinPackerAllocation;
class cmCTestResourceSpec;
class cmCTestRunTest;
/** \class cmCTestMultiProcessHandler
* \brief run parallel ctest
*
* cmCTestMultiProcessHandler
*/
class cmCTestMultiProcessHandler
{
friend class TestComparator;
friend class cmCTestRunTest;
public:
struct TestSet : public std::set<int>
{
};
struct TestMap : public std::map<int, TestSet>
{
};
struct TestList : public std::vector<int>
{
};
struct PropertiesMap
: public std::map<int, cmCTestTestHandler::cmCTestTestProperties*>
{
};
struct ResourceAllocation
{
std::string Id;
unsigned int Slots;
};
cmCTestMultiProcessHandler();
virtual ~cmCTestMultiProcessHandler();
// Set the tests
void SetTests(TestMap& tests, PropertiesMap& properties);
// Set the max number of tests that can be run at the same time.
void SetParallelLevel(size_t);
void SetTestLoad(unsigned long load);
virtual void RunTests();
void PrintOutputAsJson();
void PrintTestList();
void PrintLabels();
void SetPassFailVectors(std::vector<std::string>* passed,
std::vector<std::string>* failed)
{
this->Passed = passed;
this->Failed = failed;
}
void SetTestResults(std::vector<cmCTestTestHandler::cmCTestTestResult>* r)
{
this->TestResults = r;
}
void SetCTest(cmCTest* ctest) { this->CTest = ctest; }
void SetTestHandler(cmCTestTestHandler* handler)
{
this->TestHandler = handler;
}
cmCTestTestHandler* GetTestHandler() { return this->TestHandler; }
void SetRepeatMode(cmCTest::Repeat mode, int count)
{
this->RepeatMode = mode;
this->RepeatCount = count;
}
void SetQuiet(bool b) { this->Quiet = b; }
void InitResourceAllocator(const cmCTestResourceSpec& spec)
{
this->ResourceAllocator.InitializeFromResourceSpec(spec);
}
void CheckResourcesAvailable();
protected:
// Start the next test or tests as many as are allowed by
// ParallelLevel
void StartNextTests();
bool StartTestProcess(int test);
bool StartTest(int test);
// Mark the checkpoint for the given test
void WriteCheckpoint(int index);
void UpdateCostData();
void ReadCostData();
// Return index of a test based on its name
int SearchByName(std::string const& name);
void CreateTestCostList();
void GetAllTestDependencies(int test, TestList& dependencies);
void CreateSerialTestCostList();
void CreateParallelTestCostList();
// Removes the checkpoint file
void MarkFinished();
void EraseTest(int index);
void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
static void OnTestLoadRetryCB(uv_timer_t* timer);
void RemoveTest(int index);
// Check if we need to resume an interrupted test set
void CheckResume();
// Check if there are any circular dependencies
bool CheckCycles();
int FindMaxIndex();
inline size_t GetProcessorsUsed(int index);
std::string GetName(int index);
bool CheckStopOnFailure();
bool CheckStopTimePassed();
void SetStopTimePassed();
void LockResources(int index);
void UnlockResources(int index);
enum class ResourceAllocationError
{
NoResourceType,
InsufficientResources,
};
bool AllocateResources(int index);
bool TryAllocateResources(
int index,
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
allocations,
std::map<std::string, ResourceAllocationError>* errors = nullptr);
void DeallocateResources(int index);
bool AllResourcesAvailable();
// map from test number to set of depend tests
TestMap Tests;
TestList SortedTests;
// Total number of tests we'll be running
size_t Total;
// Number of tests that are complete
size_t Completed;
size_t RunningCount;
std::set<size_t> ProcessorsAvailable;
size_t HaveAffinity;
bool StopTimePassed = false;
// list of test properties (indices concurrent to the test map)
PropertiesMap Properties;
std::map<int, bool> TestRunningMap;
std::map<int, bool> TestFinishMap;
std::map<int, std::string> TestOutput;
std::vector<std::string>* Passed;
std::vector<std::string>* Failed;
std::vector<std::string> LastTestsFailed;
std::set<std::string> LockedResources;
std::map<int,
std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
AllocatedResources;
std::map<int, std::map<std::string, ResourceAllocationError>>
ResourceAllocationErrors;
cmCTestResourceAllocator ResourceAllocator;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
unsigned long TestLoad;
unsigned long FakeLoadForTesting;
uv_loop_t Loop;
cm::uv_timer_ptr TestLoadRetryTimer;
cmCTestTestHandler* TestHandler;
cmCTest* CTest;
bool HasCycles;
cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
int RepeatCount = 1;
bool Quiet;
bool SerialTestRunning;
};
|