#!/usr/bin/env bash # # # The contents of this file are subject to the terms of the Common Development and # Distribution License (the License). You may not use this file except in compliance with the # License. # # You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the # specific language governing permission and limitations under the License. # # When distributing Covered Software, include this CDDL Header Notice in each file and include # the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL # Header, with the fields enclosed by brackets [] replaced by your own identifying # information: "Portions copyright [year] [name of copyright owner]". # # Copyright 2026 3A Systems, LLC. # Writes to every directory server of a replication topology at once, then checks that the # replicas hold the same data (#1090). The Docker image jobs of build.yml hand their image to # the job that runs it; it runs as well on a laptop with Docker alone. # # Usage: run.sh ; the settings and their defaults are in lib.sh set -eE -o pipefail IMAGE=${1:?usage: $0 } HERE=$(cd "$(dirname "$0")" && pwd) # changelog-gaps.py reads the changelogs of the replication servers command -v python3 >/dev/null || { echo "run.sh needs python3" >&2; exit 2; } . "$HERE/lib.sh" . "$HERE/topology-up.sh" . "$HERE/monitor.sh" . "$HERE/load.sh" . "$HERE/assert-converged.sh" . "$HERE/collect.sh" # the files of an earlier run would mix into this one's: the samples are appended to, and the # summary of a run that failed early would show what a run that got further left if [ -n "$(ls -A "$OUT" 2>/dev/null)" ]; then echo "$OUT holds the files of an earlier run: remove it, or set OUT to another directory" >&2 exit 2 fi mkdir -p "$OUT" # set -E hands the trap to every $(...) as well: there a failure only ends the subshell, and # the main shell decides. A run that fails before the online checks - a load check, a wait # that timed out, which a reconnection under load would explain - counts the reconnections # while the servers are still up trap 'code=$?; [ "$BASH_SUBSHELL" -eq 0 ] || exit $code; sampler_stop; [ -f "$OUT/reconnections.txt" ] || [ ! -f "$OUT/logs/${DS_NODES%% *}.mark" ] || record_reconnections || true; timings; collect; summarize failed; [ "$KEEP" = 1 ] || cleanup; exit $code' ERR cleanup phase "topology up ($TOPOLOGY)" topology_up for n in $RS_NODES; do runs_replication_server "$n" || fail "$n runs no replication server" done for n in $DS_NODES; do case " $RS_NODES " in *" $n "*) ;; *) ! runs_replication_server "$n" || fail "$n runs a replication server although its role is directory" ;; esac done for n in $DS_NODES; do users=$(ldaps_search "$n" "ou=People,$BASE_DN" one "(objectClass=inetOrgPerson)" 1.1 | grep -c '^dn:' || true) [ "$users" -eq "$SAMPLE_DATA" ] || fail "$n holds $users of the $SAMPLE_DATA seeded users" done mark_logs record_server_ids phase "load ($DURATION s)" # the changes of the load: assert_changelogs looks for gaps among the changes made in between LOAD_START_MS=$(($(date +%s) * 1000)) sampler_start run_load sampler_stop phase "converge" wait_converged echo "converged in $CONVERGED_IN s" LOAD_END_MS=$(($(date +%s) * 1000)) if [ "$INJECT_DIVERGENCE" = 1 ]; then phase "inject a divergence" inject_divergence fi # the offline checks run after online checks that failed as well: they tell which changes are # missing where phase "online checks" checks= assert_online || checks="the online checks" phase "offline checks" stop_all assert_offline || checks="${checks:+$checks and }the offline checks" [ -z "$checks" ] || fail "$checks failed" timings summarize passed cleanup