diff --git a/.github/workflows/checks.build.yaml b/.github/workflows/checks.build.yaml index 1e8e5dc3..3efa472c 100644 --- a/.github/workflows/checks.build.yaml +++ b/.github/workflows/checks.build.yaml @@ -97,4 +97,7 @@ jobs: run: docker run -d -p 8080:80 --rm --name privacy.sexy undergroundwires/privacy.sexy:latest - name: Check server is up and returns HTTP 200 - run: node ./scripts/verify-web-server-status.js --url http://localhost:8080 + run: >- + node ./scripts/verify-web-server-status.js \ + --url http://localhost:8080 \ + --max-retries ${{ matrix.os == 'macos' && '90' || '30' }} diff --git a/scripts/verify-web-server-status.js b/scripts/verify-web-server-status.js index 599b09a1..f1ad10fb 100644 --- a/scripts/verify-web-server-status.js +++ b/scripts/verify-web-server-status.js @@ -1,62 +1,87 @@ +#!/usr/bin/env node + /** * Description: - * This script checks if a server, provided as a CLI argument, is up - * and returns an HTTP 200 status code. - * It is designed to provide easy verification of server availability - * and will retry a specified number of times. + * This script checks if a server, provided as a CLI argument, is up + * and returns an HTTP 200 status code. + * It is designed to provide easy verification of server availability + * and will retry a specified number of times. * * Usage: - * node ./scripts/verify-web-server-status.js --url [URL] + * node ./scripts/verify-web-server-status.js --url [URL] [--max-retries NUMBER] * * Options: - * --url URL of the server to check + * --url URL of the server to check + * --max-retries Maximum number of retry attempts (default: 30) */ -import { get } from 'http'; - -const MAX_RETRIES = 30; +const DEFAULT_MAX_RETRIES = 30; const RETRY_DELAY_IN_SECONDS = 3; -const URL_PARAMETER_NAME = '--url'; +const PARAMETER_NAME_URL = '--url'; +const PARAMETER_NAME_MAX_RETRIES = '--max-retries'; -function checkServer(currentRetryCount = 1) { - const serverUrl = getServerUrl(); - console.log(`Requesting ${serverUrl}...`); - get(serverUrl, (res) => { - if (res.statusCode === 200) { +async function checkServer(currentRetryCount = 1) { + const serverUrl = readRequiredParameterValue(PARAMETER_NAME_URL); + const maxRetries = parseNumber( + readOptionalParameterValue(PARAMETER_NAME_MAX_RETRIES, DEFAULT_MAX_RETRIES), + ); + console.log(`🌐 Requesting ${serverUrl}...`); + try { + const response = await fetch(serverUrl); + if (response.status === 200) { console.log('🎊 Success: The server is up and returned HTTP 200.'); process.exit(0); } else { - console.log(`Server returned HTTP status code ${res.statusCode}.`); - retry(currentRetryCount); + exitWithError(`Server returned unexpected HTTP status code ${response.statusCode}.`); } - }).on('error', (err) => { - console.error('Error making the request:', err); - retry(currentRetryCount); - }); + } catch (error) { + console.error('Error making the request:', error); + scheduleNextRetry(maxRetries, currentRetryCount); + } } -function retry(currentRetryCount) { - console.log(`Attempt ${currentRetryCount}/${MAX_RETRIES}:`); +function scheduleNextRetry(maxRetries, currentRetryCount) { + console.log(`Attempt ${currentRetryCount}/${maxRetries}:`); console.log(`Retrying in ${RETRY_DELAY_IN_SECONDS} seconds.`); - const remainingTime = (MAX_RETRIES - currentRetryCount) * RETRY_DELAY_IN_SECONDS; + const remainingTime = (maxRetries - currentRetryCount) * RETRY_DELAY_IN_SECONDS; console.log(`Time remaining before timeout: ${remainingTime}s`); - if (currentRetryCount < MAX_RETRIES) { + if (currentRetryCount < maxRetries) { setTimeout(() => checkServer(currentRetryCount + 1), RETRY_DELAY_IN_SECONDS * 1000); } else { - console.log('Failure: The server at did not return HTTP 200 within the allocated time. Exiting.'); - process.exit(1); + exitWithError('The server at did not return HTTP 200 within the allocated time.'); } } -function getServerUrl() { - const urlIndex = process.argv.indexOf(URL_PARAMETER_NAME); - if (urlIndex === -1 || urlIndex === process.argv.length - 1) { - console.error(`Parameter "${URL_PARAMETER_NAME}" is not provided.`); - process.exit(1); +function readRequiredParameterValue(parameterName) { + const parameterValue = readOptionalParameterValue(parameterName); + if (parameterValue === undefined) { + exitWithError(`Parameter "${parameterName}" is required but not provided.`); } - return process.argv[urlIndex + 1]; + return parameterValue; } -checkServer(); +function readOptionalParameterValue(parameterName, defaultValue) { + const index = process.argv.indexOf(parameterName); + if (index === -1 || index === process.argv.length - 1) { + return defaultValue; + } + return process.argv[index + 1]; +} + +function parseNumber(numberLike) { + const number = parseInt(numberLike, 10); + if (Number.isNaN(number)) { + exitWithError(`Invalid number: ${numberLike}`); + } + return number; +} + +function exitWithError(message) { + console.error(`Failure: ${message}`); + console.log('Exiting'); + process.exit(1); +} + +await checkServer();