# holochain_cli_sandbox
A library and CLI to help create, run, and interact with sandboxed Holochain conductor environments,
for testing and development purposes.
## CLI
The `hc sandbox` CLI makes it easy to run a hApp that you are working on
or someone has sent you.
It has been designed to use sensible defaults but still give you
the configurability when that's required.
Sandboxes are stored in subdirectories of your system's temp directory by
default, and references to their paths are persisted in a `.hc` file in your
current working directory as you generate sandboxes.
If you'd like to persist sandboxes in a more permanent place, you can specify
a root directory and/or names for individual sandbox directories.
### Install
#### Quick install
Follow the [quick start guide](https://developer.holochain.org/quick-start/) on the Holochain Developer Portal to get set up with all the Holochain development tools, including the `hc` CLI and official extensions.
#### Install via Cargo
##### Requirements
- [Rust](https://rustup.rs/)
- [Holochain](https://github.com/holochain/holochain) binary on the path
##### Building
You can install the `hc-sandbox` CLI tool via crates.io:
```shell
cargo install holochain_cli_sandbox
```
Or you can install the entire `hc` CLI tool, which includes `hc-sandbox` as a subcommand:
```shell
cargo install holochain_cli
```
The examples below assume that you've installed the full `hc` rather than just `hc-sandbox`.
### Common usage
The best place to start is:
```shell
hc sandbox --help
```
This will be more up to date than this readme.
#### Run
This command can be used to generate and run conductor sandboxes.
```shell
hc sandbox run --help
# or shorter
hc sandbox r -h
```
#### Generate
Generates new conductor sandboxes and installs hApps into them.
In a folder that contains your bundled hApp (see [documentation on the `hc-bundle` command](../hc_bundle/README.md)), you can generate and run a new sandbox with:
```shell
hc sandbox generate
# or shorter
hc sandbox g
```
You can also generate more than one sandbox at a time:
```shell
hc sandbox generate --num-sandboxes 5
```
This command will create randomly-named directories in your system's temp directory,
and store their paths in a `.hc` file in your current working directory.
If you have previously created sandboxes, the new sandboxes' paths will be appended
to the end of the `.hc` file. Note that if your system periodically cleans up its temp
directory, the paths may end up pointing to non-existent sandboxes over time.
You can also specify persistent directories to create your sandboxes in via the `--root` option (the root directory must exist beforehand), as well as
specify directory names for individual sandboxes via the `--directories` option. Make sure the number of directory
names matches the number of sandboxes you're trying to create; if you don't specify enough directory names, the rest will be autogenerated.
```shell
# a randomly named sandbox directory in the following directory
hc sandbox generate --root my-sandboxes/
# three explicitly named sandboxes in the system temp directory
hc sandbox generate --num-sandboxes 3 --directories alice,bob,carol
```
While these directories are useful for creating test fixtures, their usefulness on other machines and across test runs is limited, as the generated conductor configurations have machine-dependent paths and the databases accumulate data with each run.
Finally, you can specify the type of network transport the sandboxes will use to communicate with each other via a `network` subcommand at the very end.
```shell
hc sandbox generate network quic
```
You can also generate sandboxes with the underlying dpki service disabled by passing in the `--no-dpki` flag.
```shell
hc sandbox generate --no-dpki
```
You can generate and run in the same command using the `--run` option. The argument passed to `-r` is a comma-separated list of ports to bind the sandboxes' app API WebSockets to, with `0` indicating that a port should be auto-selected. Once again, make sure the number of ports matches the number of sandboxes to be run; if not enough ports are specified, the remaining sandboxes won't be run.
```shell
hc sandbox generate --num-sandboxes 5 --run 0,9500,9501,0,0 ./elemental-chat.happ
```
As a full example, this will generate and run five named sandboxes in a subdirectory called `my-sandboxes`, with app IDs set to `my-app`
using the `elemental-chat.happ` from the current directory with a QUIC
network configured to use `localhost` and full use of the DPKI service.
_You don't need to specify the filename of the hApp when there's only one in your current working directory._
```shell
hc sandbox generate \
--app-id "my-app" \
--num-sandboxes 5 \
--root my-sandboxes/ \
--directories alice,bob,carol,dave,eve \
--run 0,0,0,0,0 \
./elemental-chat.happ \
network quic
```
#### Create
Creates 'empty' sandboxes; that is, sandboxes with no apps installed. This can be useful for testing the implementation of a program that controls the conductor via the admin API, such as an application launcher. Most of the options for `hc generate` also work with `hc create`:
```shell
hc sandbox create \
--num-sandboxes 5 \
--root my-sandboxes/ \
--directories alice,bob,carol,dave,eve \
--run 0,0,0,0,0 \
network quic
```
#### Call
Allows calling the [conductor admin API](https://docs.rs/holochain_conductor_api/latest/holochain_conductor_api/enum.AdminRequest.html) API on one or more _running_ sandboxes.
Although the API functions receive input as MessagePack-serialized data,
this command lets you conveniently pass them as command-line arguments instead.
All responses that return structured data are output as JSON.
For a list of all available admin API functions, run:
```shell
hc sandbox call --help
```
For information on the input parameters of a function, run:
```shell
hc sandbox call <api-function> --help
# for example:
hc sandbox call disable-app --help
```
```text
hc-sandbox-call-disable-app 0.1.3
Calls AdminRequest::DisableApp and disables the installed app
USAGE:
hc sandbox call disable-app <app-id>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
ARGS:
<app-id> The InstalledAppId to disable
```
#### List and Clean
These commands allow you to list the persisted sandboxes
in the current directory (from the`.hc`) file.
You can use the index from:
```shell
hc sandbox list
```
Output:
```shell
hc-sandbox:
Sandboxes contained in `.hc`
0: /tmp/KOXgKVLBVvoxe8iKD4iSS
1: /tmp/m8VHwwt93Uh-nF-vr6nf6
2: /tmp/t6adQomMLI5risj8K2Tsd
```
To then call or run an individual sandbox (or subset):
```shell
hc sandbox r -i=0,2
```
You can remove all sandboxes with:
```shell
hc sandbox clean
```
This removes the sandbox directories referenced in the `.hc` file in the current working directory, as well as the `.hc` file itself.
## Library
This crate can also be used as a library so you can create more
complex sandboxes / admin calls.
See the docs:
```shell
cargo doc --open
```
and the examples.
## Testing
### Rebuilding Wasm files
In case you've made changes to the API of the host functions in the `hdi` crate, you may need to rebuild the Wasm files used in tests.
```sh
HOLOCHAIN_DIR=$(pwd)
cd ./crates/test_utils/wasm
cargo build --release --features build
cp wasm_workspace/target/wasm32-unknown-unknown/release/test_wasm_foo.wasm $HOLOCHAIN_DIR/crates/hc_sandbox/tests/fixtures/my-app/dna/zomes/test_wasm_foo.wasm
cp wasm_workspace/target/wasm32-unknown-unknown/release/test_wasm_foo.wasm $HOLOCHAIN_DIR/crates/hc_sandbox/tests/fixtures/my-app-deferred/dna/zomes/test_wasm_foo.wasm
# Go back and delete any old DNA/hApp files
cd -
find ./ -iname "*.dna" -delete
find ./ -iname "*.happ" -delete
```