diff --git a/src/fdb5/toc/TocHandler.cc b/src/fdb5/toc/TocHandler.cc index 68f769578..7b94c4830 100644 --- a/src/fdb5/toc/TocHandler.cc +++ b/src/fdb5/toc/TocHandler.cc @@ -674,6 +674,7 @@ eckit::LocalPathName TocHandler::parseSubTocRecord(const TocRecord& r, bool read eckit::MemoryStream s(&r.payload_[0], r.maxPayloadSize); eckit::LocalPathName path; s >> path; + // Handle both path and absPath for compatibility as we move from storing // absolute paths to relative paths. Either may exist in either the TOC_SUB_TOC // or TOC_CLEAR entries. @@ -682,7 +683,17 @@ eckit::LocalPathName TocHandler::parseSubTocRecord(const TocRecord& r, bool read if (path.path()[0] == '/') { absPath = findRealPath(path); if (!absPath.exists()) { - absPath = currentDirectory() / path.baseName(); + // the DB may have been moved, so try to find the subtoc in the current directory + // except in case of an overlay (subtoc name = "toc") + if (path.baseName() != "toc") { + absPath = currentDirectory() / path.baseName(); + } + else { + eckit::Log::error() + << "Skipping an FDB overlay database that is no longer available. Original path was: " << path + << std::endl; + absPath = ""; + } } } else { diff --git a/tests/fdb/api/test_auxiliary.cc b/tests/fdb/api/test_auxiliary.cc index 3c5be890b..4bd249db1 100644 --- a/tests/fdb/api/test_auxiliary.cc +++ b/tests/fdb/api/test_auxiliary.cc @@ -199,7 +199,7 @@ CASE("Ensure wipe fails if extensions are unknown") { auto iter = fdb.wipe(request, doit, false, unsafeWipeAll); while (iter.next(elem)) {} } - catch (eckit::Exception) { + catch (eckit::Exception&) { error_was_thrown = true; } EXPECT(error_was_thrown); diff --git a/tests/regressions/CMakeLists.txt b/tests/regressions/CMakeLists.txt index 207b6c486..b1d253f2f 100644 --- a/tests/regressions/CMakeLists.txt +++ b/tests/regressions/CMakeLists.txt @@ -32,6 +32,7 @@ if (HAVE_FDB_BUILD_TOOLS) # test scripts use the fdb tools endif() add_subdirectory(FDB-241) + add_subdirectory(FDB-735) if (HAVE_FDB_REMOTE) add_subdirectory(FDB-419) diff --git a/tests/regressions/FDB-735/CMakeLists.txt b/tests/regressions/FDB-735/CMakeLists.txt new file mode 100644 index 000000000..30547fdff --- /dev/null +++ b/tests/regressions/FDB-735/CMakeLists.txt @@ -0,0 +1,5 @@ +ecbuild_configure_file( FDB-735.sh.in FDB-735.sh @ONLY ) +ecbuild_add_test( + TYPE SCRIPT + COMMAND FDB-735.sh + ENVIRONMENT "${test_environment}" ) diff --git a/tests/regressions/FDB-735/FDB-735.sh.in b/tests/regressions/FDB-735/FDB-735.sh.in new file mode 100755 index 000000000..ed4e0d15e --- /dev/null +++ b/tests/regressions/FDB-735/FDB-735.sh.in @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# A 'type: select' FDB whose lanes share the same physical root can, for a +# partial (ambiguous) list/wipe request that omits the keyword used to +# discriminate between lanes, have every matching lane independently +# rediscover the *same* on-disk catalogue and process it more than once. +# +# Two lanes ("stream=oper" and "stream=dcda") share the same root. +# A request that omits "stream" entirely legitimately matches both lanes +# (SelectFDB's MatchOnMissing policy), so both are queried -- but each lane +# then scans the *shared* root and finds *both* catalogues (the per-lane +# selector is not used to filter which catalogues are relevant), so every +# catalogue is reported/wiped once per lane instead of once overall. + +set -euxo pipefail + +yell() { printf "$(basename "$0"): \033[0;31m!!! %s !!!\033[0m\\n" "$*" >&2; } +die() { yell "$*"; exit 1; } + +fdbroot="$" +fdboverlay="$" +fdbwipe="$" + +srcdir=@CMAKE_CURRENT_SOURCE_DIR@ +bindir=@CMAKE_CURRENT_BINARY_DIR@ +wdir=$bindir/FDB-735 + +### cleanup and prepare test + +rm -rf "$wdir" +mkdir -p "$wdir/etc/fdb" +mkdir -p "$wdir/root" + +cd "$wdir" + +for f in config.yaml schema +do + cp "$srcdir/$f" "$wdir/etc/fdb" +done + +export FDB_HOME="$wdir" +unset FDB5_CONFIG_FILE +unset FDB_CONFIG_FILE + +# create empty expver 1234 +$fdbroot class=od,expver=1234,stream=oper,domain=g,date=-1,time=0 --create + +# overlay 1235 --> 1234 +$fdboverlay class=od,expver=1234,stream=oper,domain=g,date=-1,time=0 class=od,expver=1235,stream=oper,domain=g,date=-1,time=0 + +# remove 1234 (dangerous, since we have an overlay!) +$fdbwipe class=od,expver=1234,stream=oper,domain=g,date=-1,time=0 --doit + +# segfault while removing 1235 +$fdbwipe class=od,expver=1235,stream=oper,domain=g,date=-1,time=0 + diff --git a/tests/regressions/FDB-735/config.yaml b/tests/regressions/FDB-735/config.yaml new file mode 100644 index 000000000..4dd904599 --- /dev/null +++ b/tests/regressions/FDB-735/config.yaml @@ -0,0 +1,8 @@ +--- +type: local +schema: ~fdb/etc/fdb/schema +engine: toc +spaces: +- handler: Default + roots: + - path: ./root diff --git a/tests/regressions/FDB-735/schema b/tests/regressions/FDB-735/schema new file mode 100644 index 000000000..36abb37fc --- /dev/null +++ b/tests/regressions/FDB-735/schema @@ -0,0 +1,12 @@ + +param: Param; +step: Step; +date: Date; +levelist: Double; +expver: Expver; +time: Time; + +[ class, expver, stream, date, time, domain + [ type, levtype + [ step, levelist, param ]] +]