summaryrefslogtreecommitdiff
path: root/test/end-to-end/target-tests
diff options
context:
space:
mode:
authorKlaus Aehlig <klaus.aehlig@huawei.com>2023-09-28 13:19:02 +0200
committerKlaus Aehlig <klaus.aehlig@huawei.com>2023-09-28 15:55:32 +0200
commitd95d8121199e2519aa441cb1a471cf5aec69574d (patch)
treef6ec8f1eba976338b46921a79d9e43282ce2bda3 /test/end-to-end/target-tests
parent2887d6553ff6948517e309819d2a0d8425842b19 (diff)
downloadjustbuild-d95d8121199e2519aa441cb1a471cf5aec69574d.tar.gz
Avoid conflicts on case-insensitive file systems
... by renaming test/end-to-end/targets.
Diffstat (limited to 'test/end-to-end/target-tests')
-rw-r--r--test/end-to-end/target-tests/TARGETS49
-rwxr-xr-xtest/end-to-end/target-tests/built-in-resolution.sh52
-rw-r--r--test/end-to-end/target-tests/configure-target.sh99
-rw-r--r--test/end-to-end/target-tests/configure-vars.sh69
-rwxr-xr-xtest/end-to-end/target-tests/glob.sh208
-rwxr-xr-xtest/end-to-end/target-tests/repo_names.sh103
-rwxr-xr-xtest/end-to-end/target-tests/upwards.sh95
7 files changed, 675 insertions, 0 deletions
diff --git a/test/end-to-end/target-tests/TARGETS b/test/end-to-end/target-tests/TARGETS
new file mode 100644
index 00000000..d45db9eb
--- /dev/null
+++ b/test/end-to-end/target-tests/TARGETS
@@ -0,0 +1,49 @@
+{ "upwards reference":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["upwards"]
+ , "test": ["upwards.sh"]
+ , "deps": [["end-to-end", "tool-under-test"]]
+ }
+, "repository naming":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["repo_names"]
+ , "test": ["repo_names.sh"]
+ , "deps": [["end-to-end", "tool-under-test"]]
+ }
+, "resolution of built-in rules":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["built-in-resolution"]
+ , "test": ["built-in-resolution.sh"]
+ , "deps": [["end-to-end", "tool-under-test"]]
+ }
+, "glob expansion":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["glob"]
+ , "test": ["glob.sh"]
+ , "deps": [["end-to-end", "tool-under-test"]]
+ }
+, "configure target name":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["configure-target"]
+ , "test": ["configure-target.sh"]
+ , "deps": [["end-to-end", "tool-under-test"]]
+ }
+, "configure variables":
+ { "type": ["@", "rules", "shell/test", "script"]
+ , "name": ["configure-vars"]
+ , "test": ["configure-vars.sh"]
+ , "deps": [["end-to-end", "tool-under-test"]]
+ }
+, "TESTS":
+ { "type": "install"
+ , "tainted": ["test"]
+ , "deps":
+ [ "upwards reference"
+ , "repository naming"
+ , "resolution of built-in rules"
+ , "glob expansion"
+ , "configure target name"
+ , "configure variables"
+ ]
+ }
+}
diff --git a/test/end-to-end/target-tests/built-in-resolution.sh b/test/end-to-end/target-tests/built-in-resolution.sh
new file mode 100755
index 00000000..6971dab6
--- /dev/null
+++ b/test/end-to-end/target-tests/built-in-resolution.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+TOOL=$(realpath ./bin/tool-under-test)
+mkdir -p .root
+BUILDROOT=$(realpath .root)
+mkdir -p out
+OUTDIR=$(realpath out)
+
+mkdir -p src/some/module
+touch src/ROOT
+cd src/some/module
+cat > RULES <<'EOI'
+{ "install":
+ { "expression":
+ { "type": "RESULT"
+ , "artifacts":
+ { "type": "singleton_map"
+ , "key": "some internal path"
+ , "value": {"type": "BLOB", "data": "FROM USER-DEFINED INSTALL"}
+ }
+ }
+ }
+}
+EOI
+cat > TARGETS <<'EOI'
+{ "user": {"type": ["./", ".", "install"]}
+, "built-in": {"type": "install", "files": {"the/public/path": "user"}}
+}
+EOI
+
+echo
+${TOOL} install built-in --local-build-root ${BUILDROOT} -o ${OUTDIR} 2>&1
+echo
+grep 'FROM USER-DEFINED INSTALL' ${OUTDIR}/the/public/path
+echo
+
+echo DONE
diff --git a/test/end-to-end/target-tests/configure-target.sh b/test/end-to-end/target-tests/configure-target.sh
new file mode 100644
index 00000000..7c4dd9fd
--- /dev/null
+++ b/test/end-to-end/target-tests/configure-target.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+TOOL=$(realpath ./bin/tool-under-test)
+mkdir -p .root
+BUILDROOT=$(realpath .root)
+mkdir -p out
+OUTDIR=$(realpath out)
+
+mkdir src
+cd src
+touch ROOT
+cat > TARGETS <<'EOI'
+{ "configured":
+ { "type": "configure"
+ , "arguments_config": ["TARGET", "FOO", "BAR"]
+ , "target": {"type": "var", "name": "TARGET"}
+ , "config":
+ { "type": "let*"
+ , "bindings":
+ [ ["FOO", {"type": "var", "name": "FOO", "default": "foo"}]
+ , ["BAR", {"type": "var", "name": "BAR", "default": "bar"}]
+ , [ "FOOBAR"
+ , { "type": "join"
+ , "$1":
+ [{"type": "var", "name": "FOO"}, {"type": "var", "name": "BAR"}]
+ }
+ ]
+ ]
+ , "body": {"type": "env", "vars": ["FOO", "BAR", "FOOBAR"]}
+ }
+ }
+, "foobar":
+ { "type": "generic"
+ , "outs": ["out.txt"]
+ , "arguments_config": ["FOOBAR"]
+ , "cmds":
+ [ { "type": "join"
+ , "separator": " "
+ , "$1":
+ [ "echo"
+ , "-n"
+ , {"type": "join_cmd", "$1": [{"type": "var", "name": "FOOBAR"}]}
+ , "> out.txt"
+ ]
+ }
+ ]
+ }
+, "bar":
+ { "type": "file_gen"
+ , "arguments_config": ["BAR"]
+ , "name": "out.txt"
+ , "data": {"type": "var", "name": "BAR"}
+ }
+}
+EOI
+echo -n unrelated > out.txt
+
+
+echo
+${TOOL} install --local-build-root "${BUILDROOT}" -o "${OUTDIR}" \
+ -D '{"TARGET": "foobar", "FOO": "_F_O_O_"}' configured 2>&1
+echo
+cat "${OUTDIR}/out.txt"
+echo
+[ $(cat "${OUTDIR}/out.txt") = "_F_O_O_bar" ]
+
+echo
+${TOOL} install --local-build-root "${BUILDROOT}" -o "${OUTDIR}" \
+ -D '{"TARGET": "bar", "FOO": "_F_O_O_"}' configured 2>&1
+echo
+cat "${OUTDIR}/out.txt"
+echo
+[ $(cat "${OUTDIR}/out.txt") = "bar" ]
+
+echo
+${TOOL} install --local-build-root "${BUILDROOT}" -o "${OUTDIR}" \
+ -D '{"TARGET": "out.txt", "FOO": "_F_O_O_"}' configured 2>&1
+echo
+cat "${OUTDIR}/out.txt"
+echo
+[ $(cat "${OUTDIR}/out.txt") = "unrelated" ]
+
+
+echo DONE
diff --git a/test/end-to-end/target-tests/configure-vars.sh b/test/end-to-end/target-tests/configure-vars.sh
new file mode 100644
index 00000000..e55581f7
--- /dev/null
+++ b/test/end-to-end/target-tests/configure-vars.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+TOOL=$(realpath ./bin/tool-under-test)
+mkdir -p .root
+BUILDROOT=$(realpath .root)
+mkdir -p out
+OUTDIR=$(realpath out)
+
+mkdir src
+cd src
+touch ROOT
+cat > TARGETS <<'EOI'
+{ "copy foo":
+ { "type": "configure"
+ , "arguments_config": ["FOO"]
+ , "target": "use bar"
+ , "config":
+ { "type": "let*"
+ , "bindings":
+ [["BAR", {"type": "var", "name": "FOO"}], ["FOO", "REDACTED"]]
+ , "body": {"type": "env", "vars": ["BAR", "FOO"]}
+ }
+ }
+, "use bar":
+ { "type": "file_gen"
+ , "arguments_config": ["BAR"]
+ , "data": {"type": "var", "name": "BAR", "default": "bar"}
+ , "name": "out.txt"
+ }
+}
+EOI
+
+
+echo
+${TOOL} analyse --local-build-root "${BUILDROOT}" \
+ --dump-vars "${OUTDIR}/vars.json" \
+ --dump-targets "${OUTDIR}/targets.json" \
+ -D '{"FOO": "the value", "BAR": "unused!"}' 'copy foo' 2>&1
+echo
+cat "${OUTDIR}/vars.json"
+echo
+cat "${OUTDIR}/targets.json"
+echo
+copy_configs=$(cat "${OUTDIR}/targets.json" | jq -acM '."@" | ."" | ."" | ."copy foo"')
+echo "${copy_configs}"
+[ $(echo "${copy_configs}" | jq length) -eq 1 ]
+config=$(echo "${copy_configs}" | jq '.[0]')
+echo $config
+[ $(echo "$config" | jq -acM 'keys') = '["FOO"]' ]
+echo "$config" | jq -acM '."FOO"'
+[ "$(echo "$config" | jq -acM '."FOO"')" = '"the value"' ]
+[ "$(cat "${OUTDIR}/vars.json")" = '["FOO"]' ]
+
+echo DONE
diff --git a/test/end-to-end/target-tests/glob.sh b/test/end-to-end/target-tests/glob.sh
new file mode 100755
index 00000000..f655b3e3
--- /dev/null
+++ b/test/end-to-end/target-tests/glob.sh
@@ -0,0 +1,208 @@
+#!/bin/sh
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+TOOL=$(realpath ./bin/tool-under-test)
+mkdir -p .root
+BUILDROOT=$(realpath .root)
+mkdir -p out
+OUTDIR_BASE=$(realpath out)
+
+echo {} > repos.json
+export CONF=$(realpath repos.json)
+
+mkdir src
+cd src
+touch ROOT
+
+echo -n A > a.txt
+chmod 644 a.txt
+echo -n B > b.txt
+echo -n C > c.txt
+chmod 755 b.txt
+mkdir d.txt
+
+mkdir foo
+echo too deep > foo/a.txt
+
+cat > RULES <<'EOI'
+{ "reflect":
+ { "target_fields": ["deps"]
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "inputs"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "foreach"
+ , "var": "x"
+ , "range": {"type": "FIELD", "name": "deps"}
+ , "body":
+ {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "x"}}
+ }
+ }
+ ]
+ , [ "keys"
+ , { "type": "singleton_map"
+ , "key": "keys.txt"
+ , "value":
+ { "type": "BLOB"
+ , "data":
+ { "type": "join"
+ , "separator": " "
+ , "$1": {"type": "keys", "$1": {"type": "var", "name": "inputs"}}
+ }
+ }
+ }
+ ]
+ , [ "content"
+ , { "type": "ACTION"
+ , "inputs":
+ { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1": {"type": "var", "name": "inputs"}
+ }
+ , "outs": ["content.txt"]
+ , "cmd":
+ [ "sh"
+ , "-c"
+ , { "type": "join"
+ , "separator": " "
+ , "$1":
+ [ "mkdir -p work && cd work &&"
+ , { "type": "join_cmd"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["cat"]
+ , { "type": "keys"
+ , "$1": {"type": "var", "name": "inputs"}
+ }
+ ]
+ }
+ }
+ , "> ../content.txt"
+ ]
+ }
+ ]
+ }
+ ]
+ , [ "outputs"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "keys"}
+ , {"type": "var", "name": "content"}
+ ]
+ }
+ ]
+ ]
+ , "body":
+ {"type": "RESULT", "artifacts": {"type": "var", "name": "outputs"}}
+ }
+ }
+}
+EOI
+
+cat > TARGETS <<'EOI'
+{ "b.txt": {"type": "file_gen", "name": "b-new.txt", "data": "fromtarget"}
+, "enumeration": {"type": "reflect", "deps": ["a.txt", "b.txt", "c.txt"]}
+, "glob": {"type": "reflect", "deps": [["GLOB", null, "*.txt"]]}
+, "with_target":
+ {"type": "reflect", "deps": [["GLOB", null, "*.txt"], "b.txt"]}
+, "not_top_level": {"type": "reflect", "deps": [["GLOB", null, "foo/*.txt"]]}
+}
+EOI
+
+do_test() {
+ echo === Enumeration refres to targets ===
+
+ ${TOOL} install -C ${CONF} --local-build-root ${BUILDROOT} -o ${OUTDIR}/enum enumeration 2>&1
+
+ cat ${OUTDIR}/enum/keys.txt
+ echo
+ cat ${OUTDIR}/enum/content.txt
+ echo
+
+ [ "$(cat ${OUTDIR}/enum/keys.txt)" = "a.txt b-new.txt c.txt" ]
+ [ "$(cat ${OUTDIR}/enum/content.txt)" = "AfromtargetC" ]
+
+ echo === Glob always refres to files and directories are ignored ===
+
+ ${TOOL} install -C ${CONF} --local-build-root ${BUILDROOT} -o ${OUTDIR}/glob glob 2>&1
+
+ cat ${OUTDIR}/glob/keys.txt
+ echo
+ cat ${OUTDIR}/glob/content.txt
+ echo
+
+ [ "$(cat ${OUTDIR}/glob/keys.txt)" = "a.txt b.txt c.txt" ]
+ [ "$(cat ${OUTDIR}/glob/content.txt)" = "ABC" ]
+
+ echo === Globs and targets can be combined ===
+
+ ${TOOL} install -C ${CONF} --local-build-root ${BUILDROOT} -o ${OUTDIR}/with_target with_target 2>&1
+
+ cat ${OUTDIR}/with_target/keys.txt
+ echo
+ cat ${OUTDIR}/with_target/content.txt
+ echo
+
+ [ "$(cat ${OUTDIR}/with_target/keys.txt)" = "a.txt b-new.txt b.txt c.txt" ]
+ [ "$(cat ${OUTDIR}/with_target/content.txt)" = "AfromtargetBC" ]
+
+ echo === Globs only inspect the top-level directory of the module ===
+
+ ${TOOL} install -C ${CONF} --local-build-root ${BUILDROOT} -o ${OUTDIR}/not_top_level not_top_level 2>&1
+
+ cat ${OUTDIR}/not_top_level/keys.txt
+ echo
+ cat ${OUTDIR}/not_top_level/content.txt
+ echo
+
+ [ -z "$(cat ${OUTDIR}/not_top_level/keys.txt)" ]
+ [ -z "$(cat ${OUTDIR}/not_top_level/content.txt)" ]
+
+ echo === Done ===
+}
+
+
+echo
+echo '***** Tests on the plain file system *****'
+echo
+OUTDIR=${OUTDIR_BASE}/file_system
+do_test
+
+echo
+echo '***** Tests on a git root *****'
+echo
+
+git init
+git add .
+git config user.name "N.O.Body"
+git config user.email "nobody@example.com"
+git commit -m 'Initial commit'
+REPO=$(realpath .git)
+TREE=$(git log -n1 --format='%T')
+
+cat > $CONF <<EOF
+{"repositories": {"": {"workspace_root": ["git tree", "${TREE}", "${REPO}"]}}}
+EOF
+echo
+cat $CONF
+echo
+
+OUTDIR=${OUTDIR_BASE}/git
+do_test
diff --git a/test/end-to-end/target-tests/repo_names.sh b/test/end-to-end/target-tests/repo_names.sh
new file mode 100755
index 00000000..aec5996a
--- /dev/null
+++ b/test/end-to-end/target-tests/repo_names.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+mkdir repo_A
+echo 'A' > repo_A/data.txt
+cat > repo_A/TARGETS <<'EOF'
+{ "hello":
+ { "type": "generic"
+ , "deps": [ "data.txt" ]
+ , "outs": [ "hello.txt" ]
+ , "cmds": [ "echo Hello `cat data.txt` > hello.txt" ]
+ }
+, "use":
+ { "type": "generic"
+ , "deps": [ [ "@" , "other" , "." , "hello" ] ]
+ , "outs": [ "use.txt" ]
+ , "cmds":
+ [ "cat hello.txt > use.txt"
+ , "echo This is A >> use.txt"
+ ]
+ }
+, "back":
+ {"type": "generic"
+ , "deps": [ ["@", "other", ".", "use"] ]
+ , "outs": [ "back.txt"]
+ , "cmds" : [ "echo I am A and I see the following file > back.txt"
+ , "echo >> back.txt"
+ , "cat use.txt >> back.txt"
+ ]
+ }
+}
+EOF
+
+mkdir repo_B
+echo 'B' > repo_B/data.txt
+cat > repo_B/TARGETS <<'EOF'
+{ "hello":
+ { "type": "generic"
+ , "deps": [ "data.txt" ]
+ , "outs": [ "hello.txt" ]
+ , "cmds": [ "echo Hello `cat data.txt` > hello.txt" ]
+ }
+, "use":
+ { "type": "generic"
+ , "deps": [ [ "@" , "other" , "." , "hello" ] ]
+ , "outs": [ "use.txt" ]
+ , "cmds":
+ [ "cat hello.txt > use.txt"
+ , "echo This is B >> use.txt"
+ ]
+ }
+, "back":
+ {"type": "generic"
+ , "deps": [ ["@", "other", ".", "use"] ]
+ , "outs": [ "back.txt"]
+ , "cmds" : [ "echo I am B and I see the following file > back.txt"
+ , "echo >> back.txt"
+ , "cat use.txt >> back.txt"
+ ]
+ }
+}
+EOF
+
+cat > bindings.json <<'EOF'
+{ "repositories" : {"A" : { "workspace_root": ["file", "repo_A"]
+ , "bindings": {"other": "B"}
+ }
+ , "B": { "workspace_root": ["file", "repo_B"]
+ , "bindings": {"other": "A"}
+ }
+ }
+}
+EOF
+
+mkdir -p .root
+
+echo == Building in A ==
+./bin/tool-under-test install -C bindings.json -o . --local-build-root .root --main A . back 2>&1
+cat back.txt
+grep -q 'I am A' back.txt
+grep -q 'This is B' back.txt
+grep -q 'Hello A' back.txt
+rm -f back.txt
+
+echo == Building in B ==
+./bin/tool-under-test install -C bindings.json -o . --local-build-root .root --main B . back 2>&1
+cat back.txt
+grep -q 'I am B' back.txt
+grep -q 'This is A' back.txt
+grep -q 'Hello B' back.txt
diff --git a/test/end-to-end/target-tests/upwards.sh b/test/end-to-end/target-tests/upwards.sh
new file mode 100755
index 00000000..fb700588
--- /dev/null
+++ b/test/end-to-end/target-tests/upwards.sh
@@ -0,0 +1,95 @@
+#!/bin/sh
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+mkdir -p .root
+
+mkdir -p src
+touch src/ROOT
+echo BAD > outside.txt
+
+# Target names that look like upwards references are OK
+
+echo "== legitimate target =="
+
+cat > src/TARGETS <<'EOF'
+{ "it":
+ { "type": "generic"
+ , "cmds": ["cat *.txt > out"]
+ , "outs": ["out"]
+ , "deps": ["../outside.txt"]
+ }
+, "../outside.txt":
+ {"type": "file_gen", "name": "inside.txt", "data": "Everything OK"}
+}
+EOF
+
+./bin/tool-under-test install -o out --workspace-root src \
+ --local-build-root .root . it 2>&1
+
+grep OK out/out
+grep BAD out/out && exit 1 || :
+
+# Upwards references in relative target names are OK;
+# continue the previous test case
+
+echo "== legitimate upwards target reference =="
+
+mkdir -p src/deep
+cat > src/deep/TARGETS <<'EOF'
+{ "OK up":
+ { "type": "generic"
+ , "cmds": ["cat *.txt > out"]
+ , "outs": ["out"]
+ , "deps": [ ["./", "..", "../outside.txt"] ]
+ }
+}
+EOF
+
+
+./bin/tool-under-test install -o out2 --workspace-root src \
+ --local-build-root .root deep 'OK up' 2>&1
+grep OK out2/out
+
+# Upwards refernces and targets outside the repo are not OK
+
+cat > TARGETS <<'EOF'
+{ "outside.txt": {"type": "file_gen", "name": "inside.txt", "data": "BAD"}}
+EOF
+
+for REF in '"../outside.txt"' \
+ '["FILE", ".", "../outside.txt"]' \
+ '["./", "..", "outside.txt"]'
+do echo "== true upwards reference $REF =="
+
+cat > src/TARGETS <<EOF
+{ "it":
+ { "type": "generic"
+ , "cmds": ["cat *.txt > out"]
+ , "outs": ["out"]
+ , "deps": [${REF}]
+ }
+}
+EOF
+
+cat src/TARGETS
+
+./bin/tool-under-test analyse --workspace-root src . it 2>&1 && exit 1 || :
+
+done
+
+
+echo DONE