]> git.corax.cc Git - toolbox/commitdiff
include/uipc: Implement uipc module as extension of ipc module
authorMatthias Kruk <m@m10k.eu>
Mon, 9 Jan 2023 09:20:41 +0000 (18:20 +0900)
committerMatthias Kruk <m@m10k.eu>
Mon, 9 Jan 2023 09:23:01 +0000 (18:23 +0900)
The uipc module contains several functions that are identical with
their ipc-counterpart. This kind of code-duplication can be avoided
using the new interface/implements mechanism.

This commit modifies the uipc module so that it extends the interface
provided by the ipc module, reusing methods of the ipc module where
possible.

include/uipc.sh
test/uipc_spec.sh

index 4b998abe0e6688206875afe5981d78096e3ec304..ccc0b4755d6b9f9e1d29363a1e31f21bcf7d23fd 100644 (file)
@@ -31,7 +31,11 @@ __init() {
        return 0
 }
 
-_uipc_msg_get() {
+uipc_get_root() {
+       echo "$__uipc_root"
+}
+
+uipc_msg_get() {
        local msg="$1"
        local field="$2"
 
@@ -50,7 +54,7 @@ _uipc_msg_version_supported() {
 
        local -i version
 
-       if ! version=$(uipc_msg_get_version "$msg"); then
+       if ! version=$(ipc_msg_get_version "$msg"); then
                log_error "Could not get version from message"
                return 1
        fi
@@ -85,7 +89,7 @@ EOF
        return 0
 }
 
-_uipc_msg_new() {
+uipc_msg_new() {
        local source="$1"
        local destination="$2"
        local data="$3"
@@ -125,319 +129,3 @@ _uipc_msg_new() {
 
        return 1
 }
-
-uipc_msg_get_version() {
-       local msg="$1"
-
-       local version
-
-       if ! version=$(_uipc_msg_get "$msg" "version"); then
-               return 1
-       fi
-
-       echo "$version"
-       return 0
-}
-
-uipc_msg_get_source() {
-       local msg="$1"
-
-       local src
-
-       if ! src=$(_uipc_msg_get "$msg" "source"); then
-               return 1
-       fi
-
-       echo "$src"
-       return 0
-}
-
-uipc_msg_get_destination() {
-       local msg="$1"
-
-       local dst
-
-       if ! dst=$(_uipc_msg_get "$msg" "destination"); then
-               return 1
-       fi
-
-       echo "$dst"
-       return 0
-}
-
-uipc_msg_get_user() {
-       local msg="$1"
-
-       local user
-
-       if ! user=$(_uipc_msg_get "$msg" "user"); then
-               return 1
-       fi
-
-       echo "$user"
-       return 0
-}
-
-uipc_msg_get_timestamp() {
-       local msg="$1"
-
-       local timestamp
-
-       if ! timestamp=$(_uipc_msg_get "$msg" "timestamp"); then
-               return 1
-       fi
-
-       echo "$timestamp"
-       return 0
-}
-
-uipc_msg_get_data() {
-       local msg="$1"
-
-       local data
-       local data_raw
-
-       if ! data=$(_uipc_msg_get "$msg" "data"); then
-               return 1
-       fi
-
-       if ! data_raw=$(ipc_decode <<< "$data"); then
-               return 1
-       fi
-
-       echo "$data_raw"
-       return 0
-}
-
-uipc_msg_get_topic() {
-       local msg="$1"
-
-       local topic
-
-       if ! topic=$(_uipc_msg_get "$msg" "topic"); then
-               return 1
-       fi
-
-       echo "$topic"
-       return 0
-}
-
-uipc_endpoint_open() {
-       local name="$1"
-
-       local endpoint
-
-       if [[ -z "$name" ]]; then
-               local self
-
-               self="${0##*/}"
-               name="priv/$USER.$self.$$.$(date +"%s").$RANDOM"
-       fi
-
-       endpoint="$__uipc_root/$name"
-
-       if ! [ -d "$endpoint" ]; then
-               if ! mkdir -p "$endpoint/subscriptions"; then
-                       return 1
-               fi
-
-               if ! queue_init "$endpoint/queue" ||
-                  ! echo "$USER" > "$endpoint/owner" ||
-                  ! chmod -R g+rwxs "$endpoint"; then
-                       if ! rm -rf "$endpoint"; then
-                               log_error "Could not clean up $endpoint"
-                       fi
-
-                       return 1
-               fi
-       fi
-
-       echo "$name"
-       return 0
-}
-
-uipc_endpoint_close() {
-       local name="$1"
-
-       local endpoint
-       local subscription
-
-       endpoint="$__uipc_root/$name"
-
-       if ! queue_destroy "$endpoint/queue"; then
-               return 1
-       fi
-
-       while read -r subscription; do
-               if ! rm "$subscription/${name//\//_}"; then
-                       log_error "Could not unsubscribe $name from $subscription"
-               fi
-       done < <(find "$endpoint/subscriptions" -mindepth 1 -maxdepth 1 -type l)
-
-       if ! rm -rf "$endpoint"; then
-               return 1
-       fi
-
-       return 0
-}
-
-_uipc_endpoint_put() {
-       local endpoint="$1"
-       local msg="$2"
-
-       local queue
-
-       queue="$__uipc_root/$endpoint/queue"
-
-       if ! queue_put "$queue" "$msg"; then
-               return 1
-       fi
-
-       return 0
-}
-
-uipc_endpoint_send() {
-       local source="$1"
-       local destination="$2"
-       local data="$3"
-       local topic="$4"
-
-       local msg
-
-       if ! msg=$(_uipc_msg_new "$source" "$destination" "$data" "$topic"); then
-               return 1
-       fi
-
-       if ! _uipc_endpoint_put "$destination" "$msg"; then
-               return 1
-       fi
-
-       return 0
-}
-
-uipc_endpoint_recv() {
-       local endpoint="$1"
-       local -i timeout="${2--1}"
-
-       local queue
-       local msg
-
-       queue="$__uipc_root/$endpoint/queue"
-
-       if ! msg=$(queue_get "$queue" "$timeout"); then
-               return 1
-       fi
-
-       echo "$msg"
-       return 0
-}
-
-_uipc_endpoint_topic_create() {
-       local topic="$1"
-
-       if ! mkdir -p "$__uipc_pubsub_root/$topic"; then
-               return 1
-       fi
-
-       return 0
-}
-
-_uipc_endpoint_topic_subscribe() {
-       local endpoint="$1"
-       local topic="$2"
-
-       local topicdir
-       local subscription
-
-       topicdir="$__uipc_pubsub_root/$topic"
-       subscription="$topicdir/${endpoint//\//_}"
-
-       if ! ln -sf "$endpoint" "$subscription"; then
-               return 1
-       fi
-
-       if ! ln -sfn "$topicdir" "$__uipc_root/$endpoint/subscriptions/$topic"; then
-               rm -f "$subscription"
-               return 1
-       fi
-
-       return 0
-}
-
-_uipc_endpoint_topic_get_subscribers() {
-       local topic="$1"
-
-       local subscription
-
-       while read -r subscription; do
-               local subscriber
-
-               if ! subscriber=$(readlink "$subscription"); then
-                       continue
-               fi
-
-               echo "$subscriber"
-       done < <(find "$__uipc_pubsub_root/$topic" -mindepth 1 -maxdepth 1 -type l)
-
-       return 0
-}
-
-uipc_endpoint_subscribe() {
-       local endpoint="$1"
-       local topic="$2"
-
-       if ! _uipc_endpoint_topic_create "$topic"; then
-               return 1
-       fi
-
-       if ! _uipc_endpoint_topic_subscribe "$endpoint" "$topic"; then
-               return 1
-       fi
-
-       return 0
-}
-
-uipc_endpoint_publish() {
-       local endpoint="$1"
-       local topic="$2"
-       local message="$3"
-
-       local subscriber
-
-       if ! _uipc_endpoint_topic_create "$topic"; then
-               return 1
-       fi
-
-       while read -r subscriber; do
-               uipc_endpoint_send "$endpoint" "$subscriber" "$message" "$topic"
-       done < <(_uipc_endpoint_topic_get_subscribers "$topic")
-
-       return 0
-}
-
-_uipc_endpoint_foreach_message_helper() {
-       local msg="$1"
-       local endpoint="$2"
-       local func="$3"
-       local args=("${@:4}")
-
-       "$func" "$endpoint" "$msg" "${args[@]}"
-       return "$?"
-}
-
-uipc_endpoint_foreach_message() {
-       local endpoint="$1"
-       local func="$2"
-       local args=("${@:3}")
-
-       local queue
-
-       queue="$__uipc_root/$endpoint/queue"
-
-       if ! queue_foreach "$queue" _uipc_endpoint_foreach_message_helper \
-                          "$endpoint" "$func" "${args[@]}"; then
-               return 1
-       fi
-
-       return 0
-}
index d11c4944f2d9934c11c0a20dbdf6821e2c23ba5b..b7bf921600db81f4c1a543a44f1c6b5fb6018553 100644 (file)
@@ -27,6 +27,32 @@ cleanup() {
        return 0
 }
 
+Describe "ipc_get_root()"
+  It "returns /var/lib/toolbox/uipc"
+    When call ipc_get_root
+    The stdout should equal "/var/lib/toolbox/uipc"
+  End
+
+  It "returns the same value as uipc_get_root()"
+    _test_ipc_uipc_get_root_equal() {
+           local uipc_root
+           local ipc_root
+
+           uipc_root=$(uipc_get_root)
+           ipc_root=$(ipc_get_root)
+
+           if [[ "$uipc_root" != "$ipc_root" ]]; then
+                   return 1
+           fi
+
+           return 0
+    }
+
+    When call _test_ipc_uipc_get_root_equal
+    The status should equal 0
+  End
+End
+
 Describe "Encoding"
   It "ipc_encode() outputs base64"
     _test_encoding() {
@@ -125,11 +151,11 @@ Describe "Message"
   BeforeAll 'setup'
   AfterAll 'cleanup'
 
-  It "_uipc_msg_new() outputs base64 encoded data"
-    _test_uipc_msg_new_is_base64() {
+  It "ipc_msg_new() outputs base64 encoded data"
+    _test_ipc_msg_new_is_base64() {
            local msg
 
-           if ! msg=$(_uipc_msg_new "from" "to" "data"); then
+           if ! msg=$(ipc_msg_new "from" "to" "data"); then
                    return 1
            fi
 
@@ -140,15 +166,15 @@ Describe "Message"
            return 0
     }
 
-    When call _test_uipc_msg_new_is_base64
+    When call _test_ipc_msg_new_is_base64
     The status should equal 0
   End
 
-  It "_uipc_msg_new() outputs an encoded JSON object"
-    _test_uipc_msg_new_is_json() {
+  It "_ipc_msg_new() outputs an encoded JSON object"
+    _test_ipc_msg_new_is_json() {
            local msg
 
-           if ! msg=$(_uipc_msg_new "from" "to" "data"); then
+           if ! msg=$(ipc_msg_new "from" "to" "data"); then
                    return 1
            fi
 
@@ -159,17 +185,17 @@ Describe "Message"
            return 0
     }
 
-    When call _test_uipc_msg_new_is_json
+    When call _test_ipc_msg_new_is_json
     The status should equal 0
     The stdout should match pattern '{*}'
     The stderr should not start with "parse error"
   End
 
-  It "_uipc_msg_new() generates valid toolbox.ipc.message objects"
-    _test_uipc_msg_new_json_schema_envelope() {
+  It "ipc_msg_new() generates valid toolbox.ipc.message objects"
+    _test_ipc_msg_new_json_schema_envelope() {
            local msg
 
-           if ! msg=$(_uipc_msg_new "from" "to" "data"); then
+           if ! msg=$(ipc_msg_new "from" "to" "data"); then
                    return 1
            fi
 
@@ -180,53 +206,53 @@ Describe "Message"
            return 0
     }
 
-    When call _test_uipc_msg_new_json_schema_envelope
+    When call _test_ipc_msg_new_json_schema_envelope
     The status should equal 0
   End
 
-  It "_uipc_msg_new()/uipc_msg_get_version() sets/gets the correct version"
-    _test_uipc_msg_new_version() {
+  It "ipc_msg_new()/ipc_msg_get_version() sets/gets the correct version"
+    _test_ipc_msg_new_version() {
            local msg
 
-           if ! msg=$(_uipc_msg_new "from" "to" "data"); then
+           if ! msg=$(ipc_msg_new "from" "to" "data"); then
                    return 1
            fi
 
-           uipc_msg_get_version "$msg"
+           ipc_msg_get_version "$msg"
     }
 
-    When call _test_uipc_msg_new_version
+    When call _test_ipc_msg_new_version
     The status should equal 0
     The stdout should equal "$__uipc_version"
   End
 
-  It "_uipc_msg_new()/uipc_msg_get_user() sets/gets the correct user"
+  It "ipc_msg_new()/ipc_msg_get_user() sets/gets the correct user"
 
-    _test_uipc_msg_new_user() {
+    _test_ipc_msg_new_user() {
            local msg
 
-           msg=$(_uipc_msg_new "from" "to" "data")
+           msg=$(ipc_msg_new "from" "to" "data")
 
-           uipc_msg_get_user "$msg"
+           ipc_msg_get_user "$msg"
     }
 
-    When call _test_uipc_msg_new_user
+    When call _test_ipc_msg_new_user
     The status should equal 0
     The stdout should equal "$USER"
   End
 
-  It "_uipc_msg_new()/uipc_msg_get_timestamp() sets/gets the correct timestamp"
-    _test_uipc_msg_new_timestamp() {
+  It "ipc_msg_new()/ipc_msg_get_timestamp() sets/gets the correct timestamp"
+    _test_ipc_msg_new_timestamp() {
            local before
            local after
            local msg
            local timestamp
 
            before=$(date +"%s")
-           msg=$(_uipc_msg_new "from" "to" "data")
+           msg=$(ipc_msg_new "from" "to" "data")
            after=$(date +"%s")
 
-           timestamp=$(uipc_msg_get_timestamp "$msg")
+           timestamp=$(ipc_msg_get_timestamp "$msg")
 
            if (( timestamp < before )) ||
               (( timestamp > after )); then
@@ -236,62 +262,62 @@ Describe "Message"
            return 0
     }
 
-    When call _test_uipc_msg_new_timestamp
+    When call _test_ipc_msg_new_timestamp
     The status should equal 0
   End
 
-  It "_uipc_msg_new()/uipc_msg_get_source() sets/gets the correct source"
-    _test_uipc_msg_new_source() {
+  It "ipc_msg_new()/ipc_msg_get_source() sets/gets the correct source"
+    _test_ipc_msg_new_source() {
            local msg
 
-           if ! msg=$(_uipc_msg_new "from" "to" "data"); then
+           if ! msg=$(ipc_msg_new "from" "to" "data"); then
                    return 1
            fi
 
-           uipc_msg_get_source "$msg"
+           ipc_msg_get_source "$msg"
     }
 
-    When call _test_uipc_msg_new_source
+    When call _test_ipc_msg_new_source
     The status should equal 0
     The stdout should equal "from"
   End
 
-  It "_uipc_msg_new()/uipc_msg_get_destination() sets/gets the correct destination"
-    _test_uipc_msg_new_destination() {
+  It "ipc_msg_new()/ipc_msg_get_destination() sets/gets the correct destination"
+    _test_ipc_msg_new_destination() {
            local msg
 
-           if ! msg=$(_uipc_msg_new "from" "to" "data"); then
+           if ! msg=$(ipc_msg_new "from" "to" "data"); then
                    return 1
            fi
 
-           uipc_msg_get_destination "$msg"
+           ipc_msg_get_destination "$msg"
     }
 
-    When call _test_uipc_msg_new_destination
+    When call _test_ipc_msg_new_destination
     The status should equal 0
     The stdout should equal "to"
   End
 
-  It "_uipc_msg_new()/uipc_msg_get_data() sets/gets the correct data"
-    _test_uipc_msg_new_data() {
+  It "ipc_msg_new()/ipc_msg_get_data() sets/gets the correct data"
+    _test_ipc_msg_new_data() {
            local msg
 
-           if ! msg=$(_uipc_msg_new "from" "to" "data"); then
+           if ! msg=$(ipc_msg_new "from" "to" "data"); then
                    return 1
            fi
 
-           uipc_msg_get_data "$msg"
+           ipc_msg_get_data "$msg"
     }
 
-    When call _test_uipc_msg_new_data
+    When call _test_ipc_msg_new_data
     The status should equal 0
     The stdout should equal "data"
   End
 End
 
-Describe "uipc_endpoint_open"
+Describe "ipc_endpoint_open"
   It "opens a public endpoint when the endpoint name is specified"
-    _test_uipc_endpoint_open_public() {
+    _test_ipc_endpoint_open_public() {
            local endpoint_name
            local endpoint
            local res
@@ -299,143 +325,143 @@ Describe "uipc_endpoint_open"
            endpoint_name="pub/test$RANDOM"
            res=1
 
-           if endpoint=$(uipc_endpoint_open "$endpoint_name"); then
+           if endpoint=$(ipc_endpoint_open "$endpoint_name"); then
                    if [[ "$endpoint" != "priv/"* ]]; then
                            res=0
                    fi
 
-                   uipc_endpoint_close "$endpoint"
+                   ipc_endpoint_close "$endpoint"
            fi
 
            return "$res"
     }
 
-    When call _test_uipc_endpoint_open_public
+    When call _test_ipc_endpoint_open_public
     The status should equal 0
   End
 
   It "opens a private endpoint when no endpoint name is specified"
-    _test_uipc_endpoint_open_private() {
+    _test_ipc_endpoint_open_private() {
            local endpoint
            local res
 
            res=1
 
-           if endpoint=$(uipc_endpoint_open); then
+           if endpoint=$(ipc_endpoint_open); then
                    if [[ "$endpoint" == "priv/"* ]]; then
                            res=0
                    fi
 
-                   uipc_endpoint_close "$endpoint"
+                   ipc_endpoint_close "$endpoint"
            fi
 
            return "$res"
     }
 
-    When call _test_uipc_endpoint_open_private
+    When call _test_ipc_endpoint_open_private
     The status should equal 0
   End
 End
 
-Describe "uipc_endpoint_close"
+Describe "ipc_endpoint_close"
   It "closes a public endpoint"
-    _test_uipc_endpoint_close_public() {
+    _test_ipc_endpoint_close_public() {
            local endpoint
 
-           if ! endpoint=$(uipc_endpoint_open "pub/test$RANDOM"); then
+           if ! endpoint=$(ipc_endpoint_open "pub/test$RANDOM"); then
                    return 1
            fi
 
-           if ! uipc_endpoint_close "$endpoint"; then
+           if ! ipc_endpoint_close "$endpoint"; then
                    return 1
            fi
 
            return 0
     }
 
-    When call _test_uipc_endpoint_close_public
+    When call _test_ipc_endpoint_close_public
     The status should equal 0
   End
 
   It "closes a private endpoint"
-    _test_uipc_endpoint_close_private() {
+    _test_ipc_endpoint_close_private() {
            local endpoint
 
-           if ! endpoint=$(uipc_endpoint_open); then
+           if ! endpoint=$(ipc_endpoint_open); then
                    return 1
            fi
 
-           if ! uipc_endpoint_close "$endpoint"; then
+           if ! ipc_endpoint_close "$endpoint"; then
                    return 1
            fi
 
            return 0
     }
 
-    When call _test_uipc_endpoint_close_private
+    When call _test_ipc_endpoint_close_private
     The status should equal 0
   End
 End
 
-Describe "uipc_endpoint_send"
+Describe "ipc_endpoint_send"
   BeforeAll 'setup'
   AfterAll 'cleanup'
 
   It "sends a message to a public endpoint"
-    _test_uipc_endpoint_send_public() {
+    _test_ipc_endpoint_send_public() {
            local endpoint
            local res
 
-           if ! endpoint=$(uipc_endpoint_open "pub/test$RANDOM"); then
+           if ! endpoint=$(ipc_endpoint_open "pub/test$RANDOM"); then
                    return 1
            fi
 
-           if uipc_endpoint_send "-" "$endpoint" "data"; then
+           if ipc_endpoint_send "-" "$endpoint" "data"; then
                    res=0
            else
                    res=1
            fi
 
-           uipc_endpoint_close "$endpoint"
+           ipc_endpoint_close "$endpoint"
 
            return "$res"
     }
 
-    When call _test_uipc_endpoint_send_public
+    When call _test_ipc_endpoint_send_public
     The status should equal 0
   End
 
   It "sends a message to a private endpoint"
-    _test_uipc_endpoint_send_private() {
+    _test_ipc_endpoint_send_private() {
            local endpoint
            local res
 
-           if ! endpoint=$(uipc_endpoint_open); then
+           if ! endpoint=$(ipc_endpoint_open); then
                    return 1
            fi
 
-           if uipc_endpoint_send "-" "$endpoint" "data"; then
+           if ipc_endpoint_send "-" "$endpoint" "data"; then
                    res=0
            else
                    res=1
            fi
 
-           uipc_endpoint_close "$endpoint"
+           ipc_endpoint_close "$endpoint"
 
            return "$res"
     }
 
-    When call _test_uipc_endpoint_send_private
+    When call _test_ipc_endpoint_send_private
     The status should equal 0
   End
 End
 
-Describe "uipc_endpoint_recv"
+Describe "ipc_endpoint_recv"
   BeforeAll 'setup'
   AfterAll 'cleanup'
 
   It "receives messages on a public endpoint"
-    _test_uipc_endpoint_recv_public() {
+    _test_ipc_endpoint_recv_public() {
            local endpoint
            local res
            local txdata
@@ -445,14 +471,14 @@ Describe "uipc_endpoint_recv"
            txdata="data$RANDOM"
            res=1
 
-           if endpoint=$(uipc_endpoint_open "pub/test$RANDOM"); then
-                   if ! uipc_endpoint_send "-" "$endpoint" "$txdata"; then
+           if endpoint=$(ipc_endpoint_open "pub/test$RANDOM"); then
+                   if ! ipc_endpoint_send "-" "$endpoint" "$txdata"; then
                            res=2
 
-                   elif ! msg=$(uipc_endpoint_recv "$endpoint" 10); then
+                   elif ! msg=$(ipc_endpoint_recv "$endpoint" 10); then
                            res=3
 
-                   elif ! rxdata=$(uipc_msg_get_data "$msg"); then
+                   elif ! rxdata=$(ipc_msg_get_data "$msg"); then
                            res=4
 
                    elif [[ "$rxdata" != "$txdata" ]]; then
@@ -462,18 +488,18 @@ Describe "uipc_endpoint_recv"
                            res=0
                    fi
 
-                   uipc_endpoint_close "$endpoint"
+                   ipc_endpoint_close "$endpoint"
            fi
 
            return "$res"
     }
 
-    When call _test_uipc_endpoint_recv_public
+    When call _test_ipc_endpoint_recv_public
     The status should equal 0
   End
 
   It "receives messages on a private endpoint"
-    _test_uipc_endpoint_recv_private() {
+    _test_ipc_endpoint_recv_private() {
            local endpoint
            local res
            local txdata
@@ -483,14 +509,14 @@ Describe "uipc_endpoint_recv"
            res=1
            txdata="data$RANDOM"
 
-           if endpoint=$(uipc_endpoint_open); then
-                   if ! uipc_endpoint_send "-" "$endpoint" "$txdata"; then
+           if endpoint=$(ipc_endpoint_open); then
+                   if ! ipc_endpoint_send "-" "$endpoint" "$txdata"; then
                            res=2
 
-                   elif ! msg=$(uipc_endpoint_recv "$endpoint"); then
+                   elif ! msg=$(ipc_endpoint_recv "$endpoint"); then
                            res=3
 
-                   elif ! rxdata=$(uipc_msg_get_data "$msg"); then
+                   elif ! rxdata=$(ipc_msg_get_data "$msg"); then
                            res=4
 
                    elif [[ "$rxdata" != "$txdata" ]]; then
@@ -500,13 +526,13 @@ Describe "uipc_endpoint_recv"
                            res=0
                    fi
 
-                   uipc_endpoint_close "$endpoint"
+                   ipc_endpoint_close "$endpoint"
            fi
 
            return "$res"
     }
 
-    When call _test_uipc_endpoint_recv_private
+    When call _test_ipc_endpoint_recv_private
     The status should equal 0
   End
 End