@rushstack/rush-http-build-cache-plugin 5.97.1 → 5.98.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 (53) hide show
  1. package/.heft/build-cache/jest-cache/haste-map-bae913f9b9aa720eb4deeae0a60a4b27-22ae7f4ce9de4306889d8c05e5cc39b9-f6b1af01a3130057bdfe3d86807211f9 +0 -0
  2. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/{9d/commons_9d513d1d600f9112f73547da918dcbb7 → 2e/commons_2e52897dfe4222d991674613f5b35882} +356 -314
  3. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/34/PrefixProxyTerminalProvider_34b4603b9c4455de1c3cc05820149fdd +65 -0
  4. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/{53/index_53d9d5a344c3984994c801733764f503 → 46/index_46761981528d09d1a0e438f06cd2c548} +6 -2
  5. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/{06/ConfigurationFile_06d7f35feb0bd944d9b9a2a4d9e112c8 → 57/ConfigurationFile_57c950e8ef4673e11bff94304a50823c} +10 -4
  6. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/{68/rushlib_68c59fa059ba441c9c6883bcfed4a8d2 → 69/rushlib_695f6e29167e91482e2906a8d09b3a5a} +17 -6
  7. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/8a/HttpBuildCacheProvidertest_8a1598e1f1b42d6933964acfb7612893 +116 -0
  8. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/8a/HttpBuildCacheProvidertest_8a1598e1f1b42d6933964acfb7612893.map +1 -0
  9. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/a3/RushHttpBuildCachePlugin_a3e8a9bb172ff361907e770dcf3268be +1551 -0
  10. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/a3/RushHttpBuildCachePlugin_a3e8a9bb172ff361907e770dcf3268be.map +1 -0
  11. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/ba/TerminalWritable_ba71b4b7bfe6a26c85f4fd0245057a0a +54 -0
  12. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/{5d/Text_5da85b5db9a2f06bbe29cdcd91e6fbca → df/Text_df57ddd200e4237e617fc183dcb5fe67} +7 -1
  13. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/ec/HttpBuildCacheProvider_ecceab34e8340fa24dde11b618ffa8a4 +4668 -0
  14. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/ec/HttpBuildCacheProvider_ecceab34e8340fa24dde11b618ffa8a4.map +1 -0
  15. package/.heft/build-cache/jest-cache/perf-cache-bae913f9b9aa720eb4deeae0a60a4b27-da39a3ee5e6b4b0d3255bfef95601890 +1 -1
  16. package/.rush/temp/operation/_phase_build/state.json +1 -1
  17. package/.rush/temp/operation/_phase_test/all.log +14 -14
  18. package/.rush/temp/operation/_phase_test/state.json +1 -1
  19. package/.rush/temp/package-deps__phase_build.json +3 -3
  20. package/.rush/temp/package-deps__phase_test.json +3 -3
  21. package/.rush/temp/{rushstack+rush-http-build-cache-plugin-_phase_build-646439b80a2010050f5b4b8a916e50afae04c3ab.log → rushstack+rush-http-build-cache-plugin-_phase_build-08118e08afc6d454e5623f20498fd64b5e3e9051.log} +2 -2
  22. package/lib/HttpBuildCacheProvider.d.ts +2 -0
  23. package/lib/HttpBuildCacheProvider.d.ts.map +1 -1
  24. package/lib/HttpBuildCacheProvider.js +26 -7
  25. package/lib/HttpBuildCacheProvider.js.map +1 -1
  26. package/lib/RushHttpBuildCachePlugin.d.ts.map +1 -1
  27. package/lib/RushHttpBuildCachePlugin.js +28 -4
  28. package/lib/RushHttpBuildCachePlugin.js.map +1 -1
  29. package/lib/test/HttpBuildCacheProvider.test.d.ts.map +1 -0
  30. package/lib/{HttpBuildCacheProvider.test.js → test/HttpBuildCacheProvider.test.js} +46 -3
  31. package/lib/test/HttpBuildCacheProvider.test.js.map +1 -0
  32. package/package.json +6 -6
  33. package/rush-logs/rush-http-build-cache-plugin._phase_test.log +14 -14
  34. package/src/HttpBuildCacheProvider.ts +36 -7
  35. package/src/RushHttpBuildCachePlugin.ts +23 -28
  36. package/src/test/HttpBuildCacheProvider.test.ts +115 -0
  37. package/temp/coverage/clover.xml +117 -109
  38. package/temp/coverage/coverage-final.json +2 -2
  39. package/temp/coverage/lcov-report/HttpBuildCacheProvider.ts.html +166 -79
  40. package/temp/coverage/lcov-report/RushHttpBuildCachePlugin.ts.html +29 -44
  41. package/temp/coverage/lcov-report/index.html +24 -24
  42. package/temp/coverage/lcov-report/index.ts.html +1 -1
  43. package/temp/coverage/lcov.info +236 -218
  44. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/e5/HttpBuildCacheProvider_e53bd002cf44ae62693f20b8c4682941 +0 -4367
  45. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/e5/HttpBuildCacheProvider_e53bd002cf44ae62693f20b8c4682941.map +0 -1
  46. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/e6/RushHttpBuildCachePlugin_e69b4b7cd4f95aa49455690c88f00247 +0 -362
  47. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/e6/RushHttpBuildCachePlugin_e69b4b7cd4f95aa49455690c88f00247.map +0 -1
  48. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/f7/HttpBuildCacheProvidertest_f710af633835df558cad54cb165c14fa +0 -73
  49. package/.heft/build-cache/jest-cache/jest-transform-cache-bae913f9b9aa720eb4deeae0a60a4b27-474488b31a4a940a3990e9eaf06f1647/f7/HttpBuildCacheProvidertest_f710af633835df558cad54cb165c14fa.map +0 -1
  50. package/lib/HttpBuildCacheProvider.test.d.ts.map +0 -1
  51. package/lib/HttpBuildCacheProvider.test.js.map +0 -1
  52. package/src/HttpBuildCacheProvider.test.ts +0 -58
  53. /package/lib/{HttpBuildCacheProvider.test.d.ts → test/HttpBuildCacheProvider.test.d.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/rush-http-build-cache-plugin",
3
- "version": "5.97.1",
3
+ "version": "5.98.0",
4
4
  "description": "Rush plugin for generic HTTP cloud build cache",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,17 +14,17 @@
14
14
  "dependencies": {
15
15
  "https-proxy-agent": "~5.0.0",
16
16
  "node-fetch": "2.6.7",
17
- "@rushstack/node-core-library": "3.56.0",
18
- "@rushstack/rush-sdk": "5.97.1"
17
+ "@rushstack/node-core-library": "3.59.0",
18
+ "@rushstack/rush-sdk": "5.98.0"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/heft-jest": "1.0.1",
22
22
  "@types/node": "14.18.36",
23
23
  "@types/node-fetch": "2.6.2",
24
- "@microsoft/rush-lib": "5.97.1",
24
+ "@microsoft/rush-lib": "5.98.0",
25
25
  "@rushstack/eslint-config": "3.2.0",
26
- "@rushstack/heft": "0.50.1",
27
- "@rushstack/heft-node-rig": "1.12.7"
26
+ "@rushstack/heft": "0.50.5",
27
+ "@rushstack/heft-node-rig": "1.12.11"
28
28
  },
29
29
  "scripts": {
30
30
  "build": "heft build --clean",
@@ -8,22 +8,22 @@ Starting test
8
8
  [jest] Using Jest version 29.5.0
9
9
 
10
10
  Run start. 1 test suite
11
- START src/HttpBuildCacheProvider.test.ts
12
- PASS src/HttpBuildCacheProvider.test.ts (duration: 0.724s, 1 passed, 0 failed)
11
+ START src/test/HttpBuildCacheProvider.test.ts
12
+ PASS src/test/HttpBuildCacheProvider.test.ts (duration: 0.693s, 2 passed, 0 failed)
13
13
 
14
14
  Tests finished:
15
- Successes: 1
15
+ Successes: 2
16
16
  Failures: 0
17
- Total: 1
18
- -----------------------------|---------|----------|---------|---------|---------------------------------------------------
19
- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
20
- -----------------------------|---------|----------|---------|---------|---------------------------------------------------
21
- All files | 42.74 | 39.02 | 40.9 | 42.74 |
22
- HttpBuildCacheProvider.ts | 47.45 | 39.02 | 50 | 47.45 | 58,89,101-174,184,209,213-214,237-249,258,297-380
23
- RushHttpBuildCachePlugin.ts | 0 | 100 | 0 | 0 | 1-81
24
- index.ts | 0 | 100 | 100 | 0 | 1-3
25
- -----------------------------|---------|----------|---------|---------|---------------------------------------------------
26
- -------------------- Finished (1.873s) --------------------
17
+ Total: 2
18
+ -----------------------------|---------|----------|---------|---------|----------------------------------------------------------------------------
19
+ File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
20
+ -----------------------------|---------|----------|---------|---------|----------------------------------------------------------------------------
21
+ All files | 53.23 | 45.55 | 47.82 | 53.23 |
22
+ HttpBuildCacheProvider.ts | 58.26 | 45.55 | 61.11 | 58.26 | 63,108-182,192,218,222-223,270-278,287,326-328,335,348-371,389-390,399-409
23
+ RushHttpBuildCachePlugin.ts | 0 | 100 | 0 | 0 | 7-77
24
+ index.ts | 0 | 100 | 100 | 0 | 1-3
25
+ -----------------------------|---------|----------|---------|---------|----------------------------------------------------------------------------
26
+ -------------------- Finished (1.935s) --------------------
27
27
  Project: @rushstack/rush-http-build-cache-plugin@5.97.1
28
- Heft version: 0.50.0
28
+ Heft version: 0.50.5
29
29
  Node version: v14.21.3
@@ -1,4 +1,4 @@
1
- import { ITerminal, Executable } from '@rushstack/node-core-library';
1
+ import { ITerminal, Executable, Async } from '@rushstack/node-core-library';
2
2
  import {
3
3
  ICloudBuildCacheProvider,
4
4
  ICredentialCacheEntry,
@@ -34,6 +34,7 @@ export interface IHttpBuildCacheProviderOptions {
34
34
  url: string;
35
35
  tokenHandler?: IHttpBuildCacheTokenHandler;
36
36
  uploadMethod?: string;
37
+ minHttpRetryDelayMs?: number;
37
38
  headers?: Record<string, string>;
38
39
  cacheKeyPrefix?: string;
39
40
  isCacheWriteAllowed: boolean;
@@ -41,6 +42,9 @@ export interface IHttpBuildCacheProviderOptions {
41
42
  rushProjectRoot: string;
42
43
  }
43
44
 
45
+ const MAX_HTTP_CACHE_ATTEMPTS: number = 3;
46
+ const DEFAULT_MIN_HTTP_RETRY_DELAY_MS = 2500;
47
+
44
48
  export class HttpBuildCacheProvider implements ICloudBuildCacheProvider {
45
49
  private readonly _pluginName: string;
46
50
  private readonly _rushSession: RushSession;
@@ -52,6 +56,7 @@ export class HttpBuildCacheProvider implements ICloudBuildCacheProvider {
52
56
  private readonly _headers: Record<string, string>;
53
57
  private readonly _cacheKeyPrefix: string;
54
58
  private readonly _tokenHandler: IHttpBuildCacheTokenHandler | undefined;
59
+ private readonly _minHttpRetryDelayMs: number;
55
60
  private __credentialCacheId: string | undefined;
56
61
 
57
62
  public get isCacheWriteAllowed(): boolean {
@@ -70,6 +75,7 @@ export class HttpBuildCacheProvider implements ICloudBuildCacheProvider {
70
75
  this._headers = options.headers ?? {};
71
76
  this._tokenHandler = options.tokenHandler;
72
77
  this._cacheKeyPrefix = options.cacheKeyPrefix ?? '';
78
+ this._minHttpRetryDelayMs = options.minHttpRetryDelayMs ?? DEFAULT_MIN_HTTP_RETRY_DELAY_MS;
73
79
  }
74
80
 
75
81
  public async tryGetCacheEntryBufferByIdAsync(
@@ -83,7 +89,8 @@ export class HttpBuildCacheProvider implements ICloudBuildCacheProvider {
83
89
  method: 'GET',
84
90
  body: undefined,
85
91
  warningText: 'Could not get cache entry',
86
- readBody: true
92
+ readBody: true,
93
+ maxAttempts: MAX_HTTP_CACHE_ATTEMPTS
87
94
  });
88
95
 
89
96
  return Buffer.isBuffer(result) ? result : undefined;
@@ -112,7 +119,8 @@ export class HttpBuildCacheProvider implements ICloudBuildCacheProvider {
112
119
  method: this._uploadMethod,
113
120
  body: objectBuffer,
114
121
  warningText: 'Could not write cache entry',
115
- readBody: false
122
+ readBody: false,
123
+ maxAttempts: MAX_HTTP_CACHE_ATTEMPTS
116
124
  });
117
125
 
118
126
  return result !== false;
@@ -197,6 +205,7 @@ export class HttpBuildCacheProvider implements ICloudBuildCacheProvider {
197
205
  body: BodyInit | undefined;
198
206
  warningText: string;
199
207
  readBody: boolean;
208
+ maxAttempts: number;
200
209
  credentialOptions?: CredentialsOptions;
201
210
  }): Promise<Buffer | boolean> {
202
211
  const { terminal, relUrl, method, body, warningText, readBody, credentialOptions } = options;
@@ -227,13 +236,33 @@ export class HttpBuildCacheProvider implements ICloudBuildCacheProvider {
227
236
  });
228
237
 
229
238
  if (!response.ok) {
230
- if (typeof credentials !== 'string' && safeCredentialOptions === CredentialsOptions.Optional) {
231
- // We tried fetching the resource without credentials and that did not work out
232
- // Try again but require credentials this time
233
- // This will trigger the provider to request credentials
239
+ const isNonCredentialResponse = response.status >= 500 && response.status < 600;
240
+
241
+ if (
242
+ !isNonCredentialResponse &&
243
+ typeof credentials !== 'string' &&
244
+ safeCredentialOptions === CredentialsOptions.Optional
245
+ ) {
246
+ // If we don't already have credentials yet, and we got a response from the server
247
+ // that is a "normal" failure (4xx), then we assume that credentials are probably
248
+ // required. Re-attempt the request, requiring credentials this time.
249
+ //
250
+ // This counts as part of the "first attempt", so it is not included in the max attempts
234
251
  return await this._http({ ...options, credentialOptions: CredentialsOptions.Required });
235
252
  }
236
253
 
254
+ if (options.maxAttempts > 1) {
255
+ // Pause a bit before retrying in case the server is busy
256
+ // Add some random jitter to the retry so we can spread out load on the remote service
257
+ // A proper solution might add exponential back off in case the retry count is high (10 or more)
258
+ const factor = 1.0 + Math.random(); // A random number between 1.0 and 2.0
259
+ const retryDelay = Math.floor(factor * this._minHttpRetryDelayMs);
260
+
261
+ await Async.sleep(retryDelay);
262
+
263
+ return await this._http({ ...options, maxAttempts: options.maxAttempts - 1 });
264
+ }
265
+
237
266
  this._reportFailure(terminal, method, response, false, warningText);
238
267
  return false;
239
268
  }
@@ -1,12 +1,9 @@
1
- import { Import } from '@rushstack/node-core-library';
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+
2
4
  import type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';
3
5
  import type { HttpBuildCacheProvider, IHttpBuildCacheProviderOptions } from './HttpBuildCacheProvider';
4
6
 
5
- const HttpBuildCacheProviderModule: typeof import('./HttpBuildCacheProvider') = Import.lazy(
6
- './HttpBuildCacheProvider',
7
- require
8
- );
9
-
10
7
  const PLUGIN_NAME: string = 'HttpBuildCachePlugin';
11
8
 
12
9
  /**
@@ -56,31 +53,29 @@ export class RushHttpBuildCachePlugin implements IRushPlugin {
56
53
 
57
54
  public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {
58
55
  rushSession.hooks.initialize.tap(this.pluginName, () => {
59
- rushSession.registerCloudBuildCacheProviderFactory(
60
- 'http',
61
- (buildCacheConfig): HttpBuildCacheProvider => {
62
- const config: IRushHttpBuildCachePluginConfig = (
63
- buildCacheConfig as typeof buildCacheConfig & {
64
- httpConfiguration: IRushHttpBuildCachePluginConfig;
65
- }
66
- ).httpConfiguration;
56
+ rushSession.registerCloudBuildCacheProviderFactory('http', async (buildCacheConfig) => {
57
+ const config: IRushHttpBuildCachePluginConfig = (
58
+ buildCacheConfig as typeof buildCacheConfig & {
59
+ httpConfiguration: IRushHttpBuildCachePluginConfig;
60
+ }
61
+ ).httpConfiguration;
67
62
 
68
- const { url, uploadMethod, headers, tokenHandler, cacheKeyPrefix, isCacheWriteAllowed } = config;
63
+ const { url, uploadMethod, headers, tokenHandler, cacheKeyPrefix, isCacheWriteAllowed } = config;
69
64
 
70
- const options: IHttpBuildCacheProviderOptions = {
71
- pluginName: this.pluginName,
72
- rushProjectRoot: rushConfig.rushJsonFolder,
73
- url: url,
74
- uploadMethod: uploadMethod,
75
- headers: headers,
76
- tokenHandler: tokenHandler,
77
- cacheKeyPrefix: cacheKeyPrefix,
78
- isCacheWriteAllowed: !!isCacheWriteAllowed
79
- };
65
+ const options: IHttpBuildCacheProviderOptions = {
66
+ pluginName: this.pluginName,
67
+ rushProjectRoot: rushConfig.rushJsonFolder,
68
+ url: url,
69
+ uploadMethod: uploadMethod,
70
+ headers: headers,
71
+ tokenHandler: tokenHandler,
72
+ cacheKeyPrefix: cacheKeyPrefix,
73
+ isCacheWriteAllowed: !!isCacheWriteAllowed
74
+ };
80
75
 
81
- return new HttpBuildCacheProviderModule.HttpBuildCacheProvider(options, rushSession);
82
- }
83
- );
76
+ const { HttpBuildCacheProvider } = await import('./HttpBuildCacheProvider');
77
+ return new HttpBuildCacheProvider(options, rushSession);
78
+ });
84
79
  });
85
80
  }
86
81
  }
@@ -0,0 +1,115 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+
4
+ jest.mock('node-fetch', function () {
5
+ return Object.assign(jest.fn(), jest.requireActual('node-fetch'));
6
+ });
7
+
8
+ import fetch, { Response } from 'node-fetch';
9
+ import { RushSession, EnvironmentConfiguration } from '@rushstack/rush-sdk';
10
+ import { StringBufferTerminalProvider, Terminal } from '@rushstack/node-core-library';
11
+
12
+ import { HttpBuildCacheProvider } from '../HttpBuildCacheProvider';
13
+
14
+ const EXAMPLE_OPTIONS = {
15
+ url: 'https://buildcache.example.acme.com',
16
+ tokenHandler: {
17
+ exec: 'node',
18
+ args: ['tokenHandler.js']
19
+ },
20
+ uploadMethod: 'POST',
21
+ isCacheWriteAllowed: false,
22
+ pluginName: 'example-plugin',
23
+ rushProjectRoot: '/repo',
24
+ minHttpRetryDelayMs: 1
25
+ };
26
+
27
+ describe('HttpBuildCacheProvider', () => {
28
+ let terminalBuffer: StringBufferTerminalProvider;
29
+ let terminal!: Terminal;
30
+
31
+ beforeEach(() => {
32
+ terminalBuffer = new StringBufferTerminalProvider();
33
+ terminal = new Terminal(terminalBuffer);
34
+ });
35
+
36
+ describe('tryGetCacheEntryBufferByIdAsync', () => {
37
+ it('prints warning if read credentials are not available', async () => {
38
+ jest.spyOn(EnvironmentConfiguration, 'buildCacheCredential', 'get').mockReturnValue(undefined);
39
+
40
+ const session: RushSession = {} as RushSession;
41
+ const provider = new HttpBuildCacheProvider(EXAMPLE_OPTIONS, session);
42
+
43
+ mocked(fetch).mockResolvedValue(
44
+ new Response('Unauthorized', {
45
+ status: 401,
46
+ statusText: 'Unauthorized'
47
+ })
48
+ );
49
+
50
+ const result = await provider.tryGetCacheEntryBufferByIdAsync(terminal, 'some-key');
51
+ expect(result).toBe(undefined);
52
+ expect(fetch).toHaveBeenCalledTimes(1);
53
+ expect(fetch).toHaveBeenNthCalledWith(1, 'https://buildcache.example.acme.com/some-key', {
54
+ body: undefined,
55
+ headers: {},
56
+ method: 'GET',
57
+ redirect: 'follow'
58
+ });
59
+ expect(terminalBuffer.getWarningOutput()).toMatchInlineSnapshot(
60
+ `"Error getting cache entry: Error: Credentials for https://buildcache.example.acme.com/ have not been provided.[n]In CI, verify that RUSH_BUILD_CACHE_CREDENTIAL contains a valid Authorization header value.[n][n]For local developers, run:[n][n] rush update-cloud-credentials --interactive[n][n]"`
61
+ );
62
+ });
63
+
64
+ it('attempts up to 3 times to download a cache entry', async () => {
65
+ jest.spyOn(EnvironmentConfiguration, 'buildCacheCredential', 'get').mockReturnValue(undefined);
66
+
67
+ const session: RushSession = {} as RushSession;
68
+ const provider = new HttpBuildCacheProvider(EXAMPLE_OPTIONS, session);
69
+
70
+ mocked(fetch).mockResolvedValueOnce(
71
+ new Response('InternalServiceError', {
72
+ status: 500,
73
+ statusText: 'InternalServiceError'
74
+ })
75
+ );
76
+ mocked(fetch).mockResolvedValueOnce(
77
+ new Response('ServiceUnavailable', {
78
+ status: 503,
79
+ statusText: 'ServiceUnavailable'
80
+ })
81
+ );
82
+ mocked(fetch).mockResolvedValueOnce(
83
+ new Response('BadGateway', {
84
+ status: 504,
85
+ statusText: 'BadGateway'
86
+ })
87
+ );
88
+
89
+ const result = await provider.tryGetCacheEntryBufferByIdAsync(terminal, 'some-key');
90
+ expect(result).toBe(undefined);
91
+ expect(fetch).toHaveBeenCalledTimes(3);
92
+ expect(fetch).toHaveBeenNthCalledWith(1, 'https://buildcache.example.acme.com/some-key', {
93
+ body: undefined,
94
+ headers: {},
95
+ method: 'GET',
96
+ redirect: 'follow'
97
+ });
98
+ expect(fetch).toHaveBeenNthCalledWith(2, 'https://buildcache.example.acme.com/some-key', {
99
+ body: undefined,
100
+ headers: {},
101
+ method: 'GET',
102
+ redirect: 'follow'
103
+ });
104
+ expect(fetch).toHaveBeenNthCalledWith(3, 'https://buildcache.example.acme.com/some-key', {
105
+ body: undefined,
106
+ headers: {},
107
+ method: 'GET',
108
+ redirect: 'follow'
109
+ });
110
+ expect(terminalBuffer.getWarningOutput()).toMatchInlineSnapshot(
111
+ `"Could not get cache entry: HTTP 504: BadGateway[n]"`
112
+ );
113
+ });
114
+ });
115
+ });
@@ -1,9 +1,9 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <coverage generated="1682615665433" clover="3.2.0">
3
- <project timestamp="1682615665433" name="All files">
4
- <metrics statements="131" coveredstatements="56" conditionals="82" coveredconditionals="32" methods="22" coveredmethods="9" elements="235" coveredelements="97" complexity="0" loc="131" ncloc="131" packages="1" files="3" classes="3"/>
2
+ <coverage generated="1684628065520" clover="3.2.0">
3
+ <project timestamp="1684628065521" name="All files">
4
+ <metrics statements="139" coveredstatements="74" conditionals="90" coveredconditionals="41" methods="23" coveredmethods="11" elements="252" coveredelements="126" complexity="0" loc="139" ncloc="139" packages="1" files="3" classes="3"/>
5
5
  <file name="HttpBuildCacheProvider.ts" path="/home/vsts/work/1/s/rush-plugins/rush-http-build-cache-plugin/src/HttpBuildCacheProvider.ts">
6
- <metrics statements="118" coveredstatements="56" conditionals="82" coveredconditionals="32" methods="18" coveredmethods="9"/>
6
+ <metrics statements="127" coveredstatements="74" conditionals="90" coveredconditionals="41" methods="18" coveredmethods="11"/>
7
7
  <line num="1" count="1" type="stmt"/>
8
8
  <line num="2" count="1" type="stmt"/>
9
9
  <line num="9" count="1" type="stmt"/>
@@ -17,125 +17,133 @@
17
17
  <line num="20" count="1" type="stmt"/>
18
18
  <line num="21" count="1" type="stmt"/>
19
19
  <line num="22" count="1" type="stmt"/>
20
- <line num="44" count="1" type="stmt"/>
21
- <line num="58" count="0" type="cond" truecount="0" falsecount="4"/>
22
- <line num="62" count="1" type="stmt"/>
23
- <line num="63" count="1" type="stmt"/>
24
- <line num="64" count="1" type="stmt"/>
25
- <line num="66" count="1" type="stmt"/>
26
- <line num="67" count="1" type="stmt"/>
27
- <line num="68" count="1" type="cond" truecount="1" falsecount="1"/>
28
- <line num="69" count="1" type="cond" truecount="3" falsecount="1"/>
29
- <line num="70" count="1" type="cond" truecount="3" falsecount="1"/>
30
- <line num="71" count="1" type="stmt"/>
31
- <line num="72" count="1" type="cond" truecount="3" falsecount="1"/>
32
- <line num="79" count="1" type="stmt"/>
33
- <line num="80" count="1" type="stmt"/>
34
- <line num="89" count="0" type="cond" truecount="0" falsecount="2"/>
35
- <line num="91" count="1" type="stmt"/>
36
- <line num="92" count="1" type="stmt"/>
37
- <line num="101" count="0" type="cond" truecount="0" falsecount="1"/>
38
- <line num="102" count="0" type="stmt"/>
39
- <line num="103" count="0" type="stmt"/>
40
- <line num="106" count="0" type="stmt"/>
41
- <line num="108" count="0" type="stmt"/>
20
+ <line num="45" count="1" type="stmt"/>
21
+ <line num="46" count="1" type="stmt"/>
22
+ <line num="48" count="1" type="stmt"/>
23
+ <line num="63" count="0" type="cond" truecount="0" falsecount="4"/>
24
+ <line num="67" count="2" type="stmt"/>
25
+ <line num="68" count="2" type="stmt"/>
26
+ <line num="69" count="2" type="stmt"/>
27
+ <line num="71" count="2" type="stmt"/>
28
+ <line num="72" count="2" type="stmt"/>
29
+ <line num="73" count="2" type="cond" truecount="1" falsecount="1"/>
30
+ <line num="74" count="2" type="cond" truecount="3" falsecount="1"/>
31
+ <line num="75" count="2" type="cond" truecount="3" falsecount="1"/>
32
+ <line num="76" count="2" type="stmt"/>
33
+ <line num="77" count="2" type="cond" truecount="3" falsecount="1"/>
34
+ <line num="78" count="2" type="cond" truecount="3" falsecount="1"/>
35
+ <line num="85" count="2" type="stmt"/>
36
+ <line num="86" count="2" type="stmt"/>
37
+ <line num="96" count="1" type="cond" truecount="1" falsecount="1"/>
38
+ <line num="98" count="1" type="stmt"/>
39
+ <line num="99" count="1" type="stmt"/>
40
+ <line num="108" count="0" type="cond" truecount="0" falsecount="1"/>
42
41
  <line num="109" count="0" type="stmt"/>
43
- <line num="118" count="0" type="stmt"/>
44
- <line num="120" count="0" type="stmt"/>
45
- <line num="121" count="0" type="stmt"/>
42
+ <line num="110" count="0" type="stmt"/>
43
+ <line num="113" count="0" type="stmt"/>
44
+ <line num="115" count="0" type="stmt"/>
45
+ <line num="116" count="0" type="stmt"/>
46
46
  <line num="126" count="0" type="stmt"/>
47
- <line num="131" count="0" type="stmt"/>
47
+ <line num="128" count="0" type="stmt"/>
48
+ <line num="129" count="0" type="stmt"/>
48
49
  <line num="134" count="0" type="stmt"/>
49
- <line num="140" count="0" type="cond" truecount="0" falsecount="1"/>
50
- <line num="141" count="0" type="stmt"/>
51
- <line num="149" count="0" type="cond" truecount="0" falsecount="2"/>
52
- <line num="150" count="0" type="stmt"/>
53
- <line num="151" count="0" type="cond" truecount="0" falsecount="2"/>
54
- <line num="153" count="0" type="stmt"/>
55
- <line num="155" count="0" type="cond" truecount="0" falsecount="1"/>
56
- <line num="156" count="0" type="stmt"/>
57
- <line num="159" count="0" type="stmt"/>
58
- <line num="160" count="0" type="stmt"/>
59
- <line num="162" count="0" type="stmt"/>
50
+ <line num="139" count="0" type="stmt"/>
51
+ <line num="142" count="0" type="stmt"/>
52
+ <line num="148" count="0" type="cond" truecount="0" falsecount="1"/>
53
+ <line num="149" count="0" type="stmt"/>
54
+ <line num="157" count="0" type="cond" truecount="0" falsecount="2"/>
55
+ <line num="158" count="0" type="stmt"/>
56
+ <line num="159" count="0" type="cond" truecount="0" falsecount="2"/>
57
+ <line num="161" count="0" type="stmt"/>
58
+ <line num="163" count="0" type="cond" truecount="0" falsecount="1"/>
60
59
  <line num="164" count="0" type="stmt"/>
60
+ <line num="167" count="0" type="stmt"/>
61
61
  <line num="168" count="0" type="stmt"/>
62
- <line num="173" count="0" type="stmt"/>
63
- <line num="174" count="0" type="stmt"/>
64
- <line num="180" count="2" type="cond" truecount="1" falsecount="0"/>
65
- <line num="181" count="1" type="stmt"/>
66
- <line num="183" count="1" type="cond" truecount="0" falsecount="1"/>
67
- <line num="184" count="0" type="stmt"/>
68
- <line num="187" count="1" type="stmt"/>
69
- <line num="190" count="2" type="stmt"/>
70
- <line num="202" count="2" type="stmt"/>
71
- <line num="203" count="2" type="cond" truecount="4" falsecount="0"/>
72
- <line num="204" count="2" type="stmt"/>
73
- <line num="205" count="1" type="stmt"/>
74
- <line num="207" count="1" type="stmt"/>
75
- <line num="208" count="1" type="cond" truecount="0" falsecount="1"/>
76
- <line num="209" count="0" type="stmt"/>
77
- <line num="212" count="1" type="stmt"/>
78
- <line num="213" count="0" type="cond" truecount="0" falsecount="1"/>
79
- <line num="214" count="0" type="stmt"/>
80
- <line num="218" count="1" type="cond" truecount="5" falsecount="1"/>
81
- <line num="220" count="1" type="stmt"/>
82
- <line num="222" count="1" type="stmt"/>
83
- <line num="229" count="1" type="cond" truecount="1" falsecount="0"/>
84
- <line num="230" count="1" type="cond" truecount="3" falsecount="0"/>
85
- <line num="234" count="1" type="stmt"/>
86
- <line num="237" count="0" type="stmt"/>
87
- <line num="238" count="0" type="stmt"/>
88
- <line num="241" count="0" type="cond" truecount="0" falsecount="2"/>
89
- <line num="243" count="0" type="stmt"/>
90
- <line num="249" count="0" type="stmt"/>
91
- <line num="257" count="2" type="cond" truecount="0" falsecount="1"/>
92
- <line num="258" count="0" type="stmt"/>
62
+ <line num="170" count="0" type="stmt"/>
63
+ <line num="172" count="0" type="stmt"/>
64
+ <line num="176" count="0" type="stmt"/>
65
+ <line num="181" count="0" type="stmt"/>
66
+ <line num="182" count="0" type="stmt"/>
67
+ <line num="188" count="5" type="cond" truecount="1" falsecount="0"/>
68
+ <line num="189" count="2" type="stmt"/>
69
+ <line num="191" count="2" type="cond" truecount="0" falsecount="1"/>
70
+ <line num="192" count="0" type="stmt"/>
71
+ <line num="195" count="2" type="stmt"/>
72
+ <line num="198" count="5" type="stmt"/>
73
+ <line num="211" count="5" type="stmt"/>
74
+ <line num="212" count="5" type="cond" truecount="4" falsecount="0"/>
75
+ <line num="213" count="5" type="stmt"/>
76
+ <line num="214" count="4" type="stmt"/>
77
+ <line num="216" count="4" type="stmt"/>
78
+ <line num="217" count="4" type="cond" truecount="0" falsecount="1"/>
79
+ <line num="218" count="0" type="stmt"/>
80
+ <line num="221" count="4" type="stmt"/>
81
+ <line num="222" count="0" type="cond" truecount="0" falsecount="1"/>
82
+ <line num="223" count="0" type="stmt"/>
83
+ <line num="227" count="4" type="cond" truecount="5" falsecount="1"/>
84
+ <line num="229" count="4" type="stmt"/>
85
+ <line num="231" count="4" type="stmt"/>
86
+ <line num="238" count="4" type="cond" truecount="1" falsecount="0"/>
87
+ <line num="239" count="4" type="cond" truecount="2" falsecount="0"/>
88
+ <line num="241" count="4" type="cond" truecount="1" falsecount="0"/>
89
+ <line num="251" count="1" type="stmt"/>
90
+ <line num="254" count="3" type="cond" truecount="1" falsecount="0"/>
91
+ <line num="258" count="2" type="stmt"/>
92
+ <line num="259" count="2" type="stmt"/>
93
93
  <line num="261" count="2" type="stmt"/>
94
- <line num="263" count="2" type="cond" truecount="1" falsecount="0"/>
95
- <line num="264" count="2" type="stmt"/>
96
- <line num="267" count="2" type="cond" truecount="3" falsecount="0"/>
97
- <line num="268" count="1" type="stmt"/>
98
- <line num="281" count="1" type="stmt"/>
99
- <line num="287" count="2" type="stmt"/>
100
- <line num="292" count="2" type="stmt"/>
101
- <line num="296" count="2" type="cond" truecount="0" falsecount="1"/>
102
- <line num="297" count="0" type="cond" truecount="0" falsecount="4"/>
103
- <line num="298" count="0" type="cond" truecount="0" falsecount="3"/>
104
- <line num="299" count="0" type="stmt"/>
105
- <line num="305" count="0" type="cond" truecount="0" falsecount="1"/>
106
- <line num="306" count="0" type="stmt"/>
107
- <line num="309" count="0" type="cond" truecount="0" falsecount="5"/>
108
- <line num="319" count="0" type="stmt"/>
109
- <line num="325" count="0" type="cond" truecount="0" falsecount="4"/>
110
- <line num="333" count="0" type="stmt"/>
111
- <line num="336" count="0" type="stmt"/>
112
- <line num="340" count="0" type="cond" truecount="0" falsecount="1"/>
113
- <line num="342" count="0" type="stmt"/>
94
+ <line num="263" count="2" type="stmt"/>
95
+ <line num="266" count="1" type="stmt"/>
96
+ <line num="267" count="1" type="stmt"/>
97
+ <line num="270" count="0" type="cond" truecount="0" falsecount="2"/>
98
+ <line num="272" count="0" type="stmt"/>
99
+ <line num="278" count="0" type="stmt"/>
100
+ <line num="286" count="5" type="cond" truecount="0" falsecount="1"/>
101
+ <line num="287" count="0" type="stmt"/>
102
+ <line num="290" count="5" type="stmt"/>
103
+ <line num="292" count="5" type="cond" truecount="1" falsecount="0"/>
104
+ <line num="293" count="5" type="stmt"/>
105
+ <line num="296" count="5" type="cond" truecount="3" falsecount="0"/>
106
+ <line num="297" count="1" type="stmt"/>
107
+ <line num="310" count="4" type="stmt"/>
108
+ <line num="316" count="5" type="stmt"/>
109
+ <line num="321" count="5" type="stmt"/>
110
+ <line num="325" count="5" type="cond" truecount="0" falsecount="1"/>
111
+ <line num="326" count="0" type="cond" truecount="0" falsecount="4"/>
112
+ <line num="327" count="0" type="cond" truecount="0" falsecount="3"/>
113
+ <line num="328" count="0" type="stmt"/>
114
+ <line num="334" count="1" type="cond" truecount="0" falsecount="1"/>
115
+ <line num="335" count="0" type="stmt"/>
116
+ <line num="338" count="1" type="cond" truecount="0" falsecount="5"/>
114
117
  <line num="348" count="0" type="stmt"/>
115
- <line num="358" count="0" type="cond" truecount="0" falsecount="5"/>
116
- <line num="360" count="0" type="stmt"/>
117
- <line num="361" count="0" type="stmt"/>
118
+ <line num="354" count="0" type="cond" truecount="0" falsecount="4"/>
119
+ <line num="362" count="0" type="stmt"/>
118
120
  <line num="365" count="0" type="stmt"/>
119
- <line num="366" count="0" type="stmt"/>
120
- <line num="370" count="0" type="stmt"/>
121
+ <line num="369" count="0" type="cond" truecount="0" falsecount="1"/>
121
122
  <line num="371" count="0" type="stmt"/>
122
- <line num="375" count="0" type="stmt"/>
123
- <line num="376" count="0" type="stmt"/>
124
- <line num="380" count="0" type="stmt"/>
123
+ <line num="377" count="1" type="stmt"/>
124
+ <line num="387" count="1" type="cond" truecount="1" falsecount="4"/>
125
+ <line num="389" count="0" type="stmt"/>
126
+ <line num="390" count="0" type="stmt"/>
127
+ <line num="394" count="1" type="stmt"/>
128
+ <line num="395" count="1" type="stmt"/>
129
+ <line num="399" count="0" type="stmt"/>
130
+ <line num="400" count="0" type="stmt"/>
131
+ <line num="404" count="0" type="stmt"/>
132
+ <line num="405" count="0" type="stmt"/>
133
+ <line num="409" count="0" type="stmt"/>
125
134
  </file>
126
135
  <file name="RushHttpBuildCachePlugin.ts" path="/home/vsts/work/1/s/rush-plugins/rush-http-build-cache-plugin/src/RushHttpBuildCachePlugin.ts">
127
- <metrics statements="11" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="4" coveredmethods="0"/>
128
- <line num="1" count="0" type="stmt"/>
129
- <line num="5" count="0" type="stmt"/>
130
- <line num="10" count="0" type="stmt"/>
131
- <line num="54" count="0" type="stmt"/>
136
+ <metrics statements="10" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="5" coveredmethods="0"/>
137
+ <line num="7" count="0" type="stmt"/>
138
+ <line num="51" count="0" type="stmt"/>
139
+ <line num="52" count="0" type="stmt"/>
132
140
  <line num="55" count="0" type="stmt"/>
141
+ <line num="56" count="0" type="stmt"/>
133
142
  <line num="58" count="0" type="stmt"/>
134
- <line num="59" count="0" type="stmt"/>
135
143
  <line num="63" count="0" type="stmt"/>
136
- <line num="68" count="0" type="stmt"/>
137
- <line num="70" count="0" type="stmt"/>
138
- <line num="81" count="0" type="stmt"/>
144
+ <line num="65" count="0" type="stmt"/>
145
+ <line num="76" count="0" type="stmt"/>
146
+ <line num="77" count="0" type="stmt"/>
139
147
  </file>
140
148
  <file name="index.ts" path="/home/vsts/work/1/s/rush-plugins/rush-http-build-cache-plugin/src/index.ts">
141
149
  <metrics statements="2" coveredstatements="0" conditionals="0" coveredconditionals="0" methods="0" coveredmethods="0"/>