panurus

Testing Guide

This document outlines how to run tests for Panurus.

Getting Started

To work with Panurus and run tests, you first need to clone the repository and set up your environment.

Clone the Repository

Clone the code and make sure it is on your $GOPATH. (Important: we assume in this documentation and default configuration that your $GOPATH has a single root-directory!). Sometimes, we use $PANURUS_PATH to refer to Panurus repository in your filesystem.

export PANURUS_PATH=$GOPATH/src/github.com/LFDT-Panurus/panurus
git clone https://github.com/LFDT-Panurus/panurus.git $PANURUS_PATH

Prerequisites

Before running tests, ensure you have the necessary tools and environment set up.

Panurus uses a system called NWO from Fabric Smart Client for its integration tests and samples to programmatically create a fabric network along with the fabric-smart-client nodes.

  1. Install Tools:
    make install-tools
    

    After installing the tools, run the checks to verify that everything is in order:

    make checks
    
  2. Download Fabric Binaries: The integration tests require Hyperledger Fabric binaries.

    In order for a fabric network to be able to be created you need to ensure you have downloaded the appropriate version of the hyperledger fabric binaries from Fabric Releases and unpack the compressed file onto your file system. This will create a directory structure of /bin and /config. You will then need to set the environment variable FAB_BINS to the bin directory.

    Do not store the fabric binaries within your panurus cloned repo as this will cause problems running the samples and integration tests as they will not be able to install chaincode.

    Almost all the samples and integration tests require the fabric binaries to be downloaded and the environment variable FAB_BINS set to point to the directory where these binaries are stored. One way to ensure this is to execute the following in the root of the panurus project:

    make download-fabric
    export FAB_BINS=$PWD/../fabric/bin
    

    You can also use this to download a different version of the fabric binaries, for example:

    FABRIC_VERSION=2.5 make download-fabric
    
  3. Docker Images: Build the necessary Docker images for testing.
    make testing-docker-images
    make docker-images
    

Unit Tests

You can run unit tests using the following make targets:

Fuzz Testing

Panurus uses Go’s native fuzzing (go test -fuzz) to exercise the stateless token validators with adversarial byte input. Fuzz targets assert that validation entry points never panic on malformed or truncated data, and — where applicable — that structurally valid encodings are still correctly accepted.

Available Fuzz Targets

Target Package What it fuzzes
FuzzVerifyTokenRequestFromRawNoPanic token/core/common Raw TokenRequest bytes fed straight into request verification.
FuzzStructuredTokenRequestSignatureEnvelope token/core/common A structurally valid request with a mutated action-signature envelope (action ID, signature bytes, duplicate signatures).
FuzzActionDeserializerNoPanic token/core/fabtoken/v1/validator A single issue or transfer action’s raw bytes through the FabToken ActionDeserializer.
FuzzActionDeserializerNoPanic token/core/zkatdlog/nogh/v1/validator A single issue or transfer action’s raw bytes through the ZKAT-DLOG ActionDeserializer, including both Range and CSP proof-type encodings.
FuzzActionDeserializerMultiActionNoPanic token/core/zkatdlog/nogh/v1/validator Two independently typed, independently fuzzed actions in the same TokenRequest.
FuzzBulletProofVerifierNoPanic token/core/zkatdlog/nogh/v1/issue Raw BulletProof issue-proof bytes through BulletProofVerifier.Verify — the call IssueValidate makes on unauthenticated wire bytes.
FuzzCSPVerifierNoPanic token/core/zkatdlog/nogh/v1/issue Raw CSP issue-proof bytes through CSPVerifier.Verify.
FuzzBulletProofVerifierNoPanic token/core/zkatdlog/nogh/v1/transfer Raw BulletProof transfer-proof bytes through BulletProofVerifier.Verify — the call TransferValidate makes on unauthenticated wire bytes.
FuzzCSPVerifierNoPanic token/core/zkatdlog/nogh/v1/transfer Raw CSP transfer-proof bytes through CSPVerifier.Verify.
FuzzTokenDeserializeNoPanic token/core/zkatdlog/nogh/v1/token Raw ledger-stored output bytes through Token.Deserialize.
FuzzMetadataDeserializeNoPanic token/core/zkatdlog/nogh/v1/token Raw ledger-stored metadata bytes through Metadata.Deserialize.
FuzzPublicParamsDeserializeNoPanic token/core/zkatdlog/nogh/v1/setup Raw ledger-stored public parameters through NewPublicParamsFromBytes, exercised by every validator/prover/verifier on startup and params update.
FuzzProofDeserializeNoPanic token/core/zkatdlog/nogh/v1/crypto/upgrade Raw untrusted token-upgrade request bytes through Proof.Deserialize.

Running the Seed Corpus

Every fuzz target ships with an f.Add seed corpus of deterministic valid and malformed inputs. These seeds run automatically as ordinary subtests whenever the package’s unit tests run — no special flag is needed:

go test ./token/core/zkatdlog/nogh/v1/validator/...
# or, for the whole repo:
make unit-tests

Running an Actual Fuzz Campaign

To mutate the seed corpus and search for new crashing or panicking inputs, run a specific target with -fuzz and bound the run with -fuzztime:

go test ./token/core/zkatdlog/nogh/v1/validator/... \
  -fuzz=FuzzActionDeserializerNoPanic -fuzztime=30s

Omit -fuzztime to let the fuzzer run until you stop it (Ctrl+C). If it finds a failing input, Go writes it to testdata/fuzz/<FuzzTestName>/<hash> in the target’s package — commit that file to add the regression permanently to the seed corpus, then re-run the failing case as a normal test with go test -run=<FuzzTestName>/<hash>.

Nightly Fuzzing in CI

.github/workflows/nightly-fuzz.yml runs every fuzz target above for up to 4h each night (02:17 UTC) against main, as a fail-fast: false matrix so one crashing target never stops the others. It can also be triggered manually via workflow_dispatch, which accepts a fuzztime input to shorten or lengthen the campaign.

If a target finds a crashing or panicking input, the workflow:

Confirmed crashes should have their seed file committed into the target’s testdata/fuzz/<FuzzTestName>/ directory (see above) to add the regression permanently to the corpus, closing out the issue once fixed.

Notes

Integration Tests

Integration tests are crucial for verifying the interaction between different components.

Run specific integration tests using the integration-tests-<target> pattern.

Common Test Targets

Here are some common integration test targets (refer to .github/workflows/tests.yml or integration/ folder for a full list):

Example Usage

To run the dlog-fabric-t1 test:

make integration-tests-dlog-fabric-t1

Enabling the Token Platform Without a TMS

By default, an FSC node only gets token: enabled: true written into its generated core.yaml if it belongs to at least one TMS (Topology.AddTMS). Topology.EnableTokenPlatform (integration/nwo/token/topology.go) lets a topology install and start the token platform on every node of an fsc.Topology with no TMS defined at all:

tokenTopology := token.NewTopology()
tokenTopology.EnableTokenPlatform(fscTopology)

This only affects configuration generation — the base token: stanza from the extension template, without any TMS-specific selector or driver configuration. It does not attach the token Go SDK to the nodes; do that separately with Topology.SetSDK or fscTopology.AddSDK(...), as usual.

The token SDK starts up cleanly with zero TMS configs (all its dependencies are lazily provided and network.Provider.Connect() is a no-op with no configured networks), but GetManagementService(...) still returns “no token management service configs found” until a TMS is registered. EnableTokenPlatform is meant as the config-generation groundwork for bringing up nodes that will have a TMS registered dynamically at runtime, once that capability exists — it is not itself a way to use tokens.

Fabric-X Tests

For tests involving Fabric-X (starts with fabricx), you need additional setup:

make fxconfig configtxgen fabricx-docker-images
make integration-tests-fabricx-dlog-t1

Cleaning Up

After running tests, especially integration tests that spin up Docker containers, you might want to clean up your environment.

# Clean up Docker artifacts (containers, volumes, networks) and generated files
make clean

# Remove all Docker containers (running and stopped)
make clean-all-containers

# Remove Fabric peer images
make clean-fabric-peer-images