Skip to content

Commit 9c06350

Browse files
authored
feat: Add support through package to support users providing a total_synthetic_timeout_millis option (#91)
1 parent 000c31d commit 9c06350

File tree

7 files changed

+1089
-176
lines changed

7 files changed

+1089
-176
lines changed

package-lock.json

Lines changed: 1026 additions & 161 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/synthetics-sdk-broken-links/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"node": ">=18"
4141
},
4242
"dependencies": {
43-
"@google-cloud/synthetics-sdk-api": "^0.5.0",
43+
"@google-cloud/synthetics-sdk-api": "^0.5.1",
4444
"puppeteer": "21.3.6"
4545
}
4646
}

packages/synthetics-sdk-broken-links/src/broken_links.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export interface BrokenLinkCheckerOptions {
4747
max_retries?: number | undefined;
4848
wait_for_selector?: string;
4949
per_link_options?: { [key: string]: PerLinkOption };
50+
total_synthetic_timeout_millis?: number;
5051
}
5152

5253
export interface PerLinkOption {
@@ -78,8 +79,7 @@ try {
7879
instantiateMetadata(synthetics_sdk_broken_links_package);
7980

8081
export async function runBrokenLinks(
81-
inputOptions: BrokenLinkCheckerOptions,
82-
total_timeout_millis = 50000
82+
inputOptions: BrokenLinkCheckerOptions
8383
): Promise<SyntheticResult> {
8484
// init
8585
const startTime = new Date().toISOString();
@@ -88,11 +88,13 @@ export async function runBrokenLinks(
8888
let browser: Browser;
8989
try {
9090
const options = processOptions(inputOptions);
91+
const adjusted_synthetic_timeout_millis =
92+
options.total_synthetic_timeout_millis! - 7000;
9193

9294
// Create Promise and variables used to set and resolve the time limit
93-
// imposed by `total_timeout_millis`
95+
// imposed by `adjusted_synthetic_timeout`
9496
const [timeLimitPromise, timeLimitTimeout, timeLimitresolver] =
95-
getTimeLimitPromise(startTime, total_timeout_millis);
97+
getTimeLimitPromise(startTime, adjusted_synthetic_timeout_millis);
9698

9799
const followed_links: BrokenLinksResultV1_SyntheticLinkResult[] = [];
98100

@@ -107,7 +109,7 @@ export async function runBrokenLinks(
107109
originPage,
108110
options,
109111
startTime,
110-
total_timeout_millis
112+
adjusted_synthetic_timeout_millis
111113
)
112114
);
113115

@@ -129,7 +131,7 @@ export async function runBrokenLinks(
129131
linksToFollow,
130132
options,
131133
startTime,
132-
total_timeout_millis
134+
adjusted_synthetic_timeout_millis
133135
))
134136
);
135137
return true;
@@ -174,15 +176,15 @@ async function checkOriginLink(
174176
originPage: Page,
175177
options: BrokenLinksResultV1_BrokenLinkCheckerOptions,
176178
startTime: string,
177-
total_timeout_millis: number
179+
adjusted_synthetic_timeout_millis: number
178180
): Promise<BrokenLinksResultV1_SyntheticLinkResult> {
179181
let originLinkResult: BrokenLinksResultV1_SyntheticLinkResult;
180182

181183
// Create Promise and variables used to set and resolve the time limit
182184
const [timeLimitPromise, timeLimitTimeout, timeLimitresolver] =
183185
getTimeLimitPromise(
184186
startTime,
185-
total_timeout_millis,
187+
adjusted_synthetic_timeout_millis,
186188
/*extraOffsetMillis=*/ 500
187189
);
188190

@@ -221,7 +223,7 @@ async function checkOriginLink(
221223
if (!finished && originLinkResult) {
222224
originLinkResult.link_passed = false;
223225
originLinkResult.error_type = 'TimeoutError';
224-
originLinkResult.error_message = `Global Timeout of 60 secs hit while waiting for selector '${options.wait_for_selector}'`;
226+
originLinkResult.error_message = `Total Synthetic Timeout of ${options.total_synthetic_timeout_millis} milliseconds hit while waiting for selector '${options.wait_for_selector}'`;
225227
process.stderr.write(originLinkResult.error_message);
226228
}
227229

packages/synthetics-sdk-broken-links/src/options_func.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ import {
3232
* @returns The sanitized input options if validation passes.
3333
* @throws {Error} If any of the input options fail validation.
3434
*/
35-
export function validateInputOptions(inputOptions: BrokenLinkCheckerOptions) {
35+
export function validateInputOptions(
36+
inputOptions: BrokenLinkCheckerOptions
37+
): BrokenLinkCheckerOptions {
3638
if (!inputOptions.origin_uri) {
3739
throw new Error('Missing origin_uri in options');
3840
} else if (
@@ -116,6 +118,18 @@ export function validateInputOptions(inputOptions: BrokenLinkCheckerOptions) {
116118
throw new Error('Invalid wait_for_selector value, must be a string');
117119
}
118120

121+
// Check total_synthetic_timeout_millis
122+
if (
123+
inputOptions.total_synthetic_timeout_millis !== undefined &&
124+
(typeof inputOptions.total_synthetic_timeout_millis !== 'number' ||
125+
inputOptions.total_synthetic_timeout_millis < 30000 ||
126+
inputOptions.total_synthetic_timeout_millis > 60000)
127+
) {
128+
throw new Error(
129+
'Invalid total_synthetic_timeout_millis value, must be a number between 30000 and 60000 inclusive'
130+
);
131+
}
132+
119133
// per_link_options
120134
for (const [key, value] of Object.entries(
121135
inputOptions.per_link_options || {}
@@ -165,6 +179,7 @@ export function validateInputOptions(inputOptions: BrokenLinkCheckerOptions) {
165179
max_retries: inputOptions.max_retries,
166180
wait_for_selector: inputOptions.wait_for_selector,
167181
per_link_options: inputOptions.per_link_options,
182+
total_synthetic_timeout_millis: inputOptions.total_synthetic_timeout_millis,
168183
};
169184
}
170185

@@ -187,6 +202,7 @@ export function setDefaultOptions(
187202
max_retries: 0,
188203
wait_for_selector: '',
189204
per_link_options: {},
205+
total_synthetic_timeout_millis: 60000,
190206
};
191207

192208
const outputOptions: BrokenLinksResultV1_BrokenLinkCheckerOptions =

packages/synthetics-sdk-broken-links/test/integration/integration.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ describe('CloudFunctionV2 Running Broken Link Synthetics', async () => {
136136
max_retries: 0,
137137
wait_for_selector: '',
138138
per_link_options: {},
139+
total_synthetic_timeout_millis: 60000,
139140
});
140141

141142
expect(origin_link)
@@ -242,6 +243,7 @@ describe('CloudFunctionV2 Running Broken Link Synthetics', async () => {
242243
max_retries: 0,
243244
wait_for_selector: '',
244245
per_link_options: {},
246+
total_synthetic_timeout_millis: 60000,
245247
});
246248

247249
expect(origin_link)
@@ -364,6 +366,7 @@ describe('CloudFunctionV2 Running Broken Link Synthetics', async () => {
364366
max_retries: 0,
365367
wait_for_selector: '',
366368
per_link_options: {},
369+
total_synthetic_timeout_millis: 60000,
367370
});
368371

369372
expect(origin_link)

packages/synthetics-sdk-broken-links/test/unit/broken_links.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,10 @@ describe('runBrokenLinks', async () => {
8484
query_selector_all: 'a[src], img[href]',
8585
get_attributes: ['href', 'src'],
8686
wait_for_selector: 'none existent',
87-
link_timeout_millis: 5000,
87+
link_timeout_millis: 35000,
88+
total_synthetic_timeout_millis: 31000,
8889
};
89-
const result = await runBrokenLinks(inputOptions, 3000);
90+
const result = await runBrokenLinks(inputOptions);
9091
const broken_links_result = result.synthetic_broken_links_result_v1;
9192

9293
const expectedOriginLinkResult: BrokenLinksResultV1_SyntheticLinkResult = {
@@ -99,7 +100,7 @@ describe('runBrokenLinks', async () => {
99100
status_code: 200,
100101
error_type: 'TimeoutError',
101102
error_message:
102-
"Global Timeout of 60 secs hit while waiting for selector 'none existent'",
103+
"Total Synthetic Timeout of 31000 milliseconds hit while waiting for selector 'none existent'",
103104
link_start_time: 'NA',
104105
link_end_time: 'NA',
105106
is_origin: true,
@@ -109,7 +110,7 @@ describe('runBrokenLinks', async () => {
109110
.excluding(['link_start_time', 'link_end_time'])
110111
.to.deep.equal(expectedOriginLinkResult);
111112
expect(broken_links_result?.followed_link_results.length).to.equal(0);
112-
}).timeout(5000);
113+
}).timeout(40000);
113114

114115
it('successful execution with 1 failing link', async () => {
115116
const origin_uri = `file:${path.join(
@@ -136,6 +137,7 @@ describe('runBrokenLinks', async () => {
136137
max_retries: 0,
137138
wait_for_selector: '',
138139
per_link_options: {},
140+
total_synthetic_timeout_millis: 60000,
139141
};
140142

141143
const expectedOriginLinkResult: BrokenLinksResultV1_SyntheticLinkResult = {

packages/synthetics-sdk-broken-links/test/unit/options_func.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,30 @@ describe('GCM Synthetics Broken Links options_func suite testing', () => {
267267
validateInputOptions(options);
268268
}).not.to.throw();
269269
});
270+
it('throws error if total_synthetic_timeout_millis is less than 30000', () => {
271+
const options = {
272+
origin_uri: 'http://example.com',
273+
total_synthetic_timeout_millis: 29000,
274+
} as BrokenLinkCheckerOptions;
275+
expect(() => {
276+
validateInputOptions(options);
277+
}).to.throw(
278+
Error,
279+
'Invalid total_synthetic_timeout_millis value, must be a number between 30000 and 60000 inclusive'
280+
);
281+
});
282+
it('throws error if total_synthetic_timeout_millis is more than 60000', () => {
283+
const options = {
284+
origin_uri: 'http://example.com',
285+
total_synthetic_timeout_millis: 61000,
286+
} as BrokenLinkCheckerOptions;
287+
expect(() => {
288+
validateInputOptions(options);
289+
}).to.throw(
290+
Error,
291+
'Invalid total_synthetic_timeout_millis value, must be a number between 30000 and 60000 inclusive'
292+
);
293+
});
270294
it('throws error if per_link_options contains an invalid uri', () => {
271295
const options = {
272296
origin_uri: 'http://example.com',
@@ -382,6 +406,7 @@ describe('GCM Synthetics Broken Links options_func suite testing', () => {
382406
max_retries: undefined,
383407
wait_for_selector: undefined,
384408
per_link_options: undefined,
409+
total_synthetic_timeout_millis: undefined
385410
} as BrokenLinkCheckerOptions;
386411

387412
expect(() => {

0 commit comments

Comments
 (0)