Browse Source

[1261] implemented IXFRDelete class (state)

JINMEI Tatuya 13 years ago
parent
commit
dc5aa6284f
2 changed files with 38 additions and 3 deletions
  1. 25 0
      src/bin/xfrin/tests/xfrin_test.py
  2. 13 3
      src/bin/xfrin/xfrin.py.in

+ 25 - 0
src/bin/xfrin/tests/xfrin_test.py

@@ -272,6 +272,31 @@ class TestXfrinIAXFDeleteSOA(TestXfrinState):
         self.assertRaises(XfrinException, self.state.handle_rr, self.conn,
                           self.ns_rrset)
 
+class TestXfrinIAXFDelete(TestXfrinState):
+    def setUp(self):
+        super().setUp()
+        XfrinIXFRDelete().set_xfrstate(self.conn, XfrinIXFRDelete())
+        self.state = self.conn.get_xfrstate()
+
+    def test_handle_delete_rr(self):
+        # Non SOA RRs are simply (goting to be) removed in this state
+        self.assertTrue(self.state.handle_rr(self.conn, self.ns_rrset))
+        self.assertEqual([('remove', self.ns_rrset)],
+                         self.conn._diff.get_buffer())
+        # The state shouldn't change
+        self.assertEqual(type(XfrinIXFRDelete()),
+                         type(self.conn.get_xfrstate()))
+
+    def test_handle_soa(self):
+        # SOA in this state means the beginning of added RRs.  This SOA
+        # should also be added in the next state, so handle_rr() should return
+        # false.
+        self.assertFalse(self.state.handle_rr(self.conn, soa_rrset))
+        self.assertEqual([], self.conn._diff.get_buffer())
+        self.assertEqual(1234, self.conn._current_serial)
+        self.assertEqual(type(XfrinAddSOA()),
+                         type(self.conn.get_xfrstate()))
+
 class TestXfrinConnection(unittest.TestCase):
     def setUp(self):
         if os.path.exists(TEST_DB_FILE):

+ 13 - 3
src/bin/xfrin/xfrin.py.in

@@ -181,17 +181,26 @@ class XfrinIXFRDeleteSOA(XfrinState):
     def handle_rr(self, conn, rr):
         if rr.get_type() != RRType.SOA():
             # this shouldn't happen; should this occur it means an internal
-            # bug.
+            #
             raise XfrinException(rr.get_type().to_text() + \
                                      ' RR is given in IXFRDeleteSOA state')
         conn._diff.remove_data(rr)
         self.set_xfrstate(conn, XfrinIXFRDelete())
         return True
 
-class XfrinAXFR(XfrinState):
+class XfrinIXFRDelete(XfrinState):
+    def handle_rr(self, conn, rr):
+        if rr.get_type() == RRType.SOA():
+            conn._current_serial = get_soa_serial(rr.get_rdata()[0])
+            self.set_xfrstate(conn, XfrinAddSOA())
+            return False
+        conn._diff.remove_data(rr)
+        return True
+
+class XfrinAddSOA(XfrinState):
     pass
 
-class XfrinIXFRDelete(XfrinState):
+class XfrinAXFR(XfrinState):
     pass
 
 class XfrinConnection(asyncore.dispatcher):
@@ -212,6 +221,7 @@ class XfrinConnection(asyncore.dispatcher):
         # transfer type may differ due to IXFR->AXFR fallback:
         self._request_type = None
         self._end_serial = None # essentially private
+        self._current_serial = None
         self.create_socket(master_addrinfo[0], master_addrinfo[1])
         self._zone_name = zone_name
         self._sock_map = sock_map