]> git.corax.cc Git - toolbox/commitdiff
test/queue: Add test cases for several queue functions
authorMatthias Kruk <m@m10k.eu>
Tue, 29 Jun 2021 00:26:08 +0000 (09:26 +0900)
committerMatthias Kruk <m@m10k.eu>
Tue, 29 Jun 2021 00:26:08 +0000 (09:26 +0900)
To ensure that the queue module behaves as intended, test cases are
needed.
This commit adds test cases to test the behavior of the following
functions.
 - queue_init()
 - queue_destroy()
 - queue_put()
 - queue_put_unique()
 - queue_put_file()
 - queue_get()
 - queue_foreach()

test/queue_spec.sh [new file with mode: 0644]

diff --git a/test/queue_spec.sh b/test/queue_spec.sh
new file mode 100644 (file)
index 0000000..b5a3fb7
--- /dev/null
@@ -0,0 +1,848 @@
+#!/bin/bash
+
+# queue_spec.sh - Test cases for the toolbox queue module
+# Copyright (C) 2021 Matthias Kruk
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+if ! . toolbox.sh; then
+       exit 1
+fi
+
+if ! include "array" "queue"; then
+       exit 1
+fi
+
+Describe "queue_init()"
+  It "creates a public queue"
+    _test_queue_init_public() {
+           local tmpdir
+           local queue
+           local ret
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+           ret=1
+
+           if queue_init "$queue" &&
+              [ -d "$queue" ]; then
+                   ret=0
+           fi
+
+           rm -rf "$tmpdir"
+           return "$ret"
+    }
+
+    When call _test_queue_init_public
+    The status should equal 0
+  End
+
+  It "creates a private queue"
+    _test_queue_init_private() {
+           local queue
+           local queue_path
+
+           queue="test$RANDOM"
+           queue_path=$(_queue_get_path "$queue")
+
+           if [[ "$queue_path" == "/" ]]; then
+                   # you never know
+                   return 1
+           fi
+
+           if ! queue_init "$queue"; then
+                   return 1
+           fi
+
+           if ! [ -d "$queue_path" ]; then
+                   return 1
+           fi
+
+           rm -rf "$queue_path"
+           return 0
+    }
+
+    When call _test_queue_init_private
+    The status should equal 0
+  End
+End
+
+Describe "queue_destroy()"
+  It "destroys a public queue"
+    _test_queue_destroy_public() {
+           local tmpdir
+           local queue
+           local ret
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+           ret=1
+
+           if ! queue_init "$queue" ||
+              ! [ -d "$queue" ]; then
+                   return 1
+           fi
+
+           if queue_destroy "$queue" &&
+              ! [ -d "$queue" ]; then
+                   ret=0
+           else
+                   rm -rf "$queue"
+           fi
+
+           return "$ret"
+    }
+
+    When call _test_queue_destroy_public
+    The status should equal 0
+  End
+
+  It "destroys a private queue"
+    _test_queue_destroy_private() {
+           local queue
+           local queue_path
+           local ret
+
+           queue="test$RANDOM"
+           queue_path=$(_queue_get_path "$queue")
+           ret=1
+
+           if [[ "$queue_path" == "/" ]] ||
+              [[ -z "$queue_path" ]]; then
+                   return 1
+           fi
+
+           if ! queue_init "$queue"; then
+                   return 1
+           fi
+
+           if ! [ -d "$queue_path" ]; then
+                   return 1
+           fi
+
+           if queue_destroy "$queue" &&
+              ! [ -d "$queue_path" ]; then
+                   ret=0
+           else
+                   rm -rf "$queue_path"
+           fi
+
+           return "$ret"
+    }
+
+    When call _test_queue_destroy_private
+    The status should equal 0
+  End
+End
+
+Describe "queue_put()"
+  It "adds an item to the queue"
+    _test_queue_put_add() {
+           local tmpdir
+           local queue
+
+           local items_before
+           local items_after
+           local item_new
+           local item
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir"
+                   return 2
+           fi
+
+           items_before=()
+           while read -r item; do
+                   items_before+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           item_new="$RANDOM.item.$RANDOM"
+
+           if ! queue_put "$queue" "$item_new"; then
+                   rm -rf "$tmpdir"
+                   return 3
+           fi
+
+           items_after=()
+           while read -r item; do
+                   items_after+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           rm -rf "$tmpdir"
+
+           items_before+=("$item_new")
+
+           if ! array_same items_before items_after; then
+                   return 4
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_put_add
+    The status should equal 0
+  End
+
+  It "adds an item to the end of the queue"
+    _test_queue_put_append() {
+           local tmpdir
+           local queue
+
+           local items_before
+           local items_after
+           local item_new
+           local item
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir"
+                   return 2
+           fi
+
+           items_before=()
+           while read -r item; do
+                   items_before+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           item_new="$RANDOM.item.$RANDOM"
+
+           if ! queue_put "$queue" "$item_new"; then
+                   rm -rf "$tmpdir"
+                   return 3
+           fi
+
+           items_after=()
+           while read -r item; do
+                   items_after+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           rm -rf "$tmpdir"
+
+           items_before+=("$item_new")
+
+           if ! array_identical items_before items_after; then
+                   return 4
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_put_append
+    The status should equal 0
+  End
+End
+
+Describe "queue_put_unique()"
+  It "adds an item to the queue"
+    _test_queue_put_unique_add() {
+           local tmpdir
+           local queue
+
+           local items_before
+           local items_after
+           local item_new
+           local item
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir"
+                   return 2
+           fi
+
+           items_before=()
+           while read -r item; do
+                   items_before+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           item_new="$RANDOM.item.$RANDOM"
+
+           if ! queue_put_unique "$queue" "$item_new"; then
+                   rm -rf "$tmpdir"
+                   return 3
+           fi
+
+           items_after=()
+           while read -r item; do
+                   items_after+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           rm -rf "$tmpdir"
+
+           items_before+=("$item_new")
+
+           if ! array_same items_before items_after; then
+                   return 4
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_put_unique_add
+    The status should equal 0
+  End
+
+  It "adds an item to the end of the queue"
+    _test_queue_put_unique_append() {
+           local tmpdir
+           local queue
+
+           local items_before
+           local items_after
+           local item_new
+           local item
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir"
+                   return 2
+           fi
+
+           items_before=()
+           while read -r item; do
+                   items_before+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           item_new="$RANDOM.item.$RANDOM"
+
+           if ! queue_put_unique "$queue" "$item_new"; then
+                   rm -rf "$tmpdir"
+                   return 3
+           fi
+
+           items_after=()
+           while read -r item; do
+                   items_after+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           rm -rf "$tmpdir"
+
+           items_before+=("$item_new")
+
+           if ! array_identical items_before items_after; then
+                   return 4
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_put_unique_append
+    The status should equal 0
+  End
+
+  It "does not add the same item twice"
+    _test_queue_put_unique_fail_not_unique() {
+           local tmpdir
+           local queue
+           local items
+           local item
+           local -i num_items
+           local err
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           err=0
+           queue="$tmpdir/queue"
+           item="$RANDOM.item.$RANDOM"
+
+           if ! queue_init "$queue"; then
+                   err=2
+
+           elif ! queue_put_unique "$queue" "$item" ||
+                ! queue_put_unique "$queue" "$item"; then
+                   # If queue_put_unique() succeeds, that means the item
+                   # is in the queue. It does not mean that it was added
+                   # by this call. It may already have been there. Long
+                   # story short, both calls must succeed.
+                   err=3
+
+           elif ! items=$(queue_foreach "$queue" echo); then
+                   err=4
+
+           elif [[ -z "$items" ]]; then
+                   err=5
+
+           elif ! num_items=$(wc -l <<< "$items"); then
+                   err=6
+
+           elif (( num_items != 1 )); then
+                   err=7
+           fi
+
+           rm -rf "$tmpdir"
+           return "$err"
+    }
+
+    When call _test_queue_put_unique_fail_not_unique
+    The status should equal 0
+  End
+End
+
+Describe "queue_put_file()"
+  It "adds a file to the queue"
+    _test_queue_put_file_add() {
+           local tmpdir
+           local queue
+
+           local items_before
+           local items_after
+           local item_new
+           local item_data
+           local item_last
+           local enqueued_data
+           local item
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           if ! item_new=$(mktemp); then
+                   rmdir "$tmpdir"
+                   return 2
+           fi
+
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir" "$item_new"
+                   return 3
+           fi
+
+           items_before=()
+           while read -r item; do
+                   items_before+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           item_data="$RANDOM.item.$RANDOM"
+           if ! echo "$item_data" > "$item_new"; then
+                   rm -rf "$tmpdir" "$item_new"
+                   return 4
+           fi
+
+           if ! queue_put_file "$queue" "$item_new"; then
+                   rm -rf "$tmpdir" "$item_new"
+                   return 5
+           fi
+
+           items_after=()
+           item_last=""
+           while read -r item; do
+                   items_after+=("$item")
+                   item_last="$item"
+           done < <(queue_foreach "$queue" echo)
+
+           if ! enqueued_data=$(< "$queue/files/${item_new##*/}"); then
+                   rm -rf "$tmpdir"
+                   return 6
+           fi
+
+           rm -rf "$tmpdir"
+
+           if [[ "$enqueued_data" != "$item_data" ]]; then
+                   return 7
+           fi
+
+           items_before+=("$item_last")
+
+           if ! array_same items_before items_after; then
+                   return 8
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_put_file_add
+    The status should equal 0
+  End
+
+  It "adds an item to the end of the queue"
+    _test_queue_put_file_append() {
+           local tmpdir
+           local queue
+
+           local items_before
+           local items_after
+           local item_new
+           local item_data
+           local item_last
+           local enqueued_data
+           local item
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           if ! item_new=$(mktemp); then
+                   rmdir "$tmpdir"
+                   return 2
+           fi
+
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir" "$item_new"
+                   return 3
+           fi
+
+           items_before=()
+           while read -r item; do
+                   items_before+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           item_data="$RANDOM.item.$RANDOM"
+           if ! echo "$item_data" > "$item_new"; then
+                   rm -rf "$tmpdir" "$item_new"
+                   return 4
+           fi
+
+           if ! queue_put_file "$queue" "$item_new"; then
+                   rm -rf "$tmpdir" "$item_new"
+                   return 5
+           fi
+
+           items_after=()
+           item_last=""
+           while read -r item; do
+                   items_after+=("$item")
+                   item_last="$item"
+           done < <(queue_foreach "$queue" echo)
+
+           if ! enqueued_data=$(< "$queue/files/${item_new##*/}"); then
+                   rm -rf "$tmpdir"
+                   return 6
+           fi
+
+           rm -rf "$tmpdir"
+
+           if [[ "$enqueued_data" != "$item_data" ]]; then
+                   return 7
+           fi
+
+           items_before+=("$item_last")
+
+           if ! array_identical items_before items_after; then
+                   return 8
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_put_file_append
+    The status should equal 0
+  End
+
+  It "does not add a file with the same name twice"
+    _test_queue_put_file_fail_not_unique() {
+           local tmpdir
+           local queue
+           local items
+           local item
+           local -i num_items
+           local err
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           err=0
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   err=2
+
+           elif ! echo "$RANDOM.item.$RANDOM" > "$tmpdir/file"; then
+                   err=3
+
+           elif ! queue_put_file "$queue" "$tmpdir/file"; then
+                   err=4
+
+           elif ! echo "$RANDOM.item.$RANDOM" > "$tmpdir/file"; then
+                   err=5
+
+           elif queue_put_file "$queue" "$tmpdir/file"; then
+                   err=6
+
+           elif ! items=$(queue_foreach "$queue" echo); then
+                   err=7
+
+           elif [[ -z "$items" ]]; then
+                   err=8
+
+           elif ! num_items=$(wc -l <<< "$items"); then
+                   err=9
+
+           elif (( num_items != 1 )); then
+                   err=10
+           fi
+
+           rm -rf "$tmpdir"
+           return "$err"
+    }
+
+    When call _test_queue_put_file_fail_not_unique
+    The status should equal 0
+  End
+End
+
+Describe "queue_get()"
+  It "gets an item from a queue"
+    _test_queue_get_simple() {
+           local tmpdir
+           local queue
+           local data_enqueued
+           local data_dequeued
+           local err
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+           data_enqueued="$RANDOM.data.$RANDOM"
+           err=0
+
+           if ! queue_init "$queue"; then
+                   err=2
+
+           elif ! queue_put "$queue" "$data_enqueued"; then
+                   err=3
+
+           elif ! data_dequeued=$(queue_get "$queue" 0); then
+                   err=4
+
+           elif [[ "$data_enqueued" != "$data_dequeued" ]]; then
+                   err=5
+           fi
+
+           rm -rf "$tmpdir"
+           return "$err"
+    }
+
+    When call _test_queue_get_simple
+    The status should equal 0
+  End
+
+  It "preserves the order of items"
+    _test_queue_get_order() {
+           local tmpdir
+           local queue
+           local data_enqueued
+           local data_dequeued
+           local err
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           queue="$tmpdir/queue"
+           data_enqueued=(1 2 3)
+           err=0
+
+           if ! queue_init "$queue"; then
+                   err=2
+
+           elif ! queue_put "$queue" "${data_enqueued[0]}" ||
+                ! queue_put "$queue" "${data_enqueued[1]}" ||
+                ! queue_put "$queue" "${data_enqueued[2]}"; then
+                   err=3
+
+           elif ! data_dequeued+=("$(queue_get "$queue")") ||
+                ! data_dequeued+=("$(queue_get "$queue")") ||
+                ! data_dequeued+=("$(queue_get "$queue")"); then
+                   err=4
+
+           elif ! array_identical data_enqueued data_dequeued; then
+                   err=5
+           fi
+
+           rm -rf "$tmpdir"
+           return "$err"
+    }
+
+    When call _test_queue_get_order
+    The status should equal 0
+  End
+
+  # FIXME: Add testcase to test queue_get() behavior when timeout > 0
+  # FIXME: Add testcase to test queue_get() behavior when timeout = 0
+  # FIXME: Add testcase to test queue_get() behavior when timeout = -1
+
+End
+
+# Describe "queue_get_file()"
+
+  # FIXME: Add testcase to test queue_get_file() primary behavior
+  # FIXME: Add testcase to test if queue_get_file() preserves the data order
+  # FIXME: Add testcase to test queue_get_file() behavior when timeout > 0
+  # FIXME: Add testcase to test queue_get_file() behavior when timeout = 0
+  # FIXME: Add testcase to test queue_get_file() behavior when timeout = -1
+
+# End
+
+Describe "queue_foreach()"
+  It "does not print anything on an empty queue"
+    _test_queue_foreach_empty() {
+           local tmpdir
+           local queue
+           local err
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           err=2
+           queue="$tmpdir/queue"
+
+           if ! queue_init "$queue"; then
+                   err=3
+
+           elif ! queue_foreach "$queue" echo "anything"; then
+                   err=4
+
+           else
+                   err=0
+           fi
+
+           rm -rf "$tmpdir"
+           return "$err"
+    }
+
+    When call _test_queue_foreach_empty
+    The status should equal 0
+  End
+
+  It "calls the callback for each element"
+    _test_queue_foreach_call_foreach() {
+           local tmpdir
+           local queue
+           local err
+           local items
+           local item
+           local contents
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           err=2
+           queue="$tmpdir/queue"
+           items=("hello" "world" "foobar")
+           contents=()
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir"
+                   return 3
+           fi
+
+           for item in "${items[@]}"; do
+                   if ! queue_put "$queue" "$item"; then
+                           rm -rf "$tmpdir"
+                           return 4
+                   fi
+           done
+
+           while read -r item; do
+                   contents+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           rm -rf "$tmpdir"
+
+           if ! array_same items contents; then
+                   return 1
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_foreach_call_foreach
+    The status should equal 0
+  End
+
+  It "preserves the order of elements"
+    _test_queue_foreach_call_order() {
+           local tmpdir
+           local queue
+           local err
+           local items
+           local item
+           local contents
+
+           if ! tmpdir=$(mktemp -d); then
+                   return 1
+           fi
+
+           err=2
+           queue="$tmpdir/queue"
+           items=("hello" "world" "foobar")
+           contents=()
+
+           if ! queue_init "$queue"; then
+                   rm -rf "$tmpdir"
+                   return 3
+           fi
+
+           for item in "${items[@]}"; do
+                   if ! queue_put "$queue" "$item"; then
+                           rm -rf "$tmpdir"
+                           return 4
+                   fi
+           done
+
+           while read -r item; do
+                   contents+=("$item")
+           done < <(queue_foreach "$queue" echo)
+
+           rm -rf "$tmpdir"
+
+           if ! array_identical items contents; then
+                   return 1
+           fi
+
+           return 0
+    }
+
+    When call _test_queue_foreach_call_order
+    The status should equal 0
+  End
+
+
+End