mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
fix(ci): exempt surefire-bound IT classes from the failsafe roster (#15830)
* fix(ci): exempt surefire-bound IT classes from the failsafe roster The non-hosted roster required every *IT class to appear in target/failsafe-reports, but packages/managed-agent-server binds ManagedAgentPackagingIT to the artifact-packaging surefire execution and excludes it from the mysql-integration failsafe (#15718). A class that is forbidden to run under failsafe therefore could never satisfy the roster: Maven reported BUILD SUCCESS with the class's 3 tests passing, then the job failed on 'ran no test in this job'. It reproduces on main with no PR code present (#15820 item 1) and turned the full tier red for every managed-agent PR. Name the surefire-bound classes per module, skip them in the roster, and fail the check if the module's pom stops binding such a name to both a surefire include and a failsafe exclude, so the exemption cannot drift away from the pom it describes. * test(managed-agent): use managed JDBC for message fixture Co-authored-by: Qwen-Coder <[email protected]> --------- Co-authored-by: Qwen-Coder <[email protected]>
This commit is contained in:
1 parent
1211409492
commit
7fc327825e
3 files changed
+81
-1
No files matched your search
+2
@@ -13,6 +13,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -43,6 +44,7 @@ class ManagedUserMessageStoreTest {
|
||||
@Autowired
|
||||
private ManagedAgentService agents;
|
||||
@Autowired
|
||||
@Qualifier("managedJdbcTemplate")
|
||||
private JdbcTemplate jdbc;
|
||||
@Autowired
|
||||
private ObjectMapper json;
|
||||
|
||||
@@ -48,6 +48,38 @@ if (!inFamily || modules.length === 0) {
|
||||
}
|
||||
|
||||
const simpleName = (className) => className.split('.').at(-1);
|
||||
|
||||
// A module can bind an `*IT` class to a surefire execution instead of failsafe.
|
||||
// Such a class is then excluded from the mysql-integration failsafe (so it can
|
||||
// never have a report) while still matching the non-hosted roster below, which
|
||||
// is a contradiction rather than a missed run: #15820 item 1. Name each such
|
||||
// class here, and keep the pom in agreement — the check below fails if a name
|
||||
// is not bound to a surefire include and a failsafe exclude in that module.
|
||||
const SUREFIRE_BOUND = new Map([
|
||||
['packages/managed-agent-server', ['ManagedAgentPackagingIT']],
|
||||
]);
|
||||
|
||||
// The module argument is whatever the job passed to Maven: relative on CI,
|
||||
// absolute in the meta-tests, so match its trailing segments.
|
||||
const boundNames = (module) => {
|
||||
const normalized = path.normalize(module).split(path.sep).join('/');
|
||||
for (const [dir, names] of SUREFIRE_BOUND) {
|
||||
if (normalized === dir || normalized.endsWith(`/${dir}`)) return names;
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const rosterExempt = (module, name) => boundNames(module).includes(name);
|
||||
|
||||
const pomBindsBoth = (module, name) => {
|
||||
const pom = path.join(module, 'pom.xml');
|
||||
if (!existsSync(pom)) return false;
|
||||
const xml = readFileSync(pom, 'utf8');
|
||||
return (
|
||||
xml.includes(`<include>**/${name}.java</include>`) &&
|
||||
xml.includes(`<exclude>**/${name}.java</exclude>`)
|
||||
);
|
||||
};
|
||||
// Not readdirSync's `recursive`: a Node older than 18.17 ignores it, and the
|
||||
// check would then find no integration test at all.
|
||||
const javaFiles = (dir, prefix = []) =>
|
||||
@@ -61,7 +93,21 @@ for (const module of modules) {
|
||||
const expected = javaFiles(path.join(module, 'src', 'test', 'java'))
|
||||
.filter((file) => file.endsWith('.java'))
|
||||
.map((file) => file.slice(0, -'.java'.length))
|
||||
.filter((className) => inFamily(simpleName(className)));
|
||||
.filter((className) => inFamily(simpleName(className)))
|
||||
.filter((className) => {
|
||||
const name = simpleName(className);
|
||||
if (!rosterExempt(module, name)) return true;
|
||||
console.log(`${module}: ${name} runs under surefire, not failsafe`);
|
||||
return false;
|
||||
});
|
||||
for (const name of boundNames(module)) {
|
||||
if (!pomBindsBoth(module, name)) {
|
||||
failed = true;
|
||||
console.error(
|
||||
`::error::${module}: ${name} is listed as surefire-bound but its pom no longer binds it to a surefire include and a failsafe exclude`,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (optIn && expected.length !== 1) {
|
||||
failed = true;
|
||||
console.error(
|
||||
|
||||
@@ -148,6 +148,38 @@ describe('check-failsafe-reports', () => {
|
||||
expect(check('hosted', hosted).status).toBe(0);
|
||||
});
|
||||
|
||||
it('exempts a class the module binds to surefire, and fails when the pom disagrees', () => {
|
||||
// The real module name, because the exemption is keyed on it: the pom binds
|
||||
// ManagedAgentPackagingIT to a surefire execution and excludes it from the
|
||||
// mysql-integration failsafe, so it can never satisfy the non-hosted roster.
|
||||
const name = 'packages/managed-agent-server';
|
||||
const sources = [
|
||||
'com.example.ManagedAgentPackagingIT',
|
||||
'com.example.OrdersIT',
|
||||
];
|
||||
const bound = module(name, sources, { 'com.example.OrdersIT': [1, 0] });
|
||||
writeFileSync(
|
||||
join(bound, 'pom.xml'),
|
||||
'<project><plugin><configuration><includes><include>**/ManagedAgentPackagingIT.java</include></includes></configuration></plugin><plugin><configuration><excludes><exclude>**/ManagedAgentPackagingIT.java</exclude></excludes></configuration></plugin></project>',
|
||||
);
|
||||
const exempt = check('non-hosted', bound);
|
||||
expect(exempt.output).toContain(
|
||||
'ManagedAgentPackagingIT runs under surefire, not failsafe',
|
||||
);
|
||||
expect(exempt.status).toBe(0);
|
||||
|
||||
// Drift guard: the exemption is only valid while the pom keeps both bindings.
|
||||
writeFileSync(
|
||||
join(bound, 'pom.xml'),
|
||||
'<project><plugin><configuration><excludes><exclude>**/ManagedAgentPackagingIT.java</exclude></excludes></configuration></plugin></project>',
|
||||
);
|
||||
const drifted = check('non-hosted', bound);
|
||||
expect(drifted.output).toContain(
|
||||
'no longer binds it to a surefire include',
|
||||
);
|
||||
expect(drifted.status).toBe(1);
|
||||
});
|
||||
|
||||
it('counts the test cases failsafe folds into an outer report', () => {
|
||||
const dir = module('nested', ['com.example.OrdersIT']);
|
||||
writeFileSync(
|
||||
|
||||
Reference in new issue
Block a user