Path: blob/master/Source/CTest/cmCTestMultiProcessHandler.h
4998 views
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying1file LICENSE.rst or https://cmake.org/licensing for details. */2#pragma once34#include "cmConfigure.h" // IWYU pragma: keep56#include <cstddef>7#include <list>8#include <map>9#include <memory>10#include <set>11#include <string>12#include <vector>1314#include <cm/optional>15#include <cm/string_view>1617#include "cmCTest.h"18#include "cmCTestResourceAllocator.h"19#include "cmCTestResourceSpec.h"20#include "cmCTestTestHandler.h"21#include "cmUVHandlePtr.h"22#include "cmUVJobServerClient.h"2324struct cmCTestBinPackerAllocation;25class cmCTestRunTest;2627/** \class cmCTestMultiProcessHandler28* \brief run parallel ctest29*30* cmCTestMultiProcessHandler31*/32class cmCTestMultiProcessHandler33{34friend class TestComparator;35friend class cmCTestRunTest;3637public:38struct TestSet : public std::set<int>39{40};41struct TestInfo42{43TestSet Depends;44};45struct TestMap : public std::map<int, TestInfo>46{47};48struct TestList : public std::vector<int>49{50};51struct PropertiesMap52: public std::map<int, cmCTestTestHandler::cmCTestTestProperties*>53{54};55struct ResourceAllocation56{57std::string Id;58unsigned int Slots;59};6061cmCTestMultiProcessHandler(cmCTest* ctest, cmCTestTestHandler* handler);62virtual ~cmCTestMultiProcessHandler();63// Set the tests64bool SetTests(TestMap tests, PropertiesMap properties);65// Set the max number of tests that can be run at the same time.66void SetParallelLevel(cm::optional<size_t> level);67void SetTestLoad(unsigned long load);68virtual void RunTests();69void PrintOutputAsJson();70void PrintTestList();71void PrintLabels();7273void SetPassFailVectors(std::vector<std::string>* passed,74std::vector<std::string>* failed)75{76this->Passed = passed;77this->Failed = failed;78}79void SetTestResults(std::vector<cmCTestTestHandler::cmCTestTestResult>* r)80{81this->TestResults = r;82}8384cmCTestTestHandler* GetTestHandler() { return this->TestHandler; }8586void SetRepeatMode(cmCTest::Repeat mode, int count)87{88this->RepeatMode = mode;89this->RepeatCount = count;90}9192void SetResourceSpecFile(std::string const& resourceSpecFile)93{94this->ResourceSpecFile = resourceSpecFile;95}9697void SetQuiet(bool b) { this->Quiet = b; }9899void CheckResourceAvailability();100101protected:102// Start the next test or tests as many as are allowed by103// ParallelLevel104void StartNextTests();105void StartTestProcess(int test);106void StartTest(int test);107// Mark the checkpoint for the given test108void WriteCheckpoint(int index);109110void UpdateCostData();111void ReadCostData();112// Return index of a test based on its name113int SearchByName(cm::string_view name);114115void CreateTestCostList();116117void GetAllTestDependencies(int test, TestList& dependencies);118void CreateSerialTestCostList();119120void CreateParallelTestCostList();121122// Removes the checkpoint file123void MarkFinished();124void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);125126void StartNextTestsOnIdle();127void StartNextTestsOnTimer();128129void RemoveTest(int index);130// Check if we need to resume an interrupted test set131void CheckResume();132// Check if there are any circular dependencies133bool CheckCycles();134int FindMaxIndex();135inline size_t GetProcessorsUsed(int index);136std::string GetName(int index);137138bool CheckStopOnFailure();139140bool CheckStopTimePassed();141void SetStopTimePassed();142143void InitializeLoop();144void FinalizeLoop();145146bool ResourceLocksAvailable(int test);147void LockResources(int index);148void UnlockResources(int index);149150enum class ResourceAvailabilityError151{152NoResourceType,153InsufficientResources,154};155156bool Complete();157bool AllocateResources(int index);158bool TryAllocateResources(159int index,160std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&161allocations,162std::map<std::string, ResourceAvailabilityError>* errors = nullptr);163void DeallocateResources(int index);164bool AllResourcesAvailable();165bool InitResourceAllocator(std::string& error);166bool CheckGeneratedResourceSpec();167168private:169cmCTest* CTest;170cmCTestTestHandler* TestHandler;171172bool UseResourceSpec = false;173cmCTestResourceSpec ResourceSpec;174std::string ResourceSpecFile;175std::string ResourceSpecSetupFixture;176cm::optional<std::size_t> ResourceSpecSetupTest;177bool HasInvalidGeneratedResourceSpec = false;178179// Tests pending selection to start. They may have dependencies.180TestMap PendingTests;181// List of pending test indexes, ordered by cost.182std::list<int> OrderedTests;183// Total number of tests we'll be running184size_t Total = 0;185// Number of tests that are complete186size_t Completed = 0;187size_t RunningCount = 0;188std::set<size_t> ProcessorsAvailable;189size_t HaveAffinity;190bool StopTimePassed = false;191// list of test properties (indices concurrent to the test map)192PropertiesMap Properties;193std::map<int, std::string> TestOutput;194std::vector<std::string>* Passed;195std::vector<std::string>* Failed;196std::vector<std::string> LastTestsFailed;197std::set<std::string> ProjectResourcesLocked;198std::map<int,199std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>200AllocatedResources;201std::map<int, std::map<std::string, ResourceAvailabilityError>>202ResourceAvailabilityErrors;203cmCTestResourceAllocator ResourceAllocator;204std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;205206// Get the maximum number of processors that may be used at once.207size_t GetParallelLevel() const;208209// With no '-j' option, default to serial testing.210cm::optional<size_t> ParallelLevel = 1;211212// Fallback parallelism limit when '-j' is given with no value.213size_t ParallelLevelDefault;214215// 'make' jobserver client. If connected, we acquire a token216// for each test before running its process.217cm::optional<cmUVJobServerClient> JobServerClient;218// List of tests that are queued to run when a token is available.219std::list<int> JobServerQueuedTests;220// Callback invoked when a token is received.221void JobServerReceivedToken();222223unsigned long TestLoad = 0;224unsigned long FakeLoadForTesting = 0;225cm::uv_loop_ptr Loop;226cm::uv_idle_ptr StartNextTestsOnIdle_;227cm::uv_timer_ptr StartNextTestsOnTimer_;228bool HasCycles = false;229cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;230int RepeatCount = 1;231bool Quiet = false;232bool SerialTestRunning = false;233};234235236