mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 14:38:23 -10:00
* fix(ci): align Java integration database and lock lifetime * test(ci): re-pin the sdk-java lock and MySQL probe after the single-step merge The merge commit staged the conflict resolution before these two re-pins were written, so they land as a follow-up in the same push: - `keeps the host lock out of every Maven child` counted three lock-bearing steps; #14903 collapsed the MariaDB lane's two Maven steps into one, so the count is now two (test job + mysql-integration). - The MySQL startup probe took the step's first `mvn` line, which is now the `-DskipTests install` staging command; select the `-Pmysql-integration` command instead so the probe still exercises the consumer. Verified: vitest sdk-java-workflow.test.js 96 passed; prettier --check clean. Co-authored-by: Qwen-Coder <[email protected]> Patrol-Run: qwen-pr-conflict/jmvgz448zlp * fix(ci): skip the MySQL binlog, drop the unused database, correct the reaper bound Three independent corrections to the mysql-integration lane this PR reworks. 1. MySQL 8 enables the binary log by default (MariaDB 10.11 did not in the configuration this lane replaced), and the datadir is an uncapped tmpfs. Nothing in packages/managed-agent-server/src or packages/sdk-java reads a binlog (0 hits for binlog|log_bin|GTID|SHOW MASTER STATUS), and the container is disposable with no replica, so `--skip-log-bin` is appended after the image name beside --innodb-use-native-aio=0. Without it the ~67 MiB hex-encoded LONGBLOB query this lane already raises max_allowed_packet for is serialized a second time into host RAM. 2. `--env MYSQL_DATABASE='runtime_broker_test'` had no consumer: the lane's only connection is -Dmysql.url=.../managed_agent_test?createDatabaseIfNotExist=true. The declaration invited a cleanup that drops createDatabaseIfNotExist and dies at first connect with Unknown database. Dropping it lets the JDBC URL own the schema and shrinks the diff. 3. The cleanup comment and removal-failure warning said the host reaper reclaims a stranded container "after a 24h age gate" / "up to a day". The real bound is ~48h: qwen-docker-cleanup.sh:31 gates on a strict `now - created_at > 86400` (exactly 24h is SKIPPED) and qwen-docker-cleanup.timer fires once a day, so a container created just after a fire is skipped at the next one and reaped at the one after. Test pins updated in the same change: the start-step assertion, the exact docker-run trace literal, and the cleanup warning literal. All three were mutant-verified red (drop --skip-log-bin / re-add MYSQL_DATABASE / restore "after 24h") and restored byte-identical. Only this PR's own copy of the reaper wording is corrected; the two pre-existing copies (sdk-java.yml's event-transport-multi-node job and release-managed-agent-reference.yml) are untouched to keep this diff scoped. Co-authored-by: Qwen-Coder <[email protected]> Patrol-Run: qwen-pr-closeout/jmvhb9cysmc --------- Co-authored-by: Qwen-Coder <[email protected]>
102 lines
3.9 KiB
JavaScript
102 lines
3.9 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2026 Qwen Team
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
import { parse } from 'yaml';
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
const read = (file) =>
|
|
readFileSync(new URL(`../../${file}`, import.meta.url), 'utf8');
|
|
|
|
const GATED_MODULES = ['packages/managed-agent-server'];
|
|
|
|
describe('SpotBugs gate witness', () => {
|
|
// A Match whose only predicate is a wildcard class or package turns the
|
|
// gate into a silent no-op: the build reports the same `BugInstance size
|
|
// is 0` as a genuinely clean tree.
|
|
it('rejects wildcard-only Match blocks in the per-module excludes files', () => {
|
|
for (const mod of GATED_MODULES) {
|
|
const xml = read(`${mod}/spotbugs-excludes.xml`);
|
|
for (const [, body] of xml.matchAll(/<Match>([\s\S]*?)<\/Match>/g)) {
|
|
const specific =
|
|
/<Bug\s+pattern="[^"]+"/.test(body) ||
|
|
/<Method[\s/>]/.test(body) ||
|
|
/<Field[\s/>]/.test(body) ||
|
|
/<Class\s+name="(?!~)/.test(body) ||
|
|
/<Package\s+name="(?!~)/.test(body);
|
|
expect(
|
|
specific,
|
|
`${mod}/spotbugs-excludes.xml: every <Match> ` +
|
|
'needs a Bug pattern, a Method/Field, or a concrete (non-~) ' +
|
|
'Class/Package name — wildcard-only blocks silence the gate',
|
|
).toBe(true);
|
|
}
|
|
}
|
|
});
|
|
|
|
// The combined Server verification checks both Server and Broker classes.
|
|
// The SDK is now its only staged dependency.
|
|
it('keeps the gate on combined Server verification without staging a Broker artifact', () => {
|
|
const workflow = parse(read('.github/workflows/sdk-java.yml'));
|
|
const steps = Object.values(workflow.jobs).flatMap(
|
|
(job) => job.steps ?? [],
|
|
);
|
|
const byName = (name) => steps.filter((step) => step.name === name);
|
|
|
|
// Hosted MySQL, the MySQL job's combined install-and-verify step and
|
|
// both EventTransport gate jobs each stage the sibling modules before
|
|
// their own verify; the Hosted failover job stages them before packaging
|
|
// the jar its arms run.
|
|
const mergedStep =
|
|
'Install and verify Managed Agent dependencies, tests, Checkstyle, and MySQL integration';
|
|
const staging = [
|
|
...byName('Install Managed Agent dependencies'),
|
|
...byName(mergedStep),
|
|
];
|
|
expect(staging.length).toBe(5);
|
|
for (const step of staging) {
|
|
expect(step.run).toContain('packages/sdk-java/qwencode/pom.xml');
|
|
expect(step.run).not.toContain('runtime-broker/pom.xml');
|
|
}
|
|
|
|
const enforcing = [
|
|
...byName(mergedStep),
|
|
...byName('Verify Hosted Java, Spring and MySQL processes'),
|
|
...byName('Verify the EventTransport broker gates'),
|
|
...byName('Verify the EventTransport multi-node gates'),
|
|
];
|
|
expect(enforcing.length).toBe(4);
|
|
for (const step of enforcing) {
|
|
// Match the command line only: the MariaDB job's merged step explains
|
|
// its own incident in comments that say 'verify', so a bare
|
|
// toContain('verify') would let prose witness the phase after a real
|
|
// narrowing to `clean test`.
|
|
const commands = step.run
|
|
.split('\n')
|
|
.filter((line) => !line.trimStart().startsWith('#'))
|
|
.join('\n');
|
|
expect(commands).toMatch(/\bclean verify\b/);
|
|
expect(step.run).not.toContain('spotbugs.skip');
|
|
}
|
|
|
|
// Global invariant: the skip lives nowhere else — not on a new or
|
|
// renamed step, and not smuggled in through MAVEN_ARGS at any env level
|
|
// (the mvn script reads that variable, so it would not show up in run).
|
|
const envBlobs = [
|
|
workflow.env,
|
|
...Object.values(workflow.jobs).map((job) => job.env),
|
|
...steps.map((step) => step.env),
|
|
];
|
|
for (const env of envBlobs) {
|
|
expect(JSON.stringify(env ?? {})).not.toContain('spotbugs.skip');
|
|
}
|
|
const withSkip = steps.filter((step) =>
|
|
step.run?.includes('spotbugs.skip'),
|
|
);
|
|
expect(withSkip).toEqual([]);
|
|
});
|
|
});
|