test/custody-transfer.tcl
changeset 0 2b3e5ec03512
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/custody-transfer.tcl	Thu Apr 21 14:57:45 2011 +0100
@@ -0,0 +1,289 @@
+#
+#    Copyright 2006 Intel Corporation
+# 
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+# 
+#        http://www.apache.org/licenses/LICENSE-2.0
+# 
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+test::name custody-transfer
+net::num_nodes 4
+set clayer tcp
+foreach {var val} $opt(opts) {
+    if {$var == "-cl" } {
+        set clayer $val
+    }
+}
+
+
+dtn::config
+
+dtn::config_interface $clayer
+dtn::config_linear_topology OPPORTUNISTIC $clayer true
+
+test::script {
+    testlog "running dtnds"
+    dtn::run_dtnd *
+    
+    testlog "waiting for dtnds to start up"
+    dtn::wait_for_dtnd *
+    
+    set N [net::num_nodes]
+    set src dtn://host-0/test
+    set dst dtn://host-[expr $N - 1]/test
+    set src_route dtn://host-0/*
+    set dst_route dtn://host-[expr $N - 1]/*
+    
+    for {set i 0} {$i < $N} {incr i} {
+	dtn::tell_dtnd $i tcl_registration dtn://host-$i/test
+    }
+
+    testlog "*"
+    testlog "* Test 1: basic custody transfer"
+    testlog "*"
+    
+    testlog "sending bundle with custody transfer"
+    set timestamp [dtn::tell_dtnd 0 sendbundle $src $dst custody]
+
+    testlog "checking that node 0 got the bundle"
+    dtn::wait_for_bundle_stats 0 {1 received 0 transmitted}
+    dtn::wait_for_bundle_stats 1 {0 received 0 transmitted}
+    dtn::wait_for_bundle_stats 2 {0 received 0 transmitted}
+    dtn::wait_for_bundle_stats 3 {0 received 0 transmitted}
+
+    testlog "checking that node 0 took custody"
+    dtn::wait_for_bundle_stats 0 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 1 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "opening link from 0-1"
+    dtn::tell_dtnd 0 link open $clayer-link:0-1
+    dtn::wait_for_link_state 0 $clayer-link:0-1 OPEN
+
+    testlog "checking that custody was transferred"
+    dtn::wait_for_bundle_stats 0 {2 received 1 transmitted}
+    dtn::wait_for_bundle_stats 1 {1 received 1 generated 1 transmitted}
+    dtn::wait_for_bundle_stats 2 {0 received 0 transmitted}
+    dtn::wait_for_bundle_stats 3 {0 received 0 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "open the rest of the links, check delivery"
+    dtn::tell_dtnd 1 link open $clayer-link:1-2
+    dtn::tell_dtnd 2 link open $clayer-link:2-3
+
+    dtn::wait_for_bundle_stats 3 {1 delivered}
+    dtn::wait_for_bundle 3 "$src,$timestamp" 30
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "*"
+    testlog "* Test 2: custody timer retransmission"
+    testlog "*"
+
+    dtn::tell_dtnd * bundle reset_stats
+
+    set custody_timer_opts "custody_timer_min=5 custody_timer_lifetime_pct=0"
+
+    testlog "removing route from node 1"
+    dtn::tell_dtnd 1 route del $dst_route
+
+    testlog "sending another bundle, checking that node 1 has custody"
+    set timestamp [dtn::tell_dtnd 0 sendbundle $src $dst custody]
+    
+    dtn::wait_for_bundle_stats 0 {2 received 1 transmitted}
+    dtn::wait_for_bundle_stats 1 {1 received 1 generated 1 transmitted}
+    dtn::wait_for_bundle_stats 2 {0 received 0 transmitted}
+    dtn::wait_for_bundle_stats 3 {0 received 0 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "adding route to null on node 1, checking transmitted"
+    eval dtn::tell_dtnd 1 route add $dst_route null $custody_timer_opts
+
+    dtn::wait_for_bundle_stats 0 {2 received 1 transmitted}
+    dtn::wait_for_bundle_stats 1 {1 received 1 generated 2 transmitted}
+    dtn::wait_for_bundle_stats 2 {0 received 0 transmitted}
+    dtn::wait_for_bundle_stats 3 {0 received 0 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "waiting for a couple retransmissions"
+
+    dtn::wait_for_bundle_stats 0 {2 received 1 transmitted}
+    dtn::wait_for_bundle_stats 1 {1 received 4 transmitted}
+    dtn::wait_for_bundle_stats 2 {0 received 0 transmitted}
+    dtn::wait_for_bundle_stats 3 {0 received 0 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "switching route back, waiting for retransmission and delivery"
+    dtn::tell_dtnd 1 route del $dst_route
+    eval dtn::tell_dtnd 1 route add $dst_route $clayer-link:1-2 $custody_timer_opts
+
+    dtn::wait_for_bundle_stats 0 {2 received 1 transmitted}
+    dtn::wait_for_bundle_stats 1 {2 received 5 transmitted}
+    dtn::wait_for_bundle_stats 2 {2 received 2 transmitted}
+    dtn::wait_for_bundle_stats 3 {1 received 1 transmitted}
+    
+    dtn::wait_for_bundle_stats 3 {1 delivered}
+    dtn::wait_for_bundle 3 "$src,$timestamp" 30
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "*"
+    testlog "* Test 3: duplicate detection"
+    testlog "*"
+
+    dtn::tell_dtnd * bundle reset_stats
+
+    set custody_timer_opts "custody_timer_min=5 custody_timer_lifetime_pct=0"
+
+    testlog "speeding up custody timer for route on node 0"
+    dtn::tell_dtnd 0 route del $dst_route
+    eval dtn::tell_dtnd 0 route add $dst_route $clayer-link:0-1 $custody_timer_opts
+    
+    testlog "removing destination route for node 1"
+    dtn::tell_dtnd 1 route del $dst_route
+    
+    testlog "switching reverse route for node 1 to null"
+    dtn::tell_dtnd 1 route del $src_route
+    dtn::tell_dtnd 1 route add $src_route null
+
+    testlog "sending another bundle"
+    set timestamp [dtn::tell_dtnd 0 sendbundle $src $dst custody]
+
+    testlog "checking that node 1 and node 0 both have custody"
+    dtn::wait_for_bundle_stats 0 {1 received 1 transmitted}
+    dtn::wait_for_bundle_stats 1 {1 received 1 generated 1 transmitted}
+    dtn::wait_for_bundle_stats 2 {0 received 0 transmitted}
+    dtn::wait_for_bundle_stats 3 {0 received 0 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "waiting for a retransmission, making sure duplicate is deleted"
+    dtn::wait_for_bundle_stats 0 {1 received 2 transmitted}
+    dtn::wait_for_bundle_stats 1 {2 received 2 generated 2 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {1 pending 1 custody}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody}
+
+    testlog "flipping back the route from 1 to 0"
+    dtn::tell_dtnd 1 route del $src_route
+    dtn::tell_dtnd 1 route add $src_route $clayer-link:1-0
+
+    testlog "waiting for another retransmission, checking custody transferred"
+    dtn::wait_for_bundle_stats 0 {2 received 3 transmitted}
+    dtn::wait_for_bundle_stats 1 {3 received 3 generated 3 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody}
+
+    testlog "adding route back to 1 and waiting for delivery"
+    dtn::tell_dtnd 1 route del $dst_route
+    dtn::tell_dtnd 1 route add $dst_route $clayer-link:1-2
+
+    dtn::wait_for_bundle_stats 3 {1 delivered}
+    dtn::wait_for_bundle 3 "$src,$timestamp" 30
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 1 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 2 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 3 {0 pending 0 custody}
+
+    testlog "*"
+    testlog "* Test 4: bundle expiration with custody"
+    testlog "*"
+    dtn::tell_dtnd * bundle reset_stats
+
+    testlog "removing route for node 1"
+    dtn::tell_dtnd 1 route del $dst_route
+
+    testlog "sending bundle, checking custody transfer"
+    set timestamp [dtn::tell_dtnd 0 sendbundle $src $dst custody expiration=10]
+    
+    dtn::wait_for_bundle_stats 0 {2 received 1 transmitted}
+    dtn::wait_for_bundle_stats 1 {1 received 1 generated 1 transmitted}
+    
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody 1 delivered}
+    dtn::wait_for_bundle_stats 1 {1 pending 1 custody 0 delivered}
+
+    testlog "waiting for bundle to expire"
+    dtn::wait_for_bundle_stats 1 {1 expired}
+
+    testlog "checking that custody was cleaned up"
+    dtn::wait_for_bundle_stats 1 {0 pending 0 custody}
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody}
+
+    testlog "checking that expiration status report was delivered"
+    dtn::wait_for_bundle_stats 0 {2 delivered}
+
+    testlog "re-adding route"
+    dtn::tell_dtnd 1 route add $dst_route $clayer-link:1-2
+
+    testlog "*"
+    testlog "* Test 5: delivery before taking custody"
+    testlog "*"
+
+    dtn::tell_dtnd * bundle reset_stats
+
+    testlog "disabling custody acceptance on node 0"
+    dtn::tell_dtnd 0 param set accept_custody 0
+
+    testlog "sending a bundle to a nonexistant registration"
+    set dst2 "dtn://host-0/test2"
+    set timestamp [dtn::tell_dtnd 0 sendbundle $src $dst2 custody expiration=10]
+
+    testlog "checking that it is pending with no custodian"
+    dtn::wait_for_bundle_stats 0 {1 received 1 pending 0 custody}
+
+    testlog "adding a registration, checking delivery"
+    dtn::tell_dtnd 0 tcl_registration $dst2
+    dtn::wait_for_bundle_stats 0 {0 pending 0 custody 1 delivered}
+    
+    # XXX/TODO: add support / test cases for:
+    #
+    # restart posts a new custody timer
+    # noroute timer
+    # no contact timer
+    # retransmission over an ONDEMAND link that's gone idle
+    # multiple routes, ensure retransmission only on one
+    # race between bundle delete and custody timer cancelling
+    
+    testlog "test success!"
+}
+
+test::exit_script {
+    testlog "stopping all dtnds"
+    dtn::stop_dtnd *
+}