Skip to content

Commit deecdd2

Browse files
NeloopMartin Kruliš
authored andcommitted
Add directory property to the exercise compilation node structure
1 parent a0d09c0 commit deecdd2

File tree

4 files changed

+55
-16
lines changed

4 files changed

+55
-16
lines changed

app/helpers/ExerciseConfig/Compilation/BoxesOptimizer.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,6 @@ private function optimizeTree(Node $rootNode) {
136136
return $n === $compared;
137137
});
138138
$child->setTestId(null); // clear the test identification
139-
// TODO: set directory
140-
// TODO: dependencies setting
141139

142140
foreach ($compared->getChildren() as $comparedChild) {
143141
$comparedChild->removeParent($compared);

app/helpers/ExerciseConfig/Compilation/DirectoriesResolver.php

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717

1818
/**
19-
* Internal exercise configuration compilation service. Handles tests in
20-
* execution and their separation into appropriate sub-directories. This mainly
21-
* means modification of file variables and prefixing them with proper
22-
* directory. Mkdir tasks will be also constructed and added to resulting tree.
19+
* Internal exercise configuration compilation service. Handles creation of the directories used during execution and
20+
* creating dumping boxes for all created directories. Alongside that for optimized boxes the name of the directory in
21+
* which they will be processed has to be found.
2322
* @note Should be called after optimisation.
2423
*/
2524
class DirectoriesResolver {
@@ -88,22 +87,22 @@ private function createDumpResultsNode(string $testId, string $testName): Node {
8887
/**
8988
* Add mkdir tasks for all directories at the beginning of the tree.
9089
* @param RootedTree $tree
91-
* @param Node[][] $testNodes indexed with testId
90+
* @param Node[][] $directoriesNodes indexed with testId
9291
* @param CompilationContext $context
9392
* @param CompilationParams $params
9493
* @return RootedTree
9594
* @throws ExerciseConfigException
9695
*/
97-
private function addDirectories(RootedTree $tree, array $testNodes,
96+
private function addDirectories(RootedTree $tree, array $directoriesNodes,
9897
CompilationContext $context, CompilationParams $params): RootedTree {
99-
if (count($testNodes) === 0) {
98+
if (count($directoriesNodes) === 0) {
10099
return $tree;
101100
}
102101

103102
// go through all tests
104103
$lastMkdirNode = null;
105104
$result = new RootedTree();
106-
foreach ($testNodes as $testId => $nodes) {
105+
foreach ($directoriesNodes as $testId => $nodes) {
107106
$testName = $context->getTestsNames()[$testId];
108107

109108
if ($lastMkdirNode === null) {
@@ -148,18 +147,31 @@ private function addDirectories(RootedTree $tree, array $testNodes,
148147
* @throws ExerciseConfigException
149148
*/
150149
public function resolve(RootedTree $tree, CompilationContext $context, CompilationParams $params): RootedTree {
151-
$testNodes = [];
150+
// Let's break it down...
151+
// DirectoriesResolver works in cooperation with BoxesOptimizer which optimizes the flow of the tasks and marks the
152+
// nodes which were optimized (this effectively means settings the test-id to null). Directories resolver then
153+
// goes through the tree and creates the directories needed for execution. If the test-id is set, it is easy and
154+
// straightforward, if it is not set the directories have to be smartly named and generated.
155+
// The algorithm follows... The tree is searched with breadth-first approach. Every node is processed in
156+
// the following way. If the node belongs to the test, the test identification is recorded and children of this node
157+
// are processed. If the node was optimised (has null test-id) then it is needed further processing. We need to
158+
// figure out the name of the directory which will be created for this optimized node and its sub-nodes. The name of
159+
// the directory is composed of categories of boxes in the most left sub-branch which does not have test-id set.
160+
// Once the name is known, it is used as a directory for the processed node and all the sub-nodes in the most left
161+
// branch of the tree. After that, children of the node are processed.
162+
163+
$directoriesNodes = [];
152164
$stack = array_reverse($tree->getRootNodes());
153165
while (!empty($stack)) {
154166
$current = array_pop($stack);
155167
$testId = $current->getTestId();
156168
if ($testId !== null) {
157169
// all nodes of each tests are saved and further dependencies
158170
// on mkdir tasks are set on them
159-
if (!array_key_exists($testId, $testNodes)) {
160-
$testNodes[$testId] = [];
171+
if (!array_key_exists($testId, $directoriesNodes)) {
172+
$directoriesNodes[$testId] = [];
161173
}
162-
$testNodes[$testId][] = $current;
174+
$directoriesNodes[$testId][] = $current;
163175
}
164176

165177
// process current node
@@ -171,7 +183,7 @@ public function resolve(RootedTree $tree, CompilationContext $context, Compilati
171183
}
172184
}
173185

174-
return $this->addDirectories($tree, $testNodes, $context, $params);
186+
return $this->addDirectories($tree, $directoriesNodes, $context, $params);
175187
}
176188

177189
}

app/helpers/ExerciseConfig/Compilation/Tree/Node.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ class Node {
2020
*/
2121
private $box;
2222

23+
/**
24+
* Directory in which box of this node should be executed and located.
25+
* @var string
26+
*/
27+
private $directory = null;
28+
2329
/**
2430
* Identification of test to which this box belongs to.
2531
* @var string
@@ -87,6 +93,25 @@ public function setBox(Box $box): Node {
8793
return $this;
8894
}
8995

96+
/**
97+
* Directory to which this nodes box belongs to.
98+
* @note Should be set for all nodes during compilation.
99+
* @return null|string
100+
*/
101+
public function getDirectory(): ?string {
102+
return $this->directory;
103+
}
104+
105+
/**
106+
* Set the directory of this node.
107+
* @param string $directory
108+
* @return Node
109+
*/
110+
public function setDirectory(string $directory): Node {
111+
$this->directory = $directory;
112+
return $this;
113+
}
114+
90115
/**
91116
* Test identification for corresponding box.
92117
* @return string|null

tests/ExerciseConfig/Compilation/Tree/Node.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,24 @@ class TestNode extends Tester\TestCase
2323
Assert::equal($test, $node->getTestId());
2424
}
2525

26-
public function testPipelineAndTest() {
26+
public function testPipelineAndTestAndDirectory() {
2727
$portNode = new PortNode(new CustomBox());
2828
$node = new Node($portNode);
2929

3030
Assert::null($node->getPipelineId());
3131
Assert::null($node->getTestId());
32+
Assert::null($node->getDirectory());
3233

3334
$pipeline = "pipeline";
3435
$test = "test";
36+
$directory = "directory";
3537
$node->setPipelineId($pipeline);
3638
$node->setTestId($test);
39+
$node->setDirectory($directory);
3740

3841
Assert::equal($pipeline, $node->getPipelineId());
3942
Assert::equal($test, $node->getTestId());
43+
Assert::equal($directory, $node->getDirectory());
4044
}
4145

4246
public function testTasks() {

0 commit comments

Comments
 (0)