From 954673869fd74e5e8b5e29ec5c81347da2fa582b Mon Sep 17 00:00:00 2001 From: Daniel Hilst <392820+dhilst@users.noreply.github.com> Date: Tue, 29 Sep 2026 17:18:06 -0300 Subject: [PATCH] test(xcat-test): a change set has no fast suite to run as one command Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com> --- xCAT-test/quick-servicenode-ub.txt | 10 ++- xCAT-test/quick-servicenode.txt | 32 ++++++++ xCAT-test/quick.sh | 79 +++++++++++++++++++ .../unit/service_node_artifacts_ubuntu.t | 57 +++++++++++++ 4 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 xCAT-test/quick-servicenode.txt create mode 100755 xCAT-test/quick.sh create mode 100644 xCAT-test/unit/service_node_artifacts_ubuntu.t diff --git a/xCAT-test/quick-servicenode-ub.txt b/xCAT-test/quick-servicenode-ub.txt index 8bf7a6ba8..bd603b5c4 100644 --- a/xCAT-test/quick-servicenode-ub.txt +++ b/xCAT-test/quick-servicenode-ub.txt @@ -6,9 +6,15 @@ # apt-get is absent, so on an EL host this list silently proves less and the trusted=yes fix # reads as unnecessary. # -# KNOWN HOLES, which is where a wrong drop will come from: nothing here covers the xdsh PATH fix -# or the named reload. Close them before trusting this list for a minimization. +# KNOWN HOLES, where a wrong drop comes from. A first run dropped four real fixes: +# - the apt source line the postscript writes. otherpkgs_apt_source_trusted measures APT, not +# what xCAT wrote. STILL OPEN. +# - the NFS export casper needs. CLOSED by service_node_artifacts_ubuntu.t. +# - the xdsh PATH fix. STILL OPEN. +# - the named reload. CLOSED by aasn_named_service_action.t. +xCAT-test/unit/service_node_artifacts_ubuntu.t +xCAT-test/unit/aasn_named_service_action.t xCAT-test/unit/ubuntu_service_subiquity_template.t xCAT-test/bats/makenamed_forwarders.bats xCAT-test/bats/otherpkgs_apt_source_trusted.bats diff --git a/xCAT-test/quick-servicenode.txt b/xCAT-test/quick-servicenode.txt new file mode 100644 index 000000000..0311a82f2 --- /dev/null +++ b/xCAT-test/quick-servicenode.txt @@ -0,0 +1,32 @@ +# The fast oracle of the service node change set: one test per fix, each written with its fix. +# +# Run it with: xCAT-test/quick.sh -f xCAT-test/quick-servicenode.txt +# +# These are the tests that failed before their fix landed. Together they stand in for the +# end-to-end service node suite, which provisions a management node, a service node and a +# compute node on two families and takes 45 to 90 minutes a run. +# +# What each one covers: +# check_provisioning_source the compute node was served by the service node, not the MN +# makenamed_forwarders a Debian service node does not forward DNS to its own stub +# otherpkgs_apt_source_trusted the staged apt source apt will accept +# stage_sn_apt_repo the Debian repository index, where createrepo does not exist +# servicenode_builder_repo the builder repository per EL release: crb, powertools, codeready +# svrutils_nfs_export_line a service node that mounts /install still exports it +# ubuntu_service_subiquity_template the service profile resolves a Subiquity template +# +# A SKIP is not a PASS. otherpkgs_apt_source_trusted skips its two resolving assertions where +# apt-get is absent, so on an EL builder that file proves less than it does on a Debian one. Run +# this list on the builder of the family the candidate touches, or read the skips. +# +# NOT covered, and known: the xdsh PATH fix, and the named working directory and reload fixes. +# A candidate that removes those passes this list and fails the end-to-end suite. Fill these in +# before trusting the list for a minimization. + +xCAT-test/bats/check_provisioning_source.bats +xCAT-test/bats/makenamed_forwarders.bats +xCAT-test/bats/otherpkgs_apt_source_trusted.bats +xCAT-test/bats/stage_sn_apt_repo.bats +xCAT-test/unit/servicenode_builder_repo.t +xCAT-test/unit/svrutils_nfs_export_line.t +xCAT-test/unit/ubuntu_service_subiquity_template.t diff --git a/xCAT-test/quick.sh b/xCAT-test/quick.sh new file mode 100755 index 000000000..e061de80d --- /dev/null +++ b/xCAT-test/quick.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# +# Run a fast subset of the unit tests: the Perl .t files with prove and the shell .bats files +# with bats, in one command, from the source tree. No build, no installed xCAT, no cluster. +# +# WHY THIS EXISTS. Delta debugging a change set runs the suite once per candidate. The +# end-to-end suite provisions machines and costs 45 to 90 minutes a run, so the rounds run on a +# fast oracle instead, and the slow suite runs once on the set that settles. This is that fast +# oracle, and it is useful on its own: it is the same two commands CI runs, without the wait. +# +# xCAT-test/quick.sh every unit test and every bats file +# xCAT-test/quick.sh path/a.t path/b.bats only those, in the order given +# xCAT-test/quick.sh -f list.txt the files named in list.txt, one per line +# +# Exit status is 0 only when every file passed. A missing file is an error, not a skip: a fast +# oracle that silently runs nothing reports PASS for a tree that contains none of the tests. + +set -u -o pipefail + +usage() { sed -n '3,20p' "$0" | sed 's/^# \{0,1\}//'; exit "${1:-0}"; } + +root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +files=() + +while [ $# -gt 0 ]; do + case "$1" in + -h|--help) usage 0 ;; + -f|--from) shift; [ -r "${1:-}" ] || { echo "quick: cannot read list '${1:-}'" >&2; exit 2; } + while read -r line; do + case "$line" in ''|\#*) continue ;; esac + files+=("$line") + done < "$1" ;; + -*) echo "quick: unknown option '$1'" >&2; usage 2 ;; + *) files+=("$1") ;; + esac + shift +done + +cd "$root" || exit 2 + +if [ "${#files[@]}" -eq 0 ]; then + echo "[quick] whole fast suite: prove -r xCAT-test/unit, then bats -r xCAT-test/bats" + rc=0 + prove -r xCAT-test/unit || rc=1 + bats -r xCAT-test/bats || rc=1 + exit $rc +fi + +# A named file that is absent means the caller asked for a test this tree does not have. Say so +# and fail: reporting PASS here is how a minimization drops the commit that adds a test. +missing=() +for f in "${files[@]}"; do [ -e "$f" ] || missing+=("$f"); done +if [ "${#missing[@]}" -gt 0 ]; then + printf '[quick] MISSING from this tree, refusing to report a result:\n' >&2 + printf ' %s\n' "${missing[@]}" >&2 + exit 2 +fi + +perl_tests=(); bats_tests=() +for f in "${files[@]}"; do + case "$f" in + *.t) perl_tests+=("$f") ;; + *.bats) bats_tests+=("$f") ;; + *) echo "quick: '$f' is neither a .t nor a .bats" >&2; exit 2 ;; + esac +done + +rc=0 +if [ "${#perl_tests[@]}" -gt 0 ]; then + echo "[quick] prove ${#perl_tests[@]} Perl test(s)" + prove "${perl_tests[@]}" || rc=1 +fi +if [ "${#bats_tests[@]}" -gt 0 ]; then + echo "[quick] bats ${#bats_tests[@]} shell test(s)" + bats "${bats_tests[@]}" || rc=1 +fi + +[ $rc -eq 0 ] && echo "[quick] PASS (${#files[@]} file(s))" || echo "[quick] FAIL" +exit $rc diff --git a/xCAT-test/unit/service_node_artifacts_ubuntu.t b/xCAT-test/unit/service_node_artifacts_ubuntu.t new file mode 100644 index 000000000..cfbad16ae --- /dev/null +++ b/xCAT-test/unit/service_node_artifacts_ubuntu.t @@ -0,0 +1,57 @@ +#!/usr/bin/env perl + +# The Ubuntu counterpart of service_node_artifacts_el.t: render the artifacts an Ubuntu service +# node needs and assert each, so the fast oracle fails for any wrong artifact rather than only +# for the defects someone has already hit. +# +# It exists because the first Ubuntu oracle dropped two real fixes. The apt test measured apt's +# behaviour rather than the line the postscript writes, and nothing asserted the export line at +# all, although casper mounts the install tree over NFS from the service node. + +use strict; +use warnings; + +use FindBin; +use Test::More; + +use lib "$FindBin::Bin/../../perl-xCAT"; +use lib "$FindBin::Bin/../../xCAT-server/lib/perl"; + +# get_file_name takes genos LAST, and update_tables_with_templates passes 'subiquity' for every +# Ubuntu 20.04 and later osimage. Passing the os version there resolves the preseed instead, which +# is the mistake this test would otherwise make about its own subject. +my %SN = (osver => 'ubuntu24.04', arch => 'x86_64', profile => 'service', genos => 'subiquity'); +my $SHARE = "$FindBin::Bin/../../xCAT-server/share/xcat/install"; + +my $have = eval { require xCAT::SvrUtils; 1 } ? 1 : 0; +ok($have, 'xCAT::SvrUtils loads') or do { done_testing(); exit 1 }; + +# 1. The installer. Ubuntu 20.04 and later install with Subiquity, and xCAT decides that from the +# NAME of the template it resolved. Without a service.subiquity.tmpl the service profile falls +# back to the debian-installer preseed and the node boots the live image without casper. +my $tmpl = xCAT::SvrUtils::get_tmpl_file_name("$SHARE/ubuntu", $SN{profile}, $SN{osver}, + $SN{arch}, $SN{genos}); +ok(defined $tmpl && length $tmpl, 'the Ubuntu service profile resolves a template'); +like($tmpl, qr{subiquity}, '... and it is a Subiquity template, or the node never installs'); +like($tmpl, qr{/service[^/]*\.tmpl$}, '... of the service profile, not compute'); + +# The compute profile must keep resolving too: an assertion that only ever looks at one profile +# cannot tell a profile fix from a lookup fix. +my $compute = xCAT::SvrUtils::get_tmpl_file_name("$SHARE/ubuntu", 'compute', $SN{osver}, + $SN{arch}, $SN{genos}); +like($compute, qr{subiquity}, 'the compute profile still resolves its own Subiquity template'); + +# 2. The NFS export. casper mounts the install tree from the service node, so a service node that +# exports nothing stops the compute node at "Unable to find a live file system on the network". +my $can_export = xCAT::SvrUtils->can('nfs_export_line') ? 1 : 0; +ok($can_export, 'SvrUtils can render an export line, without which casper finds no filesystem'); + +SKIP: { + skip 'nfs_export_line absent', 3 unless $can_export; + my $re = xCAT::SvrUtils->nfs_export_line('/install', reexport => 1); + like($re, qr{\bfsid=\d+}, 're-exporting the mounted /install carries an fsid'); + like($re, qr{\bcrossmnt\b}, '... and crossmnt'); + like($re, qr{\bno_root_squash\b}, '... and no_root_squash, which the installer needs'); +} + +done_testing();