# 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.