summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/attach.test43
-rw-r--r--test/contact.test200
-rw-r--r--test/message.test149
-rw-r--r--test/network.test146
-rw-r--r--test/storage.test201
-rw-r--r--test/sync.test93
6 files changed, 832 insertions, 0 deletions
diff --git a/test/attach.test b/test/attach.test
new file mode 100644
index 0000000..33a1483
--- /dev/null
+++ b/test/attach.test
@@ -0,0 +1,43 @@
+test:
+ spawn as p1
+ spawn as p2
+ send "create-identity Device1 Owner" to p1
+ send "create-identity Device2" to p2
+ send "watch-local-identity" to p1
+ send "watch-local-identity" to p2
+ send "start-server" to p1
+ send "start-server" to p2
+ expect from p1:
+ /local-identity Device1 Owner/
+ /peer 1 addr ${p2.node.ip} 29665/
+ /peer 1 id Device2/
+ expect from p2:
+ /local-identity Device2/
+ /peer 1 addr ${p1.node.ip} 29665/
+ /peer 1 id Device1 Owner/
+
+ send "attach-to 1" to p2
+ expect /attach-request 1 .*/ from p1
+ expect /attach-response 1 .*/ from p2
+ send "attach-reject 1" to p1
+ expect /attach-request-failed 1 user/ from p1
+ expect /attach-response-failed 1 rejected/ from p2
+
+ send "attach-to 1" to p2
+ expect /attach-request 1 .*/ from p1
+ expect /attach-response 1 .*/ from p2
+ send "attach-reject 1" to p2
+ expect /attach-request-failed 1 rejected/ from p1
+ expect /attach-response-failed 1 user/ from p2
+
+ send "attach-to 1" to p2
+ expect /attach-request 1 ([0-9]*)/ from p1 capture code1
+ expect /attach-response 1 ([0-9]*)/ from p2 capture code2
+ guard (code1 == code2)
+
+ send "attach-accept 1" to p1
+ send "attach-accept 1" to p2
+ expect /attach-request-done 1/ from p1
+ expect /attach-response-done 1/ from p2
+ expect /local-identity Device2 Owner/ from p2
+ expect /peer 1 id Device2 Owner/ from p1
diff --git a/test/contact.test b/test/contact.test
new file mode 100644
index 0000000..438aa1f
--- /dev/null
+++ b/test/contact.test
@@ -0,0 +1,200 @@
+test Contact:
+ spawn as p1
+ spawn as p2
+ spawn as p3
+ spawn as p4
+
+ send "create-identity Device1 Owner1" to p1
+ send "create-identity Device2 Owner2" to p2
+ send "create-identity Device3 Owner3" to p3
+ send "create-identity Device4" to p4
+
+ send "start-server" to p1
+ send "start-server" to p2
+ send "start-server" to p3
+ send "start-server" to p4
+
+ expect from p1:
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer1_2
+ /peer $peer1_2 id Device2 Owner2/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer1_3
+ /peer $peer1_3 id Device3 Owner3/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer1_4
+ /peer $peer1_4 id Device4/
+
+ expect from p2:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer2_1
+ /peer $peer2_1 id Device1 Owner1/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer2_3
+ /peer $peer2_3 id Device3 Owner3/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer2_4
+ /peer $peer2_4 id Device4/
+
+ expect from p3:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer3_1
+ /peer $peer3_1 id Device1 Owner1/
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer3_2
+ /peer $peer3_2 id Device2 Owner2/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer3_4
+ /peer $peer3_4 id Device4/
+
+ expect from p4:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer4_1
+ /peer $peer4_1 id Device1 Owner1/
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer4_2
+ /peer $peer4_2 id Device2 Owner2/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer4_3
+ /peer $peer4_3 id Device3 Owner3/
+
+ # Rejected contacts
+
+ send "contact-request $peer1_2" to p1
+ expect /contact-request $peer2_1 [0-9]*/ from p2
+ expect /contact-response $peer1_2 [0-9]*/ from p1
+ send "contact-reject $peer1_2" to p1
+ expect /contact-request-failed $peer2_1 rejected/ from p2
+ expect /contact-response-failed $peer1_2 user/ from p1
+
+ send "contact-request $peer1_2" to p1
+ expect /contact-request $peer2_1 [0-9]*/ from p2
+ expect /contact-response $peer1_2 [0-9]*/ from p1
+ send "contact-reject $peer2_1" to p2
+ expect /contact-request-failed $peer2_1 user/ from p2
+ expect /contact-response-failed $peer1_2 rejected/ from p1
+
+ # Contact between 1 and 2
+
+ local:
+ send "contact-request $peer1_2" to p1
+ expect /contact-request $peer2_1 ([0-9]*)/ from p2 capture code2
+ expect /contact-response $peer1_2 ([0-9]*)/ from p1 capture code1
+ guard (code1 == code2)
+
+ send "contact-accept $peer1_2" to p1
+ send "contact-accept $peer2_1" to p2
+ expect /contact-request-done $peer2_1/ from p2
+ expect /contact-response-done $peer1_2/ from p1
+
+ send "contact-list" to p1
+ expect from p1:
+ /contact-list-item [a-z0-9#]+ Owner2 Owner2/
+ /contact-list-(.*)/ capture done1_1
+ guard (done1_1 == "done")
+ send "contact-list" to p2
+ expect from p2:
+ /contact-list-item [a-z0-9#]+ Owner1 Owner1/
+ /contact-list-(.*)/ capture done1_2
+ guard (done1_2 == "done")
+
+ # Attach peer 4 to Owner1
+
+ send "watch-local-identity" to p4
+ expect /local-identity Device4/ from p4
+
+ send "attach-to $peer4_1" to p4
+ local:
+ expect /attach-request $peer1_4 ([0-9]*)/ from p1 capture code1
+ expect /attach-response $peer4_1 ([0-9]*)/ from p4 capture code4
+ guard (code1 == code4)
+
+ send "attach-accept $peer1_4" to p1
+ send "attach-accept $peer4_1" to p4
+ expect /attach-request-done $peer1_4/ from p1
+ expect /attach-response-done $peer4_1/ from p4
+ expect /local-identity Device4 Owner1/ from p4
+ expect /peer $peer1_4 id Device4 Owner1/ from p1
+ expect /peer $peer2_4 id Device4 Owner1/ from p2
+ expect /peer $peer3_4 id Device4 Owner1/ from p3
+
+ # Contact between 3 and 4
+
+ send "contact-request $peer3_4" to p3
+ local:
+ expect /contact-request $peer4_3 ([0-9]*)/ from p4 capture code4
+ expect /contact-response $peer3_4 ([0-9]*)/ from p3 capture code3
+ guard (code3 == code4)
+
+ send "contact-accept $peer3_4" to p3
+ send "contact-accept $peer4_3" to p4
+ expect /contact-request-done $peer4_3/ from p4
+ expect /contact-response-done $peer3_4/ from p3
+
+ send "contact-list" to p3
+ expect from p3:
+ /contact-list-item [a-z0-9#]+ Owner1 Owner1/
+ /contact-list-(.*)/ capture done2_3
+ guard (done2_3 == "done")
+
+ send "shared-state-get" to p1
+ expect /shared-state-get (.*)/ from p1 capture s1
+ send "shared-state-wait $s1" to p4
+ expect /shared-state-wait $s1/ from p4
+
+ send "contact-list" to p4
+ expect from p4:
+ /contact-list-item ([a-z0-9#]+) Owner2 Owner2/ capture c4_2
+ /contact-list-item ([a-z0-9#]+) Owner3 Owner3/ capture c4_3
+ /contact-list-(.*)/ capture done2_4
+ guard (done2_4 == "done")
+
+ # Check sync between 1 and 4
+
+ send "shared-state-get" to p4
+ expect /shared-state-get (.*)/ from p4 capture s4
+ send "shared-state-wait $s4" to p1
+ expect /shared-state-wait $s4/ from p1
+
+ send "contact-list" to p1
+ expect from p1:
+ /contact-list-item ([a-z0-9#]+) Owner2 Owner2/ capture c1_2
+ /contact-list-item ([a-z0-9#]+) Owner3 Owner3/ capture c1_3
+ /contact-list-(.*)/ capture done2_1
+ guard (done2_1 == "done")
+
+ # Update custom name
+
+ send "contact-set-name $c4_2 Custom2" to p4
+ expect /contact-set-name-done/ from p4
+
+ send "contact-list" to p4
+ expect from p4:
+ /contact-list-item $c4_2 Custom2 Owner2/
+ /contact-list-item $c4_3 Owner3 Owner3/
+ /contact-list-(.*)/ capture done3_4
+ guard (done3_4 == "done")
+
+ send "shared-state-get" to p4
+ expect /shared-state-get (.*)/ from p4 capture s4b
+ send "shared-state-wait $s4b" to p1
+ expect /shared-state-wait $s4b/ from p1
+
+ send "contact-list" to p1
+ expect from p1:
+ /contact-list-item $c4_2 Custom2 Owner2/
+ /contact-list-item $c4_3 Owner3 Owner3/
+ /contact-list-(.*)/ capture done3_1
+ guard (done3_1 == "done")
+
+ send "contact-set-name $c1_2 Custom2B" to p1
+ expect /contact-set-name-done/ from p1
+ send "contact-set-name $c1_3 Custom3B" to p1
+ expect /contact-set-name-done/ from p1
+
+ send "contact-list" to p1
+ expect from p1:
+ /contact-list-item $c1_2 Custom2B Owner2/
+ /contact-list-item $c1_3 Custom3B Owner3/
+ /contact-list-(.*)/ capture done4_1
+ guard (done4_1 == "done")
+
+ send "shared-state-get" to p1
+ expect /shared-state-get (.*)/ from p1 capture s1b
+ send "shared-state-wait $s1b" to p4
+ expect /shared-state-wait $s1b/ from p4
+
+ send "contact-list" to p4
+ expect from p4:
+ /contact-list-item $c4_2 Custom2B Owner2/
+ /contact-list-item $c4_3 Custom3B Owner3/
+ /contact-list-(.*)/ capture done4_4
+ guard (done4_4 == "done")
diff --git a/test/message.test b/test/message.test
new file mode 100644
index 0000000..307f11a
--- /dev/null
+++ b/test/message.test
@@ -0,0 +1,149 @@
+test DirectMessage:
+ spawn as p1
+ spawn as p2
+ send "create-identity Device1 Owner1" to p1
+ send "create-identity Device2 Owner2" to p2
+ send "start-server" to p1
+ send "start-server" to p2
+
+ expect from p1:
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer1_2
+ /peer $peer1_2 id Device2 Owner2/
+
+ expect from p2:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer2_1
+ /peer $peer2_1 id Device1 Owner1/
+
+ with p1:
+ send "dm-list-peer $peer1_2"
+ expect /dm-list-done/
+
+ # Send messages to peers
+
+ for i in [1..2]:
+ send "dm-send-peer $peer1_2 hello$i" to p1
+ expect /dm-received from Owner1 text hello$i/ from p2
+
+ for i in [1..2]:
+ send "dm-send-peer $peer2_1 hi$i" to p2
+ expect /dm-received from Owner2 text hi$i/ from p1
+
+ for i in [3..4]:
+ send "dm-send-peer $peer1_2 hello$i" to p1
+ expect /dm-received from Owner1 text hello$i/ from p2
+ send "dm-send-peer $peer2_1 hi$i" to p2
+ expect /dm-received from Owner2 text hi$i/ from p1
+
+ # Create contacts
+
+ local:
+ send "contact-request $peer1_2" to p1
+ expect /contact-request $peer2_1 ([0-9]*)/ from p2 capture code2
+ expect /contact-response $peer1_2 ([0-9]*)/ from p1 capture code1
+ guard (code1 == code2)
+
+ send "contact-accept $peer1_2" to p1
+ send "contact-accept $peer2_1" to p2
+ expect /contact-request-done $peer2_1/ from p2
+ expect /contact-response-done $peer1_2/ from p1
+
+ send "contact-list" to p1
+ expect from p1:
+ /contact-list-item ([a-z0-9#]+) Owner2 Owner2/ capture c1_2
+ /contact-list-(.*)/ capture done1_1
+
+ send "contact-list" to p2
+ expect from p2:
+ /contact-list-item ([a-z0-9#]+) Owner1 Owner1/ capture c2_1
+ /contact-list-(.*)/ capture done1_2
+
+ # Send messages to contacts
+
+ for i in [1..2]:
+ send "dm-send-contact $c1_2 hello_c_$i" to p1
+ expect /dm-received from Owner1 text hello_c_$i/ from p2
+
+ for i in [1..2]:
+ send "dm-send-contact $c2_1 hi_c_$i" to p2
+ expect /dm-received from Owner2 text hi_c_$i/ from p1
+
+ for i in [3..4]:
+ send "dm-send-contact $c1_2 hello_c_$i" to p1
+ expect /dm-received from Owner1 text hello_c_$i/ from p2
+ send "dm-send-contact $c2_1 hi_c_$i" to p2
+ expect /dm-received from Owner2 text hi_c_$i/ from p1
+
+ send "dm-list-contact $c1_2" to p1
+ send "dm-list-contact $c2_1" to p2
+ for p in [p1, p2]:
+ with p:
+ for i in [1..4]:
+ expect /dm-list-item from Owner1 text hello_c_$i/
+ expect /dm-list-item from Owner2 text hi_c_$i/
+ for i in [1..4]:
+ expect /dm-list-item from Owner1 text hello$i/
+ expect /dm-list-item from Owner2 text hi$i/
+ expect /dm-list-(.*)/ capture done
+ guard (done == "done")
+
+ # Reload message history
+
+ for p in [p1, p2]:
+ with p:
+ send "stop-server"
+ for p in [p1, p2]:
+ with p:
+ expect /stop-server-done/
+ for p in [p1, p2]:
+ with p:
+ send "start-server"
+
+ with p1:
+ send "contact-list"
+ expect:
+ /contact-list-item $c1_2 Owner2 Owner2/
+ /contact-list-(.*)/ capture done
+ guard (done == "done")
+
+ send "dm-list-contact $c1_2" to p1
+ send "dm-list-contact $c2_1" to p2
+ for p in [p1, p2]:
+ with p:
+ for i in [1..4]:
+ expect /dm-list-item from Owner1 text hello_c_$i/
+ expect /dm-list-item from Owner2 text hi_c_$i/
+ for i in [1..4]:
+ expect /dm-list-item from Owner1 text hello$i/
+ expect /dm-list-item from Owner2 text hi$i/
+ expect /dm-list-(.*)/ capture done
+ guard (done == "done")
+
+ # Send message while offline
+
+ for p in [p1, p2]:
+ with p:
+ send "stop-server"
+ for p in [p1, p2]:
+ with p:
+ expect /stop-server-done/
+ send "start-server" to p2
+
+ send "dm-send-contact $c1_2 while_offline" to p1
+ send "start-server" to p1
+
+ expect /dm-received from Owner1 text while_offline/ from p2
+
+ for p in [p1, p2]:
+ with p:
+ send "stop-server"
+ for p in [p1, p2]:
+ with p:
+ expect /stop-server-done/
+ send "start-server" to p1
+
+ send "dm-send-contact $c1_2 while_peer_offline" to p1
+ # TODO: sync from p1 on peer p2 discovery not ensured without addition wait
+ #wait
+ send "start-server" to p2
+
+ expect /dm-received from Owner1 text while_peer_offline/ from p2
diff --git a/test/network.test b/test/network.test
new file mode 100644
index 0000000..3df7376
--- /dev/null
+++ b/test/network.test
@@ -0,0 +1,146 @@
+test Discovery:
+ spawn as p1
+ spawn as p2
+ send "create-identity Device1 Owner" to p1
+ send "create-identity Device2" to p2
+ send "start-server" to p1
+ send "start-server" to p2
+ expect from p1:
+ /peer 1 addr ${p2.node.ip} 29665/
+ /peer 1 id Device2/
+ expect from p2:
+ /peer 1 addr ${p1.node.ip} 29665/
+ /peer 1 id Device1 Owner/
+
+ send "update-local-identity Device1A" to p1
+ expect /peer 1 id Device1A Owner/ from p2
+
+ send "update-shared-identity OwnerA" to p1
+ expect /peer 1 id Device1A OwnerA/ from p2
+
+ send "update-local-identity Device1B" to p1
+ expect /peer 1 id Device1B OwnerA/ from p2
+
+ send "update-shared-identity OwnerB" to p1
+ expect /peer 1 id Device1B OwnerB/ from p2
+
+ with p2:
+ send "stop-server"
+ expect /stop-server-done/
+
+ send "update-shared-identity OwnerC" to p1
+
+ with p1:
+ send "stop-server"
+ expect /stop-server-done/
+
+ spawn as p3
+ spawn as p4
+ spawn as p5
+ spawn as p6
+ send "create-identity Device3" to p3
+ send "create-identity Device4" to p4
+ send "create-identity Device5" to p5
+ send "create-identity Device6" to p6
+
+ for p in [ p1, p2, p3, p4, p5, p6 ]:
+ send "start-server" to p
+
+ expect from p1:
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer1_2
+ /peer $peer1_2 id Device2/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer1_3
+ /peer $peer1_3 id Device3/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer1_4
+ /peer $peer1_4 id Device4/
+ /peer ([0-9]+) addr ${p5.node.ip} 29665/ capture peer1_5
+ /peer $peer1_5 id Device5/
+ /peer ([0-9]+) addr ${p6.node.ip} 29665/ capture peer1_6
+ /peer $peer1_6 id Device6/
+
+ expect from p2:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer2_1
+ /peer $peer2_1 id Device1B OwnerC/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer2_3
+ /peer $peer2_3 id Device3/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer2_4
+ /peer $peer2_4 id Device4/
+ /peer ([0-9]+) addr ${p5.node.ip} 29665/ capture peer2_5
+ /peer $peer2_5 id Device5/
+ /peer ([0-9]+) addr ${p6.node.ip} 29665/ capture peer2_6
+ /peer $peer2_6 id Device6/
+
+ expect from p3:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer3_1
+ /peer $peer3_1 id Device1B OwnerC/
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer3_2
+ /peer $peer3_2 id Device2/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer3_4
+ /peer $peer3_4 id Device4/
+ /peer ([0-9]+) addr ${p5.node.ip} 29665/ capture peer3_5
+ /peer $peer3_5 id Device5/
+ /peer ([0-9]+) addr ${p6.node.ip} 29665/ capture peer3_6
+ /peer $peer3_6 id Device6/
+
+ expect from p4:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer4_1
+ /peer $peer4_1 id Device1B OwnerC/
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer4_2
+ /peer $peer4_2 id Device2/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer4_3
+ /peer $peer4_3 id Device3/
+ /peer ([0-9]+) addr ${p5.node.ip} 29665/ capture peer4_5
+ /peer $peer4_5 id Device5/
+ /peer ([0-9]+) addr ${p6.node.ip} 29665/ capture peer4_6
+ /peer $peer4_6 id Device6/
+
+ expect from p5:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer5_1
+ /peer $peer5_1 id Device1B OwnerC/
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer5_2
+ /peer $peer5_2 id Device2/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer5_3
+ /peer $peer5_3 id Device3/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer5_4
+ /peer $peer5_4 id Device4/
+ /peer ([0-9]+) addr ${p6.node.ip} 29665/ capture peer5_6
+ /peer $peer5_6 id Device6/
+
+ expect from p6:
+ /peer ([0-9]+) addr ${p1.node.ip} 29665/ capture peer6_1
+ /peer $peer6_1 id Device1B OwnerC/
+ /peer ([0-9]+) addr ${p2.node.ip} 29665/ capture peer6_2
+ /peer $peer6_2 id Device2/
+ /peer ([0-9]+) addr ${p3.node.ip} 29665/ capture peer6_3
+ /peer $peer6_3 id Device3/
+ /peer ([0-9]+) addr ${p4.node.ip} 29665/ capture peer6_4
+ /peer $peer6_4 id Device4/
+ /peer ([0-9]+) addr ${p5.node.ip} 29665/ capture peer6_5
+ /peer $peer6_5 id Device5/
+
+
+test LargeData:
+ spawn as p1
+ spawn as p2
+ send "create-identity Device1" to p1
+ send "create-identity Device2" to p2
+ send "start-server" to p1
+ send "start-server" to p2
+ expect from p1:
+ /peer 1 addr ${p2.node.ip} 29665/
+ /peer 1 id Device2/
+ expect from p2:
+ /peer 1 addr ${p1.node.ip} 29665/
+ /peer 1 id Device1/
+
+ for i in [0..10]:
+ with p1:
+ send "store blob"
+ for j in [1 .. i * 10]:
+ send "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789"
+ send ""
+ expect /store-done (blake2#[0-9a-f]*)/ capture ref
+
+ send "test-message-send 1 $ref"
+ expect /test-message-send done/
+ expect /test-message-received blob ${i*1000} $ref/ from p2
diff --git a/test/storage.test b/test/storage.test
new file mode 100644
index 0000000..9bf468e
--- /dev/null
+++ b/test/storage.test
@@ -0,0 +1,201 @@
+test Storage:
+ spawn as p1
+
+ # Root finding
+ ###############
+
+ # Diamond history
+ send to p1:
+ "store rec"
+ "text:t First root"
+ ""
+ expect from p1:
+ /store-done (blake2#[0-9a-f]*)/ capture r1
+ guard (r1 == "blake2#c4a8c69fbc8398acf76a2ec1e5a191f339c4d03c3eb425af19d6d7d5efac6b8e")
+
+ send to p1:
+ "store rec"
+ "PREV:r $r1"
+ ""
+ expect from p1:
+ /store-done (blake2#[0-9a-f]*)/ capture r2
+
+ send to p1:
+ "store rec"
+ "text:t Second branch"
+ "PREV:r $r1"
+ ""
+ expect from p1:
+ /store-done (blake2#[0-9a-f]*)/ capture r3
+
+ send to p1:
+ "store rec"
+ "PREV:r $r2"
+ "PREV:r $r3"
+ ""
+ expect from p1:
+ /store-done (blake2#[0-9a-f]*)/ capture r4
+
+ send to p1 "stored-generation $r1"
+ expect from p1 /stored-generation $r1 0/
+
+ send to p1 "stored-generation $r2"
+ expect from p1 /stored-generation $r2 1/
+
+ send to p1 "stored-generation $r3"
+ expect from p1 /stored-generation $r3 1/
+
+ send to p1 "stored-generation $r4"
+ expect from p1 /stored-generation $r4 2/
+
+ send to p1 "stored-roots $r1"
+ expect from p1 /stored-roots $r1 $r1/
+
+ send to p1 "stored-roots $r2"
+ expect from p1 /stored-roots $r2 $r1/
+
+ send to p1 "stored-roots $r3"
+ expect from p1 /stored-roots $r3 $r1/
+
+ send to p1 "stored-roots $r4"
+ expect from p1 /stored-roots $r4 $r1/
+
+ # Attach second root
+ send to p1:
+ "store rec"
+ "text:t Second root"
+ ""
+ expect from p1:
+ /store-done (blake2#[0-9a-f]*)/ capture r2_1
+
+ send to p1:
+ "store rec"
+ "PREV:r $r2_1"
+ ""
+ expect from p1:
+ /store-done (blake2#[0-9a-f]*)/ capture r2_2
+
+ send to p1:
+ "store rec"
+ "PREV:r $r2_2"
+ "PREV:r $r4"
+ ""
+ expect from p1:
+ /store-done (blake2#[0-9a-f]*)/ capture r2_3
+
+ send to p1 "stored-generation $r2_3"
+ expect from p1 /stored-generation $r2_3 3/
+
+ send to p1 "stored-generation $r2_2"
+ expect from p1 /stored-generation $r2_2 1/
+
+ send to p1 "stored-roots $r2_3"
+ expect from p1 /stored-roots $r2_3 $r2_1 $r1/
+
+ send to p1 "stored-roots $r2_2"
+ expect from p1 /stored-roots $r2_2 $r2_1/
+
+
+ # Set
+ #####
+
+ send to p1 "stored-set-add $r1"
+ expect from p1 /stored-set-add (blake2#[0-9a-f]*)/ capture s1
+ send to p1 "stored-set-add $r2 $s1"
+ expect from p1 /stored-set-add (blake2#[0-9a-f]*)/ capture s2
+ send to p1 "stored-set-add $r3 $s2"
+ expect from p1 /stored-set-add (blake2#[0-9a-f]*)/ capture s3
+ send to p1 "stored-set-add $r4 $s3"
+ expect from p1 /stored-set-add (blake2#[0-9a-f]*)/ capture s4
+
+ send to p1 "stored-set-list $s1"
+ expect from p1:
+ /stored-set-item $r1/
+ /stored-set-(.*)/ capture done1
+ guard (done1 == "done")
+
+ send to p1 "stored-set-list $s2"
+ expect from p1:
+ /stored-set-item $r2/
+ /stored-set-(.*)/ capture done2
+ guard (done2 == "done")
+
+ send to p1 "stored-set-list $s3"
+ expect from p1:
+ /stored-set-item $r2 $r3/
+ /stored-set-(.*)/ capture done3
+ guard (done3 == "done")
+
+ send to p1 "stored-set-list $s4"
+ expect from p1:
+ /stored-set-item $r4/
+ /stored-set-(.*)/ capture done4
+ guard (done4 == "done")
+
+
+ send to p1 "stored-set-add $r2_2 $s4"
+ expect from p1 /stored-set-add (blake2#[0-9a-f]*)/ capture s5
+ send to p1 "stored-set-add $r2_3 $s5"
+ expect from p1 /stored-set-add (blake2#[0-9a-f]*)/ capture s6
+
+ send to p1 "stored-set-list $s5"
+ expect from p1:
+ /stored-set-item $r4/
+ /stored-set-item $r2_2/
+ /stored-set-(.*)/ capture done5
+ guard (done5 == "done")
+
+ send to p1 "stored-set-list $s6"
+ expect from p1:
+ /stored-set-item $r2_3/
+ /stored-set-(.*)/ capture done6
+ guard (done6 == "done")
+
+
+test StorageWatcher:
+ spawn as p1
+ spawn as p2
+ send "create-identity Device1 Owner" to p1
+ send "create-identity Device2" to p2
+ send "watch-local-identity" to p1
+ send "watch-local-identity" to p2
+ send "start-server" to p1
+ send "start-server" to p2
+ expect from p1:
+ /local-identity Device1 Owner/
+ /peer 1 addr ${p2.node.ip} 29665/
+ /peer 1 id Device2/
+ expect from p2:
+ /local-identity Device2/
+ /peer 1 addr ${p1.node.ip} 29665/
+ /peer 1 id Device1 Owner/
+
+ local:
+ send "attach-to 1" to p2
+ expect /attach-request 1 ([0-9]*)/ from p1 capture code1
+ expect /attach-response 1 ([0-9]*)/ from p2 capture code2
+ guard (code1 == code2)
+
+ send "attach-accept 1" to p1
+ send "attach-accept 1" to p2
+ expect /attach-request-done 1/ from p1
+ expect /attach-response-done 1/ from p2
+ expect /local-identity Device2 Owner/ from p2
+ expect /peer 1 id Device2 Owner/ from p1
+
+ for i in [1..5]:
+ send "update-local-identity Owner2" to p1
+ send "shared-state-get" to p1
+ expect /shared-state-get (.*)/ from p1 capture s1
+
+ send "shared-state-wait $s1" to p2
+ expect /shared-state-wait $s1/ from p2
+
+ send "update-local-identity Owner1" to p1
+ send "shared-state-get" to p1
+ expect /shared-state-get (.*)/ from p1 capture s2
+
+ send "shared-state-wait $s1" to p2
+ send "shared-state-wait $s2" to p2
+ expect /shared-state-wait $s1/ from p2
+ expect /shared-state-wait $s2/ from p2
diff --git a/test/sync.test b/test/sync.test
new file mode 100644
index 0000000..ea9595d
--- /dev/null
+++ b/test/sync.test
@@ -0,0 +1,93 @@
+test:
+ spawn as p1
+ spawn as p2
+ send "create-identity Device1 Owner" to p1
+ send "create-identity Device2" to p2
+ send "watch-local-identity" to p1
+ send "watch-local-identity" to p2
+ send "watch-shared-identity" to p1
+ send "watch-shared-identity" to p2
+ send "start-server" to p1
+ send "start-server" to p2
+ expect from p1:
+ /local-identity Device1 Owner/
+ /shared-identity Owner/
+ /peer 1 addr ${p2.node.ip} 29665/
+ /peer 1 id Device2/
+ expect from p2:
+ /local-identity Device2/
+ /peer 1 addr ${p1.node.ip} 29665/
+ /peer 1 id Device1 Owner/
+
+ send "attach-to 1" to p2
+ local:
+ expect /attach-request 1 ([0-9]*)/ from p1 capture code1
+ expect /attach-response 1 ([0-9]*)/ from p2 capture code2
+ guard (code1 == code2)
+
+ send "attach-accept 1" to p1
+ send "attach-accept 1" to p2
+ expect /attach-request-done 1/ from p1
+ expect /attach-response-done 1/ from p2
+ expect /local-identity Device2 Owner/ from p2
+ expect /shared-identity Owner/ from p2
+ expect /peer 1 id Device2 Owner/ from p1
+
+ send "update-shared-identity NewOwner" to p1
+ expect /shared-identity NewOwner/ from p1
+ expect /shared-identity NewOwner/ from p2
+
+ send "update-shared-identity NewOwner2" to p2
+ expect /shared-identity NewOwner2/ from p1
+ expect /shared-identity NewOwner2/ from p2
+
+ send "update-shared-identity NewOwner3" to p1
+ expect /shared-identity NewOwner3/ from p1
+ expect /shared-identity NewOwner3/ from p2
+
+ send "shared-state-get" to p1
+ expect /shared-state-get (.*)/ from p1 capture p1state
+ send "shared-state-wait $p1state" to p2
+ expect /shared-state-wait $p1state/ from p2
+
+ subnet s
+ spawn on s as p3
+
+ with p3:
+ send "create-identity Device3"
+ send "watch-local-identity"
+ send "watch-shared-identity"
+ send "start-server"
+
+ send "peer-add ${p1.node.ip}"
+
+ expect:
+ /local-identity Device3/
+ /peer 1 addr ${p1.node.ip} 29665/
+ /peer 1 id Device1 NewOwner3/
+
+ expect from p1:
+ /peer 2 addr ${p3.node.ip} 29665/
+ /peer 2 id Device3/
+
+ send "attach-to 1" to p3
+ local:
+ expect /attach-request 2 ([0-9]*)/ from p1 capture code1
+ expect /attach-response 1 ([0-9]*)/ from p3 capture code2
+ guard (code1 == code2)
+
+ send "attach-accept 2" to p1
+ send "attach-accept 1" to p3
+
+ expect /local-identity Device3 NewOwner3/ from p3
+ expect /shared-identity NewOwner3/ from p3
+
+ send "update-shared-identity NewOwner4" to p3
+ expect /shared-identity NewOwner4/ from p1
+ expect /shared-identity NewOwner4/ from p2
+ expect /shared-identity NewOwner4/ from p3
+
+ send "update-shared-identity NewOwner5" to p2
+ expect /shared-identity NewOwner5/ from p1
+ expect /shared-identity NewOwner5/ from p2
+ expect /shared-identity NewOwner5/ from p3