From 2ecdd6816d6398f246ed58954893ba71927f2db6 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 9 Oct 2023 21:39:01 +0200 Subject: [PATCH] harness: tooling to wait for service --- packages/taler-harness/src/index.ts | 109 ++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 6 deletions(-) diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index 82d8e4326..8ed67b162 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -30,7 +30,10 @@ import { setGlobalLogLevelFromString, } from "@gnu-taler/taler-util"; import { clk } from "@gnu-taler/taler-util/clk"; -import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; +import { + HttpResponse, + createPlatformHttpLib, +} from "@gnu-taler/taler-util/http"; import { CryptoDispatcher, downloadExchangeInfo, @@ -46,7 +49,11 @@ import { runBench2 } from "./bench2.js"; import { runBench3 } from "./bench3.js"; import { runEnvFull } from "./env-full.js"; import { runEnv1 } from "./env1.js"; -import { GlobalTestState, runTestWithState } from "./harness/harness.js"; +import { + GlobalTestState, + delayMs, + runTestWithState, +} from "./harness/harness.js"; import { getTestInfo, runTests } from "./integrationtests/testrunner.js"; import { lintExchangeDeployment } from "./lint.js"; @@ -312,8 +319,7 @@ deploymentCli const exchangeInfo = await downloadExchangeInfo(exchangeBaseUrl, http); await topupReserveWithDemobank({ amount: "KUDOS:10", - corebankApiBaseUrl: - "https://bank.demo.taler.net/", + corebankApiBaseUrl: "https://bank.demo.taler.net/", exchangeInfo, http, reservePub: reserveKeyPair.pub, @@ -341,8 +347,7 @@ deploymentCli const exchangeInfo = await downloadExchangeInfo(exchangeBaseUrl, http); await topupReserveWithDemobank({ amount: "TESTKUDOS:10", - corebankApiBaseUrl: - "https://bank.test.taler.net/", + corebankApiBaseUrl: "https://bank.test.taler.net/", exchangeInfo, http, reservePub: reserveKeyPair.pub, @@ -422,6 +427,98 @@ deploymentCli ); }); +deploymentCli + .subcommand("waitService", "wait-taler-service", { + help: "Wait for the config endpoint of a Taler-style service to be available", + }) + .requiredArgument("serviceName", clk.STRING) + .requiredArgument("serviceConfigUrl", clk.STRING) + .action(async (args) => { + const serviceName = args.waitService.serviceName; + const serviceUrl = args.waitService.serviceConfigUrl; + console.log( + `Waiting for service ${serviceName} to be ready at ${serviceUrl}`, + ); + const httpLib = createPlatformHttpLib(); + while (1) { + console.log(`Fetching ${serviceUrl}`); + let resp: HttpResponse; + try { + resp = await httpLib.fetch(serviceUrl); + } catch (e) { + console.log( + `Got network error for service ${serviceName} at ${serviceUrl}`, + ); + await delayMs(1000); + continue; + } + if (resp.status != 200) { + console.log( + `Got unexpected status ${resp.status} for service at ${serviceUrl}`, + ); + await delayMs(1000); + continue; + } + let respJson: any; + try { + respJson = await resp.json(); + } catch (e) { + console.log( + `Got json error for service ${serviceName} at ${serviceUrl}`, + ); + await delayMs(1000); + continue; + } + const recServiceName = respJson.name; + console.log(`Got name ${recServiceName}`); + if (recServiceName != serviceName) { + console.log(`A different service is still running at ${serviceUrl}`); + await delayMs(1000); + continue; + } + console.log(`service ${serviceName} at ${serviceUrl} is now available`); + return; + } + }); + +deploymentCli + .subcommand("waitEndpoint", "wait-service", { + help: "Wait for an endpoint to return an HTTP 200 Ok status with JSON body", + }) + .requiredArgument("serviceEndpoint", clk.STRING) + .action(async (args) => { + const serviceUrl = args.waitEndpoint.serviceEndpoint; + console.log(`Waiting for endpoint ${serviceUrl} to be ready`); + const httpLib = createPlatformHttpLib(); + while (1) { + console.log(`Fetching ${serviceUrl}`); + let resp: HttpResponse; + try { + resp = await httpLib.fetch(serviceUrl); + } catch (e) { + console.log(`Got network error for service at ${serviceUrl}`); + await delayMs(1000); + continue; + } + if (resp.status != 200) { + console.log( + `Got unexpected status ${resp.status} for service at ${serviceUrl}`, + ); + await delayMs(1000); + continue; + } + let respJson: any; + try { + respJson = await resp.json(); + } catch (e) { + console.log(`Got json error for service at ${serviceUrl}`); + await delayMs(1000); + continue; + } + return; + } + }); + deploymentCli .subcommand("coincfg", "gen-coin-config", { help: "Generate a coin/denomination configuration for the exchange.",