gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: wallet-core: implement db mig


From: gnunet
Subject: [taler-wallet-core] branch master updated: wallet-core: implement db migration check
Date: Mon, 29 Jan 2024 12:24:50 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 64e340541 wallet-core: implement db migration check
64e340541 is described below

commit 64e340541ffcf10df4ef6400232c423aaecf81b9
Author: Florian Dold <florian@dold.me>
AuthorDate: Mon Jan 29 12:24:46 2024 +0100

    wallet-core: implement db migration check
---
 build-system/taler-build-scripts                   |   2 +-
 packages/taler-harness/src/harness/harness.ts      |  34 ++++--
 packages/taler-harness/src/harness/helpers.ts      |   2 +
 packages/taler-harness/src/index.ts                | 115 ++++++++++++++++++++-
 packages/taler-util/src/wallet-types.ts            |   6 +-
 packages/taler-wallet-core/src/wallet-api-types.ts |   5 +-
 6 files changed, 144 insertions(+), 20 deletions(-)

diff --git a/build-system/taler-build-scripts b/build-system/taler-build-scripts
index 001f5dd08..23538677f 160000
--- a/build-system/taler-build-scripts
+++ b/build-system/taler-build-scripts
@@ -1 +1 @@
-Subproject commit 001f5dd081fc8729ff8def90c4a1c3f93eb8689a
+Subproject commit 23538677f6c6be2a62f38dc6137ecdd1c76b7b15
diff --git a/packages/taler-harness/src/harness/harness.ts 
b/packages/taler-harness/src/harness/harness.ts
index b2714f496..b9164a968 100644
--- a/packages/taler-harness/src/harness/harness.ts
+++ b/packages/taler-harness/src/harness/harness.ts
@@ -1885,16 +1885,39 @@ function tryUnixConnect(socketPath: string): 
Promise<void> {
 
 export interface WalletServiceOptions {
   useInMemoryDb?: boolean;
+  /**
+   * Use a particular DB path instead of the default one in the
+   * test environment.
+   */
+  overrideDbPath?: string;
   name: string;
 }
 
+/**
+ * A wallet service that listens on a unix domain socket for commands.
+ */
 export class WalletService {
   walletProc: ProcessWrapper | undefined;
 
+  private internalDbPath: string;
+
   constructor(
     private globalState: GlobalTestState,
     private opts: WalletServiceOptions,
-  ) {}
+  ) {
+    if (this.opts.overrideDbPath) {
+      this.internalDbPath = this.opts.overrideDbPath;
+    } else {
+      if (this.opts.useInMemoryDb) {
+        this.internalDbPath = ":memory:";
+      } else {
+        this.internalDbPath = path.join(
+          this.globalState.testDir,
+          `walletdb-${this.opts.name}.sqlite3`,
+        );
+      }
+    }
+  }
 
   get socketPath() {
     const unixPath = path.join(
@@ -1905,14 +1928,7 @@ export class WalletService {
   }
 
   get dbPath() {
-    if (this.opts.useInMemoryDb) {
-      return ":memory:";
-    } else {
-      return path.join(
-        this.globalState.testDir,
-        `walletdb-${this.opts.name}.sqlite3`,
-      );
-    }
+    return this.internalDbPath;
   }
 
   async stop(): Promise<void> {
diff --git a/packages/taler-harness/src/harness/helpers.ts 
b/packages/taler-harness/src/harness/helpers.ts
index 7daa6c3c5..bb6f28246 100644
--- a/packages/taler-harness/src/harness/helpers.ts
+++ b/packages/taler-harness/src/harness/helpers.ts
@@ -405,6 +405,7 @@ export interface CreateWalletArgs {
   handleNotification?(wn: WalletNotification): void;
   name: string;
   persistent?: boolean;
+  overrideDbPath?: string;
 }
 
 export async function createWalletDaemonWithClient(
@@ -414,6 +415,7 @@ export async function createWalletDaemonWithClient(
   const walletService = new WalletService(t, {
     name: args.name,
     useInMemoryDb: !args.persistent,
+    overrideDbPath: args.overrideDbPath,
   });
   await walletService.start();
   await walletService.pingUntilAvailable();
diff --git a/packages/taler-harness/src/index.ts 
b/packages/taler-harness/src/index.ts
index 5a0ccbd12..787ea1933 100644
--- a/packages/taler-harness/src/index.ts
+++ b/packages/taler-harness/src/index.ts
@@ -20,6 +20,7 @@
 import {
   AmountString,
   Amounts,
+  BalancesResponse,
   Configuration,
   Duration,
   HttpStatusCode,
@@ -28,6 +29,7 @@ import {
   MerchantInstanceConfig,
   RegisterAccountRequest,
   TalerCorebankApiClient,
+  TransactionsResponse,
   addPaytoQueryParams,
   decodeCrock,
   generateIban,
@@ -58,12 +60,16 @@ import { runEnvFull } from "./env-full.js";
 import { runEnv1 } from "./env1.js";
 import {
   GlobalTestState,
+  WalletClient,
   delayMs,
   runTestWithState,
 } from "./harness/harness.js";
 import { getTestInfo, runTests } from "./integrationtests/testrunner.js";
 import { lintExchangeDeployment } from "./lint.js";
-import { createSimpleTestkudosEnvironmentV2 } from "./harness/helpers.js";
+import {
+  createSimpleTestkudosEnvironmentV2,
+  createWalletDaemonWithClient,
+} from "./harness/helpers.js";
 
 const logger = new Logger("taler-harness:index.ts");
 
@@ -179,6 +185,88 @@ advancedCli
     await runTestWithState(testState, runEnv1, "env1", true);
   });
 
+async function doDbChecks(
+  t: GlobalTestState,
+  walletClient: WalletClient,
+  indir: string,
+): Promise<void> {
+  // Check that balance didn't break
+  const balPath = `${indir}/wallet-balances.json`;
+  const expectedBal: BalancesResponse = JSON.parse(
+    fs.readFileSync(balPath, { encoding: "utf8" }),
+  ) as BalancesResponse;
+  const actualBal = await walletClient.call(WalletApiOperation.GetBalances, 
{});
+  t.assertDeepEqual(actualBal.balances.length, expectedBal.balances.length);
+
+  // Check that transactions didn't break
+  const txnPath = `${indir}/wallet-transactions.json`;
+  const expectedTxn: TransactionsResponse = JSON.parse(
+    fs.readFileSync(txnPath, { encoding: "utf8" }),
+  ) as TransactionsResponse;
+  const actualTxn = await walletClient.call(
+    WalletApiOperation.GetTransactions,
+    { includeRefreshes: true },
+  );
+  t.assertDeepEqual(
+    actualTxn.transactions.length,
+    expectedTxn.transactions.length,
+  );
+}
+
+advancedCli
+  .subcommand("walletDbcheck", "wallet-dbcheck", {
+    help: "Check a wallet database (used for migration testing).",
+  })
+  .requiredArgument("indir", clk.STRING)
+  .action(async (args) => {
+    const indir = args.walletDbcheck.indir;
+    if (!fs.existsSync(indir)) {
+      throw Error("directory to be checked does not exist");
+    }
+
+    const testRootDir = fs.mkdtempSync(path.join(os.tmpdir(), "taler-dbchk-"));
+    const t: GlobalTestState = new GlobalTestState({
+      testDir: testRootDir,
+    });
+    const walletDbPath = `${indir}/wallet-db.sqlite3`;
+    if (!fs.existsSync(walletDbPath)) {
+      throw new Error("wallet db to be checked does not exist");
+    }
+    const { walletClient, walletService } = await createWalletDaemonWithClient(
+      t,
+      { name: "wallet-loaded", overrideDbPath: walletDbPath },
+    );
+
+    await walletService.pingUntilAvailable();
+
+    // Do DB checks with the DB we loaded.
+    await doDbChecks(t, walletClient, indir);
+
+    const {
+      walletClient: freshWalletClient,
+      walletService: freshWalletService,
+    } = await createWalletDaemonWithClient(t, {
+      name: "wallet-fresh",
+      persistent: false,
+    });
+
+    // Check that we can still import the backup JSON.
+
+    const backupPath = `${indir}/wallet-backup.json`;
+    const backupData = JSON.parse(
+      fs.readFileSync(backupPath, { encoding: "utf8" }),
+    );
+    await freshWalletClient.call(WalletApiOperation.ImportDb, {
+      dump: backupData,
+    });
+
+    // Repeat same checks with wallet that we restored from backup
+    // instead of from the DB file.
+    await doDbChecks(t, freshWalletClient, indir);
+
+    await t.shutdown();
+  });
+
 advancedCli
   .subcommand("walletDbgen", "wallet-dbgen", {
     help: "Generate a wallet test database (to be used for migration 
testing).",
@@ -186,6 +274,9 @@ advancedCli
   .requiredArgument("outdir", clk.STRING)
   .action(async (args) => {
     const outdir = args.walletDbgen.outdir;
+    if (fs.existsSync(outdir)) {
+      throw new Error("outdir already exists, please delete first");
+    }
     fs.mkdirSync(outdir, {
       recursive: true,
     });
@@ -209,16 +300,24 @@ advancedCli
       {},
     );
 
-    const transactionsJson = walletClient.call(
+    const transactionsJson = await walletClient.call(
       WalletApiOperation.GetTransactions,
       {
         includeRefreshes: true,
       },
     );
 
-    const balancesJson = walletClient.call(WalletApiOperation.GetBalances, {});
+    const balancesJson = await walletClient.call(
+      WalletApiOperation.GetBalances,
+      {},
+    );
+
+    const backupJson = await walletClient.call(WalletApiOperation.ExportDb, 
{});
 
-    const backupJson = walletClient.call(WalletApiOperation.ExportDb, {});
+    const versionJson = await walletClient.call(
+      WalletApiOperation.GetVersion,
+      {},
+    );
 
     await walletService.stop();
 
@@ -233,6 +332,13 @@ advancedCli
     );
     fs.writeFileSync(`${outdir}/wallet-balances.json`, j2s(balancesJson));
     fs.writeFileSync(`${outdir}/wallet-backup.json`, j2s(backupJson));
+    fs.writeFileSync(`${outdir}/wallet-version.json`, j2s(versionJson));
+    fs.writeFileSync(
+      `${outdir}/meta.json`,
+      j2s({
+        timestamp: new Date(),
+      }),
+    );
   });
 
 const configCli = testingCli.subcommand("configArgs", "config", {
@@ -317,7 +423,6 @@ deploymentCli
     const paytoUri = addPaytoQueryParams(tipReserveResp.accounts[0].payto_uri, 
{
       message: `tip-reserve ${tipReserveResp.reserve_pub}`,
     });
-
     console.log("payto URI:", paytoUri);
 
     const transactions = await bankAccessApiClient.getTransactions(
diff --git a/packages/taler-util/src/wallet-types.ts 
b/packages/taler-util/src/wallet-types.ts
index 524dfe3e0..806e2f22b 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -2476,12 +2476,12 @@ export const codecForWithdrawFakebankRequest =
       .property("exchange", codecForString())
       .build("WithdrawFakebankRequest");
 
-export interface ImportDb {
+export interface ImportDbRequest {
   dump: any;
 }
 
-export const codecForImportDbRequest = (): Codec<ImportDb> =>
-  buildCodecForObject<ImportDb>()
+export const codecForImportDbRequest = (): Codec<ImportDbRequest> =>
+  buildCodecForObject<ImportDbRequest>()
     .property("dump", codecForAny())
     .build("ImportDbRequest");
 
diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts 
b/packages/taler-wallet-core/src/wallet-api-types.ts
index 594d5e14d..cc67781ae 100644
--- a/packages/taler-wallet-core/src/wallet-api-types.ts
+++ b/packages/taler-wallet-core/src/wallet-api-types.ts
@@ -139,6 +139,7 @@ import {
   AddGlobalCurrencyAuditorRequest,
   RemoveGlobalCurrencyExchangeRequest,
   RemoveGlobalCurrencyAuditorRequest,
+  ImportDbRequest,
 } from "@gnu-taler/taler-util";
 import {
   AddBackupProviderRequest,
@@ -968,8 +969,8 @@ export type ExportDbOp = {
 
 export type ImportDbOp = {
   op: WalletApiOperation.ImportDb;
-  request: any;
-  response: any;
+  request: ImportDbRequest;
+  response: EmptyObject;
 };
 
 /**

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]