This Differential adds two new unit engines both are for Golang and both uses
ArcanistGoTestResultParser to parse the result.
Details
Details
- Reviewers
- None
- Group Reviewers
Blessed Reviewers - Maniphest Tasks
- T6867: Add linter and unit test engine for Go(lang)
Test in https://github.com/julienschmidt/httprouter, must add the following arcconfig file
{ "phabricator.uri" : "https://secure.phabricator.com/", "unit.engine": "GoTestEngine" }
Then make a breaking change and run 'arc unit'.
Example output:
PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestPathClean PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestPathCleanMallocs PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestParams PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouter PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouterAPI PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouterRoot PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouterNotAllowed PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouterNotFound PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouterPanicHandler PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouterLookup PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestRouterServeFiles PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestCountParams FAIL Go::Test::github.com::julienschmidt::httprouter::TestTreeAddAndGet tree_test.go:100: maxParams mismatch for node 'ntact': is 0, should be 0 FAIL Go::Test::github.com::julienschmidt::httprouter::TestTreeWildcard tree_test.go:100: maxParams mismatch for node ':query': is 1, should be 1 PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeWildcardConflict PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeChildConflict PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeDupliatePath PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestEmptyWildcardName PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeCatchAllConflict PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeCatchAllConflictRoot PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeDoubleWildcard PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeTrailingSlashRedirect PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeFindCaseInsensitivePath PASS <1ms★ Go::Test::github.com::julienschmidt::httprouter::TestTreeInvalidNodeType
Diff Detail
Diff Detail
- Repository
- rARC Arcanist
- Branch
- go-unit-engine
- Lint
Lint Passed - Unit
Tests Passed - Build Status
Buildable 5500 Build 5519: [Placeholder Plan] Wait for 30 Seconds
Event Timeline
Comment Actions
I have a version of this with coverage support if you're interested:
<?php final class ConfigurableGolangTestEngine extends ArcanistUnitTestEngine { public function run() { $working_copy = $this->getWorkingCopy(); $this->project_root = $working_copy->getProjectRoot(); $cover_tmp = new TempFile(); $junit_tmp = new TempFile(); $future = $this->buildTestFuture($junit_tmp, $cover_tmp); $future->resolvex(); return $this->parseTestResults($junit_tmp, $cover_tmp); } public function buildTestFuture($junit_tmp, $cover_tmp) { $paths = $this->getPaths(); $config_manager = $this->getConfigurationManager(); $coverage_command = $config_manager ->getConfigFromAnySource('unit.golang.command'); $cmd_line = csprintf($coverage_command, $junit_tmp, $cover_tmp); return new ExecFuture('%C', $cmd_line); } public function parseTestResults($junit_tmp, $cover_tmp) { $parser = new ArcanistXUnitTestResultParser(); $results = $parser->parseTestResults( Filesystem::readFile($junit_tmp)); if ($this->getEnableCoverage() !== false) { $coverage_report = $this->readCoverage($cover_tmp); foreach ($results as $result) { $result->setCoverage($coverage_report); } } return $results; } public function readCoverage($path) { $coverage_data = Filesystem::readFile($path); if (empty($coverage_data)) { return array(); } $coverage_dom = new DOMDocument(); $coverage_dom->loadXML($coverage_data); $paths = $this->getPaths(); $reports = array(); $classes = $coverage_dom->getElementsByTagName('class'); $cwd = getcwd(); foreach ($classes as $class) { $absolute_path = $class->getAttribute('filename'); $relative_path = str_replace($cwd.'/', '', $absolute_path); if (is_file($absolute_path.'.go')) { $relative_path .= '.go'; $absolute_path .= '.go'; } if (!file_exists($absolute_path)) { continue; } // get total line count in file $line_count = count(file($absolute_path)); $coverage = ''; $start_line = 1; $lines = $class->getElementsByTagName('line'); for ($ii = 0; $ii < $lines->length; $ii++) { $line = $lines->item($ii); $next_line = intval($line->getAttribute('number')); for ($start_line; $start_line < $next_line; $start_line++) { $coverage .= 'N'; } if (intval($line->getAttribute('hits')) == 0) { $coverage .= 'U'; } else if (intval($line->getAttribute('hits')) > 0) { $coverage .= 'C'; } $start_line++; } if ($start_line < $line_count) { foreach (range($start_line, $line_count) as $line_num) { $coverage .= 'N'; } } $reports[$relative_path] = $coverage; } return $reports; } }
Comment Actions
That's perfect thank you!
public function buildTestFuture($junit_tmp, $cover_tmp) { $paths = $this->getPaths(); $config_manager = $this->getConfigurationManager(); $coverage_command = $config_manager ->getConfigFromAnySource('unit.golang.command'); $cmd_line = csprintf($coverage_command, $junit_tmp, $cover_tmp);
Oh cool, I did not know that you can actually configure the engine as such! I'm going to combine D12598 D12546 and D12537 into one Differential that is configurable.