Skip to content

Commit 5c6b8f0

Browse files
Second pass with more equal splitting.
1 parent ce3ea21 commit 5c6b8f0

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

src/TimeSplitterTask.php

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,6 @@ private function splitTestsByGroup(Generator $tests): array
130130

131131
private function splitTestsByRuntime(Generator $tests, TimeReport $timeReport): array
132132
{
133-
$totalRuntime = $timeReport->totalRuntime();
134-
$avgRuntime = $totalRuntime / $this->groupCount;
135-
136133
$skippedTests = [];
137134
$testsWithRuntime = [];
138135
$testsWithoutRuntime = [];
@@ -151,31 +148,41 @@ private function splitTestsByRuntime(Generator $tests, TimeReport $timeReport):
151148
}
152149
}
153150

151+
// Reverse sort, the larger runtimes are hard to fit than the smaller
152+
// ones, so lets get them out of the way first.
154153
arsort($testsWithRuntime);
155154

156155
$sums = array_fill(0, $this->groupCount, 0);
157156
$groups = array_fill(0, $this->groupCount, []);
158157

159-
$addedOne = false;
158+
$maxLoops = 3 * $this->groupCount;
160159
foreach ($testsWithRuntime as $testPath => $runtime) {
161-
$added = false;
162-
$idx = null;
163-
foreach ($sums as $idx => $sum) {
164-
if (($sum + $runtime) < $avgRuntime || !$addedOne) {
160+
$idx = 0;
161+
$loops = 0;
162+
while(true) {
163+
if ($loops > $maxLoops) {
164+
throw new TaskException(
165+
$this,
166+
"Max loop count ({$maxLoops}) reached."
167+
);
168+
}
169+
170+
$sum = $sums[$idx];
171+
$prevIdx = $idx - 1;
172+
if ($prevIdx < 0) {
173+
$prevIdx = $this->groupCount - 1;
174+
}
175+
$nextIdx = $idx + 1;
176+
if ($nextIdx === $this->groupCount) {
177+
$nextIdx = 0;
178+
}
179+
if ($sum === 0 || ($sum < $sums[$prevIdx] && $sum < $sums[$nextIdx])) {
180+
$sums[$idx] += $runtime;
165181
$groups[$idx][] = $testPath;
166-
$sum += $runtime;
167-
$sums[$idx] = $sum;
168-
$addedOne = true;
169-
$added = true;
170182
break;
171183
}
172-
}
173-
if (!$added) {
174-
if ($idx === null) {
175-
$idx = $this->groupCount - 1;
176-
}
177-
$groups[$idx][] = $testPath;
178-
$sums[$idx] += $runtime;
184+
$idx++;
185+
$loops++;
179186
}
180187
}
181188

@@ -190,6 +197,8 @@ private function splitTestsByRuntime(Generator $tests, TimeReport $timeReport):
190197
}
191198
}
192199

200+
// Add skipped tests onto the last group as they take relatively no time
201+
// to run.
193202
$maxGroupIdx = $this->groupCount - 1;
194203
if (count($skippedTests) > 0) {
195204
$groups[$maxGroupIdx] = array_merge($groups[$maxGroupIdx], $skippedTests);

0 commit comments

Comments
 (0)