@playwright-orchestrator/pg 1.3.4 → 1.4.1

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.
@@ -30,8 +30,8 @@ let PostgreSQLAdapter = class PostgreSQLAdapter extends BaseAdapter {
30
30
  this.testInfoHistoryTable = pg.escapeIdentifier(`${tableNamePrefix}_test_info_history`);
31
31
  }
32
32
  async getReportData(runId) {
33
- const { rows: [{ config }], } = await this.pool.query({
34
- text: `SELECT config FROM ${this.configTable} WHERE id = $1`,
33
+ const { rows: [{ config, shards }], } = await this.pool.query({
34
+ text: `SELECT config, shards FROM ${this.configTable} WHERE id = $1`,
35
35
  values: [runId],
36
36
  });
37
37
  if (!config)
@@ -43,6 +43,7 @@ let PostgreSQLAdapter = class PostgreSQLAdapter extends BaseAdapter {
43
43
  return {
44
44
  runId,
45
45
  config,
46
+ shards,
46
47
  tests: rows.map(({ file, projects, line, character, report }) => ({
47
48
  averageDuration: report?.ema ?? 0,
48
49
  duration: report?.duration ?? 0,
@@ -33,6 +33,7 @@ let PgInitializer = class PgInitializer {
33
33
  updated TIMESTAMP NOT NULL DEFAULT NOW(),
34
34
  config JSONB NOT NULL
35
35
  );
36
+ ALTER TABLE ${configTable} ADD COLUMN IF NOT EXISTS shards JSONB;
36
37
  CREATE TABLE IF NOT EXISTS ${testsTable} (
37
38
  run_id UUID NOT NULL,
38
39
  order_num INT NOT NULL,
@@ -1,15 +1,16 @@
1
- import type { ShardHandler } from '@playwright-orchestrator/core';
1
+ import type { ShardHandler, TestRunContext } from '@playwright-orchestrator/core';
2
2
  import type { TestItem, TestRunConfig } from '@playwright-orchestrator/core';
3
3
  import type { CreateArgs } from './create-args.js';
4
4
  import { PgPool } from './pg-pool.js';
5
5
  export declare class PgShardHandler implements ShardHandler {
6
+ private readonly runContext;
6
7
  private readonly configTable;
7
8
  private readonly testsTable;
8
9
  private readonly pool;
9
- constructor({ tableNamePrefix }: CreateArgs, pgPool: PgPool);
10
- getNextTest(runId: string, _config: TestRunConfig): Promise<TestItem | undefined>;
11
- getNextTestByProject(runId: string, project: string): Promise<TestItem | undefined>;
10
+ constructor({ tableNamePrefix }: CreateArgs, pgPool: PgPool, runContext: TestRunContext);
11
+ getNextTest(_config: TestRunConfig): Promise<TestItem | undefined>;
12
+ getNextTestByProject(project: string): Promise<TestItem | undefined>;
12
13
  private claimNextTest;
13
- startShard(runId: string): Promise<TestRunConfig>;
14
- finishShard(runId: string): Promise<void>;
14
+ startShard(): Promise<TestRunConfig>;
15
+ finishShard(): Promise<void>;
15
16
  }
@@ -11,23 +11,27 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
13
  import { injectable, inject } from 'inversify';
14
- import { RunStatus, TestStatus } from '@playwright-orchestrator/core';
14
+ import { RunStatus, SYMBOLS, TestStatus } from '@playwright-orchestrator/core';
15
15
  import { PgPool } from './pg-pool.js';
16
16
  import pg from 'pg';
17
17
  import { PG_CONFIG, PG_POOL } from './symbols.js';
18
18
  let PgShardHandler = class PgShardHandler {
19
+ runContext;
19
20
  configTable;
20
21
  testsTable;
21
22
  pool;
22
- constructor({ tableNamePrefix }, pgPool) {
23
+ constructor({ tableNamePrefix }, pgPool, runContext) {
24
+ this.runContext = runContext;
23
25
  this.pool = pgPool.pool;
24
26
  this.configTable = pg.escapeIdentifier(`${tableNamePrefix}_test_runs`);
25
27
  this.testsTable = pg.escapeIdentifier(`${tableNamePrefix}_tests`);
26
28
  }
27
- async getNextTest(runId, _config) {
29
+ async getNextTest(_config) {
30
+ const { runId } = this.runContext;
28
31
  return this.claimNextTest(runId);
29
32
  }
30
- async getNextTestByProject(runId, project) {
33
+ async getNextTestByProject(project) {
34
+ const { runId } = this.runContext;
31
35
  return this.claimNextTest(runId, project);
32
36
  }
33
37
  async claimNextTest(runId, project) {
@@ -76,7 +80,8 @@ let PgShardHandler = class PgShardHandler {
76
80
  client.release();
77
81
  }
78
82
  }
79
- async startShard(runId) {
83
+ async startShard() {
84
+ const { runId, shardId } = this.runContext;
80
85
  const client = await this.pool.connect();
81
86
  try {
82
87
  await client.query('BEGIN');
@@ -95,18 +100,27 @@ let PgShardHandler = class PgShardHandler {
95
100
  WHERE run_id = $1 AND status = $2 AND updated <= $4;`,
96
101
  values: [runId, TestStatus.Failed, TestStatus.Ready, updatedBefore],
97
102
  });
98
- result = await client.query({
103
+ await client.query({
99
104
  text: `UPDATE ${this.configTable}
100
105
  SET status = (CASE
101
106
  WHEN status = $2 THEN ${RunStatus.Run}
102
107
  ELSE ${RunStatus.RepeatRun}
103
108
  END),
104
109
  updated = NOW()
105
- WHERE id = $1
106
- RETURNING *;`,
110
+ WHERE id = $1;`,
107
111
  values: [runId, RunStatus.Created],
108
112
  });
109
113
  }
114
+ await client.query({
115
+ text: `UPDATE ${this.configTable}
116
+ SET shards = jsonb_set(
117
+ shards,
118
+ $2,
119
+ jsonb_build_object('shardId', $3, 'started', (EXTRACT(EPOCH FROM NOW()) * 1000)::bigint)
120
+ )
121
+ WHERE id = $1 AND (shards->>$3 IS NULL);`,
122
+ values: [runId, `{${shardId}}`, shardId],
123
+ });
110
124
  await client.query('COMMIT');
111
125
  return result.rows[0].config;
112
126
  }
@@ -118,17 +132,20 @@ let PgShardHandler = class PgShardHandler {
118
132
  client.release();
119
133
  }
120
134
  }
121
- async finishShard(runId) {
122
- await this.pool.query({
123
- text: `UPDATE ${this.configTable} SET status = $1, updated = NOW() WHERE id = $2`,
124
- values: [RunStatus.Finished, runId],
125
- });
135
+ async finishShard() {
136
+ const { runId, shardId } = this.runContext;
137
+ await this.pool.query(`UPDATE ${this.configTable}
138
+ SET status = $2,
139
+ updated = NOW(),
140
+ shards = jsonb_set(shards, $3, to_jsonb((EXTRACT(EPOCH FROM NOW()) * 1000)::bigint))
141
+ WHERE id = $1 AND shards #>> $3::text[] IS NULL;`, [runId, RunStatus.Finished, `{${shardId},finished}`]);
126
142
  }
127
143
  };
128
144
  PgShardHandler = __decorate([
129
145
  injectable(),
130
146
  __param(0, inject(PG_CONFIG)),
131
147
  __param(1, inject(PG_POOL)),
132
- __metadata("design:paramtypes", [Object, PgPool])
148
+ __param(2, inject(SYMBOLS.RunContext)),
149
+ __metadata("design:paramtypes", [Object, PgPool, Object])
133
150
  ], PgShardHandler);
134
151
  export { PgShardHandler };
@@ -74,11 +74,21 @@ let PgTestRunCreator = class PgTestRunCreator extends BaseTestRunCreator {
74
74
  try {
75
75
  await client.query('BEGIN');
76
76
  await client.query({
77
- text: `INSERT INTO ${this.configTable} (id, status, config) VALUES ($1, $2, $3)`,
77
+ text: `INSERT INTO ${this.configTable} (id, status, config, shards) VALUES ($1, $2, $3, '{}')`,
78
78
  values: [runId, RunStatus.Created, JSON.stringify(run.config)],
79
79
  });
80
80
  if (tests.length > 0) {
81
- const fields = ['order_num', 'file', 'line', 'character', 'projects', 'timeout', 'ema', 'children', 'test_id'];
81
+ const fields = [
82
+ 'order_num',
83
+ 'file',
84
+ 'line',
85
+ 'character',
86
+ 'projects',
87
+ 'timeout',
88
+ 'ema',
89
+ 'children',
90
+ 'test_id',
91
+ ];
82
92
  await client.query({
83
93
  text: `INSERT INTO ${this.testsTable} (run_id, ${fields.join(', ')}) VALUES ${tests
84
94
  .map((_, i) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playwright-orchestrator/pg",
3
- "version": "1.3.4",
3
+ "version": "1.4.1",
4
4
  "keywords": [],
5
5
  "author": "Rostyslav Kudrevatykh",
6
6
  "license": "Apache-2.0",
@@ -17,7 +17,7 @@
17
17
  "commander": "^13.0.0",
18
18
  "inversify": "^8.0.0-beta.0",
19
19
  "pg": "^8.13.1",
20
- "@playwright-orchestrator/core": "1.3.4"
20
+ "@playwright-orchestrator/core": "1.4.1"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/pg": "^8.11.0"