Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 30 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
### Test Image specific config
FROM rustlang/rust:nightly-alpine

FROM rust:1.90-slim-trixie

RUN apt-get update
RUN apt-get -y install pkg-config libssl-dev moreutils
# Install required packages
RUN apk add --no-cache \
bash \
coreutils \
findutils \
gawk \
grep \
sed \
parallel \
pkgconfig \
openssl-dev \
build-base \
moreutils

WORKDIR /app

# Copy project structure
COPY tests tests
COPY tests_utility tests_utility
COPY solutions solutions

# Use sparse index for Cargo (faster network)
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
RUN parallel cargo fetch --manifest-path -- $(find tests -name Cargo.toml)

# Pre-fetch all dependencies
RUN find tests -name Cargo.toml | parallel cargo fetch --manifest-path {}

# Fix permissions for Rust crates (avoid “permission denied”)
RUN find /usr/local/cargo/registry/src -type f -name '*.rs' -exec chmod 644 {} \;

# Remove solutions (only student code will be mounted)
RUN rm -rf solutions

### Default configs
# ℹ️ URL of the Repository
LABEL org.opencontainers.image.source=https://github.com/01-edu/rust-tests
# ℹ️ Description of the Test Image
LABEL org.opencontainers.image.description="01 Edu - Rust Test Image"
# ℹ️ Licence type – MIT by default
LABEL org.opencontainers.image.licenses=MIT
### Metadata labels
LABEL org.opencontainers.image.source="https://github.com/01-edu/rust-tests"
LABEL org.opencontainers.image.description="01 Edu - Rust Test Image (Alpine)"
LABEL org.opencontainers.image.licenses="MIT"

# Copy entrypoint and isolate script
COPY entrypoint.sh ./
COPY isolate.sh ./

Expand Down
54 changes: 34 additions & 20 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env bash

set -eo pipefail
IFS='
'
IFS=$'\n'

# support both variables CODE_EDITOR_RUN_ONLY and EXAM_RUN_ONLY
CODE_EDITOR_RUN_ONLY="${CODE_EDITOR_RUN_ONLY:-$EXAM_RUN_ONLY}"
Expand All @@ -13,26 +11,42 @@ cp -a /app/tests .
cp -a /app/isolate.sh .
cp -a student solutions

if test "$CODE_EDITOR_MODE"; then
cd "solutions/$EXERCISE"
# ! to support both the old and the new version of the runner we
# ! need to check the files in the code editor
if ! echo "$EDITOR_FILES" | tr ',' '\n' | grep -q 'src/main.rs'; then
if test "$CODE_EDITOR_RUN_ONLY"; then
mv src/lib.rs src/main.rs 2>&1 ||:
fi
fi
cargo init
cd
if [ "$CODE_EDITOR_MODE" ]; then
cd "solutions/$EXERCISE"
# Support both old/new code editor runners
if ! echo "$EDITOR_FILES" | tr ',' '\n' | grep -q 'src/main.rs'; then
if [ "$CODE_EDITOR_RUN_ONLY" ]; then
mv src/lib.rs src/main.rs 2>/dev/null || true
fi
fi
cargo init
cd -
fi

if ! test -f "tests/${EXERCISE}_test/Cargo.toml"; then
echo "No test file found for the exercise : $EXERCISE"
exit 1
if [ ! -f "tests/${EXERCISE}_test/Cargo.toml" ]; then
echo "No test file found for the exercise: $EXERCISE"
exit 1
fi

if test "$CODE_EDITOR_RUN_ONLY"; then
cargo run --manifest-path "solutions/$EXERCISE/Cargo.toml" -- "$@"
# Ensure EXERCISE is inherited by isolate.sh
export EXERCISE
# Ensure current directory is in PATH for isolate.sh
export PATH=".:$PATH"

if [ "$CODE_EDITOR_RUN_ONLY" ]; then
cargo run --manifest-path "solutions/$EXERCISE/Cargo.toml" -- "$@"
else
cargo --config 'target."cfg(all())".runner="./isolate.sh"' test --manifest-path "tests/${EXERCISE}_test/Cargo.toml"
# 1) Compile tests first, without running
set +e
cargo test --no-run --manifest-path "tests/${EXERCISE}_test/Cargo.toml"
rc=$?
set -e
if [ "$rc" -ne 0 ]; then
echo "Solution did not compile."
exit 1
fi

# 2) Run tests with isolate.sh as runner
cargo --config 'target."cfg(all())".runner="./isolate.sh"' \
test --manifest-path "tests/${EXERCISE}_test/Cargo.toml"
fi
28 changes: 14 additions & 14 deletions isolate.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Use:
# cargo --config 'target."cfg(all())".runner="./isolate.sh"' test [args]
# cargo --config 'target."cfg(all())".runner="./isolate.sh"' test --manifest-path "tests/${EXERCISE}_test/Cargo.toml"

set -u

Expand Down Expand Up @@ -39,7 +39,7 @@ awk -F': test' '/: test/{print $1}' "$tmpdir/list.txt" | sed 's/[[:space:]]*$//'
(
"$bin" "${filtered[@]}" 2>&1
echo "__RC__$?"
) | tee "$logfile" >/dev/null
) | tee "$logfile"
rc="$(awk -F'__RC__' '/__RC__/ {v=$2} END{print v+0}' "$logfile")"

# 3) Collect tests that actually produced a result line:
Expand All @@ -56,18 +56,18 @@ awk '
}
' "$logfile" | sed 's/[[:space:]]*$//' > "$actual"

# 4) Decide: require (a) rc==0, (b) final summary ok, (c) every expected test appeared
if [[ "$rc" -eq 0 ]] && grep -Eq '^test result: ok\.' "$logfile"; then
sort -u "$expected" -o "$expected"
sort -u "$actual" -o "$actual"
# If no tests were expected (filters matched none), that's fine too.
if comm -23 "$expected" "$actual" | read -r _; then
# there were missing tests → failure
echo "Some tests weren't ran for the exercise \`$EXERCISE\`. Perhaps the solution forcefully exits?"
exit 1
else
exit 0
fi
# 4) Decide overall success/failure
sort -u "$expected" -o "$expected"
sort -u "$actual" -o "$actual"

missing=0
if comm -23 "$expected" "$actual" | read -r _; then
echo "Some tests weren't ran for the exercise \`$EXERCISE\`. Perhaps the solution forcefully exits?"
missing=1
fi

if [[ "$rc" -eq 0 ]] && grep -Eq '^test result: ok\.' "$logfile" && [[ $missing -eq 0 ]]; then
exit 0
fi

exit 1
Loading