diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.json b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.json index 0725f864a247..d596e9294d49 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.json +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.json @@ -11,7 +11,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test1.txt", + "path": ".*/test1/file.txt", "requested-permissions": [ "write" ] } }, @@ -20,7 +20,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test2.txt", + "path": ".*/test2/file.txt", "requested-permissions": [ "write" ] } }, @@ -29,7 +29,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test3.txt", + "path": ".*/test3/file.txt", "requested-permissions": [ "write" ] } }, @@ -38,7 +38,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test4.txt", + "path": ".*/test4/file.txt", "requested-permissions": [ "write" ] } }, @@ -46,7 +46,7 @@ "action": "allow", "lifespan": "forever", "constraints": { - "path-pattern": "${BASE_PATH}/test*.txt", + "path-pattern": "${BASE_PATH}/test?/file.txt", "permissions": [ "write" ] } } diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.sh b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.sh index d20a679a1bf3..06bc01dd6e5e 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.sh +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_allow.sh @@ -1,24 +1,54 @@ #!/usr/bin/sh # A test that replying with allow forever actions previous matching prompts. +# +# When creating a new file is blocked on a reply to a request prompt, the +# directory in which the file will be created is locked from other writes. +# Thus, we can't queue up multiple outstanding writes on files in the same +# directory. Instead, we must write files in different directories in order +# for this test to succeed. TEST_DIR="$1" -WRITABLE="$(snap run --shell prompting-client.scripted -c "cd ~; pwd")/$(basename "$TEST_DIR")" +WRITABLE="$(snap run --shell prompting-client.scripted -c 'cd ~; pwd')/$(basename "$TEST_DIR")" snap run --shell prompting-client.scripted -c "mkdir -p $WRITABLE" -for name in test1.txt test2.txt test3.txt ; do +for dir in test1 test2 test3 ; do + mkdir -p "${TEST_DIR}/${dir}" + name="${dir}/file.txt" echo "Attempt to write $name in the background" - snap run --shell prompting-client.scripted -c "echo started > ${WRITABLE}/${name}; echo $name is written > ${TEST_DIR}/${name}" & - timeout 10 sh -c "while ! [ -f '${WRITABLE}/${name}' ] ; do sleep 0.1 ; done" + snap run --shell prompting-client.scripted -c "touch ${WRITABLE}/${dir}-started; echo $name is written > ${TEST_DIR}/${name}; touch ${WRITABLE}/${dir}-finished" & + if ! timeout 10 sh -c "while ! [ -f '${WRITABLE}/${dir}-started' ] ; do sleep 0.1 ; done" ; then + echo "failed to start write of $name within timeout period" + exit 1 + fi +done + +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has not yet finished" + if [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name finished before write for test4/file.txt started" + exit 1 + fi done -echo "Attempt to write test4.txt (for which client will reply)" -snap run --shell prompting-client.scripted -c "echo test4.txt is written > ${TEST_DIR}/test4.txt" +echo "Attempt to write test4/file.txt (for which client will reply)" +mkdir -p "${TEST_DIR}/test4" +snap run --shell prompting-client.scripted -c "echo test4/file.txt is written > ${TEST_DIR}/test4/file.txt" # Wait for the client to write its result and exit timeout 5 sh -c 'while pgrep -f "prompting-client-scripted" > /dev/null; do sleep 0.1; done' +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has finished" + if ! [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name did not finish after client replied" + exit 1 + fi +done + CLIENT_OUTPUT="$(cat "${TEST_DIR}/result")" if [ "$CLIENT_OUTPUT" != "success" ] ; then @@ -27,7 +57,8 @@ if [ "$CLIENT_OUTPUT" != "success" ] ; then exit 1 fi -for name in test1.txt test2.txt test3.txt test4.txt; do +for dir in test1 test2 test3 test4; do + name="${dir}/file.txt" TEST_OUTPUT="$(cat "${TEST_DIR}/${name}")" if [ "$TEST_OUTPUT" != "$name is written" ] ; then echo "file creation failed for $name" diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.json b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.json index cf106ebddb4c..d05a841fb0eb 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.json +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.json @@ -11,7 +11,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test1.txt", + "path": ".*/test1/file.txt", "requested-permissions": [ "write" ] } }, @@ -20,7 +20,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test2.txt", + "path": ".*/test2/file.txt", "requested-permissions": [ "write" ] } }, @@ -29,7 +29,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test3.txt", + "path": ".*/test3/file.txt", "requested-permissions": [ "write" ] } }, @@ -38,7 +38,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test4.txt", + "path": ".*/test4/file.txt", "requested-permissions": [ "write" ] } }, @@ -46,7 +46,7 @@ "action": "deny", "lifespan": "forever", "constraints": { - "path-pattern": "${BASE_PATH}/test*.txt", + "path-pattern": "${BASE_PATH}/test?/file.txt", "permissions": [ "write" ] } } diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.sh b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.sh index 3782cf541018..174183588bbe 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.sh +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_actioned_by_other_pid_always_deny.sh @@ -1,24 +1,54 @@ #!/usr/bin/sh # A test that replying with allow forever actions previous matching prompts. +# +# When creating a new file is blocked on a reply to a request prompt, the +# directory in which the file will be created is locked from other writes. +# Thus, we can't queue up multiple outstanding writes on files in the same +# directory. Instead, we must write files in different directories in order +# for this test to succeed. TEST_DIR="$1" -WRITABLE="$(snap run --shell prompting-client.scripted -c "cd ~; pwd")/$(basename "$TEST_DIR")" +WRITABLE="$(snap run --shell prompting-client.scripted -c 'cd ~; pwd')/$(basename "$TEST_DIR")" snap run --shell prompting-client.scripted -c "mkdir -p $WRITABLE" -for name in test1.txt test2.txt test3.txt ; do +for dir in test1 test2 test3 ; do + mkdir -p "${TEST_DIR}/${dir}" + name="${dir}/file.txt" echo "Attempt to write $name in the background" - snap run --shell prompting-client.scripted -c "echo started > ${WRITABLE}/${name}; echo $name is written > ${TEST_DIR}/${name}" & - timeout 10 sh -c "while ! [ -f '${WRITABLE}/${name}' ] ; do sleep 0.1 ; done" + snap run --shell prompting-client.scripted -c "touch ${WRITABLE}/${dir}-started; echo $name is written > ${TEST_DIR}/${name}; touch ${WRITABLE}/${dir}-finished" & + if ! timeout 10 sh -c "while ! [ -f '${WRITABLE}/${dir}-started' ] ; do sleep 0.1 ; done" ; then + echo "failed to start write of $name within timeout period" + exit 1 + fi +done + +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has not yet finished" + if [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name finished before write for test4/file.txt started" + exit 1 + fi done -echo "Attempt to write test4.txt (for which client will reply)" -snap run --shell prompting-client.scripted -c "echo test4.txt is written > ${TEST_DIR}/test4.txt" +echo "Attempt to write test4/file.txt (for which client will reply)" +mkdir -p "${TEST_DIR}/test4" +snap run --shell prompting-client.scripted -c "echo test4/file.txt is written > ${TEST_DIR}/test4/file.txt" # Wait for the client to write its result and exit timeout 5 sh -c 'while pgrep -f "prompting-client-scripted" > /dev/null; do sleep 0.1; done' +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has finished" + if ! [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name did not finish after client replied" + exit 1 + fi +done + CLIENT_OUTPUT="$(cat "${TEST_DIR}/result")" if [ "$CLIENT_OUTPUT" != "success" ] ; then @@ -27,7 +57,8 @@ if [ "$CLIENT_OUTPUT" != "success" ] ; then exit 1 fi -for name in test1.txt test2.txt test3.txt test4.txt; do +for dir in test1 test2 test3 test4; do + name="${dir}/file.txt" if [ -f "${TEST_DIR}/${name}" ] ; then echo "file creation unexpectedly succeeded for $name" exit 1 diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.json b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.json index 23026c399a30..00da5b1d373a 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.json +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.json @@ -11,7 +11,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test1.txt", + "path": ".*/test1/file.txt", "requested-permissions": [ "write" ] } }, @@ -20,7 +20,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test2.txt", + "path": ".*/test2/file.txt", "requested-permissions": [ "write" ] } }, @@ -29,7 +29,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test3.txt", + "path": ".*/test3/file.txt", "requested-permissions": [ "write" ] } }, @@ -38,7 +38,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test4.txt", + "path": ".*/test4/file.txt", "requested-permissions": [ "write" ] } }, @@ -46,7 +46,7 @@ "action": "allow", "lifespan": "single", "constraints": { - "path-pattern": "${BASE_PATH}/test*.txt", + "path-pattern": "${BASE_PATH}/test?/file.txt", "permissions": [ "write" ] } } @@ -54,7 +54,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test4.txt", + "path": ".*/test4/file.txt", "requested-permissions": [ "write" ] } }, @@ -62,7 +62,7 @@ "action": "allow", "lifespan": "single", "constraints": { - "path-pattern": "${BASE_PATH}/test*.txt", + "path-pattern": "${BASE_PATH}/test*/file.txt", "permissions": [ "write" ] } } @@ -70,7 +70,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test5.txt", + "path": ".*/test5/file.txt", "requested-permissions": [ "write" ] } }, @@ -78,7 +78,7 @@ "action": "deny", "lifespan": "forever", "constraints": { - "path-pattern": "${BASE_PATH}/test*.txt", + "path-pattern": "${BASE_PATH}/test*/file.txt", "permissions": [ "write" ] } } diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.sh b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.sh index 6c909ee376a8..fad305af23a9 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.sh +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_allow.sh @@ -1,27 +1,67 @@ #!/usr/bin/sh -# A test that replying with allow forever actions previous matching prompts. +# A test that replying with allow once does not action previous matching prompts. +# +# When creating a new file is blocked on a reply to a request prompt, the +# directory in which the file will be created is locked from other writes. +# Thus, we can't queue up multiple outstanding writes on files in the same +# directory. Instead, we must write files in different directories in order +# for this test to succeed. TEST_DIR="$1" -WRITABLE="$(snap run --shell prompting-client.scripted -c "cd ~; pwd")/$(basename "$TEST_DIR")" +WRITABLE="$(snap run --shell prompting-client.scripted -c 'cd ~; pwd')/$(basename "$TEST_DIR")" snap run --shell prompting-client.scripted -c "mkdir -p $WRITABLE" -for name in test1.txt test2.txt test3.txt ; do +for dir in test1 test2 test3 ; do + mkdir -p "${TEST_DIR}/${dir}" + name="${dir}/file.txt" echo "Attempt to write $name in the background" - snap run --shell prompting-client.scripted -c "echo started > ${WRITABLE}/${name}; echo $name is written > ${TEST_DIR}/${name}" & - timeout 10 sh -c "while ! [ -f '${WRITABLE}/${name}' ] ; do sleep 0.1 ; done" + snap run --shell prompting-client.scripted -c "touch ${WRITABLE}/${dir}-started; echo $name is written > ${TEST_DIR}/${name}; touch ${WRITABLE}/${dir}-finished" & + if ! timeout 10 sh -c "while ! [ -f '${WRITABLE}/${dir}-started' ] ; do sleep 0.1 ; done" ; then + echo "failed to start write of $name within timeout period" + exit 1 + fi done -echo "Attempt to write test4.txt (for which client will reply allow single)" -snap run --shell prompting-client.scripted -c "echo test4.txt is written > ${TEST_DIR}/test4.txt" +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has not yet finished" + if [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name finished before write for test4/file.txt started" + exit 1 + fi +done + +echo "Attempt to write test4/file.txt (for which client will reply allow single)" +mkdir -p "${TEST_DIR}/test4" +snap run --shell prompting-client.scripted -c "echo test4/file.txt is written > ${TEST_DIR}/test4/file.txt" + +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name was not actioned by reply for test4/file.txt" + if [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name finished before write for test5/file.txt started" + exit 1 + fi +done -echo "Attempt to write test5.txt (for which client will reply deny forever)" -snap run --shell prompting-client.scripted -c "echo test5.txt is written > ${TEST_DIR}/test5.txt" +echo "Attempt to write test5/file.txt (for which client will reply deny forever)" +mkdir -p "${TEST_DIR}/test5" +snap run --shell prompting-client.scripted -c "echo test5/file.txt is written > ${TEST_DIR}/test5/file.txt" # Wait for the client to write its result and exit timeout 5 sh -c 'while pgrep -f "prompting-client-scripted" > /dev/null; do sleep 0.1; done' +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has finished" + if ! [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name did not finish after client replied" + exit 1 + fi +done + CLIENT_OUTPUT="$(cat "${TEST_DIR}/result")" if [ "$CLIENT_OUTPUT" != "success" ] ; then @@ -30,13 +70,14 @@ if [ "$CLIENT_OUTPUT" != "success" ] ; then exit 1 fi -TEST_OUTPUT="$(cat "${TEST_DIR}/test4.txt")" -if [ "$TEST_OUTPUT" != "test4.txt is written" ] ; then - echo "file creation failed for test4.txt" +TEST_OUTPUT="$(cat "${TEST_DIR}/test4/file.txt")" +if [ "$TEST_OUTPUT" != "test4/file.txt is written" ] ; then + echo "file creation failed for test4/file.txt" exit 1 fi -for name in test1.txt test2.txt test3.txt test5.txt; do +for dir in test1 test2 test3 test5; do + name="${dir}/file.txt" if [ -f "${TEST_DIR}/${name}" ] ; then echo "file creation unexpectedly succeeded for $name" exit 1 diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.json b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.json index 91b814ef2d51..72d2f5cad3f6 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.json +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.json @@ -11,7 +11,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test1.txt", + "path": ".*/test1/file.txt", "requested-permissions": [ "write" ] } }, @@ -20,7 +20,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test2.txt", + "path": ".*/test2/file.txt", "requested-permissions": [ "write" ] } }, @@ -29,7 +29,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test3.txt", + "path": ".*/test3/file.txt", "requested-permissions": [ "write" ] } }, @@ -38,7 +38,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test4.txt", + "path": ".*/test4/file.txt", "requested-permissions": [ "write" ] } }, @@ -46,7 +46,7 @@ "action": "deny", "lifespan": "single", "constraints": { - "path-pattern": "${BASE_PATH}/test*.txt", + "path-pattern": "${BASE_PATH}/test*/file.txt", "permissions": [ "write" ] } } @@ -54,7 +54,7 @@ { "prompt-filter": { "constraints": { - "path": ".*/test5.txt", + "path": ".*/test5/file.txt", "requested-permissions": [ "write" ] } }, @@ -62,7 +62,7 @@ "action": "allow", "lifespan": "forever", "constraints": { - "path-pattern": "${BASE_PATH}/test*.txt", + "path-pattern": "${BASE_PATH}/test*/file.txt", "permissions": [ "write" ] } } diff --git a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.sh b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.sh index be6ac7a7a6d0..94ff56978fb9 100644 --- a/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.sh +++ b/tests/main/apparmor-prompting-integration-tests/create_multiple_not_actioned_by_other_pid_single_deny.sh @@ -1,35 +1,72 @@ #!/usr/bin/sh -# A test that replying with allow forever actions previous matching prompts. +# A test that replying with deny once does not action previous matching prompts. +# +# When creating a new file is blocked on a reply to a request prompt, the +# directory in which the file will be created is locked from other writes. +# Thus, we can't queue up multiple outstanding writes on files in the same +# directory. Instead, we must write files in different directories in order +# for this test to succeed. TEST_DIR="$1" -WRITABLE="$(snap run --shell prompting-client.scripted -c "cd ~; pwd")/$(basename "$TEST_DIR")" +WRITABLE="$(snap run --shell prompting-client.scripted -c 'cd ~; pwd')/$(basename "$TEST_DIR")" snap run --shell prompting-client.scripted -c "mkdir -p $WRITABLE" -for name in test1.txt test2.txt test3.txt ; do +for dir in test1 test2 test3 ; do + mkdir -p "${TEST_DIR}/${dir}" + name="${dir}/file.txt" echo "Attempt to write $name in the background" - snap run --shell prompting-client.scripted -c "echo started > ${WRITABLE}/${name}; echo $name is written > ${TEST_DIR}/${name}" & - timeout 10 sh -c "while ! [ -f '${WRITABLE}/${name}' ] ; do sleep 0.1 ; done" + snap run --shell prompting-client.scripted -c "touch ${WRITABLE}/${dir}-started; echo $name is written > ${TEST_DIR}/${name}; touch ${WRITABLE}/${dir}-finished" & + if ! timeout 10 sh -c "while ! [ -f '${WRITABLE}/${dir}-started' ] ; do sleep 0.1 ; done" ; then + echo "failed to start write of $name within timeout period" + exit 1 + fi +done + +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has not yet finished" + if [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name finished before write for test4/file.txt started" + exit 1 + fi done -echo "Attempt to write test4.txt (for which client will reply deny single)" -snap run --shell prompting-client.scripted -c "echo test4.txt is written > ${TEST_DIR}/test4.txt" +echo "Attempt to write test4/file.txt (for which client will reply deny single)" +mkdir -p "${TEST_DIR}/test4" +snap run --shell prompting-client.scripted -c "echo test4/file.txt is written > ${TEST_DIR}/test4/file.txt" echo "Check that original files have not yet been written" -for name in test1.txt test2.txt test3.txt; do +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" if [ -f "${TEST_DIR}/${name}" ] ; then echo "file creation unexpectedly succeeded early for $name" exit 1 fi + echo "Check that write for $name was not actioned by reply for test4/file.txt" + if [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name finished before write for test5/file.txt started" + exit 1 + fi done -echo "Attempt to write test5.txt (for which client will reply allow forever)" -snap run --shell prompting-client.scripted -c "echo test5.txt is written > ${TEST_DIR}/test5.txt" +echo "Attempt to write test5/file.txt (for which client will reply allow forever)" +mkdir -p "${TEST_DIR}/test5" +snap run --shell prompting-client.scripted -c "echo test5/file.txt is written > ${TEST_DIR}/test5/file.txt" # Wait for the client to write its result and exit timeout 5 sh -c 'while pgrep -f "prompting-client-scripted" > /dev/null; do sleep 0.1; done' +for dir in test1 test2 test3 ; do + name="${dir}/file.txt" + echo "Check that write for $name has finished" + if ! [ -f "${WRITABLE}/${dir}-finished" ] ; then + echo "write of $name did not finish after client replied" + exit 1 + fi +done + CLIENT_OUTPUT="$(cat "${TEST_DIR}/result")" if [ "$CLIENT_OUTPUT" != "success" ] ; then @@ -38,12 +75,13 @@ if [ "$CLIENT_OUTPUT" != "success" ] ; then exit 1 fi -if [ -f "${TEST_DIR}/test4.txt" ] ; then - echo "file creation unexpectedly succeeded for test4.txt" +if [ -f "${TEST_DIR}/test4/file.txt" ] ; then + echo "file creation unexpectedly succeeded for test4/file.txt" exit 1 fi -for name in test1.txt test2.txt test3.txt test5.txt; do +for dir in test1 test2 test3 test5; do + name="${dir}/file.txt" TEST_OUTPUT="$(cat "${TEST_DIR}/${name}")" if [ "$TEST_OUTPUT" != "$name is written" ] ; then echo "file creation failed for $name"