Skip to content

Commit

Permalink
regression tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Im-Beast committed Oct 14, 2024
1 parent 44fd5e1 commit de8c27c
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 3 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/regression.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Check if any regressions have happened
on: [push]
permissions:
issues: write
pull-requests: write
jobs:
regression_check:
strategy:
matrix:
coin: [monero]
runs-on: ubuntu-24.04
steps:
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 gperf gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 gcc-mingw-w64-i686 g++-mingw-w64-i686 wget xz-utils
- uses: denoland/setup-deno@v2
with:
deno-version: v2.x

- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive

- name: Patch sources
run: |
git config --global --add safe.directory '*'
git config --global user.email "[email protected]"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
- name: ccache
uses: hendrikmuhs/[email protected]
with:
key: ${{ github.job }}-${{ matrix.coin }}
- name: Cache built
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: actions/cache@v4
with:
path: |
${{ matrix.coin }}/contrib/depends/built/*
key: depends-${{ github.job }}-${{ matrix.coin }}-${{ hashFiles('*/contrib/depends/packages/*.mk') }}

- name: Run regression tests
run: deno test -A tests/
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
release/
build/
build/
tests/monero-cli
tests/libs
tests/wallets
10 changes: 8 additions & 2 deletions impls/monero.ts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@
This library does not ship with `monero_c` libraries.\
To use these bindings you have to bring your own `monero_c` libraries.\
There are at least two ways to do so:

- Ahead-of-time, during builds where you only ship necessary library for a given platform.\
See [monero-tui](https://github.com/Im-Beast/monero-tui/blob/main/.github/workflows/dev-build.yml) build workflow as an example of doing so.
See [monero-tui](https://github.com/Im-Beast/monero-tui/blob/main/.github/workflows/dev-build.yml) build workflow as
an example of doing so.
```ts
import { loadDylib, Wallet, WalletManager } from "https://raw.githubusercontent.com/MrCyjaneK/monero_c/master/impls/monero.ts/mod.ts";
import {
loadDylib,
Wallet,
WalletManager,
} from "https://raw.githubusercontent.com/MrCyjaneK/monero_c/master/impls/monero.ts/mod.ts";

// Try to load dylib from the default lib/* path
loadDylib();
Expand Down
4 changes: 4 additions & 0 deletions impls/monero.ts/src/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export class Wallet {
this.sanitizer = sanitizer;
}

getPointer(): WalletPtr {
return this.#walletPtr;
}

async store(path = ""): Promise<boolean> {
const bool = await dylib.symbols.MONERO_Wallet_store(this.#walletPtr, CString(path));
await this.throwIfError();
Expand Down
70 changes: 70 additions & 0 deletions tests/compare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { loadDylib, symbols as bindingsSymbols } from "../impls/monero.ts/src/bindings.ts";
import { Wallet, WalletManager } from "../impls/monero.ts/mod.ts";
import { readCString } from "../impls/monero.ts/src/utils.ts";
import { assertEquals } from "jsr:@std/assert";

const version = Deno.args[0];
const walletInfo = JSON.parse(Deno.args[1]);

// Those don't exist on older versions of monero_c
// @ts-expect-error -
delete bindingsSymbols.MONERO_checksum_wallet2_api_c_h;
// @ts-expect-error -
delete bindingsSymbols.MONERO_checksum_wallet2_api_c_cpp;
// @ts-expect-error -
delete bindingsSymbols.MONERO_checksum_wallet2_api_c_exp;

const symbols = {
...bindingsSymbols,

"MONERO_Wallet_secretViewKey": {
nonblocking: true,
// void* wallet_ptr
parameters: ["pointer"],
// const char*
result: "pointer",
},
"MONERO_Wallet_publicViewKey": {
nonblocking: true,
// void* wallet_ptr
parameters: ["pointer"],
// const char*
result: "pointer",
},

"MONERO_Wallet_secretSpendKey": {
nonblocking: true,
// void* wallet_ptr
parameters: ["pointer"],
// const char*
result: "pointer",
},
"MONERO_Wallet_publicSpendKey": {
nonblocking: true,
// void* wallet_ptr
parameters: ["pointer"],
// const char*
result: "pointer",
},
} as const;

const dylib = Deno.dlopen(`tests/libs/${version}/monero_libwallet2_api_c.so`, symbols);
loadDylib(dylib as Deno.DynamicLibrary<typeof bindingsSymbols>);

const walletManager = await WalletManager.new();
const wallet = await Wallet.open(walletManager, walletInfo.path, walletInfo.password);

assertEquals(await wallet.address(), walletInfo.address);

const getKey = async (wallet: Wallet, type: `${"secret" | "public"}${"Spend" | "View"}Key`) =>
await readCString(
await dylib.symbols[`MONERO_Wallet_${type}` as const](wallet.getPointer()),
);

assertEquals(await getKey(wallet, "publicSpendKey"), walletInfo.publicSpendKey);
assertEquals(await getKey(wallet, "secretSpendKey"), walletInfo.secretSpendKey);

assertEquals(await getKey(wallet, "publicViewKey"), walletInfo.publicViewKey);
assertEquals(await getKey(wallet, "secretViewKey"), walletInfo.secretViewKey);

await wallet.store(walletInfo.path);
5 changes: 5 additions & 0 deletions tests/deno.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"fmt": {
"lineWidth": 120
}
}
90 changes: 90 additions & 0 deletions tests/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions tests/regression.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { $, createWalletViaCli, downloadMoneroCli, getMoneroC, getMoneroCTags } from "./utils.ts";

Deno.test("Regression tests", async (t) => {
await Deno.remove("./tests/wallets", { recursive: true }).catch(() => {});
await Deno.mkdir("./tests/wallets", { recursive: true });

const tags = await getMoneroCTags();
const latestTag = tags[0];
await Promise.all([getMoneroC("next"), await getMoneroC(latestTag), downloadMoneroCli()]);

await t.step("Simple (next, latest, next)", async () => {
const walletInfo = await createWalletViaCli("dog", "sobaka");

for (const version of ["next", latestTag, "next"]) {
await $`deno run -A ./tests/compare.ts ${version} ${JSON.stringify(walletInfo)}`;
}
});

await t.step("All releases sequentially (all tags in the release order, next)", async () => {
tags.unshift("next");

const walletInfo = await createWalletViaCli("cat", "koshka");

for (const version of tags.toReversed()) {
if (version !== "next" && version !== tags[0]) await getMoneroC(version);
await $`deno run -A ./tests/compare.ts ${version} ${JSON.stringify(walletInfo)}`;
}

await Deno.remove("./tests/wallets", { recursive: true }).catch(() => {});
});

await Deno.remove("./tests/wallets", { recursive: true }).catch(() => {});
await Deno.remove("./tests/libs", { recursive: true }).catch(() => {});
});
Loading

0 comments on commit de8c27c

Please sign in to comment.