chiark / gitweb /
svc/connect.in: Add a new `sabotage' command to test ping-failure actions.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 8 Sep 2017 09:28:45 +0000 (10:28 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 14 Jun 2018 09:34:25 +0000 (10:34 +0100)
svc/connect.8.in
svc/connect.in

index 0d951bf7ba1aad69255cbabe7f997813c389a440..91dfd63142616a41d414bb021d14ff9eee5245da 100644 (file)
@@ -657,6 +657,17 @@ seconds are assumed.
 .\"-opts
 .RE
 .SP
+.BI "sabotage " peer
+Sabotage the
+.I peer
+so that
+.B connect
+thinks that it can't respond to pings.  This will usually provoke a
+reconnection attempt.  Use
+.B kick
+instead unless you're trying to test
+.BR connect .
+.SP
 .BI "userpeer " user
 Output a single
 .B INFO
index e8981411f2da38a7844c9db852c1b9e2c61c0ad5..dea2f905262d1b5441c2a71e0a1a3930f8faf1bf 100644 (file)
@@ -396,6 +396,7 @@ class PingPeer (object):
     me.seq = _pingseq
     _pingseq += 1
     me._failures = 0
+    me._sabotage = False
     me._last = '-'
     me._nping = 0
     me._nlost = 0
@@ -441,6 +442,7 @@ class PingPeer (object):
       S.forcekx(me._peer)
       T.spawn(run_connect, peer, peer.get('connect'))
       me._timer = M.SelTimer(time() + me._every, me._time)
+      me._sabotage = False
     else:
       S.kill(me._peer)
 
@@ -468,7 +470,10 @@ class PingPeer (object):
       elif stuff[0] == 'ping-send-failed':
         me._reconnect()
     elif code == 'INFO':
-      if stuff[0] == 'ping-ok':
+      outcome = stuff[0]
+      if outcome == 'ping-ok' and me._sabotage:
+        outcome = 'ping-timeout'
+      if outcome == 'ping-ok':
         if me._failures > 0:
           S.warn('connect', 'ping-ok', me._peer)
         t = float(stuff[1])
@@ -479,7 +484,7 @@ class PingPeer (object):
         if me._min == '-' or t < me._min: me._min = t
         if me._max == '-' or t > me._max: me._max = t
         me._timer = M.SelTimer(time() + me._every, me._time)
-      elif stuff[0] == 'ping-timeout':
+      elif outcome == 'ping-timeout':
         me._failures += 1
         me._nlost += 1
         S.warn('connect', 'ping-timeout', me._peer,
@@ -489,9 +494,16 @@ class PingPeer (object):
           me._last = 'timeout'
         else:
           me._reconnect()
-      elif stuff[0] == 'ping-peer-died':
+          me._last = 'reconnect'
+      elif outcome == 'ping-peer-died':
         me._pinger.kill(me._peer)
 
+  def sabotage(me):
+    """Sabotage the peer, for testing purposes."""
+    me._sabotage = True
+    if me._timer: me._timer.kill()
+    T.defer(me._time)
+
   def info(me):
     if not me._nping:
       mean = sd = '-'
@@ -844,6 +856,14 @@ def cmd_passive(*args):
   finally:
     del chalmap[chal]
 
+def cmd_sabotage(name):
+  """
+  sabotage NAME: Sabotage the NAMEd peer so that we think it can't be pinged.
+  """
+  try: pp = pinger.find(name)
+  except KeyError: raise T.TripeJobError('unknown-peer', name)
+  pp.sabotage()
+
 ###--------------------------------------------------------------------------
 ### Start up.
 
@@ -927,7 +947,8 @@ service_info = [('connect', T.VERSION, {
   'active': (1, 1, 'PEER', cmd_active),
   'info': (1, 1, 'PEER', cmd_info),
   'list-active': (0, 0, '', cmd_listactive),
-  'userpeer': (1, 1, 'USER', cmd_userpeer)
+  'userpeer': (1, 1, 'USER', cmd_userpeer),
+  'sabotage': (1, 1, 'PEER', cmd_sabotage)
 })]
 
 if __name__ == '__main__':