#!/bin/bash # Tests for Serval DNA rhizome operations. # # Copyright 2012 Paul Gardner-Stephen # # 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" setup_dna_rhizome() { setup_dna "$@" executeOk $dna config set debug rhizome } assert_rhizome_list() { executeOk $dna rhizome list assertStdoutLineCount '==' $(($# + 2)) assertStdoutIs --line=1 -e '8\n' assertStdoutIs --line=2 -e 'fileid:manifestid:version:inserttime:length:datavalid:date:name\n' local filename for filename; do unpack_manifest_for_grep "$filename" assertStdoutGrep --matches=1 "^$re_filehash:$re_manifestid:.*:$re_name\$" done } assert_stdout_add_file() { local filename="$1" unpack_manifest_for_grep "$filename" assertStdoutLineCount '==' 4 assertStdoutGrep --matches=1 "^name:${2:-$re_name}\$" assertStdoutGrep --matches=1 "^manifestid:$re_manifestid\$" assertStdoutGrep --matches=1 "^filehash:$re_filehash\$" assertStdoutGrep --matches=1 "^filesize:$re_size\$" } unpack_manifest_for_grep() { local filename="$1" re_size=$(( $(cat "$filename" | wc -c) + 0 )) re_filehash='[0-9a-fA-F]\{128\}' re_manifestid='[0-9a-fA-F]\{64\}' re_name="${filename##*/}" # should escape grep metacharacters # If there is a manifest file that looks like it matches this payload # file, then use its file hash to check the rhizome list output. if [ -r "$filename.manifest" ]; then local name=$(sed -n -e '/^name=/s///p' "$filename.manifest") if [ "$name" == "${filename##*/}" ]; then re_filehash=$(sed -n -e '/^filehash=/s///p' "$filename.manifest") re_manifestid=$(sed -n -e '/^id=/s///p' "$filename.manifest") fi fi } assert_manifest_newer() { local manifest1="$1" local manifest2="$2" # The new manifest must have a higher version than the original. extract_manifest_version oldversion "$manifest1" extract_manifest_version newversion "$manifest2" assert [ $newversion -gt $oldversion ] # The new manifest must have a different filehash from the original. extract_manifest_filehash oldfilehash "$manifest1" extract_manifest_filehash newfilehash "$manifest2" assert [ $oldfilehash != $newfilehash ] } strip_signatures() { for file; do cat -v "$file" | sed -e '/^^@/,$d' >"tmp.$file" && mv -f "tmp.$file" "$file" done } extract_manifest() { local _var="$1" local _manifestfile="$2" local _label="$3" local _rexp="$4" local _value=$(sed -n -e "/^$_label=$_rexp\$/s/^$_label=//p" "$_manifestfile") assert --message="$_manifestfile contains valid '$_label=' line" \ --dump-on-fail="$_manifestfile" \ [ -n "$_value" ] [ -n "$_var" ] && eval $_var=$_value } extract_manifest_id() { extract_manifest "$1" "$2" id '[0-9a-fA-F]\{64\}' } extract_manifest_filehash() { extract_manifest "$1" "$2" filehash '[0-9a-fA-F]\{128\}' } extract_manifest_version() { extract_manifest "$1" "$2" version '[0-9]\{1,\}' } doc_InitialEmptyList="Initial list is empty" setup_InitialEmptyList() { setup_dna_rhizome } test_InitialEmptyList() { assert_rhizome_list } doc_AddNoManifest="Add with no manifest file" setup_AddNoManifest() { setup_dna_rhizome assert_rhizome_list echo "A test file" >file1 echo "Another test file" >file2 } test_AddNoManifest() { executeOk $dna rhizome add file file1 assert_stdout_add_file file1 } doc_AddNonExistManifest="Add with non-existent manifest file" setup_AddNonExistManifest() { setup_dna_rhizome assert_rhizome_list echo "A test file" >file1 echo "Another test file" >file2 } test_AddNonExistManifest() { assert --error-on-fail [ ! -e file1.manifest ] executeOk $dna rhizome add file file1 file1.manifest assert_stdout_add_file file1 assert [ -r file1.manifest ] tfw_cat -v file1.manifest assertGrep file1.manifest '^name=file1$' assertGrep file1.manifest '^date=[0-9]\+$' assertGrep file1.manifest '^version=[0-9]\+$' assertGrep file1.manifest "^id=$re_manifestid\$" assertGrep file1.manifest "^filehash=$re_filehash\$" assertGrep file1.manifest "^filesize=$re_size\$" assertGrep file1.manifest "^first_byte=0$" assertGrep file1.manifest "^last_byte=$re_size\$" } doc_AddManifest="Add with minimal manifest file" setup_AddManifest() { setup_dna_rhizome assert_rhizome_list echo "A test file" >file1 echo -e 'name=wah\ndate=12345' >file1.manifest echo "Another test file" >file2 } test_AddManifest() { executeOk $dna rhizome add file file1 file1.manifest tfw_cat --stdout --stderr -v file1.manifest assert_stdout_add_file file1 wah assertGrep file1.manifest '^name=wah$' assertGrep file1.manifest '^version=[0-9]\+$' assertGrep file1.manifest '^date=12345$' assertGrep file1.manifest "^id=$re_manifestid\$" assertGrep file1.manifest "^filehash=$re_filehash\$" assertGrep file1.manifest "^filesize=$re_size\$" assertGrep file1.manifest "^first_byte=0$" assertGrep file1.manifest "^last_byte=$re_size\$" } doc_AddThenList="List contains one file after one add" setup_AddThenList() { setup_dna_rhizome assert_rhizome_list echo "A test file" >file1 echo "Another test file" >file2 } test_AddThenList() { # Add first file executeOk $dna rhizome add file file1 file1.manifest assert_rhizome_list file1 # Add second file executeOk $dna rhizome add file file2 file2.manifest assert_rhizome_list file1 file2 } doc_AddThenExtractManifest="Extract manifest after one add" setup_AddThenExtractManifest() { setup_dna_rhizome echo "A test file" >file1 executeOk $dna rhizome add file file1 file1.manifest assert_rhizome_list file1 extract_manifest_id manifestid file1.manifest extract_manifest_version version file1.manifest extract_manifest_filehash filehash file1.manifest } test_AddThenExtractManifest() { executeOk $dna rhizome extract manifest $manifestid file1x.manifest assert cmp file1.manifest file1x.manifest assertStdoutLineCount '==' 5 local size=$(( $(cat file1 | wc -c) + 0 )) assertStdoutGrep --matches=1 "^manifestid:$manifestid$" assertStdoutGrep --matches=1 "^version:$version$" assertStdoutGrep --matches=1 "^inserttime:[0-9]\+$" assertStdoutGrep --matches=1 "^filehash:$filehash$" assertStdoutGrep --matches=1 "^filesize:$size$" } doc_ExtractMissingManifest="Extract non-existent manifest" setup_ExtractMissingManifest() { setup_dna_rhizome manifestid=0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF } test_ExtractMissingManifest() { execute --exit-status=1 $dna rhizome extract manifest $manifestid foo.manifest assertStdoutLineCount '==' 0 assert [ ! -e foo.manifest ] } doc_ExtractManifestInvalidID="Extract manifest using invalid ID" setup_ExtractManifestInvalidID() { setup_dna_rhizome } test_ExtractManifestInvalidID() { execute --exit-status=255 $dna rhizome extract manifest 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEx foo.manifest assertStdoutLineCount '==' 0 assert [ ! -e foo.manifest ] execute --exit-status=255 $dna rhizome extract manifest 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE foo.manifest assertStdoutLineCount '==' 0 assert [ ! -e foo.manifest ] execute --exit-status=255 $dna rhizome extract manifest '' foo.manifest assertStdoutLineCount '==' 0 assert [ ! -e foo.manifest ] } doc_AddThenExtractFile="Extract file after one add" setup_AddThenExtractFile() { setup_dna_rhizome echo "A test file" >file1 executeOk $dna rhizome add file file1 file1.manifest assert_rhizome_list file1 extract_manifest_filehash filehash file1.manifest } test_AddThenExtractFile() { executeOk $dna rhizome extract file $filehash file1x assert cmp file1 file1x local size=$(( $(cat file1 | wc -c) + 0 )) assertStdoutLineCount '==' 2 assertStdoutGrep --matches=1 "^filehash:$filehash$" assertStdoutGrep --matches=1 "^filesize:$size$" } doc_ExtractMissingFile="Extract non-existent file" setup_ExtractMissingFile() { setup_dna_rhizome filehash=0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF } test_ExtractMissingFile() { execute --exit-status=1 $dna rhizome extract file $filehash foo assertStdoutLineCount '==' 0 assert [ ! -e foo ] } doc_ExtractFileInvalidID="Extract file using invalid ID" setup_ExtractFileInvalidID() { setup_dna_rhizome } test_ExtractFileInvalidID() { execute --exit-status=255 $dna rhizome extract file 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEx foo assertStdoutLineCount '==' 0 assert [ ! -e foo ] execute --exit-status=255 $dna rhizome extract file 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE foo assertStdoutLineCount '==' 0 assert [ ! -e foo ] execute --exit-status=255 $dna rhizome extract file '' foo assertStdoutLineCount '==' 0 assert [ ! -e foo ] } doc_AddDuplicate="Add same manifest detects duplicate" setup_AddDuplicate() { setup_dna_rhizome assert_rhizome_list echo "A test file" >file1 echo "Another test file" >file2 echo "A test file, second version" >file1_2 # Add first file executeOk $dna rhizome add file file1 file1.manifest # Add second file executeOk $dna rhizome add file file2 file2.manifest # Make sure they are both in the list. assert_rhizome_list file1 file2 } test_AddDuplicate() { # Add first file again - nothing should change in its manifests, and it # should appear that the add command succeeded (with perhaps some grumbling # on stderr). execute --exit-status=2 $dna rhizome add file file1 file1.manifestA assert [ -s file1.manifestA ] assert_stdout_add_file file1 assert_rhizome_list file1 file2 strip_signatures file1.manifest file1.manifestA assert diff file1.manifest file1.manifestA # Repeat for second file. execute --exit-status=2 $dna rhizome add file file2 file2.manifestA assert [ -s file2.manifestA ] assert_stdout_add_file file2 assert_rhizome_list file1 file2 strip_signatures file2.manifest file2.manifestA assert diff file2.manifest file2.manifestA } doc_AddMismatched="Add mismatched manifest/payload fails" setup_AddMismatched() { setup_AddDuplicate } test_AddMismatched() { # Try to add another file using an existing manifest, should fail and leave # the manifest file unchanged. cp file1.manifest file1_2.manifest execute $dna rhizome add file file1_2 file1_2.manifest assertExitStatus '!=' 0 assert cmp file1.manifest file1_2.manifest # And rhizome store should be unchanged. assert_rhizome_list file1 file2 } doc_AddUpdateSameVersion="Add new payload to existing manifest with same version" setup_AddUpdateSameVersion() { setup_AddDuplicate cp file1.manifest file1_2.manifest strip_signatures file1_2.manifest sed -i -e '/^date=/d;/^filehash=/d;/^filesize=/d' file1_2.manifest tfw_cat -v file1_2.manifest assertGrep --matches=0 file1_2.manifest '^filehash=' extract_manifest_version '' file1_2.manifest # asserts has version= line assertGrep file1_2.manifest '^id=' cp file1_2.manifest file1_2.manifest.orig } test_AddUpdateSameVersion() { tfw_cat -v file1_2.manifest execute $dna rhizome add file file1_2 file1_2.manifest assertExitStatus --stderr '!=' 0 tfw_cat -v file1_2.manifest assert cmp file1_2.manifest file1_2.manifest.orig # And rhizome store should be unchanged. assert_rhizome_list file1 file2 } doc_AddUpdateNewVersion="Add new payload to existing manifest with new version" setup_AddUpdateNewVersion() { setup_AddUpdateSameVersion extract_manifest_version version file1_2.manifest let version=version+1 sed -i -e "/^version=/s/=.*/=$version/" file1_2.manifest assertGrep --matches=1 file1_2.manifest "^version=$version$" } test_AddUpdateNewVersion() { tfw_cat -v file1_2.manifest executeOk $dna rhizome add file file1_2 file1_2.manifest assert_stdout_add_file file1_2 file1 assert_manifest_newer file1.manifest file1_2.manifest # Rhizome store contents reflect new payload. mv -f file1_2.manifest file1.manifest assert_rhizome_list file1 file2 } doc_AddUpdateAutoVersion="Add new payload to existing manifest with automatic version" setup_AddUpdateAutoVersion() { setup_AddUpdateSameVersion sed -i -e '/^version=/d' file1_2.manifest assertGrep --matches=0 file1_2.manifest '^version=' } test_AddUpdateAutoVersion() { tfw_cat -v file1_2.manifest sleep 0.001 # Ensure that at least one millisecond has elapsed executeOk $dna rhizome add file file1_2 file1_2.manifest assert_manifest_newer file1.manifest file1_2.manifest # Rhizome store contents reflect new payload. mv -f file1_2.manifest file1.manifest assert_rhizome_list file1 file2 } runTests "$@"