mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-21 22:17:53 +00:00
427 lines
14 KiB
Bash
Executable File
427 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Tests for Serval rhizome operations.
|
|
#
|
|
# Copyright 2013 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_rhizome.sh"
|
|
|
|
shopt -s extglob
|
|
|
|
setup() {
|
|
CR='
|
|
'
|
|
setup_curl 7
|
|
setup_jq 1.2
|
|
setup_servald
|
|
set_instance +A
|
|
set_rhizome_config
|
|
executeOk_servald config \
|
|
set rhizome.api.restful.users.harry.password potter \
|
|
set rhizome.api.restful.users.ron.password weasley \
|
|
set rhizome.api.restful.users.hermione.password grainger
|
|
create_single_identity
|
|
echo "$SIDA1" >sids
|
|
start_servald_instances +A
|
|
wait_until rhizome_http_server_started +A
|
|
get_rhizome_server_port PORTA +A
|
|
}
|
|
|
|
finally() {
|
|
stop_all_servald_servers
|
|
}
|
|
|
|
teardown() {
|
|
kill_all_servald_processes
|
|
assert_no_servald_processes
|
|
report_all_servald_servers
|
|
}
|
|
|
|
set_rhizome_config() {
|
|
executeOk_servald config \
|
|
set debug.httpd on \
|
|
set debug.rhizome_httpd on \
|
|
set debug.rhizome 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/rhizome/bundlelist.json"
|
|
assertStdoutIs '401'
|
|
assertGrep http.headers "^WWW-Authenticate: Basic realm=\"Serval Rhizome\"$CR\$"
|
|
}
|
|
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/rhizome/bundlelist.json"
|
|
assertStdoutIs '401'
|
|
assertGrep http.headers "^WWW-Authenticate: Basic realm=\"Serval Rhizome\"$CR\$"
|
|
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/rhizome/bundlelist.json"
|
|
assertStdoutIs '200'
|
|
}
|
|
teardown_AuthBasicWrong() {
|
|
tfw_cat http.headers http.output
|
|
teardown
|
|
}
|
|
|
|
add_bundles() {
|
|
local encrypted=false
|
|
case "$1" in
|
|
--encrypted) encrypted=true; shift;;
|
|
esac
|
|
local n
|
|
for ((n = $1; n <= $2; ++n)); do
|
|
create_file file$n $((1000 + $n))
|
|
if $encrypted; then
|
|
echo "crypt=1" >file$n.manifest
|
|
fi
|
|
executeOk_servald rhizome add file $SIDA file$n file$n.manifest
|
|
extract_stdout_manifestid BID[$n]
|
|
extract_stdout_version VERSION[$n]
|
|
extract_stdout_filesize SIZE[$n]
|
|
extract_stdout_filehash HASH[$n]
|
|
extract_stdout_date DATE[$n]
|
|
extract_stdout_BK BK[$n]
|
|
extract_stdout_rowid ROWID[$n]
|
|
extract_stdout_author AUTHOR[$n]
|
|
extract_stdout_secret SECRET[$n]
|
|
extract_stdout_inserttime INSERTTIME[$n]
|
|
if $encrypted; then
|
|
extract_stdout_crypt CRYPT[$n]
|
|
assert [ "${CRYPT[$n]}" = 1 ]
|
|
else
|
|
CRYPT[$n]=
|
|
fi
|
|
executeOk_servald rhizome export file ${HASH[$n]} raw$n
|
|
if $encrypted; then
|
|
assert ! cmp file$n raw$n
|
|
else
|
|
assert cmp file$n raw$n
|
|
fi
|
|
[ "${ROWID[$n]}" -gt "${ROWID_MAX:-0}" ] && ROWID_MAX=${ROWID[$n]}
|
|
done
|
|
}
|
|
|
|
transform_bundlelist_json() {
|
|
# The following jq(1) incantation transforms the JSON array in
|
|
# bundlelist.json from the following form (which is optimised for
|
|
# transmission size):
|
|
# {
|
|
# "header":[
|
|
# ".token", "_id", "service", "id", "version","date",".inserttime",
|
|
# ".author",".fromhere","filesize","filehash","sender","recipient",
|
|
# "name"
|
|
# ],
|
|
# "rows":[
|
|
# [ "xx", rowid1, "service1", bundleid1, version1, .... ],
|
|
# [ null, rowid2, "service2", bundleid2, version2, .... ],
|
|
# ...
|
|
# [ null, rowidN, "serviceN", bundleidN, versionN, .... ]
|
|
# ]
|
|
# }
|
|
#
|
|
# into an array of JSON objects:
|
|
# [
|
|
# {
|
|
# "__index": 0,
|
|
# ".token": "xx",
|
|
# "_id": rowid1,
|
|
# "service": service1,
|
|
# "id": bundleid1,
|
|
# "version": version1,
|
|
# ...
|
|
# },
|
|
# {
|
|
# "__index": 1,
|
|
# ".token": null,
|
|
# "_id": rowid2,
|
|
# "service": service2,
|
|
# "id": bundleid2,
|
|
# "version": version2,
|
|
# ...
|
|
# },
|
|
# ...
|
|
# {
|
|
# "__index": 2,
|
|
# ".token": null,
|
|
# "_id": rowidN,
|
|
# "service": serviceN,
|
|
# "id": bundleidN,
|
|
# "version": versionN,
|
|
# ...
|
|
# }
|
|
# ]
|
|
# which is much easier to test with jq(1) expressions.
|
|
jq '
|
|
[
|
|
.header as $header |
|
|
.rows as $rows |
|
|
$rows | keys | .[] as $index |
|
|
[ $rows[$index] as $d | $d | keys | .[] as $i | {key:$header[$i], value:$d[$i]} ] |
|
|
from_entries |
|
|
.["__index"] = $index
|
|
]
|
|
' "$1" >"$2"
|
|
}
|
|
|
|
assertJq() {
|
|
local json="$1"
|
|
local jqscript="$2"
|
|
assert --message="$jqscript" [ "$(jq "$jqscript" "$json")" = true ]
|
|
}
|
|
|
|
doc_RhizomeList="HTTP RESTful list Rhizome bundles as JSON"
|
|
setup_RhizomeList() {
|
|
setup
|
|
NBUNDLES=100
|
|
add_bundles 0 $((NBUNDLES-1))
|
|
assert [ "$ROWID_MAX" -ge "$NBUNDLES" ]
|
|
}
|
|
test_RhizomeList() {
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output bundlelist.json \
|
|
--dump-header http.headers \
|
|
--basic --user harry:potter \
|
|
"http://$addr_localhost:$PORTA/restful/rhizome/bundlelist.json"
|
|
tfw_cat http.headers bundlelist.json
|
|
tfw_preserve bundlelist.json
|
|
assert [ "$(jq '.rows | length' bundlelist.json)" = $NBUNDLES ]
|
|
transform_bundlelist_json bundlelist.json array_of_objects.json
|
|
tfw_preserve array_of_objects.json
|
|
for ((n = 0; n != NBUNDLES; ++n)); do
|
|
if [ "${ROWID[$n]}" -eq "$ROWID_MAX" ]; then
|
|
# The first row must contain a non-null token string.
|
|
token=',".token":"","__index":0,'
|
|
else
|
|
token=',".token":null,'
|
|
fi
|
|
assertJq array_of_objects.json \
|
|
"contains([
|
|
{ name:\"file$n\",
|
|
service:\"file\",
|
|
id:\"${BID[$n]}\",
|
|
version:${VERSION[$n]},
|
|
filesize:${SIZE[$n]},
|
|
filehash:\"${HASH[$n]}\",
|
|
date:${DATE[$n]},
|
|
_id:${ROWID[$n]},
|
|
\".fromhere\":1,
|
|
\".author\":\"$SIDA\"
|
|
$token
|
|
}
|
|
])"
|
|
done
|
|
}
|
|
|
|
curl_newsince() {
|
|
curl \
|
|
--silent --fail --show-error \
|
|
--no-buffer \
|
|
--output "$1" \
|
|
--basic --user harry:potter \
|
|
"http://$addr_localhost:$PORTA/restful/rhizome/newsince/$token/bundlelist.json"
|
|
}
|
|
|
|
doc_RhizomeNewSince="HTTP RESTful list Rhizome bundles since token as JSON"
|
|
setup_RhizomeNewSince() {
|
|
setup
|
|
executeOk_servald config set rhizome.api.restful.newsince_timeout 60s
|
|
executeOk_servald config set rhizome.api.restful.newsince_poll_ms 500
|
|
add_bundles 0 5
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output bundlelist.json \
|
|
--dump-header http.headers \
|
|
--basic --user harry:potter \
|
|
"http://$addr_localhost:$PORTA/restful/rhizome/bundlelist.json"
|
|
assert [ "$(jq '.rows | length' bundlelist.json)" = 6 ]
|
|
transform_bundlelist_json bundlelist.json array_of_objects.json
|
|
token=$(jq --raw-output '.[0][".token"]' array_of_objects.json)
|
|
assert [ -n "$token" ]
|
|
}
|
|
test_RhizomeNewSince() {
|
|
fork %curl1 curl_newsince newsince1.json
|
|
fork %curl2 curl_newsince newsince2.json
|
|
fork %curl3 curl_newsince newsince3.json
|
|
wait_until [ -e newsince1.json -a -e newsince2.json -a -e newsince3.json ]
|
|
add_bundles 6 10
|
|
wait_until --timeout=10 grep "${BID[10]}" newsince1.json
|
|
wait_until --timeout=10 grep "${BID[10]}" newsince2.json
|
|
wait_until --timeout=10 grep "${BID[10]}" newsince3.json
|
|
fork_terminate_all
|
|
fork_wait_all
|
|
for i in 1 2 3; do
|
|
if [ $(jq . newsince$i | wc -c) -eq 0 ]; then
|
|
echo ']}' >>newsince$i.json
|
|
assert [ $(jq . newsince$i.json | wc -c) -ne 0 ]
|
|
fi
|
|
transform_bundlelist_json newsince$i.json objects$i.json
|
|
tfw_preserve newsince$i.json objects$i.json
|
|
for ((n = 0; n <= 5; ++n)); do
|
|
assertJq objects$i.json "contains([{id:\"${BID[$n]}\"}]) | not"
|
|
done
|
|
for ((n = 6; n <= 10; ++n)); do
|
|
assertJq objects$i.json \
|
|
"contains([
|
|
{ name:\"file$n\",
|
|
service:\"file\",
|
|
id:\"${BID[$n]}\",
|
|
version:${VERSION[$n]},
|
|
filesize:${SIZE[$n]},
|
|
filehash:\"${HASH[$n]}\",
|
|
date:${DATE[$n]},
|
|
_id:${ROWID[$n]},
|
|
\".fromhere\":1,
|
|
\".author\":\"$SIDA\",
|
|
\".token\":\"\"
|
|
}
|
|
])"
|
|
done
|
|
done
|
|
}
|
|
|
|
assert_http_response_headers() {
|
|
local n=$1
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Id: ${BID[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Version: ${VERSION[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Filesize: ${SIZE[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Filehash: ${HASH[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-BK: ${BK[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Date: ${DATE[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Name: \"file$n\"$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Service: file$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Author: ${AUTHOR[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Secret: ${SECRET[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Inserttime: ${INSERTTIME[$n]}$CR\$"
|
|
assertGrep --matches=1 http.headers$n "^Serval-Rhizome-Bundle-Rowid: ${ROWID[$n]}$CR\$"
|
|
}
|
|
|
|
doc_RhizomeManifest="HTTP RESTful fetch Rhizome manifest"
|
|
setup_RhizomeManifest() {
|
|
setup
|
|
add_bundles 0 2
|
|
}
|
|
test_RhizomeManifest() {
|
|
for n in 0 1 2; do
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output bundle$n.rhm \
|
|
--dump-header http.headers$n \
|
|
--basic --user harry:potter \
|
|
"http://$addr_localhost:$PORTA/restful/rhizome/${BID[$n]}.rhm"
|
|
tfw_cat http.headers$n bundle$n.rhm
|
|
tfw_preserve bundle$n.rhm
|
|
done
|
|
for n in 0 1 2; do
|
|
assert diff file$n.manifest bundle$n.rhm
|
|
assert_http_response_headers $n
|
|
done
|
|
}
|
|
|
|
doc_RhizomePayloadRaw="HTTP RESTful fetch Rhizome raw payload"
|
|
setup_RhizomePayloadRaw() {
|
|
setup
|
|
add_bundles 0 1
|
|
add_bundles --encrypted 2 3
|
|
}
|
|
test_RhizomePayloadRaw() {
|
|
for n in 0 1 2 3; do
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output raw.bin$n \
|
|
--dump-header http.headers$n \
|
|
--basic --user harry:potter \
|
|
"http://$addr_localhost:$PORTA/restful/rhizome/${BID[$n]}/raw.bin"
|
|
tfw_cat http.headers$n raw.bin$n
|
|
done
|
|
for n in 0 1 2 3; do
|
|
assert cmp raw$n raw.bin$n
|
|
assert_http_response_headers $n
|
|
done
|
|
}
|
|
|
|
doc_RhizomePayloadDecrypted="HTTP RESTful fetch Rhizome decrypted payload"
|
|
setup_RhizomePayloadDecrypted() {
|
|
setup
|
|
add_bundles 0 1
|
|
add_bundles --encrypted 2 3
|
|
}
|
|
test_RhizomePayloadDecrypted() {
|
|
for n in 0 1 2 3; do
|
|
executeOk curl \
|
|
--silent --fail --show-error \
|
|
--output decrypted.bin$n \
|
|
--dump-header http.headers$n \
|
|
--basic --user harry:potter \
|
|
"http://$addr_localhost:$PORTA/restful/rhizome/${BID[$n]}/decrypted.bin"
|
|
tfw_cat http.headers$n decrypted.bin$n
|
|
done
|
|
for n in 0 1 2 3; do
|
|
assert cmp file$n decrypted.bin$n
|
|
assert_http_response_headers $n
|
|
done
|
|
}
|
|
|
|
doc_RhizomeInsert="Insert new Rhizome bundle"
|
|
test_RhizomeInsert() {
|
|
:
|
|
}
|
|
|
|
doc_MeshmsListConversations="HTTP RESTful list MeshMS conversations as JSON"
|
|
test_MeshmsListConversations() {
|
|
:
|
|
}
|
|
|
|
doc_MeshmsListMessages="HTTP RESTful list MeshMS messages in one conversation as JSON"
|
|
test_MeshmsListMessages() {
|
|
:
|
|
}
|
|
|
|
doc_MeshmsListMessagesSince="HTTP RESTful list MeshMS messages in one conversation since token as JSON"
|
|
test_MeshmsListMessagesSince() {
|
|
:
|
|
}
|
|
|
|
doc_MeshmsSend="HTTP RESTful send MeshMS message"
|
|
test_MeshmsSend() {
|
|
:
|
|
}
|
|
|
|
runTests "$@"
|