From 13bbd17e90d23eb23dc4a1600bb847839540639d Mon Sep 17 00:00:00 2001 From: Remo Senekowitsch Date: Sat, 24 Jan 2026 20:58:18 +0100 Subject: [PATCH 1/3] update to Rust 1.93 --- Dockerfile | 69 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index f5564e1..bfb5532 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # always build this using the latest stable release -FROM rust:1.88.0 AS build-base +FROM rust:1.93.0 AS build-base ARG JQ_VERSION=1.6 ARG JQ_URL=https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64 @@ -48,20 +48,23 @@ RUN cargo generate-lockfile && cargo local-registry --sync Cargo.lock . # version tag with a nightly one, pinned to a specific date. # official Dockerfile source: -# https://github.com/rust-lang/docker-rust/blob/master/stable/bookworm/slim/Dockerfile +# https://github.com/rust-lang/docker-rust/blob/master/stable/trixie/slim/Dockerfile ################ start-copy-pasta ################ -FROM debian:bookworm-slim +FROM debian:trixie-slim + +LABEL org.opencontainers.image.source=https://github.com/rust-lang/docker-rust ENV RUSTUP_HOME=/usr/local/rustup \ CARGO_HOME=/usr/local/cargo \ PATH=/usr/local/cargo/bin:$PATH \ - RUST_VERSION=nightly-2025-06-28 + RUST_VERSION=nightly-2026-01-22 # ~~~~~~~~^~~~~~~~~~ # pin version here RUN set -eux; \ + \ apt-get update; \ apt-get install -y --no-install-recommends \ ca-certificates \ @@ -69,30 +72,60 @@ RUN set -eux; \ libc6-dev \ wget \ ; \ - dpkgArch="$(dpkg --print-architecture)"; \ - case "${dpkgArch##*-}" in \ - amd64) rustArch='x86_64-unknown-linux-gnu'; rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c' ;; \ - armhf) rustArch='armv7-unknown-linux-gnueabihf'; rustupSha256='3b8daab6cc3135f2cd4b12919559e6adaee73a2fbefb830fadf0405c20231d61' ;; \ - arm64) rustArch='aarch64-unknown-linux-gnu'; rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c' ;; \ - i386) rustArch='i686-unknown-linux-gnu'; rustupSha256='a5db2c4b29d23e9b318b955dd0337d6b52e93933608469085c924e0d05b1df1f' ;; \ - ppc64el) rustArch='powerpc64le-unknown-linux-gnu'; rustupSha256='acd89c42b47c93bd4266163a7b05d3f26287d5148413c0d47b2e8a7aa67c9dc0' ;; \ - s390x) rustArch='s390x-unknown-linux-gnu'; rustupSha256='726b7fd5d8805e73eab4a024a2889f8859d5a44e36041abac0a2436a52d42572' ;; \ - *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \ + \ + arch="$(dpkg --print-architecture)"; \ + case "$arch" in \ + 'amd64') \ + rustArch='x86_64-unknown-linux-gnu'; \ + rustupSha256='20a06e644b0d9bd2fbdbfd52d42540bdde820ea7df86e92e533c073da0cdd43c'; \ + ;; \ + 'armhf') \ + rustArch='armv7-unknown-linux-gnueabihf'; \ + rustupSha256='3b8daab6cc3135f2cd4b12919559e6adaee73a2fbefb830fadf0405c20231d61'; \ + ;; \ + 'arm64') \ + rustArch='aarch64-unknown-linux-gnu'; \ + rustupSha256='e3853c5a252fca15252d07cb23a1bdd9377a8c6f3efa01531109281ae47f841c'; \ + ;; \ + 'i386') \ + rustArch='i686-unknown-linux-gnu'; \ + rustupSha256='a5db2c4b29d23e9b318b955dd0337d6b52e93933608469085c924e0d05b1df1f'; \ + ;; \ + 'ppc64el') \ + rustArch='powerpc64le-unknown-linux-gnu'; \ + rustupSha256='acd89c42b47c93bd4266163a7b05d3f26287d5148413c0d47b2e8a7aa67c9dc0'; \ + ;; \ + 's390x') \ + rustArch='s390x-unknown-linux-gnu'; \ + rustupSha256='726b7fd5d8805e73eab4a024a2889f8859d5a44e36041abac0a2436a52d42572'; \ + ;; \ + 'riscv64') \ + rustArch='riscv64gc-unknown-linux-gnu'; \ + rustupSha256='09e64cc1b7a3e99adaa15dd2d46a3aad9d44d71041e2a96100d165c98a8fd7a7'; \ + ;; \ + *) \ + echo >&2 "unsupported architecture: $arch"; \ + exit 1; \ + ;; \ esac; \ + \ url="https://static.rust-lang.org/rustup/archive/1.28.2/${rustArch}/rustup-init"; \ - wget "$url"; \ + wget --progress=dot:giga "$url"; \ echo "${rustupSha256} *rustup-init" | sha256sum -c -; \ + \ chmod +x rustup-init; \ ./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION --default-host ${rustArch}; \ rm rustup-init; \ chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \ - rustup --version; \ - cargo --version; \ - rustc --version; \ + \ apt-get remove -y --auto-remove \ wget \ ; \ - rm -rf /var/lib/apt/lists/*; + rm -rf /var/lib/apt/lists/*; \ + \ + rustup --version; \ + cargo --version; \ + rustc --version; ################ end-copy-pasta ################ From 6e84ace944f6709dfdcb0fb0cf0676bbe5d70fa4 Mon Sep 17 00:00:00 2001 From: Remo Senekowitsch Date: Sat, 24 Jan 2026 22:30:20 +0100 Subject: [PATCH 2/3] sort test results --- src/lib.rs | 1 + src/output.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index c543ce4..51dda14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,7 @@ where } } } + out.tests.sort(); out } diff --git a/src/output.rs b/src/output.rs index 59d3a13..3a1c619 100644 --- a/src/output.rs +++ b/src/output.rs @@ -62,6 +62,22 @@ impl TestResult { } } +impl PartialOrd for TestResult { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for TestResult { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match self.name.cmp(&other.name) { + core::cmp::Ordering::Equal => {} + ord => return ord, + } + self.test_code.cmp(&other.test_code) + } +} + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Output { pub version: u8, From 393819b93a62ba99a480960f878ef61f3e0448d9 Mon Sep 17 00:00:00 2001 From: Remo Senekowitsch Date: Sat, 24 Jan 2026 22:32:02 +0100 Subject: [PATCH 3/3] remove non-deterministic thread numbers from output --- src/output.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/output.rs b/src/output.rs index 3a1c619..0a11401 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,4 +1,7 @@ +use std::sync::LazyLock; + use crate::test_name_formatter::format_test_name; +use regex::Regex; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -19,6 +22,9 @@ pub struct TestResult { pub output: Option, } +static THREAD_PANICKED_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"thread '(?.*)' \(.*\) panicked at").unwrap()); + impl TestResult { pub fn ok(name: String, test_code: String) -> TestResult { TestResult { @@ -40,16 +46,19 @@ impl TestResult { _ => (None, message.map(|m| m.trim_start().to_owned())), }; - // This note is attached to the error message of only one test case that fails, - // but not always the same one. To avoid CI failing unnecessarily, this note - // is stripped from all messages. - // It's also not useful to students reading the output of the test runner, - // as they can't set this environment variable in the test runner themselves. let message = message.map(|m| { - m.trim_end_matches( + // This note is attached to the error message of only one test case that fails, + // but not always the same one. To avoid CI failing unnecessarily, this note + // is stripped from all messages. + // It's also not useful to students reading the output of the test runner, + // as they can't set this environment variable in the test runner themselves. + let m = m.trim_end_matches( "note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n", - ) - .to_owned() + ); + // If the test panics, the message contains a thread number that's + // not deterministic. Strip it to improve test reliability. + let m = THREAD_PANICKED_REGEX.replace(m, "thread '$testname' panicked at"); + m.to_string() }); TestResult {