@teamscale/coverage-collector 0.1.0-beta.5 → 0.1.0-beta.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamscale/coverage-collector",
3
- "version": "0.1.0-beta.5",
3
+ "version": "0.1.0-beta.7",
4
4
  "description": "Collector for JavaScript code coverage information",
5
5
  "main": "dist/src/main.js",
6
6
  "bin": "dist/src/main.js",
@@ -22,41 +22,41 @@
22
22
  "dist/**/*"
23
23
  ],
24
24
  "dependencies": {
25
- "@cqse/commons": "0.1.0-beta.4",
25
+ "@cqse/commons": "0.1.0-beta.6",
26
26
  "argparse": "^2.0.1",
27
27
  "async": "^3.2.5",
28
28
  "axios": "^1.6.7",
29
29
  "bunyan": "^1.8.15",
30
30
  "date-and-time": "^3.1.1",
31
- "dotenv": "^16.4.4",
32
- "express": "^4.18.2",
31
+ "dotenv": "^16.4.5",
32
+ "express": "^4.18.3",
33
33
  "form-data": "^4.0.0",
34
34
  "mkdirp": "^3.0.1",
35
35
  "rxjs": "^7.8.1",
36
36
  "source-map": "^0.7.4",
37
- "tmp": "^0.2.1",
37
+ "tmp": "^0.2.3",
38
38
  "typescript-optional": "^2.0.1",
39
39
  "ws": "^8.16.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@babel/core": "^7.23.9",
43
- "@babel/preset-env": "^7.23.9",
44
- "@types/argparse": "^2.0.14",
42
+ "@babel/core": "^7.24.0",
43
+ "@babel/preset-env": "^7.24.0",
44
+ "@types/argparse": "^2.0.15",
45
45
  "@types/async": "^3.2.24",
46
46
  "@types/bunyan": "^1.8.11",
47
47
  "@types/express": "^4.17.21",
48
48
  "@types/jest": "^29.5.12",
49
- "@types/node": "^20.11.19",
49
+ "@types/node": "^20.11.28",
50
50
  "@types/tmp": "^0.2.6",
51
51
  "@types/ws": "^8.5.10",
52
52
  "babel-jest": "^29.7.0",
53
- "esbuild": "^0.20.0",
53
+ "esbuild": "^0.20.2",
54
54
  "jest": "^29.7.0",
55
55
  "mockttp": "^3.10.1",
56
56
  "rimraf": "^5.0.5",
57
57
  "ts-jest": "^29.1.2",
58
58
  "ts-node": "^10.9.2",
59
- "typescript": "^5.3.3"
59
+ "typescript": "^5.4.2"
60
60
  },
61
61
  "publishConfig": {
62
62
  "access": "public"
package/dist/src/App.d.ts CHANGED
@@ -26,9 +26,10 @@ export declare class App {
26
26
  stop: () => Promise<void>;
27
27
  };
28
28
  /**
29
- * Starts a timer that dumps statistics on the number of received messages every 30s.
29
+ * Starts a timer that shows a message every min that no coverage
30
+ * was received until the opposite is the case.
30
31
  */
31
- private static startStatsTimer;
32
+ private static startNoMessageTimer;
32
33
  /**
33
34
  * Start a timer for dumping the data, depending on the configuration.
34
35
  *
package/dist/src/App.js CHANGED
@@ -103,8 +103,8 @@ class App {
103
103
  const serverState = server.start();
104
104
  // Optionally, start a timer that dumps the coverage after N seconds
105
105
  const dumpTimerState = this.maybeStartDumpTimer(config, storage, logger);
106
- // Start a timer that dumps statistics every 30s.
107
- const statsTimerState = this.startStatsTimer(logger, server);
106
+ // Start a timer that informs if no coverage was received within the last minute
107
+ const statsTimerState = this.startNoMessageTimer(logger, server);
108
108
  // Say bye bye on CTRL+C and exit the process
109
109
  process.on('SIGINT', async () => {
110
110
  // ... and do a final dump before.
@@ -123,13 +123,21 @@ class App {
123
123
  };
124
124
  }
125
125
  /**
126
- * Starts a timer that dumps statistics on the number of received messages every 30s.
126
+ * Starts a timer that shows a message every min that no coverage
127
+ * was received until the opposite is the case.
127
128
  */
128
- static startStatsTimer(logger, server) {
129
+ static startNoMessageTimer(logger, server) {
130
+ const startTime = Date.now();
129
131
  const timer = setInterval(async () => {
130
132
  const stats = server.getStatistics();
131
- logger.info(`Received ${stats.totalMessages} message since start, ${stats.totalCoverageMessages} with coverage.`);
132
- }, 1000 * 30);
133
+ if (stats.totalCoverageMessages === 0) {
134
+ logger.info(`No coverage received for ${((Date.now() - startTime) / 1000.0).toFixed(0)}s.`);
135
+ }
136
+ else {
137
+ // We can stop running the timer after we have received the first coverage.
138
+ clearInterval(timer);
139
+ }
140
+ }, 1000 * 60);
133
141
  return {
134
142
  stop: () => clearInterval(timer)
135
143
  };
@@ -167,7 +175,7 @@ class App {
167
175
  try {
168
176
  // 1. Write coverage to a file
169
177
  const [coverageFile, lines] = storage.dumpToSimpleCoverageFile(config.dump_to_folder, new Date());
170
- logger.info(`Dumped ${lines} lines of coverage to ${coverageFile}.`);
178
+ logger.debug(`Dumped ${lines} lines of coverage to ${coverageFile}.`);
171
179
  // 2. Upload to Teamscale or Artifactory if configured
172
180
  if (config.teamscale_server_url || config.artifactory_server_url) {
173
181
  await this.uploadCoverage(config, coverageFile, lines, logger);
@@ -58,12 +58,12 @@ class WebSocketCollectingServer {
58
58
  // Handle new connections from clients
59
59
  (_b = this.server) === null || _b === void 0 ? void 0 : _b.on('connection', (webSocket, req) => {
60
60
  let session = new Session_1.Session(req.socket, this.storage, this.logger);
61
- this.logger.debug(`Connection from: ${req.socket.remoteAddress}`);
61
+ this.logger.trace(`Connection from: ${req.socket.remoteAddress}`);
62
62
  // Handle disconnecting clients
63
63
  webSocket.on('close', code => {
64
64
  if (session) {
65
65
  session = null;
66
- this.logger.debug(`Closing with code ${code}`);
66
+ this.logger.trace(`Closing with code ${code}`);
67
67
  }
68
68
  });
69
69
  // Handle incoming messages
@@ -109,7 +109,7 @@ class DataStorage {
109
109
  this.coverageByProject.set(project, projectCoverage);
110
110
  }
111
111
  coveredOriginalLines.forEach(line => projectCoverage === null || projectCoverage === void 0 ? void 0 : projectCoverage.putLine(sourceFilePath, line));
112
- this.logger.debug(`Mapped Coverage: ${project} ${uniformPath} ${coveredOriginalLines}`);
112
+ this.logger.trace(`Mapped Coverage: ${project} ${uniformPath} ${coveredOriginalLines}`);
113
113
  }
114
114
  /**
115
115
  * Normalize the source file names provided by the Web browsers / from the
@@ -127,7 +127,7 @@ class DataStorage {
127
127
  // Currently only implemented to log the missing information.
128
128
  this.timesUnmappedCoverage++;
129
129
  if (this.timesUnmappedCoverage === 1) {
130
- this.logger.debug(`Received unmapped coverage for project "${project}"`);
130
+ this.logger.trace(`Received unmapped coverage for project "${project}"`);
131
131
  }
132
132
  }
133
133
  /**
@@ -1,5 +1,5 @@
1
1
  import { ConfigParameters } from '../utils/ConfigParameters';
2
- import Logger from 'bunyan';
2
+ import Logger from "bunyan";
3
3
  /**
4
4
  * Uploads a coverage file to artifactory with the provided configuration.
5
5
  */
@@ -17,7 +17,7 @@ async function uploadToArtifactory(config, logger, coverageFile, lines) {
17
17
  if (lines === 0) {
18
18
  return;
19
19
  }
20
- logger.info('Preparing upload to Artifactory');
20
+ logger.debug('Preparing upload to Artifactory');
21
21
  const form = (0, CommonUpload_1.prepareFormData)(coverageFile);
22
22
  await performArtifactoryUpload(config, form, logger);
23
23
  }
@@ -27,28 +27,35 @@ exports.prepareFormData = prepareFormData;
27
27
  * Uploads a coverage file with the provided configuration.
28
28
  */
29
29
  async function performUpload(url, form, config, uploadFunction, logger) {
30
+ var _a, _b;
30
31
  try {
31
32
  const response = await uploadFunction(url, form, config);
32
- logger.info(`Upload finished with code ${response.status}.`);
33
+ logger.debug(`Upload finished with code ${response.status}.`);
33
34
  }
34
35
  catch (error) {
35
36
  if (axios_1.default.isAxiosError(error)) {
37
+ let userMessage;
38
+ if (error.message) {
39
+ logger.error(`Upload error ${(_a = error.status) !== null && _a !== void 0 ? _a : 'UNDEFINED'}: ${error.message}`);
40
+ }
36
41
  if (error.response) {
37
- const response = error.response;
38
- if (response.status >= 400) {
39
- throw new UploadError(`Upload failed with code ${response.status}: ${response.statusText}. Response Data: ${response.data}`);
40
- }
41
- else {
42
- logger.info(`Upload with status code ${response.status} finished.`);
43
- }
42
+ // The request was made and the server responded with a status code
43
+ // that falls out of the range of 2xx
44
+ logger.error('Upload error response data:', error.response.data);
45
+ logger.error('Upload error response status:', error.response.status);
46
+ logger.error('Upload error response headers:', JSON.stringify(error.response.headers));
47
+ userMessage = `Request failed with status ${error.response.status}: ${(_b = error.response.data) !== null && _b !== void 0 ? _b : ''}`;
44
48
  }
45
49
  else if (error.request) {
46
- throw new UploadError(`Upload request did not receive a response.`);
50
+ // The request was made but no response was received
51
+ userMessage = 'No response received for the request.';
47
52
  }
48
- if (error.message) {
49
- logger.debug(`Something went wrong when uploading data: ${error.message}. Details of the error: ${(0, util_1.inspect)(error)}`);
50
- throw new UploadError(`Something went wrong when uploading data: ${error.message}`);
53
+ else {
54
+ // Something happened in setting up the request that triggered an Error
55
+ userMessage = 'Request setup failed.';
51
56
  }
57
+ // Provide a more specific message if possible
58
+ throw new UploadError(`Something went wrong when uploading data: ${userMessage}`);
52
59
  }
53
60
  throw new UploadError(`Something went wrong when uploading data: ${(0, util_1.inspect)(error)}`);
54
61
  }
@@ -18,7 +18,7 @@ async function uploadToTeamscale(config, logger, coverageFile, lines) {
18
18
  if (lines === 0) {
19
19
  return;
20
20
  }
21
- logger.info('Preparing upload to Teamscale');
21
+ logger.debug('Preparing upload to Teamscale');
22
22
  const form = (0, CommonUpload_1.prepareFormData)(coverageFile);
23
23
  const queryParameters = prepareQueryParameters(config);
24
24
  await performTeamscaleUpload(config, queryParameters, form, logger);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamscale/coverage-collector",
3
- "version": "0.1.0-beta.5",
3
+ "version": "0.1.0-beta.7",
4
4
  "description": "Collector for JavaScript code coverage information",
5
5
  "main": "dist/src/main.js",
6
6
  "bin": "dist/src/main.js",
@@ -15,41 +15,41 @@
15
15
  "dist/**/*"
16
16
  ],
17
17
  "dependencies": {
18
- "@cqse/commons": "0.1.0-beta.4",
18
+ "@cqse/commons": "0.1.0-beta.6",
19
19
  "argparse": "^2.0.1",
20
20
  "async": "^3.2.5",
21
21
  "axios": "^1.6.7",
22
22
  "bunyan": "^1.8.15",
23
23
  "date-and-time": "^3.1.1",
24
- "dotenv": "^16.4.4",
25
- "express": "^4.18.2",
24
+ "dotenv": "^16.4.5",
25
+ "express": "^4.18.3",
26
26
  "form-data": "^4.0.0",
27
27
  "mkdirp": "^3.0.1",
28
28
  "rxjs": "^7.8.1",
29
29
  "source-map": "^0.7.4",
30
- "tmp": "^0.2.1",
30
+ "tmp": "^0.2.3",
31
31
  "typescript-optional": "^2.0.1",
32
32
  "ws": "^8.16.0"
33
33
  },
34
34
  "devDependencies": {
35
- "@babel/core": "^7.23.9",
36
- "@babel/preset-env": "^7.23.9",
37
- "@types/argparse": "^2.0.14",
35
+ "@babel/core": "^7.24.0",
36
+ "@babel/preset-env": "^7.24.0",
37
+ "@types/argparse": "^2.0.15",
38
38
  "@types/async": "^3.2.24",
39
39
  "@types/bunyan": "^1.8.11",
40
40
  "@types/express": "^4.17.21",
41
41
  "@types/jest": "^29.5.12",
42
- "@types/node": "^20.11.19",
42
+ "@types/node": "^20.11.28",
43
43
  "@types/tmp": "^0.2.6",
44
44
  "@types/ws": "^8.5.10",
45
45
  "babel-jest": "^29.7.0",
46
- "esbuild": "^0.20.0",
46
+ "esbuild": "^0.20.2",
47
47
  "jest": "^29.7.0",
48
48
  "mockttp": "^3.10.1",
49
49
  "rimraf": "^5.0.5",
50
50
  "ts-jest": "^29.1.2",
51
51
  "ts-node": "^10.9.2",
52
- "typescript": "^5.3.3"
52
+ "typescript": "^5.4.2"
53
53
  },
54
54
  "publishConfig": {
55
55
  "access": "public"