Merge branch 'backport-ctest-resource-groups'

This commit is contained in:
Brad King 2019-11-05 12:59:16 -05:00
commit 016601e5e6
141 changed files with 1062 additions and 1051 deletions

View File

@ -17,7 +17,7 @@ Perform the :ref:`CTest Test Step` as a :ref:`Dashboard Client`.
[EXCLUDE_FIXTURE_SETUP <regex>]
[EXCLUDE_FIXTURE_CLEANUP <regex>]
[PARALLEL_LEVEL <level>]
[HARDWARE_SPEC_FILE <file>]
[RESOURCE_SPEC_FILE <file>]
[TEST_LOAD <threshold>]
[SCHEDULE_RANDOM <ON|OFF>]
[STOP_TIME <time-of-day>]
@ -83,10 +83,10 @@ The options are:
Specify a positive number representing the number of tests to
be run in parallel.
``HARDWARE_SPEC_FILE <file>``
``RESOURCE_SPEC_FILE <file>``
Specify a
:ref:`hardware specification file <ctest-hardware-specification-file>`. See
:ref:`ctest-hardware-allocation` for more information.
:ref:`resource specification file <ctest-resource-specification-file>`. See
:ref:`ctest-resource-allocation` for more information.
``TEST_LOAD <threshold>``
While running tests in parallel, try not to start tests when they

View File

@ -415,10 +415,10 @@ Properties on Tests
/prop_test/LABELS
/prop_test/MEASUREMENT
/prop_test/PASS_REGULAR_EXPRESSION
/prop_test/PROCESSES
/prop_test/PROCESSOR_AFFINITY
/prop_test/PROCESSORS
/prop_test/REQUIRED_FILES
/prop_test/RESOURCE_GROUPS
/prop_test/RESOURCE_LOCK
/prop_test/RUN_SERIAL
/prop_test/SKIP_REGULAR_EXPRESSION

View File

@ -90,14 +90,14 @@ Options
See `Label and Subproject Summary`_.
``--hardware-spec-file <file>``
Run CTest with :ref:`hardware allocation <ctest-hardware-allocation>` enabled,
``--resource-spec-file <file>``
Run CTest with :ref:`resource allocation <ctest-resource-allocation>` enabled,
using the
:ref:`hardware specification file <ctest-hardware-specification-file>`
:ref:`resource specification file <ctest-resource-specification-file>`
specified in ``<file>``.
When ``ctest`` is run as a `Dashboard Client`_ this sets the
``HardwareSpecFile`` option of the `CTest Test Step`_.
``ResourceSpecFile`` option of the `CTest Test Step`_.
``--test-load <level>``
While running tests in parallel (e.g. with ``-j``), try not to start
@ -980,10 +980,10 @@ Arguments to the command may specify some of the step settings.
Configuration settings include:
``HardwareSpecFile``
``ResourceSpecFile``
Specify a
:ref:`hardware specification file <ctest-hardware-specification-file>`. See
:ref:`ctest-hardware-allocation` for more information.
:ref:`resource specification file <ctest-resource-specification-file>`. See
:ref:`ctest-resource-allocation` for more information.
``LabelsForSubprojects``
Specify a semicolon-separated list of labels that will be treated as
@ -1294,22 +1294,22 @@ model is defined as follows:
Test properties.
Can contain keys for each of the supported test properties.
.. _`ctest-hardware-allocation`:
.. _`ctest-resource-allocation`:
Hardware Allocation
Resource Allocation
===================
CTest provides a mechanism for tests to specify the hardware that they need and
how much of it they need, and for users to specify the hardware availiable on
CTest provides a mechanism for tests to specify the resources that they need
in a fine-grained way, and for users to specify the resources availiable on
the running machine. This allows CTest to internally keep track of which
hardware is in use and which is free, scheduling tests in a way that prevents
them from trying to claim hardware that is not available.
resources are in use and which are free, scheduling tests in a way that
prevents them from trying to claim resources that are not available.
A common use case for this feature is for tests that require the use of a GPU.
Multiple tests can simultaneously allocate memory from a GPU, but if too many
tests try to do this at once, some of them will fail to allocate, resulting in
a failed test, even though the test would have succeeded if it had the memory
it needed. By using the hardware allocation feature, each test can specify how
it needed. By using the resource allocation feature, each test can specify how
much memory it requires from a GPU, allowing CTest to schedule tests in a way
that running several of these tests at once does not exhaust the GPU's memory
pool.
@ -1325,36 +1325,35 @@ When a test is executed, and slots from a resource are allocated to that test,
tests may assume that they have exclusive use of those slots for the duration
of the test's process.
The CTest hardware allocation feature consists of two inputs:
The CTest resource allocation feature consists of two inputs:
* The :ref:`hardware specification file <ctest-hardware-specification-file>`,
described below, which describes the hardware resources available on the
system, and
* The :prop_test:`PROCESSES` property of tests, which describes the resources
required by the test
* The :ref:`resource specification file <ctest-resource-specification-file>`,
described below, which describes the resources available on the system.
* The :prop_test:`RESOURCE_GROUPS` property of tests, which describes the
resources required by the test.
When CTest runs a test, the hardware allocated to that test is passed in the
When CTest runs a test, the resources allocated to that test are passed in the
form of a set of
:ref:`environment variables <ctest-hardware-environment-variables>` as
:ref:`environment variables <ctest-resource-environment-variables>` as
described below. Using this information to decide which resource to connect to
is left to the test writer.
Please note that these processes are not spawned by CTest. The ``PROCESSES``
property merely tells CTest what processes the test expects to launch. It is up
to the test itself to do this process spawning, and read the :ref:`environment
variables <ctest-hardware-environment-variables>` to determine which resources
each process has been allocated.
The ``RESOURCE_GROUPS`` property tells CTest what resources a test expects
to use grouped in a way meaningful to the test. The test itself must read
the :ref:`environment variables <ctest-resource-environment-variables>` to
determine which resources have been allocated to each group. For example,
each group may correspond to a process the test will spawn when executed.
.. _`ctest-hardware-specification-file`:
.. _`ctest-resource-specification-file`:
Hardware Specification File
Resource Specification File
---------------------------
The hardware specification file is a JSON file which is passed to CTest, either
on the :manual:`ctest(1)` command line as ``--hardware-spec-file``, or as the
``HARDWARE_SPEC_FILE`` argument of :command:`ctest_test`. The hardware
The resource specification file is a JSON file which is passed to CTest, either
on the :manual:`ctest(1)` command line as ``--resource-spec-file``, or as the
``RESOURCE_SPEC_FILE`` argument of :command:`ctest_test`. The resource
specification file must be a JSON object. All examples in this document assume
the following hardware specification file:
the following resource specification file:
.. code-block:: json
@ -1391,11 +1390,11 @@ the following hardware specification file:
The members are:
``local``
A JSON array consisting of CPU sockets present on the system. Currently, only
one socket is supported.
A JSON array of resource sets present on the system. Currently, this array
is restricted to being of size 1.
Each socket is a JSON object with members whose names are equal to the
desired resource types, such as ``gpu``. These names must start with a
Each array element is a JSON object with members whose names are equal to the
desired resource types, such as ``gpus``. These names must start with a
lowercase letter or an underscore, and subsequent characters can be a
lowercase letter, a digit, or an underscore. Uppercase letters are not
allowed, because certain platforms have case-insensitive environment
@ -1436,12 +1435,12 @@ In the example file above, there are four GPUs with ID's 0 through 3. GPU 0 has
2 slots, GPU 1 has 4, GPU 2 has 2, and GPU 3 has a default of 1 slot. There is
also one cryptography chip with 4 slots.
``PROCESSES`` Property
----------------------
``RESOURCE_GROUPS`` Property
----------------------------
See :prop_test:`PROCESSES` for a description of this property.
See :prop_test:`RESOURCE_GROUPS` for a description of this property.
.. _`ctest-hardware-environment-variables`:
.. _`ctest-resource-environment-variables`:
Environment Variables
---------------------
@ -1449,65 +1448,67 @@ Environment Variables
Once CTest has decided which resources to allocate to a test, it passes this
information to the test executable as a series of environment variables. For
each example below, we will assume that the test in question has a
:prop_test:`PROCESSES` property of ``2,gpus:2;gpus:4,gpus:1,crypto_chips:2``.
:prop_test:`RESOURCE_GROUPS` property of
``2,gpus:2;gpus:4,gpus:1,crypto_chips:2``.
The following variables are passed to the test process:
.. envvar:: CTEST_PROCESS_COUNT
.. envvar:: CTEST_RESOURCE_GROUP_COUNT
The total number of processes specified by the :prop_test:`PROCESSES`
The total number of groups specified by the :prop_test:`RESOURCE_GROUPS`
property. For example:
* ``CTEST_PROCESS_COUNT=3``
* ``CTEST_RESOURCE_GROUP_COUNT=3``
This variable will only be defined if :manual:`ctest(1)` has been given a
``--hardware-spec-file``, or if :command:`ctest_test` has been given a
``HARDWARE_SPEC_FILE``. If no hardware specification file has been given,
``--resource-spec-file``, or if :command:`ctest_test` has been given a
``RESOURCE_SPEC_FILE``. If no resource specification file has been given,
this variable will not be defined.
.. envvar:: CTEST_PROCESS_<num>
.. envvar:: CTEST_RESOURCE_GROUP_<num>
The list of resource types allocated to each process, with each item
The list of resource types allocated to each group, with each item
separated by a comma. ``<num>`` is a number from zero to
``CTEST_PROCESS_COUNT`` minus one. ``CTEST_PROCESS_<num>`` is defined for
each ``<num>`` in this range. For example:
``CTEST_RESOURCE_GROUP_COUNT`` minus one. ``CTEST_RESOURCE_GROUP_<num>``
is defined for each ``<num>`` in this range. For example:
* ``CTEST_PROCESS_0=gpus``
* ``CTEST_PROCESS_1=gpus``
* ``CTEST_PROCESS_2=crypto_chips,gpus``
* ``CTEST_RESOURCE_GROUP_0=gpus``
* ``CTEST_RESOURCE_GROUP_1=gpus``
* ``CTEST_RESOURCE_GROUP_2=crypto_chips,gpus``
.. envvar:: CTEST_PROCESS_<num>_<resource-type>
.. envvar:: CTEST_RESOURCE_GROUP_<num>_<resource-type>
The list of resource IDs and number of slots from each ID allocated to each
process for a given resource type. This variable consists of a series of
group for a given resource type. This variable consists of a series of
pairs, each pair separated by a semicolon, and with the two items in the pair
separated by a comma. The first item in each pair is ``id:`` followed by the
ID of a resource of type ``<resource-type>``, and the second item is
``slots:`` followed by the number of slots from that resource allocated to
the given process. For example:
the given group. For example:
* ``CTEST_PROCESS_0_GPUS=id:0,slots:2``
* ``CTEST_PROCESS_1_GPUS=id:2,slots:2``
* ``CTEST_PROCESS_2_GPUS=id:1,slots:4;id:3,slots:1``
* ``CTEST_PROCESS_2_CRYPTO_CHIPS=id:card0,slots:2``
* ``CTEST_RESOURCE_GROUP_0_GPUS=id:0,slots:2``
* ``CTEST_RESOURCE_GROUP_1_GPUS=id:2,slots:2``
* ``CTEST_RESOURCE_GROUP_2_GPUS=id:1,slots:4;id:3,slots:1``
* ``CTEST_RESOURCE_GROUP_2_CRYPTO_CHIPS=id:card0,slots:2``
In this example, process 0 gets 2 slots from GPU ``0``, process 1 gets 2 slots
from GPU ``2``, and process 2 gets 4 slots from GPU ``1`` and 2 slots from
cryptography chip ``card0``.
In this example, group 0 gets 2 slots from GPU ``0``, group 1 gets 2 slots
from GPU ``2``, and group 2 gets 4 slots from GPU ``1``, 1 slot from GPU
``3``, and 2 slots from cryptography chip ``card0``.
``<num>`` is a number from zero to ``CTEST_PROCESS_COUNT`` minus one.
``<num>`` is a number from zero to ``CTEST_RESOURCE_GROUP_COUNT`` minus one.
``<resource-type>`` is the name of a resource type, converted to uppercase.
``CTEST_PROCESS_<num>_<resource-type>`` is defined for the product of each
``<num>`` in the range listed above and each resource type listed in
``CTEST_PROCESS_<num>``.
``CTEST_RESOURCE_GROUP_<num>_<resource-type>`` is defined for the product
of each ``<num>`` in the range listed above and each resource type listed in
``CTEST_RESOURCE_GROUP_<num>``.
Because some platforms have case-insensitive names for environment variables,
the names of resource types may not clash in a case-insensitive environment.
Because of this, for the sake of simplicity, all resource types must be
listed in all lowercase in the
:ref:`hardware specification file <ctest-hardware-specification-file>` and in
the :prop_test:`PROCESSES` property, and they are converted to all uppercase
in the ``CTEST_PROCESS_<num>_<resource-type>`` environment variable.
:ref:`resource specification file <ctest-resource-specification-file>` and
in the :prop_test:`RESOURCE_GROUPS` property, and they are converted to all
uppercase in the ``CTEST_RESOURCE_GROUP_<num>_<resource-type>`` environment
variable.
See Also
========

View File

@ -1,54 +0,0 @@
PROCESSES
----------
Set to specify the number of processes spawned by a test, and the resources
that they require. See :ref:`hardware allocation <ctest-hardware-allocation>`
for more information on how this property integrates into the CTest hardware
allocation feature.
The ``PROCESSES`` property is a :ref:`semicolon-separated list <CMake Language
Lists>` of process descriptions. Each process description consists of an
optional number of processes for the description followed by a series of
resource requirements for those processes. These requirements (and the number
of processes) are separated by commas. The resource requirements consist of the
name of a resource type, followed by a colon, followed by an unsigned integer
specifying the number of slots required on one resource of the given type.
Please note that these processes are not spawned by CTest. The ``PROCESSES``
property merely tells CTest what processes the test expects to launch. It is up
to the test itself to do this process spawning, and read the :ref:`environment
variables <ctest-hardware-environment-variables>` to determine which resources
each process has been allocated.
Consider the following example:
.. code-block:: cmake
add_test(NAME MyTest COMMAND MyExe)
set_property(TEST MyTest PROPERTY PROCESSES
"2,gpus:2"
"gpus:4,crypto_chips:2")
In this example, there are two process descriptions (implicitly separated by a
semicolon.) The content of the first description is ``2,gpus:2``. This
description spawns 2 processes, each of which requires 2 slots from a single
GPU. The content of the second description is ``gpus:4,crypto_chips:2``. This
description does not specify a process count, so a default of 1 is assumed.
This single process requires 4 slots from a single GPU and 2 slots from a
single cryptography chip. In total, 3 processes are spawned from this test,
each with their own unique requirements.
When CTest sets the :ref:`environment variables
<ctest-hardware-environment-variables>` for a test, it assigns a process number
based on the process description, starting at 0 on the left and the number of
processes minus 1 on the right. For example, in the example above, the two
processes in the first description would have IDs of 0 and 1, and the single
process in the second description would have an ID of 2.
Both the ``PROCESSES`` and :prop_test:`RESOURCE_LOCK` properties serve similar
purposes, but they are distinct and orthogonal. Resources specified by
``PROCESSES`` do not affect :prop_test:`RESOURCE_LOCK`, and vice versa. Whereas
:prop_test:`RESOURCE_LOCK` is a simpler property that is used for locking one
global resource, ``PROCESSES`` is a more advanced property that allows multiple
tests to simultaneously use multiple resources of the same type, specifying
their requirements in a fine-grained manner.

View File

@ -0,0 +1,54 @@
RESOURCE_GROUPS
---------------
Specify resources required by a test, grouped in a way that is meaningful to
the test. See :ref:`resource allocation <ctest-resource-allocation>`
for more information on how this property integrates into the CTest resource
allocation feature.
The ``RESOURCE_GROUPS`` property is a :ref:`semicolon-separated list <CMake
Language Lists>` of group descriptions. Each entry consists of an optional
number of groups using the description followed by a series of resource
requirements for those groups. These requirements (and the number of groups)
are separated by commas. The resource requirements consist of the name of a
resource type, followed by a colon, followed by an unsigned integer
specifying the number of slots required on one resource of the given type.
The ``RESOURCE_GROUPS`` property tells CTest what resources a test expects
to use grouped in a way meaningful to the test. The test itself must read
the :ref:`environment variables <ctest-resource-environment-variables>` to
determine which resources have been allocated to each group. For example,
each group may correspond to a process the test will spawn when executed.
Consider the following example:
.. code-block:: cmake
add_test(NAME MyTest COMMAND MyExe)
set_property(TEST MyTest PROPERTY RESOURCE_GROUPS
"2,gpus:2"
"gpus:4,crypto_chips:2")
In this example, there are two group descriptions (implicitly separated by a
semicolon.) The content of the first description is ``2,gpus:2``. This
description specifies 2 groups, each of which requires 2 slots from a single
GPU. The content of the second description is ``gpus:4,crypto_chips:2``. This
description does not specify a group count, so a default of 1 is assumed.
This single group requires 4 slots from a single GPU and 2 slots from a
single cryptography chip. In total, 3 resource groups are specified for this
test, each with its own unique requirements.
When CTest sets the :ref:`environment variables
<ctest-resource-environment-variables>` for a test, it assigns a group number
based on the group description, starting at 0 on the left and the number of
groups minus 1 on the right. For example, in the example above, the two
groups in the first description would have IDs of 0 and 1, and the single
group in the second description would have an ID of 2.
Both the ``RESOURCE_GROUPS`` and :prop_test:`RESOURCE_LOCK` properties serve
similar purposes, but they are distinct and orthogonal. Resources specified by
``RESOURCE_GROUPS`` do not affect :prop_test:`RESOURCE_LOCK`, and vice versa.
Whereas :prop_test:`RESOURCE_LOCK` is a simpler property that is used for
locking one global resource, ``RESOURCE_GROUPS`` is a more advanced property
that allows multiple tests to simultaneously use multiple resources of the
same type, specifying their requirements in a fine-grained manner.

View File

@ -9,10 +9,10 @@ not to run concurrently.
See also :prop_test:`FIXTURES_REQUIRED` if the resource requires any setup or
cleanup steps.
Both the :prop_test:`PROCESSES` and ``RESOURCE_LOCK`` properties serve similar
purposes, but they are distinct and orthogonal. Resources specified by
:prop_test:`PROCESSES` do not affect ``RESOURCE_LOCK``, and vice versa. Whereas
``RESOURCE_LOCK`` is a simpler property that is used for locking one global
resource, :prop_test:`PROCESSES` is a more advanced property that allows
multiple tests to simultaneously use multiple resources of the same type,
specifying their requirements in a fine-grained manner.
Both the :prop_test:`RESOURCE_GROUPS` and ``RESOURCE_LOCK`` properties serve
similar purposes, but they are distinct and orthogonal. Resources specified by
:prop_test:`RESOURCE_GROUPS` do not affect ``RESOURCE_LOCK``, and vice versa.
Whereas ``RESOURCE_LOCK`` is a simpler property that is used for locking one
global resource, :prop_test:`RESOURCE_GROUPS` is a more advanced property
that allows multiple tests to simultaneously use multiple resources of the
same type, specifying their requirements in a fine-grained manner.

View File

@ -192,8 +192,8 @@ Autogen
CTest
-----
* :manual:`ctest(1)` now has the ability to serialize tests based on hardware
requirements for each test. See :ref:`ctest-hardware-allocation` for
* :manual:`ctest(1)` now has the ability to schedule tests based on resource
requirements for each test. See :ref:`ctest-resource-allocation` for
details.
* A new test property, :prop_test:`SKIP_REGULAR_EXPRESSION`, has been added.

View File

@ -921,14 +921,14 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
CTest/cmCTestGenericHandler.cxx
CTest/cmCTestHandlerCommand.cxx
CTest/cmCTestHardwareAllocator.cxx
CTest/cmCTestHardwareSpec.cxx
CTest/cmCTestResourceAllocator.cxx
CTest/cmCTestResourceSpec.cxx
CTest/cmCTestLaunch.cxx
CTest/cmCTestMemCheckCommand.cxx
CTest/cmCTestMemCheckHandler.cxx
CTest/cmCTestMultiProcessHandler.cxx
CTest/cmCTestProcessesLexerHelper.cxx
CTest/cmCTestReadCustomFilesCommand.cxx
CTest/cmCTestResourceGroupsLexerHelper.cxx
CTest/cmCTestRunScriptCommand.cxx
CTest/cmCTestRunTest.cxx
CTest/cmCTestScriptHandler.cxx
@ -960,9 +960,9 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestP4.cxx
CTest/cmCTestP4.h
LexerParser/cmCTestProcessesLexer.cxx
LexerParser/cmCTestProcessesLexer.h
LexerParser/cmCTestProcessesLexer.in.l
LexerParser/cmCTestResourceGroupsLexer.cxx
LexerParser/cmCTestResourceGroupsLexer.h
LexerParser/cmCTestResourceGroupsLexer.in.l
)
# Build CTestLib

View File

@ -23,7 +23,7 @@ namespace {
/*
* The following algorithm is used to do two things:
*
* 1) Determine if a test's hardware requirements can fit within the hardware
* 1) Determine if a test's resource requirements can fit within the resources
* present on the system, and
* 2) Do the actual allocation
*
@ -34,46 +34,46 @@ namespace {
* more combinations can be tried.
*/
template <typename AllocationStrategy>
static bool AllocateCTestHardware(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
const std::vector<std::string>& hardwareSorted, std::size_t currentIndex,
static bool AllocateCTestResources(
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
const std::vector<std::string>& resourcesSorted, std::size_t currentIndex,
std::vector<cmCTestBinPackerAllocation*>& allocations)
{
// Iterate through all large enough resources until we find a solution
std::size_t hardwareIndex = 0;
while (hardwareIndex < hardwareSorted.size()) {
auto const& resource = hardware.at(hardwareSorted[hardwareIndex]);
std::size_t resourceIndex = 0;
while (resourceIndex < resourcesSorted.size()) {
auto const& resource = resources.at(resourcesSorted[resourceIndex]);
if (resource.Free() >=
static_cast<unsigned int>(allocations[currentIndex]->SlotsNeeded)) {
// Preemptively allocate the resource
allocations[currentIndex]->Id = hardwareSorted[hardwareIndex];
allocations[currentIndex]->Id = resourcesSorted[resourceIndex];
if (currentIndex + 1 >= allocations.size()) {
// We have a solution
return true;
}
// Move the resource up the list until it is sorted again
auto hardware2 = hardware;
auto hardwareSorted2 = hardwareSorted;
hardware2[hardwareSorted2[hardwareIndex]].Locked +=
auto resources2 = resources;
auto resourcesSorted2 = resourcesSorted;
resources2[resourcesSorted2[resourceIndex]].Locked +=
allocations[currentIndex]->SlotsNeeded;
AllocationStrategy::IncrementalSort(hardware2, hardwareSorted2,
hardwareIndex);
AllocationStrategy::IncrementalSort(resources2, resourcesSorted2,
resourceIndex);
// Recurse one level deeper
if (AllocateCTestHardware<AllocationStrategy>(
hardware2, hardwareSorted2, currentIndex + 1, allocations)) {
if (AllocateCTestResources<AllocationStrategy>(
resources2, resourcesSorted2, currentIndex + 1, allocations)) {
return true;
}
}
// No solution found here, deallocate the resource and try the next one
allocations[currentIndex]->Id.clear();
auto freeSlots = hardware.at(hardwareSorted.at(hardwareIndex)).Free();
auto freeSlots = resources.at(resourcesSorted.at(resourceIndex)).Free();
do {
++hardwareIndex;
} while (hardwareIndex < hardwareSorted.size() &&
hardware.at(hardwareSorted.at(hardwareIndex)).Free() ==
++resourceIndex;
} while (resourceIndex < resourcesSorted.size() &&
resources.at(resourcesSorted.at(resourceIndex)).Free() ==
freeSlots);
}
@ -82,8 +82,8 @@ static bool AllocateCTestHardware(
}
template <typename AllocationStrategy>
static bool AllocateCTestHardware(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
static bool AllocateCTestResources(
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<cmCTestBinPackerAllocation>& allocations)
{
// Sort the resource requirements in descending order by slots needed
@ -99,103 +99,105 @@ static bool AllocateCTestHardware(
});
// Sort the resources according to sort strategy
std::vector<std::string> hardwareSorted;
hardwareSorted.reserve(hardware.size());
for (auto const& hw : hardware) {
hardwareSorted.push_back(hw.first);
std::vector<std::string> resourcesSorted;
resourcesSorted.reserve(resources.size());
for (auto const& res : resources) {
resourcesSorted.push_back(res.first);
}
AllocationStrategy::InitialSort(hardware, hardwareSorted);
AllocationStrategy::InitialSort(resources, resourcesSorted);
// Do the actual allocation
return AllocateCTestHardware<AllocationStrategy>(
hardware, hardwareSorted, std::size_t(0), allocationsPtr);
return AllocateCTestResources<AllocationStrategy>(
resources, resourcesSorted, std::size_t(0), allocationsPtr);
}
class RoundRobinAllocationStrategy
{
public:
static void InitialSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
std::vector<std::string>& hardwareSorted);
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<std::string>& resourcesSorted);
static void IncrementalSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
std::vector<std::string>& hardwareSorted, std::size_t lastAllocatedIndex);
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex);
};
void RoundRobinAllocationStrategy::InitialSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
std::vector<std::string>& hardwareSorted)
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<std::string>& resourcesSorted)
{
std::stable_sort(
hardwareSorted.rbegin(), hardwareSorted.rend(),
[&hardware](const std::string& id1, const std::string& id2) {
return hardware.at(id1).Free() < hardware.at(id2).Free();
resourcesSorted.rbegin(), resourcesSorted.rend(),
[&resources](const std::string& id1, const std::string& id2) {
return resources.at(id1).Free() < resources.at(id2).Free();
});
}
void RoundRobinAllocationStrategy::IncrementalSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
std::vector<std::string>& hardwareSorted, std::size_t lastAllocatedIndex)
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex)
{
auto tmp = hardwareSorted[lastAllocatedIndex];
auto tmp = resourcesSorted[lastAllocatedIndex];
std::size_t i = lastAllocatedIndex;
while (i < hardwareSorted.size() - 1 &&
hardware.at(hardwareSorted[i + 1]).Free() > hardware.at(tmp).Free()) {
hardwareSorted[i] = hardwareSorted[i + 1];
while (i < resourcesSorted.size() - 1 &&
resources.at(resourcesSorted[i + 1]).Free() >
resources.at(tmp).Free()) {
resourcesSorted[i] = resourcesSorted[i + 1];
++i;
}
hardwareSorted[i] = tmp;
resourcesSorted[i] = tmp;
}
class BlockAllocationStrategy
{
public:
static void InitialSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
std::vector<std::string>& hardwareSorted);
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<std::string>& resourcesSorted);
static void IncrementalSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
std::vector<std::string>& hardwareSorted, std::size_t lastAllocatedIndex);
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex);
};
void BlockAllocationStrategy::InitialSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
std::vector<std::string>& hardwareSorted)
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<std::string>& resourcesSorted)
{
std::stable_sort(
hardwareSorted.rbegin(), hardwareSorted.rend(),
[&hardware](const std::string& id1, const std::string& id2) {
return hardware.at(id1).Free() < hardware.at(id2).Free();
resourcesSorted.rbegin(), resourcesSorted.rend(),
[&resources](const std::string& id1, const std::string& id2) {
return resources.at(id1).Free() < resources.at(id2).Free();
});
}
void BlockAllocationStrategy::IncrementalSort(
const std::map<std::string, cmCTestHardwareAllocator::Resource>&,
std::vector<std::string>& hardwareSorted, std::size_t lastAllocatedIndex)
const std::map<std::string, cmCTestResourceAllocator::Resource>&,
std::vector<std::string>& resourcesSorted, std::size_t lastAllocatedIndex)
{
auto tmp = hardwareSorted[lastAllocatedIndex];
auto tmp = resourcesSorted[lastAllocatedIndex];
std::size_t i = lastAllocatedIndex;
while (i > 0) {
hardwareSorted[i] = hardwareSorted[i - 1];
resourcesSorted[i] = resourcesSorted[i - 1];
--i;
}
hardwareSorted[i] = tmp;
resourcesSorted[i] = tmp;
}
}
bool cmAllocateCTestHardwareRoundRobin(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
bool cmAllocateCTestResourcesRoundRobin(
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<cmCTestBinPackerAllocation>& allocations)
{
return AllocateCTestHardware<RoundRobinAllocationStrategy>(hardware,
allocations);
return AllocateCTestResources<RoundRobinAllocationStrategy>(resources,
allocations);
}
bool cmAllocateCTestHardwareBlock(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
bool cmAllocateCTestResourcesBlock(
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<cmCTestBinPackerAllocation>& allocations)
{
return AllocateCTestHardware<BlockAllocationStrategy>(hardware, allocations);
return AllocateCTestResources<BlockAllocationStrategy>(resources,
allocations);
}

View File

@ -8,7 +8,7 @@
#include <string>
#include <vector>
#include "cmCTestHardwareAllocator.h"
#include "cmCTestResourceAllocator.h"
struct cmCTestBinPackerAllocation
{
@ -20,12 +20,12 @@ struct cmCTestBinPackerAllocation
bool operator!=(const cmCTestBinPackerAllocation& other) const;
};
bool cmAllocateCTestHardwareRoundRobin(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
bool cmAllocateCTestResourcesRoundRobin(
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<cmCTestBinPackerAllocation>& allocations);
bool cmAllocateCTestHardwareBlock(
const std::map<std::string, cmCTestHardwareAllocator::Resource>& hardware,
bool cmAllocateCTestResourcesBlock(
const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
std::vector<cmCTestBinPackerAllocation>& allocations);
#endif

View File

@ -140,7 +140,7 @@ void cmCTestMultiProcessHandler::RunTests()
assert(this->Completed == this->Total);
assert(this->Tests.empty());
}
assert(this->AllHardwareAvailable());
assert(this->AllResourcesAvailable());
this->MarkFinished();
this->UpdateCostData();
@ -177,9 +177,9 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
}
testRun->SetIndex(test);
testRun->SetTestProperties(this->Properties[test]);
if (this->TestHandler->UseHardwareSpec) {
testRun->SetUseAllocatedHardware(true);
testRun->SetAllocatedHardware(this->AllocatedHardware[test]);
if (this->TestHandler->UseResourceSpec) {
testRun->SetUseAllocatedResources(true);
testRun->SetAllocatedResources(this->AllocatedResources[test]);
}
// Find any failed dependencies for this test. We assume the more common
@ -192,10 +192,10 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
// Always lock the resources we'll be using, even if we fail to set the
// working directory because FinishTestProcess() will try to unlock them
this->AllocateResources(test);
this->LockResources(test);
if (!this->TestsHaveSufficientHardware[test]) {
testRun->StartFailure("Insufficient hardware");
if (!this->TestsHaveSufficientResources[test]) {
testRun->StartFailure("Insufficient resources");
this->FinishTestProcess(testRun, false);
return false;
}
@ -218,26 +218,26 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
return false;
}
bool cmCTestMultiProcessHandler::AllocateHardware(int index)
bool cmCTestMultiProcessHandler::AllocateResources(int index)
{
if (!this->TestHandler->UseHardwareSpec) {
if (!this->TestHandler->UseResourceSpec) {
return true;
}
std::map<std::string, std::vector<cmCTestBinPackerAllocation>> allocations;
if (!this->TryAllocateHardware(index, allocations)) {
if (!this->TryAllocateResources(index, allocations)) {
return false;
}
auto& allocatedHardware = this->AllocatedHardware[index];
allocatedHardware.resize(this->Properties[index]->Processes.size());
auto& allocatedResources = this->AllocatedResources[index];
allocatedResources.resize(this->Properties[index]->ResourceGroups.size());
for (auto const& it : allocations) {
for (auto const& alloc : it.second) {
bool result = this->HardwareAllocator.AllocateResource(
bool result = this->ResourceAllocator.AllocateResource(
it.first, alloc.Id, alloc.SlotsNeeded);
(void)result;
assert(result);
allocatedHardware[alloc.ProcessIndex][it.first].push_back(
allocatedResources[alloc.ProcessIndex][it.first].push_back(
{ alloc.Id, static_cast<unsigned int>(alloc.SlotsNeeded) });
}
}
@ -245,14 +245,14 @@ bool cmCTestMultiProcessHandler::AllocateHardware(int index)
return true;
}
bool cmCTestMultiProcessHandler::TryAllocateHardware(
bool cmCTestMultiProcessHandler::TryAllocateResources(
int index,
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations)
{
allocations.clear();
std::size_t processIndex = 0;
for (auto const& process : this->Properties[index]->Processes) {
for (auto const& process : this->Properties[index]->ResourceGroups) {
for (auto const& requirement : process) {
for (int i = 0; i < requirement.UnitsNeeded; ++i) {
allocations[requirement.ResourceType].push_back(
@ -262,13 +262,13 @@ bool cmCTestMultiProcessHandler::TryAllocateHardware(
++processIndex;
}
auto const& availableHardware = this->HardwareAllocator.GetResources();
auto const& availableResources = this->ResourceAllocator.GetResources();
for (auto& it : allocations) {
if (!availableHardware.count(it.first)) {
if (!availableResources.count(it.first)) {
return false;
}
if (!cmAllocateCTestHardwareRoundRobin(availableHardware.at(it.first),
it.second)) {
if (!cmAllocateCTestResourcesRoundRobin(availableResources.at(it.first),
it.second)) {
return false;
}
}
@ -276,19 +276,19 @@ bool cmCTestMultiProcessHandler::TryAllocateHardware(
return true;
}
void cmCTestMultiProcessHandler::DeallocateHardware(int index)
void cmCTestMultiProcessHandler::DeallocateResources(int index)
{
if (!this->TestHandler->UseHardwareSpec) {
if (!this->TestHandler->UseResourceSpec) {
return;
}
{
auto& allocatedHardware = this->AllocatedHardware[index];
for (auto const& processAlloc : allocatedHardware) {
auto& allocatedResources = this->AllocatedResources[index];
for (auto const& processAlloc : allocatedResources) {
for (auto const& it : processAlloc) {
auto resourceType = it.first;
for (auto const& it2 : it.second) {
bool success = this->HardwareAllocator.DeallocateResource(
bool success = this->ResourceAllocator.DeallocateResource(
resourceType, it2.Id, it2.Slots);
(void)success;
assert(success);
@ -296,12 +296,12 @@ void cmCTestMultiProcessHandler::DeallocateHardware(int index)
}
}
}
this->AllocatedHardware.erase(index);
this->AllocatedResources.erase(index);
}
bool cmCTestMultiProcessHandler::AllHardwareAvailable()
bool cmCTestMultiProcessHandler::AllResourcesAvailable()
{
for (auto const& it : this->HardwareAllocator.GetResources()) {
for (auto const& it : this->ResourceAllocator.GetResources()) {
for (auto const& it2 : it.second) {
if (it2.second.Locked != 0) {
return false;
@ -312,13 +312,13 @@ bool cmCTestMultiProcessHandler::AllHardwareAvailable()
return true;
}
void cmCTestMultiProcessHandler::CheckHardwareAvailable()
void cmCTestMultiProcessHandler::CheckResourcesAvailable()
{
for (auto test : this->SortedTests) {
std::map<std::string, std::vector<cmCTestBinPackerAllocation>> allocations;
this->TestsHaveSufficientHardware[test] =
!this->TestHandler->UseHardwareSpec ||
this->TryAllocateHardware(test, allocations);
this->TestsHaveSufficientResources[test] =
!this->TestHandler->UseResourceSpec ||
this->TryAllocateResources(test, allocations);
}
}
@ -346,7 +346,7 @@ void cmCTestMultiProcessHandler::SetStopTimePassed()
}
}
void cmCTestMultiProcessHandler::AllocateResources(int index)
void cmCTestMultiProcessHandler::LockResources(int index)
{
this->LockedResources.insert(
this->Properties[index]->LockedResources.begin(),
@ -357,7 +357,7 @@ void cmCTestMultiProcessHandler::AllocateResources(int index)
}
}
void cmCTestMultiProcessHandler::DeallocateResources(int index)
void cmCTestMultiProcessHandler::UnlockResources(int index)
{
for (std::string const& i : this->Properties[index]->LockedResources) {
this->LockedResources.erase(i);
@ -404,10 +404,10 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
}
}
// Allocate hardware
if (this->TestsHaveSufficientHardware[test] &&
!this->AllocateHardware(test)) {
this->DeallocateHardware(test);
// Allocate resources
if (this->TestsHaveSufficientResources[test] &&
!this->AllocateResources(test)) {
this->DeallocateResources(test);
return false;
}
@ -417,7 +417,7 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
}
// This test was not able to start because it is waiting
// on depends to run
this->DeallocateHardware(test);
this->DeallocateResources(test);
return false;
}
@ -602,8 +602,8 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
this->TestFinishMap[test] = true;
this->TestRunningMap[test] = false;
this->WriteCheckpoint(test);
this->DeallocateHardware(test);
this->DeallocateResources(test);
this->UnlockResources(test);
this->RunningCount -= GetProcessorsUsed(test);
for (auto p : properties->Affinity) {
@ -912,14 +912,14 @@ static Json::Value DumpTimeoutAfterMatch(
return timeoutAfterMatch;
}
static Json::Value DumpProcessesToJsonArray(
static Json::Value DumpResourceGroupsToJsonArray(
const std::vector<
std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
processes)
resourceGroups)
{
Json::Value jsonProcesses = Json::arrayValue;
for (auto const& it : processes) {
Json::Value jsonProcess = Json::objectValue;
Json::Value jsonResourceGroups = Json::arrayValue;
for (auto const& it : resourceGroups) {
Json::Value jsonResourceGroup = Json::objectValue;
Json::Value requirements = Json::arrayValue;
for (auto const& it2 : it) {
Json::Value res = Json::objectValue;
@ -928,10 +928,10 @@ static Json::Value DumpProcessesToJsonArray(
res["slots"] = it2.SlotsNeeded;
requirements.append(res);
}
jsonProcess["requirements"] = requirements;
jsonProcesses.append(jsonProcess);
jsonResourceGroup["requirements"] = requirements;
jsonResourceGroups.append(jsonResourceGroup);
}
return jsonProcesses;
return jsonResourceGroups;
}
static Json::Value DumpCTestProperty(std::string const& name,
@ -1005,9 +1005,10 @@ static Json::Value DumpCTestProperties(
"PASS_REGULAR_EXPRESSION",
DumpRegExToJsonArray(testProperties.RequiredRegularExpressions)));
}
if (!testProperties.Processes.empty()) {
if (!testProperties.ResourceGroups.empty()) {
properties.append(DumpCTestProperty(
"PROCESSES", DumpProcessesToJsonArray(testProperties.Processes)));
"RESOURCE_GROUPS",
DumpResourceGroupsToJsonArray(testProperties.ResourceGroups)));
}
if (testProperties.WantAffinity) {
properties.append(

View File

@ -14,13 +14,13 @@
#include "cm_uv.h"
#include "cmCTestHardwareAllocator.h"
#include "cmCTestResourceAllocator.h"
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"
class cmCTest;
struct cmCTestBinPackerAllocation;
class cmCTestHardwareSpec;
class cmCTestResourceSpec;
class cmCTestRunTest;
/** \class cmCTestMultiProcessHandler
@ -47,7 +47,7 @@ public:
: public std::map<int, cmCTestTestHandler::cmCTestTestProperties*>
{
};
struct HardwareAllocation
struct ResourceAllocation
{
std::string Id;
unsigned int Slots;
@ -87,12 +87,12 @@ public:
void SetQuiet(bool b) { this->Quiet = b; }
void InitHardwareAllocator(const cmCTestHardwareSpec& spec)
void InitResourceAllocator(const cmCTestResourceSpec& spec)
{
this->HardwareAllocator.InitializeFromHardwareSpec(spec);
this->ResourceAllocator.InitializeFromResourceSpec(spec);
}
void CheckHardwareAvailable();
void CheckResourcesAvailable();
protected:
// Start the next test or tests as many as are allowed by
@ -134,16 +134,16 @@ protected:
bool CheckStopTimePassed();
void SetStopTimePassed();
void AllocateResources(int index);
void DeallocateResources(int index);
void LockResources(int index);
void UnlockResources(int index);
bool AllocateHardware(int index);
bool TryAllocateHardware(
bool AllocateResources(int index);
bool TryAllocateResources(
int index,
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
allocations);
void DeallocateHardware(int index);
bool AllHardwareAvailable();
void DeallocateResources(int index);
bool AllResourcesAvailable();
// map from test number to set of depend tests
TestMap Tests;
@ -166,10 +166,10 @@ protected:
std::vector<std::string> LastTestsFailed;
std::set<std::string> LockedResources;
std::map<int,
std::vector<std::map<std::string, std::vector<HardwareAllocation>>>>
AllocatedHardware;
std::map<int, bool> TestsHaveSufficientHardware;
cmCTestHardwareAllocator HardwareAllocator;
std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
AllocatedResources;
std::map<int, bool> TestsHaveSufficientResources;
cmCTestResourceAllocator ResourceAllocator;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
unsigned long TestLoad;

View File

@ -1,55 +0,0 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestProcessesLexerHelper.h"
#include "cmCTestProcessesLexer.h"
#include "cmCTestTestHandler.h"
cmCTestProcessesLexerHelper::cmCTestProcessesLexerHelper(
std::vector<std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
output)
: Output(output)
{
}
bool cmCTestProcessesLexerHelper::ParseString(const std::string& value)
{
yyscan_t lexer;
cmCTestProcesses_yylex_init_extra(this, &lexer);
auto state = cmCTestProcesses_yy_scan_string(value.c_str(), lexer);
int retval = cmCTestProcesses_yylex(lexer);
cmCTestProcesses_yy_delete_buffer(state, lexer);
cmCTestProcesses_yylex_destroy(lexer);
return retval == 0;
}
void cmCTestProcessesLexerHelper::SetProcessCount(unsigned int count)
{
this->ProcessCount = count;
}
void cmCTestProcessesLexerHelper::SetResourceType(const std::string& type)
{
this->ResourceType = type;
}
void cmCTestProcessesLexerHelper::SetNeededSlots(int count)
{
this->NeededSlots = count;
}
void cmCTestProcessesLexerHelper::WriteRequirement()
{
this->Process.push_back({ this->ResourceType, this->NeededSlots, 1 });
}
void cmCTestProcessesLexerHelper::WriteProcess()
{
for (unsigned int i = 0; i < this->ProcessCount; ++i) {
this->Output.push_back(this->Process);
}
this->Process.clear();
this->ProcessCount = 1;
}

View File

@ -1,15 +1,15 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestHardwareAllocator.h"
#include "cmCTestResourceAllocator.h"
#include <utility>
#include <vector>
#include "cmCTestHardwareSpec.h"
#include "cmCTestResourceSpec.h"
void cmCTestHardwareAllocator::InitializeFromHardwareSpec(
const cmCTestHardwareSpec& spec)
void cmCTestResourceAllocator::InitializeFromResourceSpec(
const cmCTestResourceSpec& spec)
{
this->Resources.clear();
@ -23,13 +23,13 @@ void cmCTestHardwareAllocator::InitializeFromHardwareSpec(
}
const std::map<std::string,
std::map<std::string, cmCTestHardwareAllocator::Resource>>&
cmCTestHardwareAllocator::GetResources() const
std::map<std::string, cmCTestResourceAllocator::Resource>>&
cmCTestResourceAllocator::GetResources() const
{
return this->Resources;
}
bool cmCTestHardwareAllocator::AllocateResource(const std::string& name,
bool cmCTestResourceAllocator::AllocateResource(const std::string& name,
const std::string& id,
unsigned int slots)
{
@ -51,7 +51,7 @@ bool cmCTestHardwareAllocator::AllocateResource(const std::string& name,
return true;
}
bool cmCTestHardwareAllocator::DeallocateResource(const std::string& name,
bool cmCTestResourceAllocator::DeallocateResource(const std::string& name,
const std::string& id,
unsigned int slots)
{
@ -73,13 +73,13 @@ bool cmCTestHardwareAllocator::DeallocateResource(const std::string& name,
return true;
}
bool cmCTestHardwareAllocator::Resource::operator==(
bool cmCTestResourceAllocator::Resource::operator==(
const Resource& other) const
{
return this->Total == other.Total && this->Locked == other.Locked;
}
bool cmCTestHardwareAllocator::Resource::operator!=(
bool cmCTestResourceAllocator::Resource::operator!=(
const Resource& other) const
{
return !(*this == other);

View File

@ -1,14 +1,14 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmCTestHardwareAllocator_h
#define cmCTestHardwareAllocator_h
#ifndef cmCTestResourceAllocator_h
#define cmCTestResourceAllocator_h
#include <map>
#include <string>
class cmCTestHardwareSpec;
class cmCTestResourceSpec;
class cmCTestHardwareAllocator
class cmCTestResourceAllocator
{
public:
struct Resource
@ -22,7 +22,7 @@ public:
bool operator!=(const Resource& other) const;
};
void InitializeFromHardwareSpec(const cmCTestHardwareSpec& spec);
void InitializeFromResourceSpec(const cmCTestResourceSpec& spec);
const std::map<std::string, std::map<std::string, Resource>>& GetResources()
const;

View File

@ -0,0 +1,55 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestResourceGroupsLexerHelper.h"
#include "cmCTestResourceGroupsLexer.h"
#include "cmCTestTestHandler.h"
cmCTestResourceGroupsLexerHelper::cmCTestResourceGroupsLexerHelper(
std::vector<std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
output)
: Output(output)
{
}
bool cmCTestResourceGroupsLexerHelper::ParseString(const std::string& value)
{
yyscan_t lexer;
cmCTestResourceGroups_yylex_init_extra(this, &lexer);
auto state = cmCTestResourceGroups_yy_scan_string(value.c_str(), lexer);
int retval = cmCTestResourceGroups_yylex(lexer);
cmCTestResourceGroups_yy_delete_buffer(state, lexer);
cmCTestResourceGroups_yylex_destroy(lexer);
return retval == 0;
}
void cmCTestResourceGroupsLexerHelper::SetProcessCount(unsigned int count)
{
this->ProcessCount = count;
}
void cmCTestResourceGroupsLexerHelper::SetResourceType(const std::string& type)
{
this->ResourceType = type;
}
void cmCTestResourceGroupsLexerHelper::SetNeededSlots(int count)
{
this->NeededSlots = count;
}
void cmCTestResourceGroupsLexerHelper::WriteRequirement()
{
this->Process.push_back({ this->ResourceType, this->NeededSlots, 1 });
}
void cmCTestResourceGroupsLexerHelper::WriteProcess()
{
for (unsigned int i = 0; i < this->ProcessCount; ++i) {
this->Output.push_back(this->Process);
}
this->Process.clear();
this->ProcessCount = 1;
}

View File

@ -1,25 +1,25 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmCTestProcessesLexerHelper_h
#define cmCTestProcessesLexerHelper_h
#ifndef cmCTestResourceGroupsLexerHelper_h
#define cmCTestResourceGroupsLexerHelper_h
#include <string>
#include <vector>
#include "cmCTestTestHandler.h"
class cmCTestProcessesLexerHelper
class cmCTestResourceGroupsLexerHelper
{
public:
struct ParserType
{
};
cmCTestProcessesLexerHelper(
cmCTestResourceGroupsLexerHelper(
std::vector<
std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>&
output);
~cmCTestProcessesLexerHelper() = default;
~cmCTestResourceGroupsLexerHelper() = default;
bool ParseString(const std::string& value);
@ -39,6 +39,6 @@ private:
std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement> Process;
};
#define YY_EXTRA_TYPE cmCTestProcessesLexerHelper*
#define YY_EXTRA_TYPE cmCTestResourceGroupsLexerHelper*
#endif

View File

@ -1,6 +1,6 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestHardwareSpec.h"
#include "cmCTestResourceSpec.h"
#include <map>
#include <string>
@ -16,7 +16,7 @@
static const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
static const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
bool cmCTestHardwareSpec::ReadFromJSONFile(const std::string& filename)
bool cmCTestResourceSpec::ReadFromJSONFile(const std::string& filename)
{
cmsys::ifstream fin(filename.c_str());
if (!fin) {
@ -50,7 +50,7 @@ bool cmCTestHardwareSpec::ReadFromJSONFile(const std::string& filename)
if (!localSocket.isObject()) {
return false;
}
std::map<std::string, std::vector<cmCTestHardwareSpec::Resource>> resources;
std::map<std::string, std::vector<cmCTestResourceSpec::Resource>> resources;
cmsys::RegularExpressionMatch match;
for (auto const& key : localSocket.getMemberNames()) {
if (IdentifierRegex.find(key.c_str(), match)) {
@ -59,7 +59,7 @@ bool cmCTestHardwareSpec::ReadFromJSONFile(const std::string& filename)
if (value.isArray()) {
for (auto const& item : value) {
if (item.isObject()) {
cmCTestHardwareSpec::Resource resource;
cmCTestResourceSpec::Resource resource;
if (!item.isMember("id")) {
return false;
@ -98,36 +98,36 @@ bool cmCTestHardwareSpec::ReadFromJSONFile(const std::string& filename)
return true;
}
bool cmCTestHardwareSpec::operator==(const cmCTestHardwareSpec& other) const
bool cmCTestResourceSpec::operator==(const cmCTestResourceSpec& other) const
{
return this->LocalSocket == other.LocalSocket;
}
bool cmCTestHardwareSpec::operator!=(const cmCTestHardwareSpec& other) const
bool cmCTestResourceSpec::operator!=(const cmCTestResourceSpec& other) const
{
return !(*this == other);
}
bool cmCTestHardwareSpec::Socket::operator==(
const cmCTestHardwareSpec::Socket& other) const
bool cmCTestResourceSpec::Socket::operator==(
const cmCTestResourceSpec::Socket& other) const
{
return this->Resources == other.Resources;
}
bool cmCTestHardwareSpec::Socket::operator!=(
const cmCTestHardwareSpec::Socket& other) const
bool cmCTestResourceSpec::Socket::operator!=(
const cmCTestResourceSpec::Socket& other) const
{
return !(*this == other);
}
bool cmCTestHardwareSpec::Resource::operator==(
const cmCTestHardwareSpec::Resource& other) const
bool cmCTestResourceSpec::Resource::operator==(
const cmCTestResourceSpec::Resource& other) const
{
return this->Id == other.Id && this->Capacity == other.Capacity;
}
bool cmCTestHardwareSpec::Resource::operator!=(
const cmCTestHardwareSpec::Resource& other) const
bool cmCTestResourceSpec::Resource::operator!=(
const cmCTestResourceSpec::Resource& other) const
{
return !(*this == other);
}

View File

@ -1,13 +1,13 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#ifndef cmCTestHardwareSpec_h
#define cmCTestHardwareSpec_h
#ifndef cmCTestResourceSpec_h
#define cmCTestResourceSpec_h
#include <map>
#include <string>
#include <vector>
class cmCTestHardwareSpec
class cmCTestResourceSpec
{
public:
class Resource
@ -33,8 +33,8 @@ public:
bool ReadFromJSONFile(const std::string& filename);
bool operator==(const cmCTestHardwareSpec& other) const;
bool operator!=(const cmCTestHardwareSpec& other) const;
bool operator==(const cmCTestResourceSpec& other) const;
bool operator!=(const cmCTestResourceSpec& other) const;
};
#endif

View File

@ -691,25 +691,25 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
cmSystemTools::AppendEnv(*environment);
}
if (this->UseAllocatedHardware) {
this->SetupHardwareEnvironment();
if (this->UseAllocatedResources) {
this->SetupResourcesEnvironment();
} else {
cmSystemTools::UnsetEnv("CTEST_PROCESS_COUNT");
cmSystemTools::UnsetEnv("CTEST_RESOURCE_GROUP_COUNT");
}
return this->TestProcess->StartProcess(this->MultiTestHandler.Loop,
affinity);
}
void cmCTestRunTest::SetupHardwareEnvironment()
void cmCTestRunTest::SetupResourcesEnvironment()
{
std::string processCount = "CTEST_PROCESS_COUNT=";
processCount += std::to_string(this->AllocatedHardware.size());
std::string processCount = "CTEST_RESOURCE_GROUP_COUNT=";
processCount += std::to_string(this->AllocatedResources.size());
cmSystemTools::PutEnv(processCount);
std::size_t i = 0;
for (auto const& process : this->AllocatedHardware) {
std::string prefix = "CTEST_PROCESS_";
for (auto const& process : this->AllocatedResources) {
std::string prefix = "CTEST_RESOURCE_GROUP_";
prefix += std::to_string(i);
std::string resourceList = prefix + '=';
prefix += '_';

View File

@ -88,14 +88,17 @@ public:
bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
void SetUseAllocatedHardware(bool use) { this->UseAllocatedHardware = use; }
void SetAllocatedHardware(
void SetUseAllocatedResources(bool use)
{
this->UseAllocatedResources = use;
}
void SetAllocatedResources(
const std::vector<
std::map<std::string,
std::vector<cmCTestMultiProcessHandler::HardwareAllocation>>>&
hardware)
std::vector<cmCTestMultiProcessHandler::ResourceAllocation>>>&
resources)
{
this->AllocatedHardware = hardware;
this->AllocatedResources = resources;
}
private:
@ -109,7 +112,7 @@ private:
// Run post processing of the process output for MemCheck
void MemCheckPostProcess();
void SetupHardwareEnvironment();
void SetupResourcesEnvironment();
// Returns "completed/total Test #Index: "
std::string GetTestPrefix(size_t completed, size_t total) const;
@ -129,10 +132,10 @@ private:
std::string StartTime;
std::string ActualCommand;
std::vector<std::string> Arguments;
bool UseAllocatedHardware = false;
bool UseAllocatedResources = false;
std::vector<std::map<
std::string, std::vector<cmCTestMultiProcessHandler::HardwareAllocation>>>
AllocatedHardware;
std::string, std::vector<cmCTestMultiProcessHandler::ResourceAllocation>>>
AllocatedResources;
cmCTest::Rerun RerunMode = cmCTest::Rerun::Never;
int NumberOfRunsLeft = 1; // default to 1 run of the test
int NumberOfRunsTotal = 1; // default to 1 run of the test

View File

@ -32,7 +32,7 @@ void cmCTestTestCommand::BindArguments()
this->Bind("SCHEDULE_RANDOM"_s, this->ScheduleRandom);
this->Bind("STOP_TIME"_s, this->StopTime);
this->Bind("TEST_LOAD"_s, this->TestLoad);
this->Bind("HARDWARE_SPEC_FILE"_s, this->HardwareSpecFile);
this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@ -88,8 +88,8 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
if (!this->ScheduleRandom.empty()) {
handler->SetOption("ScheduleRandom", this->ScheduleRandom.c_str());
}
if (!this->HardwareSpecFile.empty()) {
handler->SetOption("HardwareSpecFile", this->HardwareSpecFile.c_str());
if (!this->ResourceSpecFile.empty()) {
handler->SetOption("ResourceSpecFile", this->ResourceSpecFile.c_str());
}
if (!this->StopTime.empty()) {
this->CTest->SetStopTime(this->StopTime);

View File

@ -58,7 +58,7 @@ protected:
std::string ScheduleRandom;
std::string StopTime;
std::string TestLoad;
std::string HardwareSpecFile;
std::string ResourceSpecFile;
};
#endif

View File

@ -29,7 +29,7 @@
#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestProcessesLexerHelper.h"
#include "cmCTestResourceGroupsLexerHelper.h"
#include "cmDuration.h"
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
@ -289,7 +289,7 @@ cmCTestTestHandler::cmCTestTestHandler()
this->UseIncludeRegExpFlag = false;
this->UseExcludeRegExpFlag = false;
this->UseExcludeRegExpFirst = false;
this->UseHardwareSpec = false;
this->UseResourceSpec = false;
this->CustomMaximumPassedTestOutputSize = 1 * 1024;
this->CustomMaximumFailedTestOutputSize = 300 * 1024;
@ -510,12 +510,12 @@ bool cmCTestTestHandler::ProcessOptions()
}
this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
val = this->GetOption("HardwareSpecFile");
val = this->GetOption("ResourceSpecFile");
if (val) {
this->UseHardwareSpec = true;
if (!this->HardwareSpec.ReadFromJSONFile(val)) {
this->UseResourceSpec = true;
if (!this->ResourceSpec.ReadFromJSONFile(val)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Could not read hardware spec file: " << val << std::endl);
"Could not read resource spec file: " << val << std::endl);
return false;
}
}
@ -1237,8 +1237,8 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->SetTestLoad(this->CTest->GetTestLoad());
}
if (this->UseHardwareSpec) {
parallel->InitHardwareAllocator(this->HardwareSpec);
if (this->UseResourceSpec) {
parallel->InitResourceAllocator(this->ResourceSpec);
}
*this->LogFile
@ -1283,7 +1283,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
parallel->SetPassFailVectors(&passed, &failed);
this->TestResults.clear();
parallel->SetTestResults(&this->TestResults);
parallel->CheckHardwareAvailable();
parallel->CheckResourcesAvailable();
if (this->CTest->ShouldPrintLabels()) {
parallel->PrintLabels();
@ -1626,11 +1626,11 @@ std::string cmCTestTestHandler::FindExecutable(
return fullPath;
}
bool cmCTestTestHandler::ParseProcessesProperty(
bool cmCTestTestHandler::ParseResourceGroupsProperty(
const std::string& val,
std::vector<std::vector<cmCTestTestResourceRequirement>>& processes)
std::vector<std::vector<cmCTestTestResourceRequirement>>& resourceGroups)
{
cmCTestProcessesLexerHelper lexer(processes);
cmCTestResourceGroupsLexerHelper lexer(resourceGroups);
return lexer.ParseString(val);
}
@ -2203,8 +2203,8 @@ bool cmCTestTestHandler::SetTestsProperties(
if (key == "PROCESSOR_AFFINITY") {
rt.WantAffinity = cmIsOn(val);
}
if (key == "PROCESSES") {
if (!ParseProcessesProperty(val, rt.Processes)) {
if (key == "RESOURCE_GROUPS") {
if (!ParseResourceGroupsProperty(val, rt.ResourceGroups)) {
return false;
}
}

View File

@ -19,7 +19,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmCTestGenericHandler.h"
#include "cmCTestHardwareSpec.h"
#include "cmCTestResourceSpec.h"
#include "cmDuration.h"
#include "cmListFileCache.h"
@ -158,7 +158,7 @@ public:
std::set<std::string> FixturesCleanup;
std::set<std::string> FixturesRequired;
std::set<std::string> RequireSuccessDepends;
std::vector<std::vector<cmCTestTestResourceRequirement>> Processes;
std::vector<std::vector<cmCTestTestResourceRequirement>> ResourceGroups;
// Private test generator properties used to track backtraces
cmListFileBacktrace Backtrace;
};
@ -202,9 +202,9 @@ public:
std::vector<std::string>& extraPaths,
std::vector<std::string>& failed);
static bool ParseProcessesProperty(
static bool ParseResourceGroupsProperty(
const std::string& val,
std::vector<std::vector<cmCTestTestResourceRequirement>>& processes);
std::vector<std::vector<cmCTestTestResourceRequirement>>& resourceGroups);
using ListOfTests = std::vector<cmCTestTestProperties>;
@ -336,8 +336,8 @@ private:
cmsys::RegularExpression IncludeTestsRegularExpression;
cmsys::RegularExpression ExcludeTestsRegularExpression;
bool UseHardwareSpec;
cmCTestHardwareSpec HardwareSpec;
bool UseResourceSpec;
cmCTestResourceSpec ResourceSpec;
void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart);
cmsys::RegularExpression DartStuff1;

View File

@ -2,8 +2,8 @@
/cmCommandArgumentLexer.h generated
/cmCommandArgumentParser.cxx generated
/cmCommandArgumentParserTokens.h generated
/cmCTestProcessesLexer.cxx generated
/cmCTestProcessesLexer.h generated
/cmCTestResourceGroupsLexer.cxx generated
/cmCTestResourceGroupsLexer.h generated
/cmDependsJavaLexer.cxx generated
/cmDependsJavaLexer.h generated
/cmDependsJavaParser.cxx generated

View File

@ -14,213 +14,213 @@
#endif
#ifdef yy_create_buffer
#define cmCTestProcesses_yy_create_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_create_buffer_ALREADY_DEFINED
#else
#define yy_create_buffer cmCTestProcesses_yy_create_buffer
#define yy_create_buffer cmCTestResourceGroups_yy_create_buffer
#endif
#ifdef yy_delete_buffer
#define cmCTestProcesses_yy_delete_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_delete_buffer_ALREADY_DEFINED
#else
#define yy_delete_buffer cmCTestProcesses_yy_delete_buffer
#define yy_delete_buffer cmCTestResourceGroups_yy_delete_buffer
#endif
#ifdef yy_scan_buffer
#define cmCTestProcesses_yy_scan_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_scan_buffer_ALREADY_DEFINED
#else
#define yy_scan_buffer cmCTestProcesses_yy_scan_buffer
#define yy_scan_buffer cmCTestResourceGroups_yy_scan_buffer
#endif
#ifdef yy_scan_string
#define cmCTestProcesses_yy_scan_string_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_scan_string_ALREADY_DEFINED
#else
#define yy_scan_string cmCTestProcesses_yy_scan_string
#define yy_scan_string cmCTestResourceGroups_yy_scan_string
#endif
#ifdef yy_scan_bytes
#define cmCTestProcesses_yy_scan_bytes_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_scan_bytes_ALREADY_DEFINED
#else
#define yy_scan_bytes cmCTestProcesses_yy_scan_bytes
#define yy_scan_bytes cmCTestResourceGroups_yy_scan_bytes
#endif
#ifdef yy_init_buffer
#define cmCTestProcesses_yy_init_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_init_buffer_ALREADY_DEFINED
#else
#define yy_init_buffer cmCTestProcesses_yy_init_buffer
#define yy_init_buffer cmCTestResourceGroups_yy_init_buffer
#endif
#ifdef yy_flush_buffer
#define cmCTestProcesses_yy_flush_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_flush_buffer_ALREADY_DEFINED
#else
#define yy_flush_buffer cmCTestProcesses_yy_flush_buffer
#define yy_flush_buffer cmCTestResourceGroups_yy_flush_buffer
#endif
#ifdef yy_load_buffer_state
#define cmCTestProcesses_yy_load_buffer_state_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_load_buffer_state_ALREADY_DEFINED
#else
#define yy_load_buffer_state cmCTestProcesses_yy_load_buffer_state
#define yy_load_buffer_state cmCTestResourceGroups_yy_load_buffer_state
#endif
#ifdef yy_switch_to_buffer
#define cmCTestProcesses_yy_switch_to_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_switch_to_buffer_ALREADY_DEFINED
#else
#define yy_switch_to_buffer cmCTestProcesses_yy_switch_to_buffer
#define yy_switch_to_buffer cmCTestResourceGroups_yy_switch_to_buffer
#endif
#ifdef yypush_buffer_state
#define cmCTestProcesses_yypush_buffer_state_ALREADY_DEFINED
#define cmCTestResourceGroups_yypush_buffer_state_ALREADY_DEFINED
#else
#define yypush_buffer_state cmCTestProcesses_yypush_buffer_state
#define yypush_buffer_state cmCTestResourceGroups_yypush_buffer_state
#endif
#ifdef yypop_buffer_state
#define cmCTestProcesses_yypop_buffer_state_ALREADY_DEFINED
#define cmCTestResourceGroups_yypop_buffer_state_ALREADY_DEFINED
#else
#define yypop_buffer_state cmCTestProcesses_yypop_buffer_state
#define yypop_buffer_state cmCTestResourceGroups_yypop_buffer_state
#endif
#ifdef yyensure_buffer_stack
#define cmCTestProcesses_yyensure_buffer_stack_ALREADY_DEFINED
#define cmCTestResourceGroups_yyensure_buffer_stack_ALREADY_DEFINED
#else
#define yyensure_buffer_stack cmCTestProcesses_yyensure_buffer_stack
#define yyensure_buffer_stack cmCTestResourceGroups_yyensure_buffer_stack
#endif
#ifdef yylex
#define cmCTestProcesses_yylex_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_ALREADY_DEFINED
#else
#define yylex cmCTestProcesses_yylex
#define yylex cmCTestResourceGroups_yylex
#endif
#ifdef yyrestart
#define cmCTestProcesses_yyrestart_ALREADY_DEFINED
#define cmCTestResourceGroups_yyrestart_ALREADY_DEFINED
#else
#define yyrestart cmCTestProcesses_yyrestart
#define yyrestart cmCTestResourceGroups_yyrestart
#endif
#ifdef yylex_init
#define cmCTestProcesses_yylex_init_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_init_ALREADY_DEFINED
#else
#define yylex_init cmCTestProcesses_yylex_init
#define yylex_init cmCTestResourceGroups_yylex_init
#endif
#ifdef yylex_init_extra
#define cmCTestProcesses_yylex_init_extra_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_init_extra_ALREADY_DEFINED
#else
#define yylex_init_extra cmCTestProcesses_yylex_init_extra
#define yylex_init_extra cmCTestResourceGroups_yylex_init_extra
#endif
#ifdef yylex_destroy
#define cmCTestProcesses_yylex_destroy_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_destroy_ALREADY_DEFINED
#else
#define yylex_destroy cmCTestProcesses_yylex_destroy
#define yylex_destroy cmCTestResourceGroups_yylex_destroy
#endif
#ifdef yyget_debug
#define cmCTestProcesses_yyget_debug_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_debug_ALREADY_DEFINED
#else
#define yyget_debug cmCTestProcesses_yyget_debug
#define yyget_debug cmCTestResourceGroups_yyget_debug
#endif
#ifdef yyset_debug
#define cmCTestProcesses_yyset_debug_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_debug_ALREADY_DEFINED
#else
#define yyset_debug cmCTestProcesses_yyset_debug
#define yyset_debug cmCTestResourceGroups_yyset_debug
#endif
#ifdef yyget_extra
#define cmCTestProcesses_yyget_extra_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_extra_ALREADY_DEFINED
#else
#define yyget_extra cmCTestProcesses_yyget_extra
#define yyget_extra cmCTestResourceGroups_yyget_extra
#endif
#ifdef yyset_extra
#define cmCTestProcesses_yyset_extra_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_extra_ALREADY_DEFINED
#else
#define yyset_extra cmCTestProcesses_yyset_extra
#define yyset_extra cmCTestResourceGroups_yyset_extra
#endif
#ifdef yyget_in
#define cmCTestProcesses_yyget_in_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_in_ALREADY_DEFINED
#else
#define yyget_in cmCTestProcesses_yyget_in
#define yyget_in cmCTestResourceGroups_yyget_in
#endif
#ifdef yyset_in
#define cmCTestProcesses_yyset_in_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_in_ALREADY_DEFINED
#else
#define yyset_in cmCTestProcesses_yyset_in
#define yyset_in cmCTestResourceGroups_yyset_in
#endif
#ifdef yyget_out
#define cmCTestProcesses_yyget_out_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_out_ALREADY_DEFINED
#else
#define yyget_out cmCTestProcesses_yyget_out
#define yyget_out cmCTestResourceGroups_yyget_out
#endif
#ifdef yyset_out
#define cmCTestProcesses_yyset_out_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_out_ALREADY_DEFINED
#else
#define yyset_out cmCTestProcesses_yyset_out
#define yyset_out cmCTestResourceGroups_yyset_out
#endif
#ifdef yyget_leng
#define cmCTestProcesses_yyget_leng_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_leng_ALREADY_DEFINED
#else
#define yyget_leng cmCTestProcesses_yyget_leng
#define yyget_leng cmCTestResourceGroups_yyget_leng
#endif
#ifdef yyget_text
#define cmCTestProcesses_yyget_text_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_text_ALREADY_DEFINED
#else
#define yyget_text cmCTestProcesses_yyget_text
#define yyget_text cmCTestResourceGroups_yyget_text
#endif
#ifdef yyget_lineno
#define cmCTestProcesses_yyget_lineno_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_lineno_ALREADY_DEFINED
#else
#define yyget_lineno cmCTestProcesses_yyget_lineno
#define yyget_lineno cmCTestResourceGroups_yyget_lineno
#endif
#ifdef yyset_lineno
#define cmCTestProcesses_yyset_lineno_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_lineno_ALREADY_DEFINED
#else
#define yyset_lineno cmCTestProcesses_yyset_lineno
#define yyset_lineno cmCTestResourceGroups_yyset_lineno
#endif
#ifdef yyget_column
#define cmCTestProcesses_yyget_column_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_column_ALREADY_DEFINED
#else
#define yyget_column cmCTestProcesses_yyget_column
#define yyget_column cmCTestResourceGroups_yyget_column
#endif
#ifdef yyset_column
#define cmCTestProcesses_yyset_column_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_column_ALREADY_DEFINED
#else
#define yyset_column cmCTestProcesses_yyset_column
#define yyset_column cmCTestResourceGroups_yyset_column
#endif
#ifdef yywrap
#define cmCTestProcesses_yywrap_ALREADY_DEFINED
#define cmCTestResourceGroups_yywrap_ALREADY_DEFINED
#else
#define yywrap cmCTestProcesses_yywrap
#define yywrap cmCTestResourceGroups_yywrap
#endif
#ifdef yyalloc
#define cmCTestProcesses_yyalloc_ALREADY_DEFINED
#define cmCTestResourceGroups_yyalloc_ALREADY_DEFINED
#else
#define yyalloc cmCTestProcesses_yyalloc
#define yyalloc cmCTestResourceGroups_yyalloc
#endif
#ifdef yyrealloc
#define cmCTestProcesses_yyrealloc_ALREADY_DEFINED
#define cmCTestResourceGroups_yyrealloc_ALREADY_DEFINED
#else
#define yyrealloc cmCTestProcesses_yyrealloc
#define yyrealloc cmCTestResourceGroups_yyrealloc
#endif
#ifdef yyfree
#define cmCTestProcesses_yyfree_ALREADY_DEFINED
#define cmCTestResourceGroups_yyfree_ALREADY_DEFINED
#else
#define yyfree cmCTestProcesses_yyfree
#define yyfree cmCTestResourceGroups_yyfree
#endif
/* First, we deal with platform-specific or compiler-specific issues. */
@ -526,7 +526,7 @@ void yyfree ( void * , yyscan_t yyscanner );
/* Begin user sect3 */
#define cmCTestProcesses_yywrap(yyscanner) (/*CONSTCOND*/1)
#define cmCTestResourceGroups_yywrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
typedef flex_uint8_t YY_CHAR;
@ -648,12 +648,12 @@ This file must be translated to C++ and modified to build everywhere.
Run flex >= 2.6 like this:
flex --nounistd -DFLEXINT_H --noline --header-file=cmCTestProcessesLexer.h -ocmCTestProcessesLexer.cxx cmCTestProcessesLexer.in.l
flex --nounistd -DFLEXINT_H --noline --header-file=cmCTestResourceGroupsLexer.h -ocmCTestResourceGroupsLexer.cxx cmCTestResourceGroupsLexer.in.l
Modify cmCTestProcessesLexer.cxx:
- remove trailing whitespace: sed -i 's/\s*$//' cmCTestProcessesLexer.h cmCTestProcessesLexer.cxx
- remove blank lines at end of file: sed -i '${/^$/d;}' cmCTestProcessesLexer.h cmCTestProcessesLexer.cxx
- #include "cmStandardLexer.h" at the top: sed -i '1i#include "cmStandardLexer.h"' cmCTestProcessesLexer.cxx
Modify cmCTestResourceGroupsLexer.cxx:
- remove trailing whitespace: sed -i 's/\s*$//' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
- remove blank lines at end of file: sed -i '${/^$/d;}' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
- #include "cmStandardLexer.h" at the top: sed -i '1i#include "cmStandardLexer.h"' cmCTestResourceGroupsLexer.cxx
*/
@ -661,7 +661,7 @@ Modify cmCTestProcessesLexer.cxx:
#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
#include "cmCTestProcessesLexerHelper.h"
#include "cmCTestResourceGroupsLexerHelper.h"
#include <string>
@ -670,8 +670,8 @@ Modify cmCTestProcessesLexer.cxx:
/*--------------------------------------------------------------------------*/
#define INITIAL 0
#define PROCESSES_START 1
#define PROCESSES_END 2
#define RESOURCE_GROUPS_START 1
#define RESOURCE_GROUPS_END 2
#define RESOURCE_START 3
#define RESOURCE_COUNT 4
#define RESOURCE_END 5
@ -990,7 +990,7 @@ YY_RULE_SETUP
case 2:
YY_RULE_SETUP
{
BEGIN(PROCESSES_END);
BEGIN(RESOURCE_GROUPS_END);
std::size_t len = yyleng;
yyextra->SetProcessCount(std::stoll(yytext, &len, 10));
}
@ -1013,18 +1013,18 @@ YY_RULE_SETUP
case 5:
YY_RULE_SETUP
{
BEGIN(PROCESSES_START);
BEGIN(RESOURCE_GROUPS_START);
}
YY_BREAK
case 6:
YY_RULE_SETUP
{
BEGIN(PROCESSES_START);
BEGIN(RESOURCE_GROUPS_START);
yyextra->WriteProcess();
}
YY_BREAK
case YY_STATE_EOF(RESOURCE_START):
case YY_STATE_EOF(PROCESSES_END):
case YY_STATE_EOF(RESOURCE_GROUPS_END):
case YY_STATE_EOF(RESOURCE_END):
{
yyextra->WriteProcess();
@ -1032,7 +1032,7 @@ case YY_STATE_EOF(RESOURCE_END):
}
YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(PROCESSES_START):
case YY_STATE_EOF(RESOURCE_GROUPS_START):
{
return 0;
}

View File

@ -1,6 +1,6 @@
#ifndef cmCTestProcesses_yyHEADER_H
#define cmCTestProcesses_yyHEADER_H 1
#define cmCTestProcesses_yyIN_HEADER 1
#ifndef cmCTestResourceGroups_yyHEADER_H
#define cmCTestResourceGroups_yyHEADER_H 1
#define cmCTestResourceGroups_yyIN_HEADER 1
#define FLEXINT_H 1
#define YY_INT_ALIGNED short int
@ -16,213 +16,213 @@
#endif
#ifdef yy_create_buffer
#define cmCTestProcesses_yy_create_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_create_buffer_ALREADY_DEFINED
#else
#define yy_create_buffer cmCTestProcesses_yy_create_buffer
#define yy_create_buffer cmCTestResourceGroups_yy_create_buffer
#endif
#ifdef yy_delete_buffer
#define cmCTestProcesses_yy_delete_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_delete_buffer_ALREADY_DEFINED
#else
#define yy_delete_buffer cmCTestProcesses_yy_delete_buffer
#define yy_delete_buffer cmCTestResourceGroups_yy_delete_buffer
#endif
#ifdef yy_scan_buffer
#define cmCTestProcesses_yy_scan_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_scan_buffer_ALREADY_DEFINED
#else
#define yy_scan_buffer cmCTestProcesses_yy_scan_buffer
#define yy_scan_buffer cmCTestResourceGroups_yy_scan_buffer
#endif
#ifdef yy_scan_string
#define cmCTestProcesses_yy_scan_string_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_scan_string_ALREADY_DEFINED
#else
#define yy_scan_string cmCTestProcesses_yy_scan_string
#define yy_scan_string cmCTestResourceGroups_yy_scan_string
#endif
#ifdef yy_scan_bytes
#define cmCTestProcesses_yy_scan_bytes_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_scan_bytes_ALREADY_DEFINED
#else
#define yy_scan_bytes cmCTestProcesses_yy_scan_bytes
#define yy_scan_bytes cmCTestResourceGroups_yy_scan_bytes
#endif
#ifdef yy_init_buffer
#define cmCTestProcesses_yy_init_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_init_buffer_ALREADY_DEFINED
#else
#define yy_init_buffer cmCTestProcesses_yy_init_buffer
#define yy_init_buffer cmCTestResourceGroups_yy_init_buffer
#endif
#ifdef yy_flush_buffer
#define cmCTestProcesses_yy_flush_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_flush_buffer_ALREADY_DEFINED
#else
#define yy_flush_buffer cmCTestProcesses_yy_flush_buffer
#define yy_flush_buffer cmCTestResourceGroups_yy_flush_buffer
#endif
#ifdef yy_load_buffer_state
#define cmCTestProcesses_yy_load_buffer_state_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_load_buffer_state_ALREADY_DEFINED
#else
#define yy_load_buffer_state cmCTestProcesses_yy_load_buffer_state
#define yy_load_buffer_state cmCTestResourceGroups_yy_load_buffer_state
#endif
#ifdef yy_switch_to_buffer
#define cmCTestProcesses_yy_switch_to_buffer_ALREADY_DEFINED
#define cmCTestResourceGroups_yy_switch_to_buffer_ALREADY_DEFINED
#else
#define yy_switch_to_buffer cmCTestProcesses_yy_switch_to_buffer
#define yy_switch_to_buffer cmCTestResourceGroups_yy_switch_to_buffer
#endif
#ifdef yypush_buffer_state
#define cmCTestProcesses_yypush_buffer_state_ALREADY_DEFINED
#define cmCTestResourceGroups_yypush_buffer_state_ALREADY_DEFINED
#else
#define yypush_buffer_state cmCTestProcesses_yypush_buffer_state
#define yypush_buffer_state cmCTestResourceGroups_yypush_buffer_state
#endif
#ifdef yypop_buffer_state
#define cmCTestProcesses_yypop_buffer_state_ALREADY_DEFINED
#define cmCTestResourceGroups_yypop_buffer_state_ALREADY_DEFINED
#else
#define yypop_buffer_state cmCTestProcesses_yypop_buffer_state
#define yypop_buffer_state cmCTestResourceGroups_yypop_buffer_state
#endif
#ifdef yyensure_buffer_stack
#define cmCTestProcesses_yyensure_buffer_stack_ALREADY_DEFINED
#define cmCTestResourceGroups_yyensure_buffer_stack_ALREADY_DEFINED
#else
#define yyensure_buffer_stack cmCTestProcesses_yyensure_buffer_stack
#define yyensure_buffer_stack cmCTestResourceGroups_yyensure_buffer_stack
#endif
#ifdef yylex
#define cmCTestProcesses_yylex_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_ALREADY_DEFINED
#else
#define yylex cmCTestProcesses_yylex
#define yylex cmCTestResourceGroups_yylex
#endif
#ifdef yyrestart
#define cmCTestProcesses_yyrestart_ALREADY_DEFINED
#define cmCTestResourceGroups_yyrestart_ALREADY_DEFINED
#else
#define yyrestart cmCTestProcesses_yyrestart
#define yyrestart cmCTestResourceGroups_yyrestart
#endif
#ifdef yylex_init
#define cmCTestProcesses_yylex_init_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_init_ALREADY_DEFINED
#else
#define yylex_init cmCTestProcesses_yylex_init
#define yylex_init cmCTestResourceGroups_yylex_init
#endif
#ifdef yylex_init_extra
#define cmCTestProcesses_yylex_init_extra_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_init_extra_ALREADY_DEFINED
#else
#define yylex_init_extra cmCTestProcesses_yylex_init_extra
#define yylex_init_extra cmCTestResourceGroups_yylex_init_extra
#endif
#ifdef yylex_destroy
#define cmCTestProcesses_yylex_destroy_ALREADY_DEFINED
#define cmCTestResourceGroups_yylex_destroy_ALREADY_DEFINED
#else
#define yylex_destroy cmCTestProcesses_yylex_destroy
#define yylex_destroy cmCTestResourceGroups_yylex_destroy
#endif
#ifdef yyget_debug
#define cmCTestProcesses_yyget_debug_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_debug_ALREADY_DEFINED
#else
#define yyget_debug cmCTestProcesses_yyget_debug
#define yyget_debug cmCTestResourceGroups_yyget_debug
#endif
#ifdef yyset_debug
#define cmCTestProcesses_yyset_debug_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_debug_ALREADY_DEFINED
#else
#define yyset_debug cmCTestProcesses_yyset_debug
#define yyset_debug cmCTestResourceGroups_yyset_debug
#endif
#ifdef yyget_extra
#define cmCTestProcesses_yyget_extra_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_extra_ALREADY_DEFINED
#else
#define yyget_extra cmCTestProcesses_yyget_extra
#define yyget_extra cmCTestResourceGroups_yyget_extra
#endif
#ifdef yyset_extra
#define cmCTestProcesses_yyset_extra_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_extra_ALREADY_DEFINED
#else
#define yyset_extra cmCTestProcesses_yyset_extra
#define yyset_extra cmCTestResourceGroups_yyset_extra
#endif
#ifdef yyget_in
#define cmCTestProcesses_yyget_in_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_in_ALREADY_DEFINED
#else
#define yyget_in cmCTestProcesses_yyget_in
#define yyget_in cmCTestResourceGroups_yyget_in
#endif
#ifdef yyset_in
#define cmCTestProcesses_yyset_in_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_in_ALREADY_DEFINED
#else
#define yyset_in cmCTestProcesses_yyset_in
#define yyset_in cmCTestResourceGroups_yyset_in
#endif
#ifdef yyget_out
#define cmCTestProcesses_yyget_out_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_out_ALREADY_DEFINED
#else
#define yyget_out cmCTestProcesses_yyget_out
#define yyget_out cmCTestResourceGroups_yyget_out
#endif
#ifdef yyset_out
#define cmCTestProcesses_yyset_out_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_out_ALREADY_DEFINED
#else
#define yyset_out cmCTestProcesses_yyset_out
#define yyset_out cmCTestResourceGroups_yyset_out
#endif
#ifdef yyget_leng
#define cmCTestProcesses_yyget_leng_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_leng_ALREADY_DEFINED
#else
#define yyget_leng cmCTestProcesses_yyget_leng
#define yyget_leng cmCTestResourceGroups_yyget_leng
#endif
#ifdef yyget_text
#define cmCTestProcesses_yyget_text_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_text_ALREADY_DEFINED
#else
#define yyget_text cmCTestProcesses_yyget_text
#define yyget_text cmCTestResourceGroups_yyget_text
#endif
#ifdef yyget_lineno
#define cmCTestProcesses_yyget_lineno_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_lineno_ALREADY_DEFINED
#else
#define yyget_lineno cmCTestProcesses_yyget_lineno
#define yyget_lineno cmCTestResourceGroups_yyget_lineno
#endif
#ifdef yyset_lineno
#define cmCTestProcesses_yyset_lineno_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_lineno_ALREADY_DEFINED
#else
#define yyset_lineno cmCTestProcesses_yyset_lineno
#define yyset_lineno cmCTestResourceGroups_yyset_lineno
#endif
#ifdef yyget_column
#define cmCTestProcesses_yyget_column_ALREADY_DEFINED
#define cmCTestResourceGroups_yyget_column_ALREADY_DEFINED
#else
#define yyget_column cmCTestProcesses_yyget_column
#define yyget_column cmCTestResourceGroups_yyget_column
#endif
#ifdef yyset_column
#define cmCTestProcesses_yyset_column_ALREADY_DEFINED
#define cmCTestResourceGroups_yyset_column_ALREADY_DEFINED
#else
#define yyset_column cmCTestProcesses_yyset_column
#define yyset_column cmCTestResourceGroups_yyset_column
#endif
#ifdef yywrap
#define cmCTestProcesses_yywrap_ALREADY_DEFINED
#define cmCTestResourceGroups_yywrap_ALREADY_DEFINED
#else
#define yywrap cmCTestProcesses_yywrap
#define yywrap cmCTestResourceGroups_yywrap
#endif
#ifdef yyalloc
#define cmCTestProcesses_yyalloc_ALREADY_DEFINED
#define cmCTestResourceGroups_yyalloc_ALREADY_DEFINED
#else
#define yyalloc cmCTestProcesses_yyalloc
#define yyalloc cmCTestResourceGroups_yyalloc
#endif
#ifdef yyrealloc
#define cmCTestProcesses_yyrealloc_ALREADY_DEFINED
#define cmCTestResourceGroups_yyrealloc_ALREADY_DEFINED
#else
#define yyrealloc cmCTestProcesses_yyrealloc
#define yyrealloc cmCTestResourceGroups_yyrealloc
#endif
#ifdef yyfree
#define cmCTestProcesses_yyfree_ALREADY_DEFINED
#define cmCTestResourceGroups_yyfree_ALREADY_DEFINED
#else
#define yyfree cmCTestProcesses_yyfree
#define yyfree cmCTestResourceGroups_yyfree
#endif
/* First, we deal with platform-specific or compiler-specific issues. */
@ -423,15 +423,15 @@ void yyfree ( void * , yyscan_t yyscanner );
/* Begin user sect3 */
#define cmCTestProcesses_yywrap(yyscanner) (/*CONSTCOND*/1)
#define cmCTestResourceGroups_yywrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
#define yytext_ptr yytext_r
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
#define INITIAL 0
#define PROCESSES_START 1
#define PROCESSES_END 2
#define RESOURCE_GROUPS_START 1
#define RESOURCE_GROUPS_END 2
#define RESOURCE_START 3
#define RESOURCE_COUNT 4
#define RESOURCE_END 5
@ -543,150 +543,150 @@ extern int yylex (yyscan_t yyscanner);
#undef YY_DECL
#endif
#ifndef cmCTestProcesses_yy_create_buffer_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_create_buffer_ALREADY_DEFINED
#undef yy_create_buffer
#endif
#ifndef cmCTestProcesses_yy_delete_buffer_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_delete_buffer_ALREADY_DEFINED
#undef yy_delete_buffer
#endif
#ifndef cmCTestProcesses_yy_scan_buffer_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_scan_buffer_ALREADY_DEFINED
#undef yy_scan_buffer
#endif
#ifndef cmCTestProcesses_yy_scan_string_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_scan_string_ALREADY_DEFINED
#undef yy_scan_string
#endif
#ifndef cmCTestProcesses_yy_scan_bytes_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_scan_bytes_ALREADY_DEFINED
#undef yy_scan_bytes
#endif
#ifndef cmCTestProcesses_yy_init_buffer_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_init_buffer_ALREADY_DEFINED
#undef yy_init_buffer
#endif
#ifndef cmCTestProcesses_yy_flush_buffer_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_flush_buffer_ALREADY_DEFINED
#undef yy_flush_buffer
#endif
#ifndef cmCTestProcesses_yy_load_buffer_state_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_load_buffer_state_ALREADY_DEFINED
#undef yy_load_buffer_state
#endif
#ifndef cmCTestProcesses_yy_switch_to_buffer_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_switch_to_buffer_ALREADY_DEFINED
#undef yy_switch_to_buffer
#endif
#ifndef cmCTestProcesses_yypush_buffer_state_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yypush_buffer_state_ALREADY_DEFINED
#undef yypush_buffer_state
#endif
#ifndef cmCTestProcesses_yypop_buffer_state_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yypop_buffer_state_ALREADY_DEFINED
#undef yypop_buffer_state
#endif
#ifndef cmCTestProcesses_yyensure_buffer_stack_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyensure_buffer_stack_ALREADY_DEFINED
#undef yyensure_buffer_stack
#endif
#ifndef cmCTestProcesses_yylex_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yylex_ALREADY_DEFINED
#undef yylex
#endif
#ifndef cmCTestProcesses_yyrestart_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyrestart_ALREADY_DEFINED
#undef yyrestart
#endif
#ifndef cmCTestProcesses_yylex_init_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yylex_init_ALREADY_DEFINED
#undef yylex_init
#endif
#ifndef cmCTestProcesses_yylex_init_extra_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yylex_init_extra_ALREADY_DEFINED
#undef yylex_init_extra
#endif
#ifndef cmCTestProcesses_yylex_destroy_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yylex_destroy_ALREADY_DEFINED
#undef yylex_destroy
#endif
#ifndef cmCTestProcesses_yyget_debug_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_debug_ALREADY_DEFINED
#undef yyget_debug
#endif
#ifndef cmCTestProcesses_yyset_debug_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_debug_ALREADY_DEFINED
#undef yyset_debug
#endif
#ifndef cmCTestProcesses_yyget_extra_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_extra_ALREADY_DEFINED
#undef yyget_extra
#endif
#ifndef cmCTestProcesses_yyset_extra_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_extra_ALREADY_DEFINED
#undef yyset_extra
#endif
#ifndef cmCTestProcesses_yyget_in_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_in_ALREADY_DEFINED
#undef yyget_in
#endif
#ifndef cmCTestProcesses_yyset_in_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_in_ALREADY_DEFINED
#undef yyset_in
#endif
#ifndef cmCTestProcesses_yyget_out_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_out_ALREADY_DEFINED
#undef yyget_out
#endif
#ifndef cmCTestProcesses_yyset_out_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_out_ALREADY_DEFINED
#undef yyset_out
#endif
#ifndef cmCTestProcesses_yyget_leng_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_leng_ALREADY_DEFINED
#undef yyget_leng
#endif
#ifndef cmCTestProcesses_yyget_text_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_text_ALREADY_DEFINED
#undef yyget_text
#endif
#ifndef cmCTestProcesses_yyget_lineno_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_lineno_ALREADY_DEFINED
#undef yyget_lineno
#endif
#ifndef cmCTestProcesses_yyset_lineno_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_lineno_ALREADY_DEFINED
#undef yyset_lineno
#endif
#ifndef cmCTestProcesses_yyget_column_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_column_ALREADY_DEFINED
#undef yyget_column
#endif
#ifndef cmCTestProcesses_yyset_column_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_column_ALREADY_DEFINED
#undef yyset_column
#endif
#ifndef cmCTestProcesses_yywrap_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yywrap_ALREADY_DEFINED
#undef yywrap
#endif
#ifndef cmCTestProcesses_yyget_lval_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_lval_ALREADY_DEFINED
#undef yyget_lval
#endif
#ifndef cmCTestProcesses_yyset_lval_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_lval_ALREADY_DEFINED
#undef yyset_lval
#endif
#ifndef cmCTestProcesses_yyget_lloc_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyget_lloc_ALREADY_DEFINED
#undef yyget_lloc
#endif
#ifndef cmCTestProcesses_yyset_lloc_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyset_lloc_ALREADY_DEFINED
#undef yyset_lloc
#endif
#ifndef cmCTestProcesses_yyalloc_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyalloc_ALREADY_DEFINED
#undef yyalloc
#endif
#ifndef cmCTestProcesses_yyrealloc_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyrealloc_ALREADY_DEFINED
#undef yyrealloc
#endif
#ifndef cmCTestProcesses_yyfree_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyfree_ALREADY_DEFINED
#undef yyfree
#endif
#ifndef cmCTestProcesses_yytext_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yytext_ALREADY_DEFINED
#undef yytext
#endif
#ifndef cmCTestProcesses_yyleng_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyleng_ALREADY_DEFINED
#undef yyleng
#endif
#ifndef cmCTestProcesses_yyin_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyin_ALREADY_DEFINED
#undef yyin
#endif
#ifndef cmCTestProcesses_yyout_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyout_ALREADY_DEFINED
#undef yyout
#endif
#ifndef cmCTestProcesses_yy_flex_debug_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yy_flex_debug_ALREADY_DEFINED
#undef yy_flex_debug
#endif
#ifndef cmCTestProcesses_yylineno_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yylineno_ALREADY_DEFINED
#undef yylineno
#endif
#ifndef cmCTestProcesses_yytables_fload_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yytables_fload_ALREADY_DEFINED
#undef yytables_fload
#endif
#ifndef cmCTestProcesses_yytables_destroy_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yytables_destroy_ALREADY_DEFINED
#undef yytables_destroy
#endif
#ifndef cmCTestProcesses_yyTABLES_NAME_ALREADY_DEFINED
#ifndef cmCTestResourceGroups_yyTABLES_NAME_ALREADY_DEFINED
#undef yyTABLES_NAME
#endif
#undef cmCTestProcesses_yyIN_HEADER
#endif /* cmCTestProcesses_yyHEADER_H */
#undef cmCTestResourceGroups_yyIN_HEADER
#endif /* cmCTestResourceGroups_yyHEADER_H */

View File

@ -7,12 +7,12 @@ This file must be translated to C++ and modified to build everywhere.
Run flex >= 2.6 like this:
flex --nounistd -DFLEXINT_H --noline --header-file=cmCTestProcessesLexer.h -ocmCTestProcessesLexer.cxx cmCTestProcessesLexer.in.l
flex --nounistd -DFLEXINT_H --noline --header-file=cmCTestResourceGroupsLexer.h -ocmCTestResourceGroupsLexer.cxx cmCTestResourceGroupsLexer.in.l
Modify cmCTestProcessesLexer.cxx:
- remove trailing whitespace: sed -i 's/\s*$//' cmCTestProcessesLexer.h cmCTestProcessesLexer.cxx
- remove blank lines at end of file: sed -i '${/^$/d;}' cmCTestProcessesLexer.h cmCTestProcessesLexer.cxx
- #include "cmStandardLexer.h" at the top: sed -i '1i#include "cmStandardLexer.h"' cmCTestProcessesLexer.cxx
Modify cmCTestResourceGroupsLexer.cxx:
- remove trailing whitespace: sed -i 's/\s*$//' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
- remove blank lines at end of file: sed -i '${/^$/d;}' cmCTestResourceGroupsLexer.h cmCTestResourceGroupsLexer.cxx
- #include "cmStandardLexer.h" at the top: sed -i '1i#include "cmStandardLexer.h"' cmCTestResourceGroupsLexer.cxx
*/
@ -20,7 +20,7 @@ Modify cmCTestProcessesLexer.cxx:
#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
#include "cmCTestProcessesLexerHelper.h"
#include "cmCTestResourceGroupsLexerHelper.h"
#include <string>
@ -29,15 +29,15 @@ Modify cmCTestProcessesLexer.cxx:
/*--------------------------------------------------------------------------*/
%}
%option prefix="cmCTestProcesses_yy"
%option prefix="cmCTestResourceGroups_yy"
%option reentrant
%option noyywrap
%option nodefault
%pointer
%s PROCESSES_START
%s PROCESSES_END
%s RESOURCE_GROUPS_START
%s RESOURCE_GROUPS_END
%s RESOURCE_START
%s RESOURCE_COUNT
%s RESOURCE_END
@ -47,13 +47,13 @@ IDENTIFIER [a-z_][a-z0-9_]*
%%
<INITIAL,PROCESSES_START,RESOURCE_START>{IDENTIFIER}: {
<INITIAL,RESOURCE_GROUPS_START,RESOURCE_START>{IDENTIFIER}: {
BEGIN(RESOURCE_COUNT);
yyextra->SetResourceType(std::string(yytext, yyleng - 1));
}
<INITIAL,PROCESSES_START>{NUMBER} {
BEGIN(PROCESSES_END);
<INITIAL,RESOURCE_GROUPS_START>{NUMBER} {
BEGIN(RESOURCE_GROUPS_END);
std::size_t len = yyleng;
yyextra->SetProcessCount(std::stoll(yytext, &len, 10));
}
@ -65,25 +65,25 @@ IDENTIFIER [a-z_][a-z0-9_]*
yyextra->WriteRequirement();
}
<PROCESSES_END,RESOURCE_END>,+ {
<RESOURCE_GROUPS_END,RESOURCE_END>,+ {
BEGIN(RESOURCE_START);
}
<INITIAL,PROCESSES_START,RESOURCE_START>;+ {
BEGIN(PROCESSES_START);
<INITIAL,RESOURCE_GROUPS_START,RESOURCE_START>;+ {
BEGIN(RESOURCE_GROUPS_START);
}
<PROCESSES_END,RESOURCE_END>;+ {
BEGIN(PROCESSES_START);
<RESOURCE_GROUPS_END,RESOURCE_END>;+ {
BEGIN(RESOURCE_GROUPS_START);
yyextra->WriteProcess();
}
<RESOURCE_START,PROCESSES_END,RESOURCE_END><<EOF>> {
<RESOURCE_START,RESOURCE_GROUPS_END,RESOURCE_END><<EOF>> {
yyextra->WriteProcess();
return 0;
}
<INITIAL,PROCESSES_START><<EOF>> {
<INITIAL,RESOURCE_GROUPS_START><<EOF>> {
return 0;
}

View File

@ -2139,12 +2139,12 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"ExcludeFixtureCleanupRegularExpression", args[i].c_str());
}
if (this->CheckArgument(arg, "--hardware-spec-file") &&
if (this->CheckArgument(arg, "--resource-spec-file") &&
i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("HardwareSpecFile",
this->GetTestHandler()->SetPersistentOption("ResourceSpecFile",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("HardwareSpecFile",
this->GetMemCheckHandler()->SetPersistentOption("ResourceSpecFile",
args[i].c_str());
}

View File

@ -106,7 +106,7 @@ static const char* cmDocumentationOptions[][2] = {
"Allow each test to run up to <n> times if it times out" },
{ "--max-width <width>", "Set the max width for a test name to output" },
{ "--interactive-debug-mode [0|1]", "Set the interactive mode to 0 or 1." },
{ "--hardware-spec-file <file>", "Set the hardware spec file to use." },
{ "--resource-spec-file <file>", "Set the resource spec file to use." },
{ "--no-label-summary", "Disable timing summary information for labels." },
{ "--no-subproject-summary",
"Disable timing summary information for "

View File

@ -8,9 +8,9 @@ include_directories(
set(CMakeLib_TESTS
testArgumentParser.cxx
testCTestBinPacker.cxx
testCTestProcesses.cxx
testCTestHardwareAllocator.cxx
testCTestHardwareSpec.cxx
testCTestResourceAllocator.cxx
testCTestResourceSpec.cxx
testCTestResourceGroups.cxx
testGeneratedFileStream.cxx
testRST.cxx
testRange.cxx
@ -32,7 +32,7 @@ add_executable(testUVProcessChainHelper testUVProcessChainHelper.cxx)
set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
set(testUVProcessChain_ARGS $<TARGET_FILE:testUVProcessChainHelper>)
set(testUVStreambuf_ARGS $<TARGET_FILE:cmake>)
set(testCTestHardwareSpec_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
set(testCTestResourceSpec_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
if(WIN32)
list(APPEND CMakeLib_TESTS

View File

@ -5,12 +5,12 @@
#include <vector>
#include "cmCTestBinPacker.h"
#include "cmCTestHardwareAllocator.h"
#include "cmCTestResourceAllocator.h"
struct ExpectedPackResult
{
std::vector<int> SlotsNeeded;
std::map<std::string, cmCTestHardwareAllocator::Resource> Hardware;
std::map<std::string, cmCTestResourceAllocator::Resource> Resources;
bool ExpectedReturnValue;
std::vector<cmCTestBinPackerAllocation> ExpectedRoundRobinAllocations;
std::vector<cmCTestBinPackerAllocation> ExpectedBlockAllocations;
@ -233,18 +233,18 @@ bool TestExpectedPackResult(const ExpectedPackResult& expected)
roundRobinAllocations.push_back({ index++, n, "" });
}
bool roundRobinResult = cmAllocateCTestHardwareRoundRobin(
expected.Hardware, roundRobinAllocations);
bool roundRobinResult = cmAllocateCTestResourcesRoundRobin(
expected.Resources, roundRobinAllocations);
if (roundRobinResult != expected.ExpectedReturnValue) {
std::cout
<< "cmAllocateCTestHardwareRoundRobin did not return expected value"
<< "cmAllocateCTestResourcesRoundRobin did not return expected value"
<< std::endl;
return false;
}
if (roundRobinResult &&
roundRobinAllocations != expected.ExpectedRoundRobinAllocations) {
std::cout << "cmAllocateCTestHardwareRoundRobin did not return expected "
std::cout << "cmAllocateCTestResourcesRoundRobin did not return expected "
"allocations"
<< std::endl;
return false;
@ -258,15 +258,15 @@ bool TestExpectedPackResult(const ExpectedPackResult& expected)
}
bool blockResult =
cmAllocateCTestHardwareBlock(expected.Hardware, blockAllocations);
cmAllocateCTestResourcesBlock(expected.Resources, blockAllocations);
if (blockResult != expected.ExpectedReturnValue) {
std::cout << "cmAllocateCTestHardwareBlock did not return expected value"
std::cout << "cmAllocateCTestResourcesBlock did not return expected value"
<< std::endl;
return false;
}
if (blockResult && blockAllocations != expected.ExpectedBlockAllocations) {
std::cout << "cmAllocateCTestHardwareBlock did not return expected"
std::cout << "cmAllocateCTestResourcesBlock did not return expected"
" allocations"
<< std::endl;
return false;

View File

@ -3,24 +3,24 @@
#include <string>
#include <vector>
#include "cmCTestHardwareAllocator.h"
#include "cmCTestHardwareSpec.h"
#include "cmCTestResourceAllocator.h"
#include "cmCTestResourceSpec.h"
static const cmCTestHardwareSpec spec{ { {
static const cmCTestResourceSpec spec{ { {
/* clang-format off */
{ "gpus", { { "0", 4 }, { "1", 8 }, { "2", 0 }, { "3", 8 } } },
/* clang-format on */
} } };
bool testInitializeFromHardwareSpec()
bool testInitializeFromResourceSpec()
{
bool retval = true;
cmCTestHardwareAllocator allocator;
allocator.InitializeFromHardwareSpec(spec);
cmCTestResourceAllocator allocator;
allocator.InitializeFromResourceSpec(spec);
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected{
/* clang-format off */
{ "gpus", {
@ -43,11 +43,11 @@ bool testAllocateResource()
{
bool retval = true;
cmCTestHardwareAllocator allocator;
allocator.InitializeFromHardwareSpec(spec);
cmCTestResourceAllocator allocator;
allocator.InitializeFromResourceSpec(spec);
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected1{
/* clang-format off */
{ "gpus", {
@ -70,7 +70,7 @@ bool testAllocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected2{
/* clang-format off */
{ "gpus", {
@ -93,7 +93,7 @@ bool testAllocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected3{
/* clang-format off */
{ "gpus", {
@ -116,7 +116,7 @@ bool testAllocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected4{
/* clang-format off */
{ "gpus", {
@ -145,7 +145,7 @@ bool testAllocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected5{
/* clang-format off */
{ "gpus", {
@ -168,7 +168,7 @@ bool testAllocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected6{
/* clang-format off */
{ "gpus", {
@ -191,7 +191,7 @@ bool testAllocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected7{
/* clang-format off */
{ "gpus", {
@ -220,11 +220,11 @@ bool testDeallocateResource()
{
bool retval = true;
cmCTestHardwareAllocator allocator;
allocator.InitializeFromHardwareSpec(spec);
cmCTestResourceAllocator allocator;
allocator.InitializeFromResourceSpec(spec);
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected1{
/* clang-format off */
{ "gpus", {
@ -253,7 +253,7 @@ bool testDeallocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected2{
/* clang-format off */
{ "gpus", {
@ -276,7 +276,7 @@ bool testDeallocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected3{
/* clang-format off */
{ "gpus", {
@ -299,7 +299,7 @@ bool testDeallocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected4{
/* clang-format off */
{ "gpus", {
@ -322,7 +322,7 @@ bool testDeallocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected5{
/* clang-format off */
{ "gpus", {
@ -345,7 +345,7 @@ bool testDeallocateResource()
}
static const std::map<
std::string, std::map<std::string, cmCTestHardwareAllocator::Resource>>
std::string, std::map<std::string, cmCTestResourceAllocator::Resource>>
expected6{
/* clang-format off */
{ "gpus", {
@ -374,23 +374,23 @@ bool testResourceFree()
{
bool retval = true;
const cmCTestHardwareAllocator::Resource r1{ 5, 0 };
const cmCTestResourceAllocator::Resource r1{ 5, 0 };
if (r1.Free() != 5) {
std::cout << "cmCTestHardwareAllocator::Resource::Free() did not return "
std::cout << "cmCTestResourceAllocator::Resource::Free() did not return "
"expected value for { 5, 0 }\n";
retval = false;
}
const cmCTestHardwareAllocator::Resource r2{ 3, 2 };
const cmCTestResourceAllocator::Resource r2{ 3, 2 };
if (r2.Free() != 1) {
std::cout << "cmCTestHardwareAllocator::Resource::Free() did not return "
std::cout << "cmCTestResourceAllocator::Resource::Free() did not return "
"expected value for { 3, 2 }\n";
retval = false;
}
const cmCTestHardwareAllocator::Resource r3{ 4, 4 };
const cmCTestResourceAllocator::Resource r3{ 4, 4 };
if (r3.Free() != 0) {
std::cout << "cmCTestHardwareAllocator::Resource::Free() did not return "
std::cout << "cmCTestResourceAllocator::Resource::Free() did not return "
"expected value for { 4, 4 }\n";
retval = false;
}
@ -398,12 +398,12 @@ bool testResourceFree()
return retval;
}
int testCTestHardwareAllocator(int, char** const)
int testCTestResourceAllocator(int, char** const)
{
int retval = 0;
if (!testInitializeFromHardwareSpec()) {
std::cout << "in testInitializeFromHardwareSpec()\n";
if (!testInitializeFromResourceSpec()) {
std::cout << "in testInitializeFromResourceSpec()\n";
retval = -1;
}

View File

@ -106,24 +106,25 @@ bool TestExpectedParseResult(const ExpectedParseResult& expected)
std::vector<std::vector<cmCTestTestHandler::cmCTestTestResourceRequirement>>
result;
bool retval;
if ((retval = cmCTestTestHandler::ParseProcessesProperty(
if ((retval = cmCTestTestHandler::ParseResourceGroupsProperty(
expected.String, result)) != expected.ExpectedReturnValue) {
std::cout << "ParseProcessesProperty(\"" << expected.String
std::cout << "ParseResourceGroupsProperty(\"" << expected.String
<< "\") returned " << retval << ", should be "
<< expected.ExpectedReturnValue << std::endl;
return false;
}
if (result != expected.ExpectedValue) {
std::cout << "ParseProcessesProperty(\"" << expected.String
<< "\") did not yield expected set of processes" << std::endl;
std::cout << "ParseResourceGroupsProperty(\"" << expected.String
<< "\") did not yield expected set of resource groups"
<< std::endl;
return false;
}
return true;
}
int testCTestProcesses(int /*unused*/, char* /*unused*/ [])
int testCTestResourceGroups(int /*unused*/, char* /*unused*/ [])
{
int retval = 0;

View File

@ -2,16 +2,16 @@
#include <string>
#include <vector>
#include "cmCTestHardwareSpec.h"
#include "cmCTestResourceSpec.h"
struct ExpectedSpec
{
std::string Path;
bool ParseResult;
cmCTestHardwareSpec Expected;
cmCTestResourceSpec Expected;
};
static const std::vector<ExpectedSpec> expectedHardwareSpecs = {
static const std::vector<ExpectedSpec> expectedResourceSpecs = {
/* clang-format off */
{"spec1.json", true, {{{
{"gpus", {
@ -44,9 +44,9 @@ static const std::vector<ExpectedSpec> expectedHardwareSpecs = {
};
static bool testSpec(const std::string& path, bool expectedResult,
const cmCTestHardwareSpec& expected)
const cmCTestResourceSpec& expected)
{
cmCTestHardwareSpec actual;
cmCTestResourceSpec actual;
bool result = actual.ReadFromJSONFile(path);
if (result != expectedResult) {
std::cout << "ReadFromJSONFile(\"" << path << "\") returned " << result
@ -63,7 +63,7 @@ static bool testSpec(const std::string& path, bool expectedResult,
return true;
}
int testCTestHardwareSpec(int argc, char** const argv)
int testCTestResourceSpec(int argc, char** const argv)
{
if (argc < 2) {
std::cout << "Invalid arguments.\n";
@ -71,9 +71,9 @@ int testCTestHardwareSpec(int argc, char** const argv)
}
int retval = 0;
for (auto const& spec : expectedHardwareSpecs) {
for (auto const& spec : expectedResourceSpecs) {
std::string path = argv[1];
path += "/testCTestHardwareSpec_data/";
path += "/testCTestResourceSpec_data/";
path += spec.Path;
if (!testSpec(path, spec.ParseResult, spec.Expected)) {
retval = -1;

View File

@ -336,7 +336,7 @@ add_RunCMake_test(no_install_prefix)
add_RunCMake_test(configure_file)
add_RunCMake_test(CTestTimeoutAfterMatch)
# cthwalloc links against CMakeLib and CTestLib, which means it can't be built
# ctresalloc links against CMakeLib and CTestLib, which means it can't be built
# if CMake_TEST_EXTERNAL_CMAKE is activated (the compiler might be different.)
# So, it has to be provided in the original build tree.
if(CMake_TEST_EXTERNAL_CMAKE)
@ -344,7 +344,7 @@ if(CMake_TEST_EXTERNAL_CMAKE)
if(NOT CMAKE_VERSION VERSION_LESS 3.12)
set(no_package_root_path NO_PACKAGE_ROOT_PATH)
endif()
find_program(cthwalloc cthwalloc PATHS ${CMake_TEST_EXTERNAL_CMAKE}
find_program(ctresalloc ctresalloc PATHS ${CMake_TEST_EXTERNAL_CMAKE}
NO_DEFAULT_PATH
${no_package_root_path}
NO_CMAKE_PATH
@ -353,25 +353,25 @@ if(CMake_TEST_EXTERNAL_CMAKE)
NO_CMAKE_SYSTEM_PATH
NO_CMAKE_FIND_ROOT_PATH
)
if(cthwalloc)
add_executable(cthwalloc IMPORTED)
set_property(TARGET cthwalloc PROPERTY IMPORTED_LOCATION ${cthwalloc})
if(ctresalloc)
add_executable(ctresalloc IMPORTED)
set_property(TARGET ctresalloc PROPERTY IMPORTED_LOCATION ${ctresalloc})
endif()
else()
add_executable(cthwalloc CTestHardwareAllocation/cthwalloc.cxx)
target_link_libraries(cthwalloc CTestLib)
target_include_directories(cthwalloc PRIVATE
add_executable(ctresalloc CTestResourceAllocation/ctresalloc.cxx)
target_link_libraries(ctresalloc CTestLib)
target_include_directories(ctresalloc PRIVATE
${CMake_BINARY_DIR}/Source
${CMake_SOURCE_DIR}/Source
${CMake_SOURCE_DIR}/Source/CTest
)
set_property(TARGET cthwalloc PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMake_BIN_DIR})
set_property(TARGET ctresalloc PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMake_BIN_DIR})
endif()
if(TARGET cthwalloc)
add_RunCMake_test(CTestHardwareAllocation -DCTHWALLOC_COMMAND=$<TARGET_FILE:cthwalloc>)
if(TARGET ctresalloc)
add_RunCMake_test(CTestResourceAllocation -DCTRESALLOC_COMMAND=$<TARGET_FILE:ctresalloc>)
else()
message(WARNING "Could not find or build cthwalloc")
message(WARNING "Could not find or build ctresalloc")
endif()
find_package(Qt4 QUIET)

View File

@ -307,7 +307,7 @@ function(run_ShowOnly)
add_test(ShowOnly \"${CMAKE_COMMAND}\" -E echo)
set_tests_properties(ShowOnly PROPERTIES
WILL_FAIL true
PROCESSES \"2,threads:2,gpus:4;gpus:2,threads:4\"
RESOURCE_GROUPS \"2,threads:2,gpus:4;gpus:2,threads:4\"
REQUIRED_FILES RequiredFileDoesNotExist
_BACKTRACE_TRIPLES \"file1;1;add_test;file0;;\"
)

View File

@ -80,12 +80,12 @@ def check_willfail_property(p):
assert p["name"] == "WILL_FAIL"
assert p["value"] == True
def check_processes_property(p):
def check_resource_groups_property(p):
assert is_dict(p)
assert sorted(p.keys()) == ["name", "value"]
assert is_string(p["name"])
assert is_list(p["value"])
assert p["name"] == "PROCESSES"
assert p["name"] == "RESOURCE_GROUPS"
assert len(p["value"]) == 3
assert is_dict(p["value"][0])
@ -147,7 +147,7 @@ def check_workingdir_property(p):
def check_properties(p):
assert is_list(p)
assert len(p) == 4
check_processes_property(p[0])
check_resource_groups_property(p[0])
check_reqfiles_property(p[1])
check_willfail_property(p[2])
check_workingdir_property(p[3])

View File

@ -1,23 +0,0 @@
function(setup_hardware_tests)
if(CTEST_HARDWARE_ALLOC_ENABLED)
add_test(NAME HardwareSetup COMMAND "${CMAKE_COMMAND}" -E remove -f "${CMAKE_BINARY_DIR}/cthwalloc.log")
endif()
endfunction()
function(add_hardware_test name sleep_time proc)
if(CTEST_HARDWARE_ALLOC_ENABLED)
add_test(NAME "${name}" COMMAND "${CTHWALLOC_COMMAND}" write "${CMAKE_BINARY_DIR}/cthwalloc.log" "${name}" "${sleep_time}" "${proc}")
set_property(TEST "${name}" PROPERTY DEPENDS HardwareSetup)
else()
add_test(NAME "${name}" COMMAND "${CTHWALLOC_COMMAND}" write "${CMAKE_BINARY_DIR}/cthwalloc.log" "${name}" "${sleep_time}")
endif()
set_property(TEST "${name}" PROPERTY PROCESSES "${proc}")
list(APPEND HARDWARE_TESTS "${name}")
set(HARDWARE_TESTS "${HARDWARE_TESTS}" PARENT_SCOPE)
endfunction()
function(cleanup_hardware_tests)
if(CTEST_HARDWARE_ALLOC_ENABLED)
file(WRITE "${CMAKE_BINARY_DIR}/hwtests.txt" "${HARDWARE_TESTS}")
endif()
endfunction()

View File

@ -1,167 +0,0 @@
include(RunCMake)
include(RunCTest)
###############################################################################
# Test cthwalloc itself - we want to make sure it's not just rubber-stamping
# the test results
###############################################################################
function(cthwalloc_verify_log expected_contents)
if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/cthwalloc.log")
string(APPEND RunCMake_TEST_FAILED "Log file was not written\n")
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
return()
endif()
file(READ "${RunCMake_TEST_BINARY_DIR}/cthwalloc.log" actual_contents)
if(NOT actual_contents STREQUAL expected_contents)
string(APPEND RunCMake_TEST_FAILED "Actual log did not match expected log\n")
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
endif()
endfunction()
function(run_cthwalloc_write_proc name proc)
file(REMOVE "${RunCMake_BINARY_DIR}/${name}-build/cthwalloc.log")
run_cthwalloc_write_proc_nodel("${name}" "${proc}" "${ARGN}")
endfunction()
function(run_cthwalloc_write_proc_nodel name proc)
string(REPLACE ";" "\\;" proc "${proc}")
run_cmake_command(${name} "${CMAKE_COMMAND}" -E env "${ARGN}" "${CTHWALLOC_COMMAND}" write "${RunCMake_BINARY_DIR}/${name}-build/cthwalloc.log" "${name}" 0 "${proc}")
endfunction()
function(run_cthwalloc_write_noproc name)
run_cmake_command(${name} "${CMAKE_COMMAND}" -E env "${ARGN}" "${CTHWALLOC_COMMAND}" write "${RunCMake_BINARY_DIR}/${name}-build/cthwalloc.log" "${name}" 0)
endfunction()
function(run_cthwalloc_verify name tests)
string(REPLACE ";" "\\;" tests "${tests}")
run_cmake_command(${name} "${CTHWALLOC_COMMAND}" verify "${RunCMake_SOURCE_DIR}/${name}.log" "${CMAKE_CURRENT_LIST_DIR}/hwspec.json" "${tests}")
endfunction()
unset(ENV{CTEST_PROCESS_COUNT})
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/cthwalloc-write-proc-good1-build")
file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/cthwalloc-write-proc-good1-build")
file(WRITE "${RunCMake_BINARY_DIR}/cthwalloc-write-proc-good1-build/cthwalloc.log"
[[begin test1
alloc widgets 0 1
dealloc widgets 0 1
end test1
]])
run_cthwalloc_write_proc_nodel(cthwalloc-write-proc-good1 "1,widgets:2,transmogrifiers:1;2,widgets:1,widgets:2"
CTEST_PROCESS_COUNT=3
CTEST_PROCESS_0=widgets,transmogrifiers
CTEST_PROCESS_0_WIDGETS=id:0,slots:2
CTEST_PROCESS_0_TRANSMOGRIFIERS=id:calvin,slots:1
CTEST_PROCESS_1=widgets
"CTEST_PROCESS_1_WIDGETS=id:0,slots:1\\;id:2,slots:2"
CTEST_PROCESS_2=widgets
"CTEST_PROCESS_2_WIDGETS=id:0,slots:1\\;id:2,slots:2"
)
set(RunCMake_TEST_NO_CLEAN 0)
run_cthwalloc_write_proc(cthwalloc-write-proc-good2 "widgets:8"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
CTEST_PROCESS_0_WIDGETS=id:3,slots:8
)
run_cthwalloc_write_proc(cthwalloc-write-proc-nocount "widgets:8")
run_cthwalloc_write_proc(cthwalloc-write-proc-badcount "widgets:8"
CTEST_PROCESS_COUNT=2
)
run_cthwalloc_write_proc(cthwalloc-write-proc-nores "widgets:8"
CTEST_PROCESS_COUNT=1
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badres "widgets:8"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets,transmogrifiers
)
run_cthwalloc_write_proc(cthwalloc-write-proc-nowidgets "widgets:8"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badwidgets1 "widgets:8"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
CTEST_PROCESS_0_WIDGETS=
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badwidgets2 "widgets:8"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
"CTEST_PROCESS_0_WIDGETS=id:3,slots:8\\;id:0,slots:1"
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badwidgets3 "widgets:8"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
CTEST_PROCESS_0_WIDGETS=id:3,slots:7
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badwidgets4 "widgets:8"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
CTEST_PROCESS_0_WIDGETS=invalid
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badwidgets5 "widgets:2,widgets:2"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
"CTEST_PROCESS_0_WIDGETS=id:0,slots:2\\;id:0,slots:1"
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badwidgets6 "widgets:2"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
"CTEST_PROCESS_0_WIDGETS=id:0,slots:2\\;id:0,slots:1"
)
run_cthwalloc_write_proc(cthwalloc-write-proc-badwidgets7 "widgets:2,widgets:2"
CTEST_PROCESS_COUNT=1
CTEST_PROCESS_0=widgets
CTEST_PROCESS_0_WIDGETS=id:0,slots:2
)
run_cthwalloc_write_noproc(cthwalloc-write-noproc-good1)
run_cthwalloc_write_noproc(cthwalloc-write-noproc-count
CTEST_PROCESS_COUNT=1
)
run_cthwalloc_verify(cthwalloc-verify-good1 "test1;test2")
run_cthwalloc_verify(cthwalloc-verify-good2 "")
run_cthwalloc_verify(cthwalloc-verify-nolog "")
run_cthwalloc_verify(cthwalloc-verify-nores "")
run_cthwalloc_verify(cthwalloc-verify-noid "")
run_cthwalloc_verify(cthwalloc-verify-notenough "")
run_cthwalloc_verify(cthwalloc-verify-baddealloc "")
run_cthwalloc_verify(cthwalloc-verify-leak "")
run_cthwalloc_verify(cthwalloc-verify-badtest1 "")
run_cthwalloc_verify(cthwalloc-verify-badtest2 "test1")
run_cthwalloc_verify(cthwalloc-verify-badtest3 "test1")
run_cthwalloc_verify(cthwalloc-verify-badtest4 "test1")
run_cthwalloc_verify(cthwalloc-verify-badtest5 "test1")
run_cthwalloc_verify(cthwalloc-verify-nobegin "test1")
run_cthwalloc_verify(cthwalloc-verify-noend "test1")
###############################################################################
# Now test the hardware allocation feature of CTest
###############################################################################
function(run_ctest_hardware name parallel random)
run_ctest("${name}-ctest-s-hw" "-DCTEST_HARDWARE_ALLOC_ENABLED=1" "-DCTHWALLOC_COMMAND=${CTHWALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
run_ctest("${name}-ctest-s-nohw" "-DCTEST_HARDWARE_ALLOC_ENABLED=0" "-DCTHWALLOC_COMMAND=${CTHWALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
endfunction()
function(verify_ctest_hardware)
file(READ "${RunCMake_TEST_BINARY_DIR}/hwtests.txt" hwtests)
execute_process(COMMAND "${CTHWALLOC_COMMAND}" verify "${RunCMake_TEST_BINARY_DIR}/cthwalloc.log" "${CMAKE_CURRENT_LIST_DIR}/hwspec.json" "${hwtests}"
OUTPUT_VARIABLE output ERROR_QUIET RESULT_VARIABLE result)
if(result)
string(APPEND RunCMake_TEST_FAILED "${output}")
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
endif()
endfunction()
run_ctest_hardware(lotsoftests 10 1)
run_ctest_hardware(checkfree1 2 0)
run_ctest_hardware(checkfree2 1 0)
run_ctest_hardware(notenough1 1 0)
run_ctest_hardware(notenough2 1 0)
run_ctest_hardware(ensure_parallel 2 0)
set(ENV{CTEST_PROCESS_COUNT} 2)
run_ctest_hardware(process_count 1 0)
unset(ENV{CTEST_PROCESS_COUNT})

View File

@ -1 +0,0 @@
verify_ctest_hardware()

View File

@ -1,7 +0,0 @@
setup_hardware_tests()
add_hardware_test(Test1 1 "widgets:8")
add_hardware_test(Test2 1 "fluxcapacitors:50;fluxcapacitors:50,widgets:8")
add_hardware_test(Test3 1 "fluxcapacitors:121")
cleanup_hardware_tests()

View File

@ -1 +0,0 @@
verify_ctest_hardware()

View File

@ -1,8 +0,0 @@
setup_hardware_tests()
# This test is an attack on the hardware scheduling algorithm. It has been
# carefully crafted to fool the algorithm into thinking there isn't sufficient
# hardware for it.
add_hardware_test(Test1 1 "widgets:2;4,widgets:4")
cleanup_hardware_tests()

View File

@ -1,6 +0,0 @@
cthwalloc_verify_log(
[[begin cthwalloc-write-proc-good2
alloc widgets 3 8
dealloc widgets 3 8
end cthwalloc-write-proc-good2
]])

View File

@ -1 +0,0 @@
verify_ctest_hardware()

View File

@ -1,16 +0,0 @@
setup_hardware_tests()
add_hardware_test(Test1 2 "widgets:8;2,widgets:2")
add_hardware_test(Test2 5 "fluxcapacitors:40")
add_hardware_test(Test3 1 "10,widgets:1,fluxcapacitors:2")
add_hardware_test(Test4 4 "fluxcapacitors:121")
foreach(i RANGE 5 50)
add_hardware_test(Test${i} 1 "2,widgets:1")
endforeach()
foreach(i RANGE 51 100)
add_hardware_test(Test${i} 1 "2,transmogrifiers:2")
endforeach()
cleanup_hardware_tests()

View File

@ -1,3 +0,0 @@
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/cthwalloc.log")
set(RunCMake_TEST_FAILED "cthwalloc.log should not exist")
endif()

View File

@ -1,4 +0,0 @@
^Insufficient hardware
CMake Error at [^
]*/Tests/RunCMake/CTestHardwareAllocation/notenough1-ctest-s-hw/test\.cmake:[0-9]+ \(message\):
Tests did not pass$

View File

@ -1,5 +0,0 @@
setup_hardware_tests()
add_hardware_test(Test1 1 "fluxcapacitors:200")
cleanup_hardware_tests()

View File

@ -1,3 +0,0 @@
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/cthwalloc.log")
set(RunCMake_TEST_FAILED "cthwalloc.log should not exist")
endif()

View File

@ -1,4 +0,0 @@
^Insufficient hardware
CMake Error at [^
]*/Tests/RunCMake/CTestHardwareAllocation/notenough2-ctest-s-hw/test\.cmake:[0-9]+ \(message\):
Tests did not pass$

View File

@ -1,5 +0,0 @@
setup_hardware_tests()
add_hardware_test(Test1 1 "terminators:2")
cleanup_hardware_tests()

View File

@ -1 +0,0 @@
verify_ctest_hardware()

View File

@ -1,5 +0,0 @@
setup_hardware_tests()
add_hardware_test(Test1 1 "widgets:1")
cleanup_hardware_tests()

View File

@ -4,6 +4,6 @@ if(CASE_NAME MATCHES "^(.*)-ctest-s")
set(projname "${CMAKE_MATCH_1}")
project(${projname} NONE)
include(CTest)
include("@RunCMake_SOURCE_DIR@/HardwareCommon.cmake")
include("@RunCMake_SOURCE_DIR@/ResourceCommon.cmake")
include("@RunCMake_SOURCE_DIR@/${projname}.cmake")
endif()

View File

@ -0,0 +1,23 @@
function(setup_resource_tests)
if(CTEST_RESOURCE_ALLOC_ENABLED)
add_test(NAME ResourceSetup COMMAND "${CMAKE_COMMAND}" -E remove -f "${CMAKE_BINARY_DIR}/ctresalloc.log")
endif()
endfunction()
function(add_resource_test name sleep_time proc)
if(CTEST_RESOURCE_ALLOC_ENABLED)
add_test(NAME "${name}" COMMAND "${CTRESALLOC_COMMAND}" write "${CMAKE_BINARY_DIR}/ctresalloc.log" "${name}" "${sleep_time}" "${proc}")
set_property(TEST "${name}" PROPERTY DEPENDS ResourceSetup)
else()
add_test(NAME "${name}" COMMAND "${CTRESALLOC_COMMAND}" write "${CMAKE_BINARY_DIR}/ctresalloc.log" "${name}" "${sleep_time}")
endif()
set_property(TEST "${name}" PROPERTY RESOURCE_GROUPS "${proc}")
list(APPEND RESOURCE_TESTS "${name}")
set(RESOURCE_TESTS "${RESOURCE_TESTS}" PARENT_SCOPE)
endfunction()
function(cleanup_resource_tests)
if(CTEST_RESOURCE_ALLOC_ENABLED)
file(WRITE "${CMAKE_BINARY_DIR}/restests.txt" "${RESOURCE_TESTS}")
endif()
endfunction()

View File

@ -0,0 +1,167 @@
include(RunCMake)
include(RunCTest)
###############################################################################
# Test ctresalloc itself - we want to make sure it's not just rubber-stamping
# the test results
###############################################################################
function(ctresalloc_verify_log expected_contents)
if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log")
string(APPEND RunCMake_TEST_FAILED "Log file was not written\n")
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
return()
endif()
file(READ "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log" actual_contents)
if(NOT actual_contents STREQUAL expected_contents)
string(APPEND RunCMake_TEST_FAILED "Actual log did not match expected log\n")
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
endif()
endfunction()
function(run_ctresalloc_write_proc name proc)
file(REMOVE "${RunCMake_BINARY_DIR}/${name}-build/ctresalloc.log")
run_ctresalloc_write_proc_nodel("${name}" "${proc}" "${ARGN}")
endfunction()
function(run_ctresalloc_write_proc_nodel name proc)
string(REPLACE ";" "\\;" proc "${proc}")
run_cmake_command(${name} "${CMAKE_COMMAND}" -E env "${ARGN}" "${CTRESALLOC_COMMAND}" write "${RunCMake_BINARY_DIR}/${name}-build/ctresalloc.log" "${name}" 0 "${proc}")
endfunction()
function(run_ctresalloc_write_noproc name)
run_cmake_command(${name} "${CMAKE_COMMAND}" -E env "${ARGN}" "${CTRESALLOC_COMMAND}" write "${RunCMake_BINARY_DIR}/${name}-build/ctresalloc.log" "${name}" 0)
endfunction()
function(run_ctresalloc_verify name tests)
string(REPLACE ";" "\\;" tests "${tests}")
run_cmake_command(${name} "${CTRESALLOC_COMMAND}" verify "${RunCMake_SOURCE_DIR}/${name}.log" "${CMAKE_CURRENT_LIST_DIR}/resspec.json" "${tests}")
endfunction()
unset(ENV{CTEST_RESOURCE_GROUP_COUNT})
set(RunCMake_TEST_NO_CLEAN 1)
file(REMOVE_RECURSE "${RunCMake_BINARY_DIR}/ctresalloc-write-proc-good1-build")
file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/ctresalloc-write-proc-good1-build")
file(WRITE "${RunCMake_BINARY_DIR}/ctresalloc-write-proc-good1-build/ctresalloc.log"
[[begin test1
alloc widgets 0 1
dealloc widgets 0 1
end test1
]])
run_ctresalloc_write_proc_nodel(ctresalloc-write-proc-good1 "1,widgets:2,transmogrifiers:1;2,widgets:1,widgets:2"
CTEST_RESOURCE_GROUP_COUNT=3
CTEST_RESOURCE_GROUP_0=widgets,transmogrifiers
CTEST_RESOURCE_GROUP_0_WIDGETS=id:0,slots:2
CTEST_RESOURCE_GROUP_0_TRANSMOGRIFIERS=id:calvin,slots:1
CTEST_RESOURCE_GROUP_1=widgets
"CTEST_RESOURCE_GROUP_1_WIDGETS=id:0,slots:1\\;id:2,slots:2"
CTEST_RESOURCE_GROUP_2=widgets
"CTEST_RESOURCE_GROUP_2_WIDGETS=id:0,slots:1\\;id:2,slots:2"
)
set(RunCMake_TEST_NO_CLEAN 0)
run_ctresalloc_write_proc(ctresalloc-write-proc-good2 "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
CTEST_RESOURCE_GROUP_0_WIDGETS=id:3,slots:8
)
run_ctresalloc_write_proc(ctresalloc-write-proc-nocount "widgets:8")
run_ctresalloc_write_proc(ctresalloc-write-proc-badcount "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=2
)
run_ctresalloc_write_proc(ctresalloc-write-proc-nores "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badres "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets,transmogrifiers
)
run_ctresalloc_write_proc(ctresalloc-write-proc-nowidgets "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badwidgets1 "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
CTEST_RESOURCE_GROUP_0_WIDGETS=
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badwidgets2 "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
"CTEST_RESOURCE_GROUP_0_WIDGETS=id:3,slots:8\\;id:0,slots:1"
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badwidgets3 "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
CTEST_RESOURCE_GROUP_0_WIDGETS=id:3,slots:7
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badwidgets4 "widgets:8"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
CTEST_RESOURCE_GROUP_0_WIDGETS=invalid
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badwidgets5 "widgets:2,widgets:2"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
"CTEST_RESOURCE_GROUP_0_WIDGETS=id:0,slots:2\\;id:0,slots:1"
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badwidgets6 "widgets:2"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
"CTEST_RESOURCE_GROUP_0_WIDGETS=id:0,slots:2\\;id:0,slots:1"
)
run_ctresalloc_write_proc(ctresalloc-write-proc-badwidgets7 "widgets:2,widgets:2"
CTEST_RESOURCE_GROUP_COUNT=1
CTEST_RESOURCE_GROUP_0=widgets
CTEST_RESOURCE_GROUP_0_WIDGETS=id:0,slots:2
)
run_ctresalloc_write_noproc(ctresalloc-write-noproc-good1)
run_ctresalloc_write_noproc(ctresalloc-write-noproc-count
CTEST_RESOURCE_GROUP_COUNT=1
)
run_ctresalloc_verify(ctresalloc-verify-good1 "test1;test2")
run_ctresalloc_verify(ctresalloc-verify-good2 "")
run_ctresalloc_verify(ctresalloc-verify-nolog "")
run_ctresalloc_verify(ctresalloc-verify-nores "")
run_ctresalloc_verify(ctresalloc-verify-noid "")
run_ctresalloc_verify(ctresalloc-verify-notenough "")
run_ctresalloc_verify(ctresalloc-verify-baddealloc "")
run_ctresalloc_verify(ctresalloc-verify-leak "")
run_ctresalloc_verify(ctresalloc-verify-badtest1 "")
run_ctresalloc_verify(ctresalloc-verify-badtest2 "test1")
run_ctresalloc_verify(ctresalloc-verify-badtest3 "test1")
run_ctresalloc_verify(ctresalloc-verify-badtest4 "test1")
run_ctresalloc_verify(ctresalloc-verify-badtest5 "test1")
run_ctresalloc_verify(ctresalloc-verify-nobegin "test1")
run_ctresalloc_verify(ctresalloc-verify-noend "test1")
###############################################################################
# Now test the resource allocation feature of CTest
###############################################################################
function(run_ctest_resource name parallel random)
run_ctest("${name}-ctest-s-res" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
run_ctest("${name}-ctest-s-nores" "-DCTEST_RESOURCE_ALLOC_ENABLED=0" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
endfunction()
function(verify_ctest_resources)
file(READ "${RunCMake_TEST_BINARY_DIR}/restests.txt" restests)
execute_process(COMMAND "${CTRESALLOC_COMMAND}" verify "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log" "${CMAKE_CURRENT_LIST_DIR}/resspec.json" "${restests}"
OUTPUT_VARIABLE output ERROR_QUIET RESULT_VARIABLE result)
if(result)
string(APPEND RunCMake_TEST_FAILED "${output}")
set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
endif()
endfunction()
run_ctest_resource(lotsoftests 10 1)
run_ctest_resource(checkfree1 2 0)
run_ctest_resource(checkfree2 1 0)
run_ctest_resource(notenough1 1 0)
run_ctest_resource(notenough2 1 0)
run_ctest_resource(ensure_parallel 2 0)
set(ENV{CTEST_RESOURCE_GROUP_COUNT} 2)
run_ctest_resource(process_count 1 0)
unset(ENV{CTEST_RESOURCE_GROUP_COUNT})

View File

@ -0,0 +1 @@
verify_ctest_resources()

View File

@ -0,0 +1,7 @@
setup_resource_tests()
add_resource_test(Test1 1 "widgets:8")
add_resource_test(Test2 1 "fluxcapacitors:50;fluxcapacitors:50,widgets:8")
add_resource_test(Test3 1 "fluxcapacitors:121")
cleanup_resource_tests()

View File

@ -0,0 +1 @@
verify_ctest_resources()

View File

@ -0,0 +1,8 @@
setup_resource_tests()
# This test is an attack on the resource scheduling algorithm. It has been
# carefully crafted to fool the algorithm into thinking there aren't sufficient
# resources for it.
add_resource_test(Test1 1 "widgets:2;4,widgets:4")
cleanup_resource_tests()

Some files were not shown because too many files have changed in this diff Show More