summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2014-01-12 10:29:02 +0000
committerLars Wirzenius <liw@liw.fi>2014-01-12 10:29:02 +0000
commitdff58cd5e33003fdf3eb73549c450b76838c6cbe (patch)
tree747c820bab9f2465815971227f3ab51d0335e681
parente65bdd1e04d01f3ef1e842f10d52e261050b599e (diff)
downloadobnam-dff58cd5e33003fdf3eb73549c450b76838c6cbe.tar.gz
Add test for multiple clients sharing a repository
As part of this, make every repository operation step require an explicit client name. The v6 reference formats have a client name embedded that is the hostname of my laptop, so make those tests use that name. This fixes what would not have run previously on any system that isn't named havelock. Oops.
-rw-r--r--yarns/0020-test-environment.yarn10
-rw-r--r--yarns/0030-basics.yarn18
-rw-r--r--yarns/0040-generations.yarn62
-rw-r--r--yarns/0050-multiple-clients.yarn40
-rw-r--r--yarns/0100-fuse.yarn12
-rw-r--r--yarns/0200-repo-formats.yarn19
-rw-r--r--yarns/9000-implements.yarn73
-rw-r--r--yarns/obnam.sh6
8 files changed, 148 insertions, 92 deletions
diff --git a/yarns/0020-test-environment.yarn b/yarns/0020-test-environment.yarn
index cc254ba7..607ecb2f 100644
--- a/yarns/0020-test-environment.yarn
+++ b/yarns/0020-test-environment.yarn
@@ -57,8 +57,8 @@ access over localhost, without requiring a password to be entered.
The user may disable such tests when the test suite is running,
by asking yarn to set the `OBNAM_TEST_SSH` to `no`.
-Obnam configuration
--------------------
+Obnam configuration and multiple users/clients
+----------------------------------------------
In the tests, Obnam is run without a default configuration
(`--no-default-config`), to avoid the user's settings affecting the
@@ -72,6 +72,12 @@ tests that run Obnam MUST use `run_obnam`. In addition to adding the
`$DATADIR/obnam.conf` configuration file, for single-client tests, or
`$DATADIR/$CLIENT.obnam.conf` for multi-client tests.
+We simulate multiple clients by providing each client with a different
+configuration, though on the command line instead of using
+configuration files. The relevant settings are `--client-name` and
+the backup roots (command line arguments to `obnam backup` or
+the `--root` setting).
+
Encryption keys
---------------
diff --git a/yarns/0030-basics.yarn b/yarns/0030-basics.yarn
index e5007487..3324dc45 100644
--- a/yarns/0030-basics.yarn
+++ b/yarns/0030-basics.yarn
@@ -20,10 +20,10 @@ program must be able to handle.
SCENARIO backup simple data
GIVEN 100kB of new data in directory L
AND a manifest of directory L in M
- WHEN user backs up directory L to repository R
- AND user restores their latest generation in repository R into X
+ WHEN user U backs up directory L to repository R
+ AND user U restores their latest generation in repository R into X
THEN L, restored to X, matches manifest M
- AND user can fsck the repository R
+ AND user U can fsck the repository R
Backup sparse files
-------------------
@@ -47,8 +47,8 @@ more disk space than the one in live data.
SCENARIO backup a sparse file
GIVEN a file S in L, with a hole, data, a hole
AND a manifest of directory L in M
- WHEN user backs up directory L to repository R
- AND user restores their latest generation in repository R into X
+ WHEN user U backs up directory L to repository R
+ AND user U restores their latest generation in repository R into X
THEN L, restored to X, matches manifest M
AND file S from L, restored in X doesn't use more disk
@@ -82,8 +82,8 @@ duplication.
SCENARIO backup non-basic filesystem objects
GIVEN directory L with interesting filesystem objects
AND a manifest of directory L in M
- WHEN user backs up directory L to repository R
- AND user restores their latest generation in repository R into X
+ WHEN user U backs up directory L to repository R
+ AND user U restores their latest generation in repository R into X
THEN L, restored to X, matches manifest M
Pretend backing up: the `--pretend` setting
@@ -96,8 +96,8 @@ than a real one.
SCENARIO a pretend backup
GIVEN directory L with interesting filesystem objects
- WHEN user backs up directory L to repository R
+ WHEN user U backs up directory L to repository R
GIVEN a manifest of directory R in M1
- WHEN user pretends to back up directory L to repository R
+ WHEN user U pretends to back up directory L to repository R
GIVEN a manifest of directory R in M2
THEN manifests M1 and M2 match
diff --git a/yarns/0040-generations.yarn b/yarns/0040-generations.yarn
index f36afdf6..9c741b4d 100644
--- a/yarns/0040-generations.yarn
+++ b/yarns/0040-generations.yarn
@@ -24,12 +24,12 @@ problem.)
SCENARIO backup two generations
GIVEN 1MB of new data in directory L
AND a manifest of directory L in G1
- WHEN user backs up directory L to repository R
+ WHEN user U backs up directory L to repository R
GIVEN 2MB of new data in directory L
AND a manifest of directory L in G2
- WHEN user backs up directory L to repository R
- AND user restores generation 1 to R1 from repository R
- AND user restores generation 2 to R2 from repository R
+ WHEN user U backs up directory L to repository R
+ AND user U restores generation 1 to R1 from repository R
+ AND user U restores generation 2 to R2 from repository R
THEN L, restored to R1, matches manifest G1
AND L, restored to R2, matches manifest G2
@@ -41,11 +41,11 @@ commands should show that number of generations.
SCENARIO list generations
GIVEN 1MB of new data in directory L
- WHEN user backs up directory L to repository R
- AND user backs up directory L to repository R
- AND user backs up directory L to repository R
- THEN user sees 3 generations in repository R
- AND user sees 3 generation ids in repository R
+ WHEN user U backs up directory L to repository R
+ AND user U backs up directory L to repository R
+ AND user U backs up directory L to repository R
+ THEN user U sees 3 generations in repository R
+ AND user U sees 3 generation ids in repository R
Listing contents of a generation (`obnam ls`)
--------------------------------
@@ -56,10 +56,10 @@ everything, or only a specific directory to list.
SCENARIO list generation content
GIVEN 1MB of new data in directory D
- WHEN user backs up directory D to repository R
- AND user lists latest generation in repository R into all.txt
+ WHEN user U backs up directory D to repository R
+ AND user U lists latest generation in repository R into all.txt
THEN all.txt matches /.*/D/.
- WHEN user lists D in latest generation in repository R into some.txt
+ WHEN user U lists D in latest generation in repository R into some.txt
THEN all lines in some.txt match (/D|Generation)
The first line of the generation listing contains the word
@@ -72,7 +72,7 @@ root directory) fails. The following is a test for that bug by
requesting `D/` to be listed, and verifying that we get at least one
line for that.
- WHEN user lists D/ in latest generation in repository R into bug.txt
+ WHEN user U lists D/ in latest generation in repository R into bug.txt
THEN bug.txt matches /D
Comparing generations (`obnam diff`)
@@ -84,9 +84,9 @@ generations are identical:
SCENARIO diff identical generations
GIVEN 1K of new data in directory L
- WHEN user backs up directory L to repository R
- AND user backs up directory L to repository R
- AND user diffs generations 1 and 2 in repository R into D
+ WHEN user U backs up directory L to repository R
+ AND user U backs up directory L to repository R
+ AND user U diffs generations 1 and 2 in repository R into D
THEN file D is empty
If we make a change to the data, that should be reflected in the diff.
@@ -94,10 +94,10 @@ We'll assume the diff works, we'll just check whether it's empty.
SCENARIO diff modified generations
GIVEN 1K of new data in directory L
- WHEN user backs up directory L to repository R
+ WHEN user U backs up directory L to repository R
GIVEN 1K of new data in directory L
- WHEN user backs up directory L to repository R
- AND user diffs generations 1 and 2 in repository R into D
+ WHEN user U backs up directory L to repository R
+ AND user U diffs generations 1 and 2 in repository R into D
THEN file D is not empty
Forgetting a specific generation (`obnam forget`)
@@ -111,16 +111,16 @@ checking that the remaining one is the one we want.
SCENARIO remove specific generations
GIVEN 1kB of new data in directory L
AND a manifest of directory L in M1
- WHEN user backs up directory L to repository R
+ WHEN user U backs up directory L to repository R
GIVEN 1kB of new data in directory L
AND a manifest of directory L in M2
- WHEN user backs up directory L to repository R
- AND user forgets the oldest generation in repository R
- THEN user sees 1 generation in repository R
- WHEN user restores their latest generation in repository R into X
+ WHEN user U backs up directory L to repository R
+ AND user U forgets the oldest generation in repository R
+ THEN user U sees 1 generation in repository R
+ WHEN user U restores their latest generation in repository R into X
THEN L, restored to X, matches manifest M2
- WHEN user forgets the oldest generation in repository R
- THEN user sees 0 generations in repository R
+ WHEN user U forgets the oldest generation in repository R
+ THEN user U sees 0 generations in repository R
Forgetting generations according to a schedule (`obnam forget --keep`)
-------------------------------------------------------------
@@ -130,11 +130,11 @@ The normal way of forgetting generations is with the `obnam forget
SCENARIO remove generations according to schedule
GIVEN 1kB of new data in directory L
- WHEN user backs up directory L to repository R
+ WHEN user U backs up directory L to repository R
GIVEN 1kB of new data in directory L
AND a manifest of directory L in M
- WHEN user backs up directory L to repository R
- AND user forgets according to schedule 1y in repository R
- THEN user sees 1 generation in repository R
- WHEN user restores their latest generation in repository R into X
+ WHEN user U backs up directory L to repository R
+ AND user U forgets according to schedule 1y in repository R
+ THEN user U sees 1 generation in repository R
+ WHEN user U restores their latest generation in repository R into X
THEN L, restored to X, matches manifest M
diff --git a/yarns/0050-multiple-clients.yarn b/yarns/0050-multiple-clients.yarn
new file mode 100644
index 00000000..63383654
--- /dev/null
+++ b/yarns/0050-multiple-clients.yarn
@@ -0,0 +1,40 @@
+Multiple clients sharing a repository
+=====================================
+
+An Obnam backup repository may be shared by multiple clients. There
+are a couple of aspects of this that need testing: whether it works at
+all, when each client is run in sequence, and whether it works
+concurrently, with locks used to exclude other clients from modifying
+the shared data.
+
+The concurrency is really hard to test well. There is a non-yarn test
+for locking, which we assume will test that, and so in this yarn test
+suite we do not test concurrency at all.
+
+ SCENARIO two clients sharing a repository
+ GIVEN directory L1 with interesting filesystem objects
+ AND directory L2 with interesting filesystem objects
+ AND a manifest of directory L1 in M1
+ AND a manifest of directory L2 in M2
+ WHEN user U1 backs up directory L1 to repository R
+ WHEN user U2 backs up directory L2 to repository R
+ AND user U1 restores their latest generation in repository R into X1
+ AND user U2 restores their latest generation in repository R into X2
+ THEN L1, restored to X1, matches manifest M1
+ AND L2, restored to X2, matches manifest M2
+
+In addition to backing up, we check for forget working. We first make
+a change to both sets of live data, and
+
+ GIVEN 1kB of new data in directory L1
+ AND 2kB of new data in directory L2
+ AND a manifest of directory L1 in M1A
+ AND a manifest of directory L2 in M2A
+ WHEN user U1 backs up directory L1 to repository R
+ AND user U2 backs up directory L2 to repository R
+ AND user U1 forgets the oldest generation in repository R
+ AND user U2 forgets the oldest generation in repository R
+ AND user U1 restores their latest generation in repository R into X1A
+ AND user U2 restores their latest generation in repository R into X2A
+ THEN L1, restored to X1A, matches manifest M1A
+ AND L2, restored to X2A, matches manifest M2A
diff --git a/yarns/0100-fuse.yarn b/yarns/0100-fuse.yarn
index 1a4f6d88..8efe3e40 100644
--- a/yarns/0100-fuse.yarn
+++ b/yarns/0100-fuse.yarn
@@ -9,8 +9,8 @@ test suite concentrates on verifying that at least the basics work.
ASSUMING user is in group fuse
GIVEN directory L with interesting filesystem objects
AND a manifest of directory L in M
- WHEN user backs up directory L to repository R
- AND user FUSE mounts the repository R at F
+ WHEN user U backs up directory L to repository R
+ AND user U FUSE mounts the repository R at F
THEN L, restored to F/latest, matches manifest M
FINALLY unmount repository F
@@ -23,10 +23,10 @@ We do the backup, and verify that it can be accessed correctly, by
doing a manifest of the live data before the backup, and then
against the FUSE mount, and comparing the two manifests.
- IMPLEMENTS WHEN user FUSE mounts the repository (\S+) at (\S+)
- mkdir "$DATADIR/$MATCH_2"
- run_obnam mount -r "$DATADIR/$MATCH_1" \
- --to "$DATADIR/$MATCH_2" --viewmode multiple
+ IMPLEMENTS WHEN user (\S+) FUSE mounts the repository (\S+) at (\S+)
+ mkdir "$DATADIR/$MATCH_3"
+ run_obnam "$MATCH_1" mount -r "$DATADIR/$MATCH_2" \
+ --to "$DATADIR/$MATCH_3" --viewmode multiple
If we did do the fuse mount, **always** unmount it, even when a step
failed. We do not want failed test runs to leavo mounts lying around.
diff --git a/yarns/0200-repo-formats.yarn b/yarns/0200-repo-formats.yarn
index 4e00393a..9ad0898c 100644
--- a/yarns/0200-repo-formats.yarn
+++ b/yarns/0200-repo-formats.yarn
@@ -35,18 +35,18 @@ First, the normal one reference repository.
SCENARIO use repository format 6
GIVEN unpacked test data from test-data/repo-format-6-encrypted-deflated.tar.xz in T
- WHEN user restores generation 1 in T/repo to R1
+ WHEN user havelock restores generation 1 in T/repo to R1
THEN restored data in R1 matches T/manifest-1
- WHEN user restores generation 2 in T/repo to R2
+ WHEN user havelock restores generation 2 in T/repo to R2
THEN restored data in R2 matches T/manifest-2
Then, the in-tree repository.
SCENARIO use repository format 6 with in-tree data
GIVEN unpacked test data from test-data/repo-format-6-in-tree-data.tar.xz in T
- WHEN user restores generation 1 in T/repo to R1
+ WHEN user havelock restores generation 1 in T/repo to R1
THEN restored data in R1 matches T/manifest-1
- WHEN user restores generation 2 in T/repo to R2
+ WHEN user havelock restores generation 2 in T/repo to R2
THEN restored data in R2 matches T/manifest-2
Implementations
@@ -63,12 +63,13 @@ First, we unpack the test data into a known location.
Then we restore the requested generation.
- IMPLEMENTS WHEN user restores generation (\d+) in (\S+) to (\S+)
+ IMPLEMENTS WHEN user (\S+) restores generation (\d+) in (\S+) to (\S+)
export GNUPGHOME="$SRCDIR/test-gpghome"
- genid=$(run_obnam -r "$DATADIR/$MATCH_2" \
- --encrypt-with=3B1802F81B321347 genids | sed -n "${MATCH_1}p")
- run_obnam -r "$DATADIR/$MATCH_2" --encrypt-with=3B1802F81B321347 \
- restore --to "$DATADIR/$MATCH_3" --generation "$genid"
+ genid=$(run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_3" \
+ --encrypt-with=3B1802F81B321347 genids | sed -n "${MATCH_2}p")
+ run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_3" \
+ --encrypt-with=3B1802F81B321347 \
+ restore --to "$DATADIR/$MATCH_4" --generation "$genid"
Finally, we verify the restored data against the manifest. We have one
tricky bit here: there is no guarantee what the path to the root of
diff --git a/yarns/9000-implements.yarn b/yarns/9000-implements.yarn
index ee35a4f9..1de44c15 100644
--- a/yarns/9000-implements.yarn
+++ b/yarns/9000-implements.yarn
@@ -20,7 +20,8 @@ Functions:
* `run_obnam`: run Obnam from the source tree, ignoring any
system-wide or user configuration and using only the configuration
specified by the test suite itself (`--no-default-config`). Run in
- quiet mode (`--quiet`).
+ quiet mode (`--quiet`). The first argument to `run_obnam` is the
+ client name.
* `manifest`: run summain in a way that produces a useable manifest,
which can be compared with diff with a later manifest.
@@ -87,13 +88,13 @@ Backing up
The simplest way to run a backup, for single-client scenarios. In
addition to backing up, this makes a manifest of the data.
- IMPLEMENTS WHEN user backs up directory (\S+) to repository (\S+)
- run_obnam backup -r "$DATADIR/$MATCH_2" "$DATADIR/$MATCH_1"
+ IMPLEMENTS WHEN user (\S+) backs up directory (\S+) to repository (\S+)
+ run_obnam "$MATCH_1" backup -r "$DATADIR/$MATCH_3" "$DATADIR/$MATCH_2"
We can also just pretend to make a backup.
- IMPLEMENTS WHEN user pretends to back up directory (\S+) to repository (\S+)
- run_obnam backup --pretend -r "$DATADIR/$MATCH_2" "$DATADIR/$MATCH_1"
+ IMPLEMENTS WHEN user (\S+) pretends to back up directory (\S+) to repository (\S+)
+ run_obnam "$MATCH_1" backup --pretend -r "$DATADIR/$MATCH_3" "$DATADIR/$MATCH_2"
fsck'ing a repository
---------------------
@@ -101,73 +102,79 @@ fsck'ing a repository
Verify that the repository itself is OK, by running `obnam fsck` on
it.
- IMPLEMENTS THEN user can fsck the repository (\S+)
- run_obnam fsck -r "$DATADIR/$MATCH_1"
+ IMPLEMENTS THEN user (\S+) can fsck the repository (\S+)
+ run_obnam "$MATCH_1" fsck -r "$DATADIR/$MATCH_2"
Restoring data
--------------
We need a way to restore data from a test backup repository.
- IMPLEMENTS WHEN user restores their latest generation in repository (\S+) into (\S+)
- run_obnam restore -r "$DATADIR/$MATCH_1" --to "$DATADIR/$MATCH_2"
+ IMPLEMENTS WHEN user (\S+) restores their latest generation in repository (\S+) into (\S+)
+ run_obnam "$MATCH_1" restore -r "$DATADIR/$MATCH_2" --to "$DATADIR/$MATCH_3"
Restore a specific generation. The generation number is an ordinal in
the list of generations, not the "generation id" Obnam assigns, as
that is unpredictable.
- IMPLEMENTS WHEN user restores generation (\d+) to (\S+) from repository (\S+)
- id=$(run_obnam -r "$DATADIR/$MATCH_3" genids |
- awk -v "n=$MATCH_1" 'NR == n')
- run_obnam restore -r "$DATADIR/$MATCH_3" \
- --to "$DATADIR/$MATCH_2" --generation "$id"
+ IMPLEMENTS WHEN user (\S+) restores generation (\d+) to (\S+) from repository (\S+)
+ client="$MATCH_1"
+ gen="$MATCH_2"
+ to="$DATADIR/$MATCH_3"
+ repo="$DATADIR/$MATCH_4"
+ id=$(run_obnam "$client" -r "$repo" genids |
+ awk -v "n=$gen" 'NR == n')
+ run_obnam "$client" restore -r "$repo" \
+ --to "$to" --generation "$id"
Removing (forgetting) generations
---------------------------------
Remove the oldest generation.
- IMPLEMENTS WHEN user forgets the oldest generation in repository (\S+)
+ IMPLEMENTS WHEN user (\S+) forgets the oldest generation in repository (\S+)
# The grep below at the end of pipeline is there to make sure
# the pipeline fails if there were no generations.
- id=$(run_obnam -r "$DATADIR/$MATCH_1" genids | head -n1 | grep .)
- run_obnam forget -r "$DATADIR/$MATCH_1" "$id"
+ id=$(run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_2" genids |
+ head -n1 | grep .)
+ run_obnam "$MATCH_1" forget -r "$DATADIR/$MATCH_2" "$id"
Remove according to a `--keep` schedule.
- IMPLEMENTS WHEN user forgets according to schedule (\S+) in repository (\S+)
- run_obnam forget -r "$DATADIR/$MATCH_2" --keep "$MATCH_1"
+ IMPLEMENTS WHEN user (\S+) forgets according to schedule (\S+) in repository (\S+)
+ run_obnam "$MATCH_1" forget -r "$DATADIR/$MATCH_3" --keep "$MATCH_2"
List generations
----------------
List everything in a generation. Capture the listing in a named file.
- IMPLEMENTS WHEN user lists latest generation in repository (\S+) into (\S+)
- run_obnam ls -r "$DATADIR/$MATCH_1" > "$DATADIR/$MATCH_2"
+ IMPLEMENTS WHEN user (\S+) lists latest generation in repository (\S+) into (\S+)
+ run_obnam "$MATCH_1" ls -r "$DATADIR/$MATCH_2" > "$DATADIR/$MATCH_3"
List only parts of a generation. Again, capture in a named file.
- IMPLEMENTS WHEN user lists (\S+) in latest generation in repository (\S+) into (\S+)
- run_obnam ls -r "$DATADIR/$MATCH_2" "$DATADIR/$MATCH_1" > "$DATADIR/$MATCH_3"
+ IMPLEMENTS WHEN user (\S+) lists (\S+) in latest generation in repository (\S+) into (\S+)
+ run_obnam "$MATCH_1" ls -r "$DATADIR/$MATCH_3" "$DATADIR/$MATCH_2" > "$DATADIR/$MATCH_4"
Checks on generations
---------------------
Check that number of generations is correct.
- IMPLEMENTS THEN user sees (\d+) generation(s?) in repository (\S+)
- run_obnam generations -r "$DATADIR/$MATCH_3" > "$DATADIR/generation.list"
+ IMPLEMENTS THEN user (\S+) sees (\d+) generation(s?) in repository (\S+)
+ run_obnam "$MATCH_1" generations -r "$DATADIR/$MATCH_4" \
+ > "$DATADIR/generation.list"
n=$(wc -l < "$DATADIR/generation.list")
- test "$MATCH_1" = "$n"
+ test "$MATCH_2" = "$n"
Ditto for generation ids.
- IMPLEMENTS THEN user sees (\d+) generation ids in repository (\S+)
- run_obnam generations -r "$DATADIR/$MATCH_2" \
+ IMPLEMENTS THEN user (\S+) sees (\d+) generation ids in repository (\S+)
+ run_obnam "$MATCH_1" generations -r "$DATADIR/$MATCH_3" \
> "$DATADIR/generation-id.list"
n=$(wc -l < "$DATADIR/generation-id.list")
- test "$MATCH_1" = "$n"
+ test "$MATCH_2" = "$n"
Diffs between generations
-------------------------
@@ -176,10 +183,10 @@ Compute the difference between two generations. The generations are
identified by the ordinal, not generation id, since the ids are
unpredictable.
- IMPLEMENTS WHEN user diffs generations (\d+) and (\d+) in repository (\S+) into (\S+)
- id1=$(run_obnam -r "$DATADIR/$MATCH_3" genids | awk -v "n=$MATCH_1" 'NR == n')
- id2=$(run_obnam -r "$DATADIR/$MATCH_3" genids | awk -v "n=$MATCH_2" 'NR == n')
- run_obnam diff -r "$DATADIR/$MATCH_3" "$id1" "$id2" > "$DATADIR/$MATCH_4"
+ IMPLEMENTS WHEN user (\S+) diffs generations (\d+) and (\d+) in repository (\S+) into (\S+)
+ id1=$(run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_4" genids | awk -v "n=$MATCH_2" 'NR == n')
+ id2=$(run_obnam "$MATCH_1" -r "$DATADIR/$MATCH_4" genids | awk -v "n=$MATCH_3" 'NR == n')
+ run_obnam "$MATCH_1" diff -r "$DATADIR/$MATCH_4" "$id1" "$id2" > "$DATADIR/$MATCH_5"
Checks on files
---------------
diff --git a/yarns/obnam.sh b/yarns/obnam.sh
index 27dbe57b..09319b37 100644
--- a/yarns/obnam.sh
+++ b/yarns/obnam.sh
@@ -17,11 +17,13 @@
# Run Obnam in a safe way that ignore's any configuration files outside
-# the test.
+# the test. The first argument MUST be the client name.
run_obnam()
{
- "$SRCDIR/obnam" --no-default-config --quiet \
+ local name="$1"
+ shift
+ "$SRCDIR/obnam" --no-default-config --quiet --client-name="$name" \
--log-level debug --log "$DATADIR/obnam.log" "$@"
}