diff --git a/Dockerfile b/Dockerfile index 45c36f1..678b336 100644 --- a/Dockerfile +++ b/Dockerfile @@ -219,11 +219,11 @@ FROM "${GOLANG_IMAGE}" AS dlv RUN go install github.com/go-delve/delve/cmd/dlv@latest FROM "${RUST_IMAGE}" AS libkrun-build -ARG LIBKRUN_VERSION=v1.15.1 +ARG LIBKRUN_VERSION=v1.17.4 RUN --mount=type=cache,sharing=locked,id=libkrun-aptlib,target=/var/lib/apt \ --mount=type=cache,sharing=locked,id=libkrun-aptcache,target=/var/cache/apt \ - apt-get update && apt-get install -y git libclang-19-dev llvm make + apt-get update && apt-get install -y git libcap-ng-dev libclang-19-dev llvm make RUN git clone --depth 1 --branch ${LIBKRUN_VERSION} https://github.com/containers/libkrun.git && \ cd libkrun && \ diff --git a/Makefile b/Makefile index e0a211b..f6f287d 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,13 @@ _output/nerdbox-initrd: cmd/vminitd FORCE @echo "$(WHALE) $@" $(BUILDX) bake initrd +_output/integration.test: integration FORCE + @echo "$(WHALE) $@" + $(GO) test -c -o $@ ${GO_LDFLAGS} ${GO_TAGS} ./integration +ifeq ($(OS),Darwin) + codesign --entitlements cmd/containerd-shim-nerdbox-v1/containerd-shim-nerdbox-v1.entitlements --force -s - $@ +endif + _output/test_vminitd: cmd/test_vminitd FORCE @echo "$(WHALE) $@" $(GO) build ${DEBUG_GO_GCFLAGS} ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o $@ ${GO_LDFLAGS} ${GO_TAGS} ./$< @@ -169,3 +176,7 @@ verify-vendor: ## verify if all the go.mod/go.sum files are up-to-date test-unit: go test -count=1 $(shell go list ./... | grep -v /integration) + +test-integration: _output/integration.test + @echo "$(WHALE) $@" + gotestsum -f testname --raw-command ./integration/test.sh diff --git a/integration/main_test.go b/integration/main_test.go index 0385265..68f2769 100644 --- a/integration/main_test.go +++ b/integration/main_test.go @@ -20,6 +20,7 @@ import ( "log" "os" "path/filepath" + "strings" "testing" "github.com/containerd/nerdbox/internal/vm" @@ -27,13 +28,23 @@ import ( ) func TestMain(m *testing.M) { - var err error - - absPath, err := filepath.Abs("../build") + e, err := os.Executable() if err != nil { - log.Fatalf("Failed to resolve build path: %v", err) + log.Fatalf("Failed to get executable path: %v", err) + } + exeDir := filepath.Dir(e) + paths := filepath.SplitList(os.Getenv("PATH")) + for _, p := range []string{ + "../_output", + ".", + } { + absPath := filepath.Clean(filepath.Join(exeDir, p)) + // Prepend to slice + paths = append(paths, "") + copy(paths[1:], paths) + paths[0] = absPath } - if err := os.Setenv("PATH", absPath+":"+os.Getenv("PATH")); err != nil { + if err := os.Setenv("PATH", strings.Join(paths, string(filepath.ListSeparator))); err != nil { log.Fatalf("Failed to set PATH environment variable: %v", err) } @@ -53,7 +64,14 @@ func runWithVM(t *testing.T, runTest func(*testing.T, vm.Instance)) { }, } { t.Run(tc.name, func(t *testing.T) { - vm, err := tc.vmm.NewInstance(t.Context(), t.TempDir()) + td := t.TempDir() + t.Chdir(td) + // Use Getwd to resolve symlinks (e.g., /var -> /private/var on macOS) + resolvedTd, err := os.Getwd() + if err != nil { + t.Fatal("Failed to get current working directory:", err) + } + vm, err := tc.vmm.NewInstance(t.Context(), resolvedTd) if err != nil { t.Fatal("Failed to create VM instance:", err) } diff --git a/integration/test.sh b/integration/test.sh new file mode 100755 index 0000000..580603c --- /dev/null +++ b/integration/test.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +# Copyright The containerd Authors. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +cd "$(dirname "$0")" + +# Build the test binary if it doesn't exist +if [[ ! -f ../_output/integration.test ]]; then + go test -c -o ../_output/integration.test . + + # Sign it with hypervisor entitlement on macOS + if [[ "$OSTYPE" == "darwin"* ]]; then + codesign --sign - --entitlements ../cmd/containerd-shim-nerdbox-v1/containerd-shim-nerdbox-v1.entitlements --force ../_output/integration.test &>/dev/null + fi +fi + +# Run each test individually +tests=( + "TestSystemInfo" + "TestStreamInitialization" +) + +for test in "${tests[@]}"; do + go tool test2json -t -p "github.com/containerd/nerdbox/integration" ../_output/integration.test -test.parallel 1 -test.v -test.run "$test" +done