testit-js-commons 3.7.9 → 4.0.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.
Files changed (45) hide show
  1. package/lib/common/types/config.type.d.ts +8 -0
  2. package/lib/common/utils/index.d.ts +1 -0
  3. package/lib/common/utils/index.js +1 -0
  4. package/lib/common/utils/tms-load-test-run-debug.d.ts +3 -0
  5. package/lib/common/utils/tms-load-test-run-debug.js +20 -0
  6. package/lib/helpers/config/config.helper.js +14 -6
  7. package/lib/helpers/config/config.helper.test.d.ts +1 -0
  8. package/lib/helpers/config/config.helper.test.js +40 -0
  9. package/lib/services/attachments/attachments.service.js +89 -22
  10. package/lib/services/index.d.ts +1 -0
  11. package/lib/services/index.js +1 -0
  12. package/lib/services/syncstorage/index.d.ts +2 -0
  13. package/lib/services/syncstorage/index.js +18 -0
  14. package/lib/services/syncstorage/syncstorage.runner.d.ts +49 -0
  15. package/lib/services/syncstorage/syncstorage.runner.js +350 -0
  16. package/lib/services/syncstorage/syncstorage.runner.test.d.ts +1 -0
  17. package/lib/services/syncstorage/syncstorage.runner.test.js +78 -0
  18. package/lib/services/syncstorage/syncstorage.type.d.ts +21 -0
  19. package/lib/services/syncstorage/syncstorage.type.js +19 -0
  20. package/lib/services/testruns/testruns.converter.d.ts +2 -0
  21. package/lib/services/testruns/testruns.converter.js +3 -0
  22. package/lib/services/testruns/testruns.service.d.ts +2 -0
  23. package/lib/services/testruns/testruns.service.js +62 -1
  24. package/lib/services/testruns/testruns.type.d.ts +2 -0
  25. package/lib/strategy/base.strategy.d.ts +4 -0
  26. package/lib/strategy/base.strategy.js +97 -2
  27. package/lib/sync-storage/dist/ApiClient.js +655 -0
  28. package/lib/sync-storage/dist/api/CompletionApi.js +114 -0
  29. package/lib/sync-storage/dist/api/HealthApi.js +69 -0
  30. package/lib/sync-storage/dist/api/SystemApi.js +69 -0
  31. package/lib/sync-storage/dist/api/TestResultsApi.js +122 -0
  32. package/lib/sync-storage/dist/api/WorkersApi.js +113 -0
  33. package/lib/sync-storage/dist/index.js +118 -0
  34. package/lib/sync-storage/dist/model/CompletionResponse.js +86 -0
  35. package/lib/sync-storage/dist/model/HealthStatusResponse.js +86 -0
  36. package/lib/sync-storage/dist/model/InProgressPublishedResponse.js +74 -0
  37. package/lib/sync-storage/dist/model/RegisterRequest.js +114 -0
  38. package/lib/sync-storage/dist/model/RegisterResponse.js +122 -0
  39. package/lib/sync-storage/dist/model/SetWorkerStatusRequest.js +102 -0
  40. package/lib/sync-storage/dist/model/SetWorkerStatusResponse.js +90 -0
  41. package/lib/sync-storage/dist/model/ShutdownResponse.js +90 -0
  42. package/lib/sync-storage/dist/model/TestResultCutApiModel.js +122 -0
  43. package/lib/sync-storage/dist/model/TestResultSaveResponse.js +90 -0
  44. package/lib/sync-storage/index.d.ts +772 -0
  45. package/package.json +7 -4
@@ -10,6 +10,8 @@ export interface CliOptions {
10
10
  tmsConfigFile: string;
11
11
  tmsAutomaticCreationTestCases: boolean;
12
12
  tmsAutomaticUpdationLinksToTestCases: boolean;
13
+ tmsSyncStorageEnabled: boolean;
14
+ tmsSyncStoragePort: string;
13
15
  }
14
16
  export interface EnvironmentOptions {
15
17
  TMS_URL: string;
@@ -23,6 +25,8 @@ export interface EnvironmentOptions {
23
25
  TMS_AUTOMATIC_CREATION_TEST_CASES: string;
24
26
  TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES: string;
25
27
  TMS_CERT_VALIDATION: string;
28
+ TMS_SYNC_STORAGE_ENABLED: string;
29
+ TMS_SYNC_STORAGE_PORT: string;
26
30
  }
27
31
  export interface ProcessEnvOptions {
28
32
  TMS_URL?: string;
@@ -36,6 +40,8 @@ export interface ProcessEnvOptions {
36
40
  TMS_AUTOMATIC_CREATION_TEST_CASES?: string;
37
41
  TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES?: string;
38
42
  TMS_CERT_VALIDATION?: string;
43
+ TMS_SYNC_STORAGE_ENABLED?: string;
44
+ TMS_SYNC_STORAGE_PORT?: string;
39
45
  }
40
46
  export interface AdapterConfig {
41
47
  url: string;
@@ -48,4 +54,6 @@ export interface AdapterConfig {
48
54
  automaticCreationTestCases?: boolean;
49
55
  automaticUpdationLinksToTestCases?: boolean;
50
56
  certValidation?: boolean;
57
+ syncStorageEnabled?: boolean;
58
+ syncStoragePort?: string;
51
59
  }
@@ -1,2 +1,3 @@
1
1
  export * from "./utils";
2
2
  export * from "./html-escape.util";
3
+ export * from "./tms-load-test-run-debug";
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./utils"), exports);
18
18
  __exportStar(require("./html-escape.util"), exports);
19
+ __exportStar(require("./tms-load-test-run-debug"), exports);
@@ -0,0 +1,3 @@
1
+ /** Set `TMS_DEBUG_LOAD_TEST_RUN=1` (or `true`) for loadTestRun / TMS result POST tracing. */
2
+ export declare function isTmsLoadTestRunDebug(): boolean;
3
+ export declare function logTmsLoadTestRun(message: string, data?: Record<string, unknown>): void;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /** Set `TMS_DEBUG_LOAD_TEST_RUN=1` (or `true`) for loadTestRun / TMS result POST tracing. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.isTmsLoadTestRunDebug = isTmsLoadTestRunDebug;
5
+ exports.logTmsLoadTestRun = logTmsLoadTestRun;
6
+ function isTmsLoadTestRunDebug() {
7
+ const v = process.env.TMS_DEBUG_LOAD_TEST_RUN;
8
+ return v === "1" || (v === null || v === void 0 ? void 0 : v.toLowerCase()) === "true";
9
+ }
10
+ function logTmsLoadTestRun(message, data) {
11
+ if (!isTmsLoadTestRunDebug()) {
12
+ return;
13
+ }
14
+ if (data && Object.keys(data).length > 0) {
15
+ console.log(`[testit-js-commons:loadTestRun] ${message}`, data);
16
+ }
17
+ else {
18
+ console.log(`[testit-js-commons:loadTestRun] ${message}`);
19
+ }
20
+ }
@@ -61,7 +61,7 @@ class ConfigComposer {
61
61
  return config;
62
62
  }
63
63
  mergeAll(file, env, base) {
64
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
64
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
65
65
  return {
66
66
  url: this.resolveAllProperties(file.url, env === null || env === void 0 ? void 0 : env.TMS_URL, base === null || base === void 0 ? void 0 : base.url),
67
67
  projectId: this.resolveAllProperties(file.projectId, env === null || env === void 0 ? void 0 : env.TMS_PROJECT_ID, base === null || base === void 0 ? void 0 : base.projectId),
@@ -72,11 +72,13 @@ class ConfigComposer {
72
72
  configurationId: this.resolveAllProperties(file.configurationId, env === null || env === void 0 ? void 0 : env.TMS_CONFIGURATION_ID, base === null || base === void 0 ? void 0 : base.configurationId),
73
73
  automaticCreationTestCases: (_f = (_e = (_d = file.automaticCreationTestCases) !== null && _d !== void 0 ? _d : stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_AUTOMATIC_CREATION_TEST_CASES)) !== null && _e !== void 0 ? _e : base === null || base === void 0 ? void 0 : base.automaticCreationTestCases) !== null && _f !== void 0 ? _f : false,
74
74
  automaticUpdationLinksToTestCases: (_j = (_h = (_g = file.automaticUpdationLinksToTestCases) !== null && _g !== void 0 ? _g : stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES)) !== null && _h !== void 0 ? _h : base === null || base === void 0 ? void 0 : base.automaticUpdationLinksToTestCases) !== null && _j !== void 0 ? _j : false,
75
- certValidation: (_m = (_l = (_k = file.certValidation) !== null && _k !== void 0 ? _k : stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_CERT_VALIDATION)) !== null && _l !== void 0 ? _l : base === null || base === void 0 ? void 0 : base.certValidation) !== null && _m !== void 0 ? _m : true
75
+ certValidation: (_m = (_l = (_k = file.certValidation) !== null && _k !== void 0 ? _k : stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_CERT_VALIDATION)) !== null && _l !== void 0 ? _l : base === null || base === void 0 ? void 0 : base.certValidation) !== null && _m !== void 0 ? _m : true,
76
+ syncStorageEnabled: (_q = (_p = (_o = file.syncStorageEnabled) !== null && _o !== void 0 ? _o : stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_SYNC_STORAGE_ENABLED)) !== null && _p !== void 0 ? _p : base === null || base === void 0 ? void 0 : base.syncStorageEnabled) !== null && _q !== void 0 ? _q : true,
77
+ syncStoragePort: this.resolveAllProperties(file.syncStoragePort, env === null || env === void 0 ? void 0 : env.TMS_SYNC_STORAGE_PORT, base === null || base === void 0 ? void 0 : base.syncStoragePort) || "49152",
76
78
  };
77
79
  }
78
80
  merge(env, base) {
79
- var _a, _b, _c, _d, _e, _f, _g, _h;
81
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
80
82
  return {
81
83
  url: this.resolveProperties(env === null || env === void 0 ? void 0 : env.TMS_URL, base === null || base === void 0 ? void 0 : base.url),
82
84
  projectId: this.resolveProperties(env === null || env === void 0 ? void 0 : env.TMS_PROJECT_ID, base === null || base === void 0 ? void 0 : base.projectId),
@@ -87,11 +89,13 @@ class ConfigComposer {
87
89
  configurationId: this.resolveProperties(env === null || env === void 0 ? void 0 : env.TMS_CONFIGURATION_ID, base === null || base === void 0 ? void 0 : base.configurationId),
88
90
  automaticCreationTestCases: (_d = (_c = stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_AUTOMATIC_CREATION_TEST_CASES)) !== null && _c !== void 0 ? _c : base === null || base === void 0 ? void 0 : base.automaticCreationTestCases) !== null && _d !== void 0 ? _d : false,
89
91
  automaticUpdationLinksToTestCases: (_f = (_e = stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES)) !== null && _e !== void 0 ? _e : base === null || base === void 0 ? void 0 : base.automaticUpdationLinksToTestCases) !== null && _f !== void 0 ? _f : false,
90
- certValidation: (_h = (_g = stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_CERT_VALIDATION)) !== null && _g !== void 0 ? _g : base === null || base === void 0 ? void 0 : base.certValidation) !== null && _h !== void 0 ? _h : true
92
+ certValidation: (_h = (_g = stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_CERT_VALIDATION)) !== null && _g !== void 0 ? _g : base === null || base === void 0 ? void 0 : base.certValidation) !== null && _h !== void 0 ? _h : true,
93
+ syncStorageEnabled: (_k = (_j = stringToBoolean(env === null || env === void 0 ? void 0 : env.TMS_SYNC_STORAGE_ENABLED)) !== null && _j !== void 0 ? _j : base === null || base === void 0 ? void 0 : base.syncStorageEnabled) !== null && _k !== void 0 ? _k : true,
94
+ syncStoragePort: this.resolveProperties(env === null || env === void 0 ? void 0 : env.TMS_SYNC_STORAGE_PORT, base === null || base === void 0 ? void 0 : base.syncStoragePort) || "49152",
91
95
  };
92
96
  }
93
97
  mergeEnv(dotEnv, processEnv) {
94
- var _a, _b, _c, _d;
98
+ var _a, _b, _c, _d, _e;
95
99
  return {
96
100
  TMS_URL: this.resolveProperties(dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_URL, processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_URL),
97
101
  TMS_PROJECT_ID: this.resolveProperties(dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_PROJECT_ID, processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_PROJECT_ID),
@@ -102,7 +106,9 @@ class ConfigComposer {
102
106
  TMS_CONFIGURATION_ID: this.resolveProperties(dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_CONFIGURATION_ID, processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_CONFIGURATION_ID),
103
107
  TMS_AUTOMATIC_CREATION_TEST_CASES: (_b = dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_AUTOMATIC_CREATION_TEST_CASES) !== null && _b !== void 0 ? _b : processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_AUTOMATIC_CREATION_TEST_CASES,
104
108
  TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES: (_c = dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES) !== null && _c !== void 0 ? _c : processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES,
105
- TMS_CERT_VALIDATION: (_d = dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_CERT_VALIDATION) !== null && _d !== void 0 ? _d : processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_CERT_VALIDATION
109
+ TMS_CERT_VALIDATION: (_d = dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_CERT_VALIDATION) !== null && _d !== void 0 ? _d : processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_CERT_VALIDATION,
110
+ TMS_SYNC_STORAGE_ENABLED: (_e = dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_SYNC_STORAGE_ENABLED) !== null && _e !== void 0 ? _e : processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_SYNC_STORAGE_ENABLED,
111
+ TMS_SYNC_STORAGE_PORT: this.resolveProperties(dotEnv === null || dotEnv === void 0 ? void 0 : dotEnv.TMS_SYNC_STORAGE_PORT, processEnv === null || processEnv === void 0 ? void 0 : processEnv.TMS_SYNC_STORAGE_PORT),
106
112
  };
107
113
  }
108
114
  resolveAllProperties(file, env, base) {
@@ -180,6 +186,8 @@ function parseProcessEnvConfig() {
180
186
  TMS_AUTOMATIC_CREATION_TEST_CASES: process.env.TMS_AUTOMATIC_CREATION_TEST_CASES,
181
187
  TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES: process.env.TMS_AUTOMATIC_UPDATION_LINKS_TO_TEST_CASES,
182
188
  TMS_CONFIG_FILE: process.env.TMS_PRIVATE_TOKEN,
189
+ TMS_SYNC_STORAGE_ENABLED: process.env.TMS_SYNC_STORAGE_ENABLED,
190
+ TMS_SYNC_STORAGE_PORT: process.env.TMS_SYNC_STORAGE_PORT,
183
191
  };
184
192
  }
185
193
  function stringToAdapterMode(str) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_helper_1 = require("./config.helper");
4
+ describe("ConfigComposer sync-storage defaults", () => {
5
+ const env = process.env;
6
+ beforeEach(() => {
7
+ jest.resetModules();
8
+ process.env = Object.assign({}, env);
9
+ delete process.env.TMS_SYNC_STORAGE_ENABLED;
10
+ delete process.env.TMS_SYNC_STORAGE_PORT;
11
+ });
12
+ afterAll(() => {
13
+ process.env = env;
14
+ });
15
+ it("should enable sync-storage by default", () => {
16
+ const config = new config_helper_1.ConfigComposer().merge(undefined, {
17
+ url: "http://localhost:8080",
18
+ privateToken: "token",
19
+ projectId: "11111111-1111-1111-1111-111111111111",
20
+ configurationId: "22222222-2222-2222-2222-222222222222",
21
+ testRunId: "33333333-3333-3333-3333-333333333333",
22
+ });
23
+ expect(config.syncStorageEnabled).toBe(true);
24
+ expect(config.syncStoragePort).toBe("49152");
25
+ });
26
+ it("should allow disabling sync-storage via env", () => {
27
+ const config = new config_helper_1.ConfigComposer().merge({
28
+ TMS_SYNC_STORAGE_ENABLED: "false",
29
+ TMS_SYNC_STORAGE_PORT: "59999",
30
+ }, {
31
+ url: "http://localhost:8080",
32
+ privateToken: "token",
33
+ projectId: "11111111-1111-1111-1111-111111111111",
34
+ configurationId: "22222222-2222-2222-2222-222222222222",
35
+ testRunId: "33333333-3333-3333-3333-333333333333",
36
+ });
37
+ expect(config.syncStorageEnabled).toBe(false);
38
+ expect(config.syncStoragePort).toBe("59999");
39
+ });
40
+ });
@@ -48,42 +48,103 @@ const TestitApiClient = __importStar(require("testit-api-client"));
48
48
  const common_1 = require("../../common");
49
49
  const buffer_1 = require("buffer");
50
50
  const fs = __importStar(require("fs"));
51
+ const UPLOAD_MAX_ATTEMPTS = 5;
52
+ const UPLOAD_RETRY_BASE_MS = 500;
53
+ /** Minimum HTTP timeout for attachment POST (ms); reduces false timeouts on slow TLS. */
54
+ const UPLOAD_CLIENT_TIMEOUT_MS = 120000;
55
+ function sleep(ms) {
56
+ return new Promise((resolve) => setTimeout(resolve, ms));
57
+ }
58
+ function unwrapAttachmentError(err) {
59
+ if (!err || typeof err !== "object") {
60
+ return err;
61
+ }
62
+ const nested = err.error;
63
+ if (nested instanceof Error || (nested && typeof nested === "object")) {
64
+ return nested;
65
+ }
66
+ const cause = err.cause;
67
+ if (cause instanceof Error || (cause && typeof cause === "object")) {
68
+ return cause;
69
+ }
70
+ return err;
71
+ }
72
+ function isTransientAttachmentError(err) {
73
+ var _a, _b, _c, _d, _e;
74
+ const e = unwrapAttachmentError(err);
75
+ const status = (_b = (_a = e === null || e === void 0 ? void 0 : e.response) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : (_c = err === null || err === void 0 ? void 0 : err.response) === null || _c === void 0 ? void 0 : _c.status;
76
+ if (typeof status === "number" && status >= 400 && status < 500)
77
+ return false;
78
+ if (typeof status === "number" && status >= 500)
79
+ return true;
80
+ const code = (_d = e === null || e === void 0 ? void 0 : e.code) !== null && _d !== void 0 ? _d : err === null || err === void 0 ? void 0 : err.code;
81
+ if (code === "ECONNRESET" || code === "ETIMEDOUT" || code === "EPIPE" || code === "ECONNABORTED")
82
+ return true;
83
+ if ((e === null || e === void 0 ? void 0 : e.errno) === -104 || (err === null || err === void 0 ? void 0 : err.errno) === -104)
84
+ return true;
85
+ const msg = (_e = e === null || e === void 0 ? void 0 : e.message) !== null && _e !== void 0 ? _e : err === null || err === void 0 ? void 0 : err.message;
86
+ if (typeof msg === "string" && /socket hang up|ECONNRESET|ETIMEDOUT|ECONNREFUSED|read ECONNRESET/i.test(msg)) {
87
+ return true;
88
+ }
89
+ return false;
90
+ }
91
+ function withUploadRetry(fn) {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ let last;
94
+ for (let attempt = 1; attempt <= UPLOAD_MAX_ATTEMPTS; attempt++) {
95
+ try {
96
+ return yield fn();
97
+ }
98
+ catch (e) {
99
+ last = e;
100
+ if (!isTransientAttachmentError(e) || attempt === UPLOAD_MAX_ATTEMPTS) {
101
+ throw e;
102
+ }
103
+ yield sleep(UPLOAD_RETRY_BASE_MS * attempt);
104
+ }
105
+ }
106
+ throw last;
107
+ });
108
+ }
51
109
  class AttachmentsService extends common_1.BaseService {
52
110
  constructor(config) {
53
111
  super(config);
54
112
  this.config = config;
55
113
  this._client = new TestitApiClient.AttachmentsApi();
56
- // Set the base path from config if provided
57
114
  if (this.config.url) {
58
115
  this._client.apiClient.basePath = this.config.url.replace(/\/+$/, "");
59
116
  }
117
+ const t = this._client.apiClient.timeout;
118
+ this._client.apiClient.timeout = Math.max(typeof t === "number" ? t : 60000, UPLOAD_CLIENT_TIMEOUT_MS);
60
119
  }
61
120
  uploadTextAttachment(content, filename) {
62
121
  return __awaiter(this, void 0, void 0, function* () {
63
- // Create a Buffer for the content
64
122
  const bufferContent = typeof content === "string" ? buffer_1.Buffer.from(content, "utf-8") : content;
65
123
  const fileName = filename !== null && filename !== void 0 ? filename : common_1.Utils.generateFileName();
66
124
  try {
67
- // Try to create a temporary file with the correct name to workaround filename issue
68
125
  const tempDir = common_1.Utils.createTempDir();
69
126
  const tempFilePath = `${tempDir}/${fileName}`;
70
127
  try {
71
- // Write buffer to temporary file
72
128
  fs.writeFileSync(tempFilePath, bufferContent);
73
- // Use the temporary file with the API client
74
- const fileStream = fs.createReadStream(tempFilePath);
75
- // @ts-ignore
76
- const response = yield this._client.apiV2AttachmentsPost({ file: fileStream });
77
- const data = response.body || response;
78
- return [{ id: data.id }];
129
+ const id = yield withUploadRetry(() => __awaiter(this, void 0, void 0, function* () {
130
+ const fileStream = fs.createReadStream(tempFilePath);
131
+ try {
132
+ // @ts-ignore
133
+ const response = yield this._client.apiV2AttachmentsPost({ file: fileStream });
134
+ const data = response.body || response;
135
+ return data.id;
136
+ }
137
+ finally {
138
+ fileStream.destroy();
139
+ }
140
+ }));
141
+ return [{ id }];
79
142
  }
80
143
  finally {
81
- // Clean up temporary file and directory
82
144
  try {
83
145
  if (fs.existsSync(tempFilePath)) {
84
146
  fs.unlinkSync(tempFilePath);
85
147
  }
86
- // Try to remove the temp directory
87
148
  if (fs.existsSync(tempDir)) {
88
149
  fs.rmdirSync(tempDir);
89
150
  }
@@ -107,18 +168,25 @@ class AttachmentsService extends common_1.BaseService {
107
168
  }
108
169
  uploadAttachments(paths) {
109
170
  return __awaiter(this, void 0, void 0, function* () {
110
- const attachmentIds = yield Promise.all(paths.map((path) => __awaiter(this, void 0, void 0, function* () {
171
+ const attachmentIds = [];
172
+ for (const path of paths) {
111
173
  try {
112
- // Verify file exists
113
174
  if (!fs.existsSync(path)) {
114
175
  throw new Error(`File not found: ${path}`);
115
176
  }
116
- // Create a read stream directly from the file
117
- const fileStream = common_1.Utils.readStream(path);
118
- // @ts-ignore
119
- const response = yield this._client.apiV2AttachmentsPost({ file: fileStream });
120
- const data = response.body || response;
121
- return data.id;
177
+ const id = yield withUploadRetry(() => __awaiter(this, void 0, void 0, function* () {
178
+ const fileStream = common_1.Utils.readStream(path);
179
+ try {
180
+ // @ts-ignore
181
+ const response = yield this._client.apiV2AttachmentsPost({ file: fileStream });
182
+ const data = response.body || response;
183
+ return data.id;
184
+ }
185
+ finally {
186
+ fileStream.destroy();
187
+ }
188
+ }));
189
+ attachmentIds.push(id);
122
190
  }
123
191
  catch (error) {
124
192
  console.error(`Error uploading attachment ${path}:`, error);
@@ -130,8 +198,7 @@ class AttachmentsService extends common_1.BaseService {
130
198
  }
131
199
  throw error;
132
200
  }
133
- })));
134
- // Convert array of IDs to array of Attachment objects
201
+ }
135
202
  return attachmentIds.map((id) => ({ id }));
136
203
  });
137
204
  }
@@ -2,3 +2,4 @@ export * from "./attachments";
2
2
  export * from "./autotests";
3
3
  export * from "./testresults";
4
4
  export * from "./testruns";
5
+ export * from "./syncstorage";
@@ -18,3 +18,4 @@ __exportStar(require("./attachments"), exports);
18
18
  __exportStar(require("./autotests"), exports);
19
19
  __exportStar(require("./testresults"), exports);
20
20
  __exportStar(require("./testruns"), exports);
21
+ __exportStar(require("./syncstorage"), exports);
@@ -0,0 +1,2 @@
1
+ export * from "./syncstorage.runner";
2
+ export * from "./syncstorage.type";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./syncstorage.runner"), exports);
18
+ __exportStar(require("./syncstorage.type"), exports);
@@ -0,0 +1,49 @@
1
+ import { AdapterConfig } from "../../common";
2
+ import { ISyncStorageRunner, TestResultCutModel, WorkerStatus } from "./syncstorage.type";
3
+ export declare class SyncStorageRunner implements ISyncStorageRunner {
4
+ private readonly testRunId;
5
+ private readonly config;
6
+ private static readonly VERSION;
7
+ private static readonly STARTUP_TIMEOUT_MS;
8
+ private static readonly STARTUP_POLL_MS;
9
+ private static readonly PROCESS_WARMUP_MS;
10
+ private static readonly REQUEST_TIMEOUT_MS;
11
+ private static readonly RETRY_COUNT;
12
+ private static readonly IN_PROGRESS_POLL_MS;
13
+ private static readonly REPO_BASE;
14
+ private readonly workerPid;
15
+ private readonly baseUrl;
16
+ private readonly serviceUrl;
17
+ private readonly port;
18
+ private isMaster;
19
+ private alreadyInProgress;
20
+ private inProgressPublishing;
21
+ private running;
22
+ private syncStorageProcess?;
23
+ private readonly healthApi;
24
+ private readonly workersApi;
25
+ private readonly testResultsApi;
26
+ private readonly completionApi;
27
+ private readonly registerRequestModel;
28
+ private readonly setWorkerStatusRequestModel;
29
+ private readonly testResultCutModel;
30
+ constructor(testRunId: string, config: AdapterConfig);
31
+ start(): Promise<boolean>;
32
+ isActive(): boolean;
33
+ isMasterWorker(): boolean;
34
+ isAlreadyInProgress(): boolean;
35
+ waitForInProgressPublished(timeoutMs: number): Promise<boolean>;
36
+ sendInProgressTestResult(model: TestResultCutModel): Promise<boolean>;
37
+ setWorkerStatus(status: WorkerStatus): Promise<void>;
38
+ completeProcessing(): Promise<void>;
39
+ private healthcheck;
40
+ private startLocalProcess;
41
+ private waitForStartup;
42
+ private prepareExecutable;
43
+ private getBinaryName;
44
+ private getOsPart;
45
+ private getArchPart;
46
+ private downloadFile;
47
+ private delay;
48
+ private withRetry;
49
+ }