diff --git a/app/cdash/app/Controller/Api/Index.php b/app/cdash/app/Controller/Api/Index.php index b70f94fd90..a1b6b94347 100644 --- a/app/cdash/app/Controller/Api/Index.php +++ b/app/cdash/app/Controller/Api/Index.php @@ -248,7 +248,16 @@ public function getDynamicBuilds(): array $sql .= ' WHERE ' . implode(' AND ', $whereClauses); $sql .= ' AND b.starttime < ? '; $params[] = $this->endDate; - $sql .= $this->filterSQL; + // The API labels a dynamic row with the target group name ($rule->name), + // while g.name is the row's source group. Apply group-name filters to + // the target group; leave every other filter on the source row. + $dynamic_filter_sql = str_replace( + 'g.name', '?', (string) $this->filterSQL, $group_filter_count); + $sql .= $dynamic_filter_sql; + $params = array_merge( + $params, + array_fill(0, $group_filter_count, $rule->name) + ); $sql .= ' ORDER BY b.submittime DESC LIMIT 1 '; $union_parts[] = "($sql)"; diff --git a/app/cdash/tests/CMakeLists.txt b/app/cdash/tests/CMakeLists.txt index 7e3307e952..e4ab2532ce 100644 --- a/app/cdash/tests/CMakeLists.txt +++ b/app/cdash/tests/CMakeLists.txt @@ -709,8 +709,11 @@ set_tests_properties(donehandler PROPERTIES DEPENDS submission_assign_buildid) add_php_test(expiredbuildrules) set_tests_properties(expiredbuildrules PROPERTIES DEPENDS donehandler) +add_php_test(dynamicbuildgroupfilters) +set_tests_properties(dynamicbuildgroupfilters PROPERTIES DEPENDS expiredbuildrules) + add_php_test(filterblocks) -set_tests_properties(filterblocks PROPERTIES DEPENDS expiredbuildrules) +set_tests_properties(filterblocks PROPERTIES DEPENDS dynamicbuildgroupfilters) add_php_test(indexnextprevious) set_tests_properties(indexnextprevious PROPERTIES DEPENDS filterblocks) diff --git a/app/cdash/tests/test_dynamicbuildgroupfilters.php b/app/cdash/tests/test_dynamicbuildgroupfilters.php new file mode 100644 index 0000000000..d349f3a074 --- /dev/null +++ b/app/cdash/tests/test_dynamicbuildgroupfilters.php @@ -0,0 +1,98 @@ +createProject(['Name' => self::PROJECT_NAME]); + + $site = Site::create(['name' => 'dynamic-group-filter-site']); + $build = new Build(); + $build->Name = self::BUILD_NAME; + $build->ProjectId = $projectid; + $build->SiteId = $site->id; + $build->SetStamp('20090223-0710-Nightly'); + $build->StartTime = '2009-02-23 07:10:00'; + $this->assertTrue($build->AddBuild()); + + $dynamic_group = new BuildGroup(); + $dynamic_group->SetProjectId($projectid); + $dynamic_group->SetName('latest results'); + $dynamic_group->SetType('Latest'); + $dynamic_group->Save(); + + DB::table('build2grouprule')->insert([ + 'groupid' => $dynamic_group->GetId(), + 'buildname' => $build->Name, + 'siteid' => $site->id, + 'parentgroupid' => $build->GroupId, + 'starttime' => '1980-01-01 00:00:00', + 'endtime' => '1980-01-01 00:00:00', + ]); + + $this->assertGroupFilterReturnsOnly('Nightly', self::BUILD_NAME); + $this->assertGroupFilterReturnsOnly('latest results', self::BUILD_NAME); + $this->assertGroupAndBuildFilterReturnsNoGroups('latest results', 'other-build'); + + $dynamic_group->Delete(); + remove_project_builds($projectid); + Project::findOrFail((int) $projectid)->delete(); + $site->delete(); + } + + /** @return list */ + private function getFilteredBuildGroups(string $group_name, string $build_name): array + { + $filter = http_build_query([ + 'filtercount' => 2, + 'filtercombine' => 'and', + 'showfilters' => 1, + 'field1' => 'groupname', + 'compare1' => 61, + 'value1' => $group_name, + 'field2' => 'buildname', + 'compare2' => 61, + 'value2' => $build_name, + ]); + $this->get( + $this->url . '/api/v1/index.php?project=' . self::PROJECT_NAME + . "&date=2009-02-23&$filter" + ); + $content = $this->getBrowser()->getContent(); + /** @var array{buildgroups: list} $response */ + $response = json_decode($content, true); + + return $response['buildgroups']; + } + + private function assertGroupFilterReturnsOnly(string $group_name, string $build_name): void + { + $buildgroups = $this->getFilteredBuildGroups($group_name, $build_name); + + $this->assertTrue( + count($buildgroups) > 0, + "Expected group-name filter to return '$group_name'" + ); + foreach ($buildgroups as $buildgroup_response) { + $this->assertEqual($group_name, $buildgroup_response['name']); + } + } + + private function assertGroupAndBuildFilterReturnsNoGroups( + string $group_name, + string $build_name, + ): void { + $this->assertEqual([], $this->getFilteredBuildGroups($group_name, $build_name)); + } +}