@dionlarson/playwright-orchestrator-mysql 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mysql-adapter.d.ts +1 -0
- package/dist/mysql-adapter.js +33 -21
- package/package.json +1 -1
package/dist/mysql-adapter.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class MySQLAdapter extends Adapter {
|
|
|
14
14
|
failTest(params: ResultTestParams): Promise<void>;
|
|
15
15
|
saveTestRun({ runId, testRun, args, historyWindow }: SaveTestRunParams): Promise<void>;
|
|
16
16
|
initialize(): Promise<void>;
|
|
17
|
+
private addTitleColumnIfNeeded;
|
|
17
18
|
startShard(runId: string): Promise<TestRunConfig>;
|
|
18
19
|
finishShard(runId: string): Promise<void>;
|
|
19
20
|
dispose(): Promise<void>;
|
package/dist/mysql-adapter.js
CHANGED
|
@@ -42,31 +42,27 @@ export class MySQLAdapter extends Adapter {
|
|
|
42
42
|
const client = await this.pool.getConnection();
|
|
43
43
|
try {
|
|
44
44
|
await client.beginTransaction();
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
SELECT * FROM ??
|
|
55
|
-
WHERE run_id = UUID_TO_BIN(?) AND order_num = @order_num`, [
|
|
56
|
-
this.testsTable,
|
|
57
|
-
runId,
|
|
58
|
-
TestStatus.Ready,
|
|
45
|
+
// Use UPDATE ... ORDER BY ... LIMIT 1 for truly atomic claim.
|
|
46
|
+
// This locks exactly one row during the UPDATE, preventing race conditions.
|
|
47
|
+
// Store the claimed order_num in a session variable for the subsequent SELECT.
|
|
48
|
+
const [result] = await client.query(`UPDATE ?? SET status = ?, updated = CURRENT_TIMESTAMP, order_num = (@claimed_order := order_num)
|
|
49
|
+
WHERE run_id = UUID_TO_BIN(?) AND status = ?
|
|
50
|
+
ORDER BY order_num
|
|
51
|
+
LIMIT 1;
|
|
52
|
+
|
|
53
|
+
SELECT * FROM ?? WHERE run_id = UUID_TO_BIN(?) AND order_num = @claimed_order`, [
|
|
59
54
|
this.testsTable,
|
|
60
55
|
TestStatus.Ongoing,
|
|
61
56
|
runId,
|
|
57
|
+
TestStatus.Ready,
|
|
62
58
|
this.testsTable,
|
|
63
59
|
runId,
|
|
64
60
|
]);
|
|
65
61
|
await client.commit();
|
|
66
|
-
if (result[
|
|
62
|
+
if (result[1].length === 0)
|
|
67
63
|
return undefined;
|
|
68
|
-
const { file, line, pos, project, timeout, order_num } = result[
|
|
69
|
-
return { file, position: `${line}:${pos}`, project, timeout, order: order_num };
|
|
64
|
+
const { file, line, pos, project, timeout, order_num, title } = result[1][0];
|
|
65
|
+
return { file, position: `${line}:${pos}`, project, timeout, order: order_num, title };
|
|
70
66
|
}
|
|
71
67
|
catch (e) {
|
|
72
68
|
await client.rollback();
|
|
@@ -86,9 +82,9 @@ export class MySQLAdapter extends Adapter {
|
|
|
86
82
|
let tests = this.transformTestRunToItems(testRun.testRun);
|
|
87
83
|
const testInfos = await this.loadTestInfos(tests);
|
|
88
84
|
tests = this.sortTests(tests, testInfos, { historyWindow });
|
|
89
|
-
const testValues = tests.map(({ position, order, file, project, timeout }) => {
|
|
85
|
+
const testValues = tests.map(({ position, order, file, project, timeout, title }) => {
|
|
90
86
|
const [line, character] = position.split(':');
|
|
91
|
-
return [runId, order, file, +line, +character, project, timeout];
|
|
87
|
+
return [runId, order, file, +line, +character, project, timeout, title];
|
|
92
88
|
});
|
|
93
89
|
const values = [
|
|
94
90
|
this.configTable,
|
|
@@ -101,8 +97,8 @@ export class MySQLAdapter extends Adapter {
|
|
|
101
97
|
await this.pool.query({
|
|
102
98
|
sql: `
|
|
103
99
|
INSERT INTO ?? (id, status, config) VALUES (UUID_TO_BIN(?), ?, ?);
|
|
104
|
-
INSERT INTO ?? (run_id, order_num, file, line, pos, project, timeout) VALUES ${testValues
|
|
105
|
-
.map(() => '(UUID_TO_BIN(?), ?, ?, ?, ?, ?, ?)')
|
|
100
|
+
INSERT INTO ?? (run_id, order_num, file, line, pos, project, timeout, title) VALUES ${testValues
|
|
101
|
+
.map(() => '(UUID_TO_BIN(?), ?, ?, ?, ?, ?, ?, ?)')
|
|
106
102
|
.join(', ')}`,
|
|
107
103
|
values: values,
|
|
108
104
|
});
|
|
@@ -124,6 +120,7 @@ export class MySQLAdapter extends Adapter {
|
|
|
124
120
|
pos INT NOT NULL,
|
|
125
121
|
project TEXT NOT NULL,
|
|
126
122
|
timeout INT NOT NULL,
|
|
123
|
+
title TEXT NOT NULL DEFAULT '',
|
|
127
124
|
updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
128
125
|
report JSON,
|
|
129
126
|
PRIMARY KEY (run_id, order_num),
|
|
@@ -156,6 +153,21 @@ export class MySQLAdapter extends Adapter {
|
|
|
156
153
|
this.testInfoTable,
|
|
157
154
|
],
|
|
158
155
|
});
|
|
156
|
+
// Migration: add title column if it doesn't exist (for existing databases)
|
|
157
|
+
await this.addTitleColumnIfNeeded();
|
|
158
|
+
}
|
|
159
|
+
async addTitleColumnIfNeeded() {
|
|
160
|
+
try {
|
|
161
|
+
await this.pool.query({
|
|
162
|
+
sql: `ALTER TABLE ?? ADD COLUMN title TEXT NOT NULL DEFAULT ''`,
|
|
163
|
+
values: [this.testsTable],
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
// Error code 1060 = Duplicate column name (column already exists)
|
|
168
|
+
if (e.errno !== 1060)
|
|
169
|
+
throw e;
|
|
170
|
+
}
|
|
159
171
|
}
|
|
160
172
|
async startShard(runId) {
|
|
161
173
|
const client = await this.pool.getConnection();
|