lnd/lntest/README.md

117 lines
4.9 KiB
Markdown
Raw Normal View History

2022-07-22 13:32:16 +02:00
# `lntest`
`lntest` is a package which holds the components used for the `lnd`s
integration tests. It is responsible for managing `lnd` nodes, chain backends
and miners, advancing nodes states and providing assertions.
### Quick Start
A simple example to run the integration test.
```go
func TestFoo(t *testing.T) {
// Get the binary path and setup the harness test.
//
// TODO: define the binary path to lnd and the name of the database
// backend.
harnessTest := lntemp.SetupHarness(t, binary, *dbBackendFlag)
defer harnessTest.Stop()
// Setup standby nodes, Alice and Bob, which will be alive and shared
// among all the test cases.
harnessTest.SetupStandbyNodes()
// Run the subset of the test cases selected in this tranche.
//
// TODO: define your own testCases.
for _, tc := range testCases {
tc := tc
t.Run(tc.Name, func(st *testing.T) {
// Create a separate harness test for the testcase to
// avoid overwriting the external harness test that is
// tied to the parent test.
ht := harnessTest.Subtest(st)
2022-07-22 13:32:16 +02:00
// Run the test cases.
ht.RunTestCase(tc)
})
}
}
```
### Package Structure
This package has four major components, `HarnessTest`, `HarnessMiner`,
`node.HarnessNode` and `rpc.HarnessRPC`, with the following architecture,
```
+----------------------------------------------------------+
| |
| HarnessTest |
| |
| +----------------+ +----------------+ +--------------+ |
| | HarnessNode | | HarnessNode | | HarnessMiner | |
| | | | | +--------------+ |
| | +------------+ | | +------------+ | |
| | | HarnessRPC | | | | HarnessRPC | | +--------------+ |
| | +------------+ | | +------------+ | | HarnessMiner | |
| +----------------+ +----------------+ +--------------+ |
+----------------------------------------------------------+
```
- `HarnessRPC` holds all the RPC clients and adds a layer over all the RPC
methods to assert no error happened at the RPC level.
- `HarnessNode` builds on top of the `HarnessRPC`. It is responsible for
managing the `lnd` node, including start and stop pf the `lnd` process,
authentication of the gRPC connection, topology subscription(`NodeWatcher`)
and maintains an internal state(`NodeState`).
2024-03-20 06:44:17 +01:00
- `HarnessMiner` builds on top of `btcd`s `rcptest.Harness` and is responsible
2022-07-22 13:32:16 +02:00
for managing blocks and the mempool.
- `HarnessTest` builds on top of `testing.T` and can be viewed as the assertion
machine. It provides multiple ways to initialize a node, such as with/without
seed, backups, etc. It also handles interactions between nodes like
connecting nodes and opening/closing channels so its easier to acquire or
validate a desired test states such as nodes balance, mempool condition,
etc.
### Standby Nodes
Standby nodes are `HarnessNode`s created when initializing the integration test
and stay alive across all the test cases. Creating a new node is not without a
cost. With block height increasing, it takes significantly longer to initialize
a new node and wait for it to be synced. Standby nodes, however, dont have
this problem as they are digesting blocks all the time. Thus, its encouraged to
2022-07-22 13:32:16 +02:00
use standby nodes wherever possible.
Currently, there are two standby nodes, Alice and Bob. Their internal states are
2022-07-22 13:32:16 +02:00
recorded and taken into account when `HarnessTest` makes assertions. When
making a new test case using `Subtest`, theres a cleanup function which
further validates the current test case has no dangling uncleaned states, such
as transactions left in mempool, open channels, etc.
### Different Code Used in `lntest`
Since the miner in `lntest` uses regtest, it has a very fast block production
rate, which is the greatest difference between the conditions it simulates and
the real-world has. Aside from that, `lnd` has several places that use
different code, which is triggered by the build flag `integration`, to speed up
the tests. They are summarized as followings,
1. `funding.checkPeerChannelReadyInterval`, which is used when we wait for the
peer to send us `ChannelReady`. This value is 1 second in `lnd`, and 10
milliseconds in `lntest`.
2. `lncfg.ProtocolOptions`, which is used to specify protocol flags. In `lnd`,
anchor and script enforced lease are enabled by default, while in `lntest`,
they are disabled by default.
3. Reduced scrypt parameters are used in `lntest`. In `lnd`, the parameters N,
R, and P are imported from `snacl`, while in `lntest` they are replaced with
`waddrmgr.FastScryptOptions`. Both `macaroon` and `aezeed` are affected.
4. The method, `nextRevocationProducer`, defined in `LightningWallet` is
slightly different. For `lnwallet`, it will check a special pre-defined
channel ID to test restoring channel backups created with the old revocation
root derivation method.