test: VM smoke and Lightning regtest suites
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
93a58e18f6
commit
7f4a71b98d
4 changed files with 358 additions and 0 deletions
109
tests/regtest-core.nix
Normal file
109
tests/regtest-core.nix
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# regtest-core — NixOS-native Lightning regtest integration test.
|
||||
#
|
||||
# A reproducible, hermetic replacement for the core of the docker
|
||||
# `legend-regtest-enviroment` stack (aiolabs/omnixient#27): one VM running
|
||||
# bitcoind(regtest) + Core Lightning + LND (the bitcoin pack's nix-bitcoin
|
||||
# modules), driving a real payment flow and asserting it settles.
|
||||
#
|
||||
# Both LN nodes are co-located on one node and share the local bitcoind;
|
||||
# lnd's p2p port is moved to 9736 so it doesn't clash with clightning's
|
||||
# 9735. CLIs are run as the nix-bitcoin `operator` user, matching how
|
||||
# nix-bitcoin's own test suite drives them.
|
||||
#
|
||||
# The node config is shared with the interactive dev VM via
|
||||
# tests/regtest-node.nix so the two can never drift.
|
||||
#
|
||||
# Run headless:
|
||||
# nix build .#checks.x86_64-linux.regtest-core -L
|
||||
# Interactive driver (poke the node by hand):
|
||||
# nix build .#checks.x86_64-linux.regtest-core.driverInteractive
|
||||
# ./result/bin/nixos-test-driver
|
||||
# Friendlier interactive shell (SSH, copy/paste, operator user, helpers):
|
||||
# nix run .#regtest (see docs/regtest.md)
|
||||
{
|
||||
nixpkgs,
|
||||
system ? "x86_64-linux",
|
||||
nix-bitcoin,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
in
|
||||
pkgs.testers.runNixOSTest {
|
||||
name = "omni-regtest-core";
|
||||
|
||||
nodes.regtest = {
|
||||
imports = [
|
||||
nix-bitcoin.nixosModules.default
|
||||
./regtest-node.nix # shared bitcoind + CLN + LND config
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
def op(cmd):
|
||||
"""Run a command as the nix-bitcoin operator and return stdout."""
|
||||
return regtest.succeed(f"runuser -u operator -- {cmd}")
|
||||
|
||||
regtest.start()
|
||||
|
||||
# --- services up ---
|
||||
regtest.wait_for_unit("bitcoind.service")
|
||||
regtest.wait_for_unit("clightning.service")
|
||||
regtest.wait_for_unit("lnd.service")
|
||||
|
||||
# CLIs answer (clightning/lnd take a moment past unit-active to be RPC-ready).
|
||||
regtest.wait_until_succeeds("runuser -u operator -- lightning-cli getinfo", timeout=120)
|
||||
regtest.wait_until_succeeds("runuser -u operator -- lncli getinfo", timeout=120)
|
||||
|
||||
# --- both LN nodes synced to the pre-mined regtest chain ---
|
||||
regtest.wait_until_succeeds(
|
||||
f"[[ $(runuser -u operator -- lightning-cli getinfo | jq -M .blockheight) == {110} ]]",
|
||||
timeout=120,
|
||||
)
|
||||
regtest.wait_until_succeeds(
|
||||
f"[[ $(runuser -u operator -- lncli getinfo | jq -M .block_height) == {110} ]]",
|
||||
timeout=120,
|
||||
)
|
||||
|
||||
# --- fund LND's on-chain wallet from the bitcoind test wallet ---
|
||||
lnd_addr = op("lncli newaddress p2wkh | jq -r .address").strip()
|
||||
op(f"bitcoin-cli -rpcwallet=test sendtoaddress {lnd_addr} 5")
|
||||
mine_addr = op("bitcoin-cli -rpcwallet=test getnewaddress").strip()
|
||||
op(f"bitcoin-cli -rpcwallet=test generatetoaddress 6 {mine_addr}")
|
||||
regtest.wait_until_succeeds(
|
||||
"[[ $(runuser -u operator -- lncli walletbalance | jq -M '.confirmed_balance | tonumber') -gt 0 ]]",
|
||||
timeout=120,
|
||||
)
|
||||
|
||||
# --- connect LND -> CLN and open a channel ---
|
||||
cln_id = op("lightning-cli getinfo | jq -r .id").strip()
|
||||
op(f"lncli connect {cln_id}@127.0.0.1:9735")
|
||||
op(f"lncli openchannel --node_key={cln_id} --local_amt=1000000") # 0.01 BTC
|
||||
|
||||
# confirm the channel and wait for it to go active on the LND side
|
||||
op(f"bitcoin-cli -rpcwallet=test generatetoaddress 6 {mine_addr}")
|
||||
regtest.wait_until_succeeds(
|
||||
"[[ $(runuser -u operator -- lncli listchannels | jq '[.channels[] | select(.active)] | length') -ge 1 ]]",
|
||||
timeout=240,
|
||||
)
|
||||
|
||||
# --- CLN issues an invoice, LND pays it ---
|
||||
bolt11 = op(
|
||||
"lightning-cli invoice 100000000 regtest-core-test 'regtest-core payment' | jq -r .bolt11"
|
||||
).strip() # 100000 sat = 100,000,000 msat
|
||||
op(f"lncli payinvoice --force {bolt11}")
|
||||
|
||||
# --- assert CLN saw the invoice settle ---
|
||||
regtest.wait_until_succeeds(
|
||||
"[[ $(runuser -u operator -- lightning-cli listinvoices regtest-core-test "
|
||||
"| jq -r '.invoices[0].status') == paid ]]",
|
||||
timeout=180,
|
||||
)
|
||||
|
||||
print("regtest-core: LND -> CLN channel opened and invoice paid ✓")
|
||||
'';
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue