#!/bin/bash # Tests for Serval DNA MeshMS HTTP RESTful interface # # Copyright 2013-2014 Serval Project, Inc. # # 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 2 # 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. source "${0%/*}/../testframework.sh" source "${0%/*}/../testdefs.sh" source "${0%/*}/../testdefs_json.sh" source "${0%/*}/../testdefs_meshms.sh" shopt -s extglob setup_instance() { set_instance $1 set_meshms_config executeOk_servald config \ set api.restful.users.harry.password potter \ set api.restful.users.ron.password weasley \ set api.restful.users.hermione.password grainger set_extra_config if [ -z "$IDENTITY_COUNT" ]; then create_single_identity else create_identities $IDENTITY_COUNT fi } setup() { setup_curl 7 setup_json setup_servald export SERVALD_RHIZOME_DB_RETRY_LIMIT_MS=60000 setup_instance +A start_servald_instances +A wait_until servald_restful_http_server_started +A get_servald_restful_http_server_port PORTA +A } finally() { stop_all_servald_servers } teardown() { kill_all_servald_processes assert_no_servald_processes report_all_servald_servers } set_extra_config() { : } set_meshms_config() { executeOk_servald config \ set debug.http_server on \ set debug.httpd on \ set debug.meshms on \ set debug.verbose on \ set log.console.level debug } doc_AuthBasicMissing="HTTP RESTful missing Basic Authentication credentials" test_AuthBasicMissing() { executeOk curl \ --silent --show-error --write-out '%{http_code}' \ --output http.output \ --dump-header http.headers \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA/conversationlist.json" assertStdoutIs '401' assertGrep http.headers "^WWW-Authenticate: Basic realm=\"Serval RESTful API\"$CR\$" assertJq http.output 'contains({"http_status_code": 401})' assertJq http.output 'contains({"http_status_message": ""})' } teardown_AuthBasicMissing() { tfw_cat http.headers http.output teardown } doc_AuthBasicWrong="HTTP RESTful incorrect Basic Authentication credentials" test_AuthBasicWrong() { executeOk curl \ --silent --show-error --write-out '%{http_code}' \ --output http.output \ --dump-header http.headers \ --basic --user fred:nurks \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA/conversationlist.json" assertStdoutIs '401' assertGrep http.headers "^WWW-Authenticate: Basic realm=\"Serval RESTful API\"$CR\$" assertJq http.output 'contains({"http_status_code": 401})' assertJq http.output 'contains({"http_status_message": ""})' executeOk curl \ --silent --fail --show-error --write-out '%{http_code}' \ --output http.output \ --dump-header http.headers \ --basic --user ron:weasley \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA/conversationlist.json" assertStdoutIs '200' } teardown_AuthBasicWrong() { tfw_cat http.headers http.output teardown } doc_MeshmsListConversations="HTTP RESTful list MeshMS conversations as JSON" setup_MeshmsListConversations() { IDENTITY_COUNT=5 setup # create 3 threads, with all permutations of incoming and outgoing messages executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1" executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2" executeOk_servald meshms send message $SIDA1 $SIDA4 "Message3" executeOk_servald meshms send message $SIDA4 $SIDA1 "Message4" } test_MeshmsListConversations() { executeOk curl \ --silent --fail --show-error \ --output conversationlist1.json \ --dump-header http.headers \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/conversationlist.json" tfw_cat http.headers conversationlist1.json tfw_preserve conversationlist1.json assert [ "$(jq '.rows | length' conversationlist1.json)" = 3 ] transform_list_json conversationlist1.json conversations1.json tfw_preserve conversations1.json assertJq conversations1.json \ "contains([ { my_sid: \"$SIDA1\", their_sid: \"$SIDA2\", read: true, last_message: 0, read_offset: 0 } ])" assertJq conversations1.json \ "contains([ { my_sid: \"$SIDA1\", their_sid: \"$SIDA3\", read: false, last_message: 11, read_offset: 0 } ])" assertJq conversations1.json \ "contains([ { my_sid: \"$SIDA1\", their_sid: \"$SIDA4\", read: false, last_message: 14, read_offset: 0 } ])" # mark all incoming messages as read executeOk_servald meshms read messages $SIDA1 executeOk_servald meshms read messages $SIDA1 $SIDA3 tfw_cat --stderr executeOk curl \ --silent --fail --show-error \ --output conversationlist2.json \ --dump-header http.headers \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/conversationlist.json" tfw_cat http.headers conversationlist2.json tfw_preserve conversationlist2.json assert [ "$(jq '.rows | length' conversationlist2.json)" = 3 ] transform_list_json conversationlist2.json conversations2.json tfw_preserve conversations2.json assertJq conversations2.json \ "contains([ { my_sid: \"$SIDA1\", their_sid: \"$SIDA2\", read: true, last_message: 0, read_offset: 0 } ])" assertJq conversations2.json \ "contains([ { my_sid: \"$SIDA1\", their_sid: \"$SIDA3\", read: true, last_message: 11, read_offset: 11 } ])" assertJq conversations2.json \ "contains([ { my_sid: \"$SIDA1\", their_sid: \"$SIDA4\", read: true, last_message: 14, read_offset: 14 } ])" } doc_MeshmsListMessages="HTTP RESTful list MeshMS messages in one conversation as JSON" setup_MeshmsListMessages() { IDENTITY_COUNT=2 setup meshms_add_messages $SIDA1 $SIDA2 '><>>A>A<>><><><>>>A>A><<<<<>><>>A<<>' let NROWS=NSENT+NRECV+(NACK?1:0) executeOk_servald meshms list messages $SIDA1 $SIDA2 delivered_offset=$(sed -n -e '/^[0-9]\+:[0-9]\+:[0-9]\+:ACK:delivered$/{n;s/^[0-9]\+:\([0-9]\+\):[0-9]\+:>:.*/\1/p;q}' "$TFWSTDOUT") [ -z "$delivered_offset" ] && delivered_offset=0 read_offset=$(sed -n -e 's/^[0-9]\+:\([0-9]\+\):[0-9]\+:MARK:read$/\1/p' "$TFWSTDOUT") [ -z "$read_offset" ] && read_offset=0 tfw_log "delivered: $delivered_offset; read: $read_offset" } test_MeshmsListMessages() { executeOk curl \ --silent --fail --show-error \ --output messagelist.json \ --dump-header http.headers \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/$SIDA2/messagelist.json" tfw_cat http.headers messagelist.json tfw_preserve messagelist.json assert [ "$(jq '.rows | length' messagelist.json)" = $NROWS ] transform_list_json messagelist.json messages.json tfw_preserve messages.json seen_ack=false let i=0 for ((j = NMESSAGE-1; j >= 0; --j)); do case ${MESSAGE[$j]} in 'ACK') $seen_ack && continue esac assertJq messages.json '(.['$i'].token | length) > 0' assertJq messages.json '.['$i'].my_sid == "'$SIDA1'"' assertJq messages.json '.['$i'].their_sid == "'$SIDA2'"' case ${MESSAGE[$j]} in '>') assertJq messages.json '.['$i'].type == ">"' assertJqIs messages.json '.['$i'].text' "${TEXT[$j]}" assertJq messages.json '.['$i'].delivered == (.['$i'].offset <= '$delivered_offset')' let ++i ;; '<') assertJq messages.json '.['$i'].type == "<"' assertJqIs messages.json '.['$i'].text' "${TEXT[$j]}" assertJq messages.json '.['$i'].read == (.['$i'].offset <= '$read_offset')' let ++i ;; 'ACK') assertJq messages.json '.['$i'].type == "ACK"' assertJq messages.json '.['$i'].text == null' assertJq messages.json '.['$i'].ack_offset == '$delivered_offset let ++i seen_ack=true ;; esac done } doc_MeshmsListMessagesNoIdentity="HTTP RESTful list MeshMS messages from unknown identity" setup_MeshmsListMessagesNoIdentity() { setup SIDX=0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF } test_MeshmsListMessagesNoIdentity() { execute curl \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDX/$SIDA/messagelist.json" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 419 assertJq http.body 'contains({"http_status_code": 419})' assertJqGrep --ignore-case http.body '.http_status_message' 'identity locked' assertJq http.body 'contains({"meshms_status_code": 2})' assertJqGrep --ignore-case http.body '.meshms_status_message' 'identity.*unknown' } doc_MeshmsListMessagesNewSince="HTTP RESTful list MeshMS messages in one conversation since token as JSON" setup_MeshmsListMessagesNewSince() { IDENTITY_COUNT=2 set_extra_config() { executeOk_servald config set api.restful.newsince_timeout 1s } setup meshms_add_messages $SIDA1 $SIDA2 '><>>A>A<>><><><>>>A>A><<<<<>><>>A<<>' let NROWS=NSENT+NRECV+(NACK?1:0) executeOk curl \ --silent --fail --show-error \ --output messagelist.json \ --dump-header http.headers \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/$SIDA2/messagelist.json" assert [ "$(jq '.rows | length' messagelist.json)" = $NROWS ] transform_list_json messagelist.json messages.json tfw_preserve messages.json for ((i = 0; i < NROWS; i += 3)); do token[$i]=$(jq --raw-output '.['$i'].token' messages.json) done } test_MeshmsListMessagesNewSince() { for ((i = 0; i < NROWS; i += 3)); do # At most five requests going at once [ $i -ge 15 ] && fork_wait %curl$((i-15)) fork %curl$i executeOk curl \ --silent --fail --show-error \ --output messagelist$i.json \ --dump-header http.headers$i \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/$SIDA2/newsince/${token[$i]}/messagelist.json" done fork_wait_all for ((i = 0; i < NROWS; i += 3)); do transform_list_json messagelist$i.json messages$i.json tfw_preserve messages$i.json jq '.[:'$i']' messages.json > messages_expected$i.json tfw_preserve messages_expected$i.json { echo '{"a":'; cat messages_expected$i.json; echo ',"b":'; cat messages$i.json; echo '}'; } >tmp.json assertJq tmp.json '.a == .b' done } grepall() { local pattern="$1" shift for file; do grep "$pattern" "$file" || return $? done return 0 } doc_MeshmsListMessagesNewSinceArrival="HTTP RESTful list newly arriving MeshMS messages in one conversation as JSON" setup_MeshmsListMessagesNewSinceArrival() { IDENTITY_COUNT=2 set_extra_config() { executeOk_servald config set api.restful.newsince_timeout 60s } setup # Use REST interface to send messages, not CLI, in order to avoid a database # locking storm meshms_use_restful harry potter meshms_add_messages $SIDA1 $SIDA2 '><>A>' let NROWS=NSENT+NRECV+(NACK?1:0) executeOk curl \ --silent --fail --show-error \ --output messagelist.json \ --dump-header http.headers \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/$SIDA2/messagelist.json" assert [ "$(jq '.rows | length' messagelist.json)" = $NROWS ] transform_list_json messagelist.json messages.json tfw_preserve messages.json token=$(jq --raw-output '.[0].token' messages.json) assert [ -n "$token" ] } test_MeshmsListMessagesNewSinceArrival() { for i in 1 2 3; do fork %curl$i executeOk --timeout=360 curl \ --silent --fail --show-error \ --no-buffer \ --output newsince$i.json \ --basic --user harry:potter \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/$SIDA2/newsince/$token/messagelist.json" done wait_until [ -e newsince1.json -a -e newsince2.json -a -e newsince3.json ] for message in '>Rumplestiltskin' 'A' 'Eulenspiegel'; do meshms_add_messages $SIDA1 $SIDA2 "${message:0:1}" "${message:1}" case ${message:0:1} in '<'|'>') waitfor="${message:1}";; 'A') waitfor="ACK";; *) error "message=${message}";; esac wait_until --timeout=10 grepall "$waitfor" newsince{1,2,3}.json done fork_terminate_all fork_wait_all } teardown_MeshmsListMessagesNewSinceArrival() { tfw_preserve newsince{1,2,3}.json teardown } doc_MeshmsSend="HTTP RESTful send MeshMS message" setup_MeshmsSend() { IDENTITY_COUNT=2 setup } test_MeshmsSend() { executeOk curl \ -H "Expect:" \ --silent --fail --show-error \ --output sendmessage.json \ --basic --user harry:potter \ --form "message=Hello World;type=text/plain;charset=utf-8" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/$SIDA2/sendmessage" executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutGrep --matches=1 ':>:Hello World' executeOk curl \ -H "Expect:" \ --silent --fail --show-error \ --output sendmessage.json \ --basic --user ron:weasley \ --form "message=Hello back!;type=text/plain;charset=utf-8" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/sendmessage" executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutGrep --matches=1 ':>:Hello World$' assertStdoutGrep --matches=1 ':<:Hello back!$' } doc_MeshmsSendMissingMessage="HTTP RESTful MeshMS send missing 'message' form part" setup_MeshmsSendMissingMessage() { IDENTITY_COUNT=2 setup } test_MeshmsSendMissingMessage() { execute curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ --data '' \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/sendmessage" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 400 assertJq http.body 'contains({"http_status_code": 400})' assertJqGrep --ignore-case http.body '.http_status_message' 'missing.*message.*form.*part' executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutLineCount '==' 2 } doc_MeshmsSendDuplicateMessage="HTTP RESTful MeshMS send duplicate 'message' form parts" setup_MeshmsSendDuplicateMessage() { IDENTITY_COUNT=2 setup } test_MeshmsSendDuplicateMessage() { execute curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ --form "message=Hello one;type=text/plain;charset=utf-8" \ --form "message=Hello two;type=text/plain;charset=utf-8" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/sendmessage" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 400 assertJq http.body 'contains({"http_status_code": 400})' assertJqGrep --ignore-case http.body '.http_status_message' 'duplicate.*message.*form.*part' executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutLineCount '==' 2 } doc_MeshmsSendMessageMissingContentType="HTTP RESTful MeshMS send 'message' form part missing Content-Type" setup_MeshmsSendMessageMissingContentType() { IDENTITY_COUNT=2 setup } test_MeshmsSendMessageMissingContentType() { execute curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ --form "message=Hello there" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/sendmessage" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 400 assertJq http.body 'contains({"http_status_code": 400})' assertJqGrep --ignore-case http.body '.http_status_message' 'missing.*content.*type' executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutLineCount '==' 2 } doc_MeshmsSendMessageUnsupportedContentType="HTTP RESTful MeshMS send 'message' form part unsupported Content-Type" setup_MeshmsSendMessageUnsupportedContentType() { IDENTITY_COUNT=2 setup } test_MeshmsSendMessageUnsupportedContentType() { execute curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ --form "message=Hello there;type=text/rich" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/sendmessage" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 415 assertJq http.body 'contains({"http_status_code": 415})' assertJqGrep --ignore-case http.body '.http_status_message' 'unsupported.*content.*type' executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutLineCount '==' 2 } doc_MeshmsSendMessageMissingCharset="HTTP RESTful MeshMS send 'message' form part missing charset" setup_MeshmsSendMessageMissingCharset() { IDENTITY_COUNT=2 setup } test_MeshmsSendMessageMissingCharset() { execute curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ --form "message=Hello there;type=text/plain" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/sendmessage" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 400 assertJq http.body 'contains({"http_status_code": 400})' assertJqGrep --ignore-case http.body '.http_status_message' 'missing.*charset' executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutLineCount '==' 2 } doc_MeshmsSendMessageUnsupportedCharset="HTTP RESTful MeshMS send 'message' form part unsupported charset" setup_MeshmsSendMessageUnsupportedCharset() { IDENTITY_COUNT=2 setup } test_MeshmsSendMessageUnsupportedCharset() { execute curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ --form "message=Hello there;type=text/plain;charset=latin-1" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/sendmessage" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 415 assertJq http.body 'contains({"http_status_code": 415})' assertJqGrep --ignore-case http.body '.http_status_message' 'unsupported.*charset' executeOk_servald meshms list messages $SIDA1 $SIDA2 assertStdoutLineCount '==' 2 } doc_MeshmsSendNoIdentity="HTTP RESTful MeshMS send from unknown identity" setup_MeshmsSendNoIdentity() { setup SIDX=0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF } test_MeshmsSendNoIdentity() { execute curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http.body \ --dump-header http.header \ --basic --user harry:potter \ --form "message=Hello;type=text/plain;charset=utf-8" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDX/$SIDA/sendmessage" tfw_cat http.header http.body assertExitStatus == 0 assertStdoutIs 419 assertJq http.body 'contains({"http_status_code": 419})' assertJqGrep --ignore-case http.body '.http_status_message' 'identity locked' assertJq http.body 'contains({"meshms_status_code": 2})' assertJqGrep --ignore-case http.body '.meshms_status_message' 'identity.*unknown' } doc_MeshmsReadAllConversations="HTTP RESTful MeshMS mark all conversations read" setup_MeshmsReadAllConversations() { IDENTITY_COUNT=5 setup # create 3 threads, with all permutations of incoming and outgoing messages executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1" executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2" executeOk_servald meshms send message $SIDA1 $SIDA4 "Message3" executeOk_servald meshms send message $SIDA4 $SIDA1 "Message4" executeOk_servald meshms list conversations $SIDA1 assertStdoutGrep --stderr --matches=1 ":$SIDA2::0:0\$" assertStdoutGrep --stderr --matches=1 ":$SIDA3:unread:11:0\$" assertStdoutGrep --stderr --matches=1 ":$SIDA4:unread:14:0\$" } test_MeshmsReadAllConversations() { executeOk curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http_body \ --basic --user harry:potter \ --request POST \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/readall" tfw_cat http_body assertExitStatus == 0 assertStdoutIs 201 executeOk_servald meshms list conversations $SIDA1 assertStdoutGrep --stderr --matches=1 ":$SIDA2::0:0\$" assertStdoutGrep --stderr --matches=1 ":$SIDA3::11:11\$" assertStdoutGrep --stderr --matches=1 ":$SIDA4::14:14\$" } doc_MeshmsPostSpuriousContent="HTTP RESTful MeshMS rejects unwanted content in POST request" setup_MeshmsPostSpuriousContent() { IDENTITY_COUNT=2 setup # create 3 threads, with all permutations of incoming and outgoing messages executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1" executeOk_servald meshms send message $SIDA2 $SIDA1 "Message2" executeOk_servald meshms send message $SIDA1 $SIDA2 "Message3" executeOk_servald meshms send message $SIDA2 $SIDA1 "Message4" executeOk_servald meshms list conversations $SIDA1 assertStdoutGrep --stderr --matches=1 ":$SIDA2:unread:35:0\$" } test_MeshmsPostSpuriousContent() { executeOk curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http_body \ --basic --user harry:potter \ --request POST \ --form "offset=0" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA1/readall" tfw_cat http_body assertExitStatus == 0 assertStdoutIs 400 assertJq http_body 'contains({"http_status_code": 400})' assertJqGrep --ignore-case http_body '.http_status_message' 'content length' executeOk_servald meshms list conversations $SIDA1 assertStdoutGrep --stderr --matches=1 ":$SIDA2:unread:35:0\$" } doc_MeshmsReadAllMessages="HTTP RESTful MeshMS mark all conversations read" setup_MeshmsReadAllMessages() { IDENTITY_COUNT=5 setup # create 3 threads, with all permutations of incoming and outgoing messages executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1" executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2" executeOk_servald meshms send message $SIDA1 $SIDA2 "Message3" executeOk_servald meshms send message $SIDA1 $SIDA4 "Message4" executeOk_servald meshms send message $SIDA4 $SIDA1 "Message5" executeOk_servald meshms send message $SIDA1 $SIDA2 "Message6" executeOk_servald meshms list messages $SIDA2 $SIDA1 tfw_cat --stdout executeOk_servald meshms list conversations $SIDA2 assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:45:0\$" } test_MeshmsReadAllMessages() { executeOk curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http_body \ --basic --user harry:potter \ --request POST \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/readall" tfw_cat http_body assertExitStatus == 0 assertStdoutIs 201 executeOk_servald meshms list conversations $SIDA2 assertStdoutGrep --stderr --matches=1 ":$SIDA1::45:45\$" } doc_MeshmsReadMessage="HTTP RESTful MeshMS mark a message as read" setup_MeshmsReadMessage() { IDENTITY_COUNT=5 setup # create 3 threads, with all permutations of incoming and outgoing messages executeOk_servald meshms send message $SIDA1 $SIDA2 "Message1" executeOk_servald meshms send message $SIDA3 $SIDA1 "Message2" executeOk_servald meshms send message $SIDA1 $SIDA2 "Message3" executeOk_servald meshms send message $SIDA1 $SIDA4 "Message4" executeOk_servald meshms send message $SIDA4 $SIDA1 "Message5" executeOk_servald meshms send message $SIDA1 $SIDA2 "Message6" executeOk_servald meshms list conversations $SIDA2 assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:45:0\$" } test_MeshmsReadMessage() { executeOk curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output http_body \ --basic --user harry:potter \ --request POST \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/recv/22/read" tfw_cat http_body assertExitStatus == 0 assertStdoutIs 201 executeOk_servald meshms list conversations $SIDA2 assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:45:22\$" executeOk curl \ -H "Expect:" \ --silent --show-error --write-out '%{http_code}' \ --output read.json \ --basic --user harry:potter \ --request POST \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA2/$SIDA1/recv/11/read" tfw_cat read.json assertExitStatus == 0 assertStdoutIs 200 executeOk_servald meshms list conversations $SIDA2 assertStdoutGrep --stderr --matches=1 ":$SIDA1:unread:45:22\$" } doc_sendFlood="Send lots of messages over the network" setup_sendFlood() { setup_curl 7 setup_json setup_servald export SERVALD_RHIZOME_DB_RETRY_LIMIT_MS=60000 set_extra_config() { executeOk_servald config set debug.rhizome_sync_keys on } setup_instance +A setup_instance +B start_servald_instances +A +B wait_until servald_restful_http_server_started +A get_servald_restful_http_server_port PORTA +A wait_until servald_restful_http_server_started +B get_servald_restful_http_server_port PORTB +B tfw_log "PORTA = $PORTA, PORTB = $PORTB" } test_sendFlood() { set_instance +A for (( j=0; j<5; j++ )) do for (( i=0; i<5; i++ )) do tfw_log "Sending message $i $j" curl \ -H "Expect:" \ --silent --fail --show-error \ --output /dev/null \ --basic --user harry:potter \ --form "message=0123456789012345678901234567890123456789 $(date +%s%N) $j $i;type=text/plain;charset=utf-8" \ "http://$addr_localhost:$PORTA/restful/meshms/$SIDA/$SIDB/sendmessage" done # TODO wait for sync complete sleep 2 set_instance +B executeOk_servald rhizome list tfw_cat --stdout executeOk_servald route print tfw_cat --stdout executeOk curl \ --silent --fail --show-error \ --output conversationlist.json \ --dump-header http.headers \ --basic --user harry:potter \ "http://$addr_localhost:$PORTB/restful/meshms/$SIDB/conversationlist.json" tfw_cat http.headers conversationlist.json done set_instance +B executeOk curl \ --silent --fail --show-error \ --output conversationlist.json \ --dump-header http.headers \ --basic --user harry:potter \ "http://$addr_localhost:$PORTB/restful/meshms/$SIDB/conversationlist.json" tfw_cat http.headers conversationlist.json } runTests "$@"