aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-harness/src/harness/harness.ts
diff options
context:
space:
mode:
authorÖzgür Kesim <oec-taler@kesim.org>2023-10-06 16:33:05 +0200
committerÖzgür Kesim <oec-taler@kesim.org>2023-10-06 16:33:05 +0200
commitfe7b51ef2736edbf04f5bbd9d19f2a2d04baccc2 (patch)
tree66c68c8d6a666f6e74dc663c9ee4f07879f6626c /packages/taler-harness/src/harness/harness.ts
parent35611f0bf9cf67638b171c2a300fab1797d3d8f0 (diff)
parent97d7be7503168f4f3bbd05905d32aa76ca1636b2 (diff)
Merge branch 'master' into age-withdraw
Diffstat (limited to 'packages/taler-harness/src/harness/harness.ts')
-rw-r--r--packages/taler-harness/src/harness/harness.ts181
1 files changed, 159 insertions, 22 deletions
diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts
index 0c3c367af..e30cbcb54 100644
--- a/packages/taler-harness/src/harness/harness.ts
+++ b/packages/taler-harness/src/harness/harness.ts
@@ -28,7 +28,7 @@ import {
AccountAddDetails,
AmountJson,
Amounts,
- BankAccessApiClient,
+ TalerCorebankApiClient,
Configuration,
CoreApiResponse,
Duration,
@@ -565,7 +565,7 @@ class BankServiceBase {
protected globalTestState: GlobalTestState,
protected bankConfig: BankConfig,
protected configFile: string,
- ) { }
+ ) {}
}
export interface HarnessExchangeBankAccount {
@@ -580,7 +580,8 @@ export interface HarnessExchangeBankAccount {
*/
export class FakebankService
extends BankServiceBase
- implements BankServiceHandle {
+ implements BankServiceHandle
+{
proc: ProcessWrapper | undefined;
http = createPlatformHttpLib({ enableThrottling: false });
@@ -649,9 +650,8 @@ export class FakebankService
return `http://localhost:${this.bankConfig.httpPort}/`;
}
- get bankAccessApiBaseUrl(): string {
- let url = new URL("taler-bank-access/", this.baseUrl);
- return url.href;
+ get corebankApiBaseUrl(): string {
+ return this.baseUrl;
}
async createExchangeAccount(
@@ -665,8 +665,8 @@ export class FakebankService
return {
accountName: accountName,
accountPassword: password,
- accountPaytoUri: getPayto(accountName),
- wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/taler-wire-gateway/${accountName}/`,
+ accountPaytoUri: generateRandomPayto(accountName),
+ wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/accounts/${accountName}/taler-wire-gateway/`,
};
}
@@ -691,23 +691,157 @@ export class FakebankService
"bank",
);
await this.pingUntilAvailable();
- const bankClient = new BankAccessApiClient(this.bankAccessApiBaseUrl);
+ const bankClient = new TalerCorebankApiClient(this.corebankApiBaseUrl);
for (const acc of this.accounts) {
await bankClient.registerAccount(acc.accountName, acc.accountPassword);
}
}
async pingUntilAvailable(): Promise<void> {
- const url = `http://localhost:${this.bankConfig.httpPort}/taler-bank-integration/config`;
+ const url = `http://localhost:${this.bankConfig.httpPort}/config`;
await pingProc(this.proc, url, "bank");
}
}
+/**
+ * Implementation of the bank service using the "taler-fakebank-run" tool.
+ */
+export class LibeufinBankService
+ extends BankServiceBase
+ implements BankServiceHandle
+{
+ proc: ProcessWrapper | undefined;
+
+ http = createPlatformHttpLib({ enableThrottling: false });
+
+ // We store "created" accounts during setup and
+ // register them after startup.
+ private accounts: {
+ accountName: string;
+ accountPassword: string;
+ }[] = [];
+
+ /**
+ * Create a new fakebank service handle.
+ *
+ * First generates the configuration for the fakebank and
+ * then creates a fakebank handle, but doesn't start the fakebank
+ * service yet.
+ */
+ static async create(
+ gc: GlobalTestState,
+ bc: BankConfig,
+ ): Promise<LibeufinBankService> {
+ const config = new Configuration();
+ const testDir = bc.overrideTestDir ?? gc.testDir;
+ setTalerPaths(config, testDir + "/talerhome");
+ config.setString("libeufin-bankdb-postgres", "config", bc.database);
+ config.setString("libeufin-bank", "currency", bc.currency);
+ config.setString("libeufin-bank", "port", `${bc.httpPort}`);
+ config.setString("libeufin-bank", "serve", "tcp");
+ config.setString(
+ "libeufin-bank",
+ "DEFAULT_CUSTOMER_DEBT_LIMIT",
+ `${bc.currency}:500`,
+ );
+ config.setString(
+ "libeufin-bank",
+ "DEFAULT_ADMIN_DEBT_LIMIT",
+ `${bc.currency}:999999`,
+ );
+ config.setString(
+ "libeufin-bank",
+ "registration_bonus",
+ `${bc.currency}:100`,
+ );
+ config.setString("libeufin-bank", "registration_bonus_enabled", `yes`);
+ config.setString("libeufin-bank", "max_auth_token_duration", "1h");
+ const cfgFilename = testDir + "/bank.conf";
+ config.write(cfgFilename, { excludeDefaults: true });
+
+ return new LibeufinBankService(gc, bc, cfgFilename);
+ }
+
+ static fromExistingConfig(
+ gc: GlobalTestState,
+ opts: { overridePath?: string },
+ ): FakebankService {
+ const testDir = opts.overridePath ?? gc.testDir;
+ const cfgFilename = testDir + `/bank.conf`;
+ const config = Configuration.load(cfgFilename);
+ const bc: BankConfig = {
+ allowRegistrations:
+ config.getYesNo("libeufin-bank", "allow_registrations").orUndefined() ??
+ true,
+ currency: config.getString("libeufin-bank", "currency").required(),
+ database: config
+ .getString("libeufin-bankdb-postgres", "config")
+ .required(),
+ httpPort: config.getNumber("libeufin-bank", "port").required(),
+ maxDebt: config
+ .getString("libeufin-bank", "DEFAULT_CUSTOMER_DEBT_LIMIT")
+ .required(),
+ };
+ return new FakebankService(gc, bc, cfgFilename);
+ }
+
+ setSuggestedExchange(e: ExchangeServiceInterface) {
+ if (!!this.proc) {
+ throw Error("Can't set suggested exchange while bank is running.");
+ }
+ const config = Configuration.load(this.configFile);
+ config.setString("libeufin-bank", "suggested_withdrawal_exchange", e.baseUrl);
+ config.write(this.configFile, { excludeDefaults: true });
+ }
+
+ get baseUrl(): string {
+ return `http://localhost:${this.bankConfig.httpPort}/`;
+ }
+
+ get corebankApiBaseUrl(): string {
+ return this.baseUrl;
+ }
+
+ get port() {
+ return this.bankConfig.httpPort;
+ }
+
+ async start(): Promise<void> {
+ logger.info("starting libeufin-bank");
+ if (this.proc) {
+ logger.info("libeufin-bank already running, not starting again");
+ return;
+ }
+
+ await sh(
+ this.globalTestState,
+ "libeufin-bank-dbinit",
+ `libeufin-bank dbinit -r -c "${this.configFile}"`,
+ );
+
+ this.proc = this.globalTestState.spawnService(
+ "libeufin-bank",
+ ["serve", "-c", this.configFile],
+ "libeufin-bank-httpd",
+ );
+ await this.pingUntilAvailable();
+ const bankClient = new TalerCorebankApiClient(this.corebankApiBaseUrl);
+ for (const acc of this.accounts) {
+ await bankClient.registerAccount(acc.accountName, acc.accountPassword);
+ }
+ }
+
+ async pingUntilAvailable(): Promise<void> {
+ const url = `http://localhost:${this.bankConfig.httpPort}/config`;
+ await pingProc(this.proc, url, "libeufin-bank");
+ }
+}
+
// Use libeufin bank instead of pybank.
const useLibeufinBank = false;
export interface BankServiceHandle {
- readonly bankAccessApiBaseUrl: string;
+ readonly corebankApiBaseUrl: string;
readonly http: HttpRequestLibrary;
}
@@ -1012,7 +1146,7 @@ export class ExchangeService implements ExchangeServiceInterface {
private exchangeConfig: ExchangeConfig,
private configFilename: string,
private keyPair: EddsaKeyPair,
- ) { }
+ ) {}
get name() {
return this.exchangeConfig.name;
@@ -1368,7 +1502,7 @@ export class MerchantService implements MerchantServiceInterface {
private globalState: GlobalTestState,
private merchantConfig: MerchantConfig,
private configFilename: string,
- ) { }
+ ) {}
private currentTimetravelOffsetMs: number | undefined;
@@ -1496,7 +1630,7 @@ export class MerchantService implements MerchantServiceInterface {
return await this.addInstanceWithWireAccount({
id: "default",
name: "Default Instance",
- paytoUris: [getPayto("merchant-default")],
+ paytoUris: [generateRandomPayto("merchant-default")],
auth: {
method: "external",
},
@@ -1659,6 +1793,7 @@ export async function runTestWithState(
e.message,
`error detail: ${j2s(e.errorDetail)}`,
);
+ console.error(e.stack);
} else {
console.error("FATAL: test failed with exception", e);
}
@@ -1706,7 +1841,7 @@ export class WalletService {
constructor(
private globalState: GlobalTestState,
private opts: WalletServiceOptions,
- ) { }
+ ) {}
get socketPath() {
const unixPath = path.join(
@@ -1815,7 +1950,7 @@ export class WalletClient {
return client.call(operation, payload);
}
- constructor(private args: WalletClientArgs) { }
+ constructor(private args: WalletClientArgs) {}
async connect(): Promise<void> {
const waiter = this.waiter;
@@ -1882,9 +2017,11 @@ export class WalletCli {
? `--crypto-worker=${cliOpts.cryptoWorkerType}`
: "";
const logName = `wallet-${self.name}`;
- const command = `taler-wallet-cli ${self.timetravelArg ?? ""
- } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${self.dbfile
- }' api '${op}' ${shellWrap(JSON.stringify(payload))}`;
+ const command = `taler-wallet-cli ${
+ self.timetravelArg ?? ""
+ } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${
+ self.dbfile
+ }' api '${op}' ${shellWrap(JSON.stringify(payload))}`;
const resp = await sh(self.globalTestState, logName, command);
logger.info("--- wallet core response ---");
logger.info(resp);
@@ -1967,7 +2104,7 @@ export class WalletCli {
}
}
-export function getRandomIban(salt: string | null = null): string {
+export function generateRandomTestIban(salt: string | null = null): string {
function getBban(salt: string | null): string {
if (!salt) return Math.random().toString().substring(2, 6);
let hashed = hash(stringToBytes(salt));
@@ -1999,9 +2136,9 @@ export function getWireMethodForTest(): string {
* Generate a payto address, whose authority depends
* on whether the banking is served by euFin or Pybank.
*/
-export function getPayto(label: string): string {
+export function generateRandomPayto(label: string): string {
if (useLibeufinBank)
- return `payto://iban/SANDBOXX/${getRandomIban(
+ return `payto://iban/SANDBOXX/${generateRandomTestIban(
label,
)}?receiver-name=${label}`;
return `payto://x-taler-bank/localhost/${label}`;