# Testing Unikraft with Applications
These instructions are meant for core developers, maintainers and testers, i.e. people that work on the core components of the Unikraft ecosystem:
- the [`unikraft` core repositories](https://github.com/unikraft/unikraft)
- library repositories, such as [`lib-musl`](https://github.com/unikraft/lib-musl), [`lib-lwip`](https://github.com/unikraft/lib-lwip), [`lib-libelf`](https://github.com/unikraft/lib-libelf) etc.
- application repositories, such as [`app-elfloader`](https://github.com/unikraft/app-elfloader)
Changes to these repositories are to be tested using these instructions before upstreaming.
Typically they are part of the development process, with the developer and reviewer testing changes and contributions.
Testing Unikraft with applications means using the [`catalog`](https://github.com/unikraft/catalog) and [`catalog-core`](https://github.com/unikraft/catalog-core) repositories.
The [`catalog` repository](https://github.com/unikraft/catalog) is meant for users.
It uses [KraftKit](https://github.com/unikraft/kraftkit) (and `Kraftfile`s) to build and run applications.
The [`catalog-core` repository](https://github.com/unikraft/catalog-core) is meant for core developers, testers and maintainers.
It uses first-principle tools to build and run applications: `make` / `Makefile` and direct use of QEMU / Firecracker / Xen.
## Set Up
You will test core repositories.
This means you will have to do two steps:
1. Have core repositories cloned locally.
1. Point build and run scripts and configuration files to these repositories.
These are the files in the [`catalog`](https://github.com/unikraft/catalog) and [`catalog-core`](https://github.com/unikraft/catalog-core) repositories.
### Requirements
Use a baremetal Linux installation to be able to test QEMU and Firecracker.
For Xen-based builds you need an Xen-enabled kernel.
For Firecracker on ARM64 or Xen on ARM64 you need dedicated ARM64 hardware.
Follow the [instructions in `catalog-core` repository](https://github.com/unikraft/catalog-core) to install requirements.
Install the `yq` package.
For Debian/Ubuntu distributions, use:
```console
sudo apt install yq
```
Install the latest version of [KraftKit](https://github.com/unikraft/kraftkit):
```console
curl --proto '=https' --tlsv1.2 -sSf https://get.kraftkit.sh | sh
```
### Have Core Repositories Cloned Locally
Have the following (conventional) directory hierarchy:
```text
repos/
|-- apps/
| `-- elfloader/
|-- libs/
| |-- compiler-rt/
| |-- libcxx/
| |-- libcxxabi/
| |-- libelf/
| |-- libunwind/
| |-- lwip/
| |-- musl/
| |-- nginx/
| [...]
| `-- python3/
`-- unikraft/
```
You can create the hierarchy directly by using the [`setup.sh` script](https://github.com/unikraft/catalog-core/blob/main/setup.sh):
```console
wget https://raw.githubusercontent.com/unikraft/catalog-core/refs/heads/main/setup.sh
chmod a+x setup.sh
./setup.sh
```
Otherwise, if you are already using you own hierarchy, create the `repos/` directory and within create symbolic links to the corresponding repositories.
As a developer, you want to have the entries in the hierarchy point to your local work repositories.
Any updates you do to your local work repositories will be visible as part of the hierarchy.
In the end, get to a hierarchy as above.
### Set Up `catalog-core` Repository
Clone the [`catalog-core` repository](https://github.com/unikraft/catalog-core) locally:
```console
git clone ... https://github.com/unikraft/catalog
cd catalog-core/
```
Checkout the `test` branch:
```console
git checkout -b test origin/test
```
Within the cloned directory create a symbolic link to the `repos/` directory you created above:
```console
ln -sfn /path/to/repos/directory .
```
You will end up with a `repos` symbolic link in the current directory:
```console
$ ls -F
c-fs/ c-hello/ c-http/ cpp-hello/ cpp-http/ elfloader-basic/ elfloader-net/ nginx/ python3-hello/ README.md repos@ setup.sh* test.overall.sh*
```
### Set Up `catalog` Repository
Clone the [`catalog` repository in the `unikraft-upb` GitHub organization](https://github.com/unikraft-upb/catalog) locally:
```console
git clone https://github.com/unikraft-upb/catalog
cd catalog/
```
Checkout the `test` branch:
```console
git checkout -b test origin/test
```
Within the cloned directory create a symbolic link to the `repos/` directory you created above:
```console
ln -sfn /path/to/repos/directory .
```
## Have Repository Updates
As a developer or tester, make sure the current state of repositories is the one you want to test.
That is, make sure you are on the correct branch, or different commits or branches are merged for testing, or you did a local change you want to test.
## Actual Testing
The actual testing means testing applications in the `catalog-core` and `catalog` repositories.
### Test Using the `catalog-core` Repository
Before anything, make sure Docker is properly working:
```console
docker run --rm hello-world
```
Inside the clone of [`catalog-core` repository](https://github.com/unikraft/catalog-core), run the `test.overall.sh` script.
The script will do all setup, build and run steps:
```console
./test.overall.sh
```
The output will look like:
```console
[c-fs]
build.qemu.x86_64 ... PASSED
run.qemu.x86_64 ... PASSED
build.qemu.arm64 ... PASSED
run.qemu.arm64 ... PASSED
build.fc.x86_64 ... PASSED
run.fc.x86_64 ... PASSED
build.fc.arm64 ... PASSED
build.xen.x86_64 ... PASSED
build.xen.arm64 ... PASSED
[...]
```
Detailed logs are found in the `scripts/test/log/` directory for each application directory:
```console
$ ls c-fs/scripts/test/log/
build.fc.arm64 build.fc.x86_64 build.qemu.arm64 build.qemu.x86_64 build.xen.arm64 build.xen.x86_64 run.fc.x86_64 run.qemu.arm64 run.qemu.x86_64
```
To run the tests and build with Clang, use the command:
```console
$ CC=clang ./test.overall.sh
```
### Test Using the `catalog` Repository
Before anything, make sure Docker is properly working:
```console
docker run --rm hello-world
```
And be sure to have started the BuildKit container used to cache builds:
```console
docker run -d --name buildkit --privileged moby/buildkit:latest
export KRAFTKIT_BUILDKIT_HOST=docker-container://buildkit
```
Inside the clone of [`catalog` repository](https://github.com/unikraft/catalog), run the `test.overall.sh` script.
The script will do all setup, build and run steps:
```console
./test.overall.sh
```
The output will look like:
```console
HEAD is now at 5d03c9e testing: Introduce script to update Kraftfiles
build.library/imaginary/1.2 ... PASSED
build.library/r/4.3.3 ... PASSED
build.library/hugo/0.122 ... PASSED
[...]
```
Detailed logs are found in the `build.log`, `run.log` and `check.log` files for each application directory:
```console
$ ls library/mongo/6.0/
build.log check.log check.sh Dockerfile Kraftfile README.md repos run.config run.log
$ ls examples/http-c
check.log check.sh Dockerfile http_server.c Kraftfile README.md repos run.config run.log
```
## Available Setup
The above setup is readily available on the [`wasp` server in UPB](https://docs.google.com/document/d/19OcxNqArWTXc-vtj63iTeeKMAgvUzJOHN3KVYvqSB2Q/edit?tab=t.0#heading=h.rrykdnv9izj5).
Access the server via SSH and enter the `app-testing/` directory:
```console
unikraft@wasp:~$ cd app-testing/
unikraft@wasp:~/app-testing$ ls -F
catalog/ catalog-core/ repos/ setup.sh*
```
You can test using the `test.overall.sh` script in the `catalog-core/` and `catalog/` directories, respectively.