go-build/pkg/build/builders/rust_test.go

151 lines
3.9 KiB
Go

package builders
import (
"context"
"os"
"strings"
"testing"
"dappco.re/go/core/build/internal/ax"
"dappco.re/go/core/build/pkg/build"
"dappco.re/go/core/io"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func setupFakeRustToolchain(t *testing.T, binDir string) {
t.Helper()
script := `#!/bin/sh
set -eu
log_file="${RUST_BUILD_LOG_FILE:-}"
if [ -n "$log_file" ]; then
printf '%s\n' "$(basename "$0")" >> "$log_file"
printf '%s\n' "$@" >> "$log_file"
printf '%s\n' "CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-}" >> "$log_file"
printf '%s\n' "TARGET_OS=${TARGET_OS:-}" >> "$log_file"
printf '%s\n' "TARGET_ARCH=${TARGET_ARCH:-}" >> "$log_file"
env | sort >> "$log_file"
fi
target_triple=""
prev=""
for arg in "$@"; do
if [ "$prev" = "--target" ]; then
target_triple="$arg"
prev=""
continue
fi
if [ "$arg" = "--target" ]; then
prev="--target"
fi
done
target_dir="${CARGO_TARGET_DIR:-target}"
release_dir="$target_dir/$target_triple/release"
mkdir -p "$release_dir"
name="${NAME:-rustapp}"
artifact="$release_dir/$name"
case "$target_triple" in
*-windows-*)
artifact="$artifact.exe"
;;
esac
printf 'fake rust artifact\n' > "$artifact"
chmod +x "$artifact" 2>/dev/null || true
`
require.NoError(t, ax.WriteFile(ax.Join(binDir, "cargo"), []byte(script), 0o755))
}
func setupRustTestProject(t *testing.T) string {
t.Helper()
dir := t.TempDir()
require.NoError(t, ax.WriteFile(ax.Join(dir, "Cargo.toml"), []byte("[package]\nname = \"testapp\"\nversion = \"0.1.0\""), 0o644))
require.NoError(t, ax.MkdirAll(ax.Join(dir, "src"), 0o755))
require.NoError(t, ax.WriteFile(ax.Join(dir, "src", "main.rs"), []byte("fn main() {}"), 0o644))
return dir
}
func TestRust_RustBuilderName_Good(t *testing.T) {
builder := NewRustBuilder()
assert.Equal(t, "rust", builder.Name())
}
func TestRust_RustBuilderDetect_Good(t *testing.T) {
fs := io.Local
t.Run("detects Cargo.toml projects", func(t *testing.T) {
dir := t.TempDir()
require.NoError(t, ax.WriteFile(ax.Join(dir, "Cargo.toml"), []byte("{}"), 0o644))
builder := NewRustBuilder()
detected, err := builder.Detect(fs, dir)
assert.NoError(t, err)
assert.True(t, detected)
})
t.Run("returns false for empty directory", func(t *testing.T) {
builder := NewRustBuilder()
detected, err := builder.Detect(fs, t.TempDir())
assert.NoError(t, err)
assert.False(t, detected)
})
}
func TestRust_RustBuilderBuild_Good(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
binDir := t.TempDir()
setupFakeRustToolchain(t, binDir)
t.Setenv("PATH", binDir+string(os.PathListSeparator)+os.Getenv("PATH"))
projectDir := setupRustTestProject(t)
outputDir := t.TempDir()
logDir := t.TempDir()
logPath := ax.Join(logDir, "rust.log")
t.Setenv("RUST_BUILD_LOG_FILE", logPath)
builder := NewRustBuilder()
cfg := &build.Config{
FS: io.Local,
ProjectDir: projectDir,
OutputDir: outputDir,
Name: "testapp",
Version: "v1.2.3",
Env: []string{"FOO=bar"},
}
targets := []build.Target{{OS: "linux", Arch: "amd64"}}
artifacts, err := builder.Build(context.Background(), cfg, targets)
require.NoError(t, err)
require.Len(t, artifacts, 1)
assert.FileExists(t, artifacts[0].Path)
assert.Equal(t, "linux", artifacts[0].OS)
assert.Equal(t, "amd64", artifacts[0].Arch)
content, err := ax.ReadFile(logPath)
require.NoError(t, err)
lines := strings.Split(strings.TrimSpace(string(content)), "\n")
require.GreaterOrEqual(t, len(lines), 5)
assert.Equal(t, "cargo", lines[0])
assert.Equal(t, "build", lines[1])
assert.Equal(t, "--release", lines[2])
assert.Equal(t, "--target", lines[3])
assert.Equal(t, "x86_64-unknown-linux-gnu", lines[4])
assert.Contains(t, lines, "CARGO_TARGET_DIR="+ax.Join(outputDir, "linux_amd64"))
assert.Contains(t, string(content), "FOO=bar")
}
func TestRust_RustBuilderInterface_Good(t *testing.T) {
var _ build.Builder = (*RustBuilder)(nil)
var _ build.Builder = NewRustBuilder()
}