Document build and test targets, and make local test runs self-contained by default (.test-data) (#2288)

This commit is contained in:
Michael Zhang authored and GitHub committed 2026-10-02 09:42:11 -07:00
1 parent 0a48a1bdbf
commit 1cd4cb3115
3 files changed
+103 -7

No files matched your search

+4
View File
@@ -32,3 +32,7 @@ coverage-reports/
# API docs for local preview only.
_site/
_serve/
# Default APP_ROOT and SCRATCH_ROOT for local test runs.
.test-data/
.test-scratch/
+73 -5
View File
@@ -11,13 +11,71 @@ To build the `container` project, you need:
## Compile and test
Build `container` and the background services from source, and run basic and integration tests in an isolated application data directory:
Build `container` and the background services from source, then run the unit and integration tests in an isolated application data directory:
```bash
rm -rf test-data
make APP_ROOT=test-data all test integration
make verify
```
This is the quickest way to verify your toolchain after cloning. `make verify` runs the `all`, `test`, and `integration` targets. The integration suite boots virtual machines and downloads a kernel and images, so the first run takes a while.
> [!IMPORTANT]
> `make integration` stops any `container` services you already have running and leaves them stopped when it finishes; run `container system start` afterward to get back to your own installation.
### Build and test targets
| Target | What it does |
| --- | --- |
| `make verify` | Runs `all`, `test`, and `integration`. |
| `make all` | Compiles, then installs the binaries into `bin/` and `libexec/` in your project directory. |
| `make test` | Runs the unit tests. |
| `make integration` | Runs the CLI and integration test suites. These start the `container` services, create containers, and boot virtual machines. |
| `make install` | Builds an installer package and installs it to `/usr/local`. |
| `make clean` | Runs `cleantest`, then `cleanbuild`. |
| `make cleanbuild` | Removes `bin/`, `libexec/`, generated docs, and coverage output. |
| `make cleantest` | Stops the `container` services and removes the `APP_ROOT` and `SCRATCH_ROOT` directories. |
### Isolating test data with `APP_ROOT`
By default, the test targets use `.test-data` in your project directory, so they do not disturb the images, containers, and volumes you use day to day, which live in `~/Library/Application Support/com.apple.container`.
`APP_ROOT` sets that directory, and is passed as `--app-root` to the services the test targets start.
How `make integration` treats `APP_ROOT`:
- It erases the directory's contents before each run.
- Set `APP_ROOT=` (empty) to run against `~/Library/Application Support/com.apple.container` instead. The tests will not erase it, but they will create and delete containers in it. Use this when you want the tests to exercise a realistic installation.
### Recommended iteration loop
> [!IMPORTANT]
> If you have an instance of `container` running, stop it using `container system stop` before starting the dev CLI. Each user account has a single set of `com.apple.container.*` services, so a test run cannot coexist with an installation you are using.
```bash
# 1. Build
make all
# 2. Unit tests
make test
# 3. Test the dev CLI
./bin/container system start --app-root .test-data
```
### Integration test options
| Variable | Default | Effect |
| --- | --- | --- |
| `PRESERVE_KERNELS` | `false` | Set to `true` to keep the `kernels` directory when the run clears `APP_ROOT`, so repeated runs do not download the kernel again. |
| `LOG_ROOT` | unset | Passes `--log-root` to the services, and writes swift-testing event streams to the given path. |
A typical iteration on the integration tests:
```bash
make PRESERVE_KERNELS=true LOG_ROOT=.test-data/logs integration
```
### Build installer package
Copy the binaries to `/usr/local/bin` and `/usr/local/libexec` (requires entering an administrator password):
```bash
@@ -27,10 +85,20 @@ make install
Or to install a release build, with better performance than the debug build:
```bash
BUILD_CONFIGURATION=release make all test integration
BUILD_CONFIGURATION=release make verify
BUILD_CONFIGURATION=release make install
```
### Clean up
Stop the services, remove the build outputs, and delete the test directories:
```bash
make clean
```
Use `make cleanbuild` to remove only the build outputs, or `make cleantest` to stop the services and remove only the `APP_ROOT` and `SCRATCH_ROOT` directories.
## Compile protobufs
`container` uses gRPC to communicate to the builder virtual machine that creates images from `Dockerfile`s, and depends on specific versions of `grpc-swift` and `swift-protobuf`. If you make changes to the gRPC APIs in the [container-builder-shim](https://github.com/apple/container-builder-shim) project, install the tools and re-generate the gRPC code in this project using:
@@ -91,7 +159,7 @@ to prepare your build environment.
6. Build `container`.
```
make clean all
make APP_ROOT= clean all
```
7. Restart the `container` services.
+26 -2
View File
@@ -36,6 +36,10 @@ DSYM_DIR := bin/$(BUILD_CONFIGURATION)/bundle/container-dSYM
DSYM_PATH := bin/$(BUILD_CONFIGURATION)/bundle/container-dSYM.zip
CODESIGN_OPTS ?= --force --sign - --timestamp=none
# Default isolated application data root under the project directory so test runs do not touch your
# own installation. Override with APP_ROOT=/your/path, or APP_ROOT= (empty) to run against
# the default ~/Library/Application Support/com.apple.container.
APP_ROOT ?= $(ROOT_DIR)/.test-data
# Conditionally use a temporary data directory for integration tests
SYSTEM_START_OPTS :=
@@ -63,6 +67,9 @@ SUDO ?= sudo
include Protobuf.Makefile
.PHONY: verify
verify: all test integration
.PHONY: all
all: container
all: init-block
@@ -312,7 +319,12 @@ define RUN_INTEGRATION
endef
.PHONY: integration
integration: init-block
integration: container init-block
@echo "HOSTNAME: $$(hostname)"
$(RUN_INTEGRATION)
.PHONY: integration-only
integration-only: init-block
@echo "HOSTNAME: $$(hostname)"
$(RUN_INTEGRATION)
@@ -423,10 +435,22 @@ cleancontent:
@rm -rf ~/Library/Application\ Support/com.apple.container
.PHONY: clean
clean:
clean: cleantest cleanbuild
.PHONY: cleanbuild
cleanbuild:
@echo Cleaning build files...
@rm -rf bin/ libexec/
@rm -rf _site _serve
@rm -f $(COV_REPORT_FILE)
@rm -rf $(COVERAGE_OUTPUT_DIR)
@$(SWIFT) package clean
.PHONY: cleantest
cleantest:
@echo Stopping container services...
@bin/container system stop 2>/dev/null || true
@scripts/ensure-container-stopped.sh -a || true
@if [ -n "$(APP_ROOT)" ]; then echo "Removing $(APP_ROOT)..." ; rm -rf "$(APP_ROOT)" ; fi
@echo "Removing $(SCRATCH_ROOT)..."
@rm -rf "$(SCRATCH_ROOT)"