Browse Source

[1261] implemented IXFRDeleteSOA class (state)

JINMEI Tatuya 13 years ago
parent
commit
15e60f1f54
2 changed files with 53 additions and 12 deletions
  1. 39 10
      src/bin/xfrin/tests/xfrin_test.py
  2. 14 2
      src/bin/xfrin/xfrin.py.in

+ 39 - 10
src/bin/xfrin/tests/xfrin_test.py

@@ -18,6 +18,7 @@ import socket
 import io
 import io
 from isc.testutils.tsigctx_mock import MockTSIGContext
 from isc.testutils.tsigctx_mock import MockTSIGContext
 from xfrin import *
 from xfrin import *
+from isc.xfrin.diff import Diff
 import isc.log
 import isc.log
 
 
 #
 #
@@ -178,10 +179,30 @@ class TestXfrinState(unittest.TestCase):
                                         TEST_RRCLASS, TEST_DB_FILE,
                                         TEST_RRCLASS, TEST_DB_FILE,
                                         threading.Event(),
                                         threading.Event(),
                                         TEST_MASTER_IPV4_ADDRINFO)
                                         TEST_MASTER_IPV4_ADDRINFO)
+        self.begin_soa = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.SOA(),
+                               RRTTL(3600))
+        self.begin_soa.add_rdata(Rdata(RRType.SOA(), TEST_RRCLASS,
+                                       'm. r. 1230 0 0 0 0'))
         self.ns_rrset = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.NS(),
         self.ns_rrset = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.NS(),
                               RRTTL(3600))
                               RRTTL(3600))
         self.ns_rrset.add_rdata(Rdata(RRType.NS(), TEST_RRCLASS,
         self.ns_rrset.add_rdata(Rdata(RRType.NS(), TEST_RRCLASS,
                                       'ns.example.com'))
                                       'ns.example.com'))
+        self.__data_operations = []
+        self.conn._diff = Diff(self, TEST_ZONE_NAME)
+
+    # The following methods are to emulate a data source updater used by
+    # the Diff object.  For our testing purposes they can simply be no-op.
+    def get_updater(self, zone_name, replace):
+        return self
+
+    def add_rrset(self, rrset):
+        pass
+
+    def remove_rrset(self, rrset):
+        pass
+
+    def commit(self):
+        pass
 
 
 class TestXfrinInitialSOA(TestXfrinState):
 class TestXfrinInitialSOA(TestXfrinState):
     def setUp(self):
     def setUp(self):
@@ -209,11 +230,7 @@ class TestXfrinFirstData(TestXfrinState):
 
 
     def test_handle_ixfr_begin_soa(self):
     def test_handle_ixfr_begin_soa(self):
         self.conn._request_type = RRType.IXFR()
         self.conn._request_type = RRType.IXFR()
-        begin_soa = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.SOA(),
-                          RRTTL(3600))
-        begin_soa.add_rdata(Rdata(RRType.SOA(), TEST_RRCLASS,
-                                  'm. r. 1230 0 0 0 0'))
-        self.assertFalse(self.state.handle_rr(self.conn, begin_soa))
+        self.assertFalse(self.state.handle_rr(self.conn, self.begin_soa))
         self.assertEqual(type(XfrinIXFRDeleteSOA()),
         self.assertEqual(type(XfrinIXFRDeleteSOA()),
                          type(self.conn.get_xfrstate()))
                          type(self.conn.get_xfrstate()))
 
 
@@ -221,11 +238,7 @@ class TestXfrinFirstData(TestXfrinState):
         # If the original type is AXFR, other conditions aren't considered,
         # If the original type is AXFR, other conditions aren't considered,
         # and AXFR processing will continue
         # and AXFR processing will continue
         self.conn._request_type = RRType.AXFR()
         self.conn._request_type = RRType.AXFR()
-        begin_soa = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.SOA(),
-                          RRTTL(3600))
-        begin_soa.add_rdata(Rdata(RRType.SOA(), TEST_RRCLASS,
-                                  'm. r. 1230 0 0 0 0'))
-        self.assertFalse(self.state.handle_rr(self.conn, begin_soa))
+        self.assertFalse(self.state.handle_rr(self.conn, self.begin_soa))
         self.assertEqual(type(XfrinAXFR()), type(self.conn.get_xfrstate()))
         self.assertEqual(type(XfrinAXFR()), type(self.conn.get_xfrstate()))
 
 
     def test_handle_ixfr_to_axfr(self):
     def test_handle_ixfr_to_axfr(self):
@@ -243,6 +256,22 @@ class TestXfrinFirstData(TestXfrinState):
         self.assertFalse(self.state.handle_rr(self.conn, soa_rrset))
         self.assertFalse(self.state.handle_rr(self.conn, soa_rrset))
         self.assertEqual(type(XfrinAXFR()), type(self.conn.get_xfrstate()))
         self.assertEqual(type(XfrinAXFR()), type(self.conn.get_xfrstate()))
 
 
+class TestXfrinIAXFDeleteSOA(TestXfrinState):
+    def setUp(self):
+        super().setUp()
+        self.state = XfrinIXFRDeleteSOA()
+
+    def test_handle_rr(self):
+        self.assertTrue(self.state.handle_rr(self.conn, self.begin_soa))
+        self.assertEqual(type(XfrinIXFRDelete()),
+                         type(self.conn.get_xfrstate()))
+        self.assertEqual([('remove', self.begin_soa)],
+                         self.conn._diff.get_buffer())
+
+    def test_handle_non_soa(self):
+        self.assertRaises(XfrinException, self.state.handle_rr, self.conn,
+                          self.ns_rrset)
+
 class TestXfrinConnection(unittest.TestCase):
 class TestXfrinConnection(unittest.TestCase):
     def setUp(self):
     def setUp(self):
         if os.path.exists(TEST_DB_FILE):
         if os.path.exists(TEST_DB_FILE):

+ 14 - 2
src/bin/xfrin/xfrin.py.in

@@ -29,6 +29,7 @@ from isc.config.ccsession import *
 from isc.notify import notify_out
 from isc.notify import notify_out
 import isc.util.process
 import isc.util.process
 import isc.net.parse
 import isc.net.parse
+import isc.xfrin.diff
 from isc.log_messages.xfrin_messages import *
 from isc.log_messages.xfrin_messages import *
 
 
 isc.log.init("b10-xfrin")
 isc.log.init("b10-xfrin")
@@ -172,16 +173,27 @@ class XfrinFirstData(XfrinState):
             self.set_xfrstate(conn, XfrinIXFRDeleteSOA())
             self.set_xfrstate(conn, XfrinIXFRDeleteSOA())
         else:
         else:
             logger.debug(DBG_XFRIN_TRACE, XFRIN_GOT_NONINCREMENTAL_RESP,
             logger.debug(DBG_XFRIN_TRACE, XFRIN_GOT_NONINCREMENTAL_RESP,
-                         conn.zone_str())
+                 conn.zone_str())
             self.set_xfrstate(conn, XfrinAXFR())
             self.set_xfrstate(conn, XfrinAXFR())
         return False    # need to revisit this RR in an update context
         return False    # need to revisit this RR in an update context
 
 
 class XfrinIXFRDeleteSOA(XfrinState):
 class XfrinIXFRDeleteSOA(XfrinState):
-    pass
+    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 XfrinAXFR(XfrinState):
     pass
     pass
 
 
+class XfrinIXFRDelete(XfrinState):
+    pass
+
 class XfrinConnection(asyncore.dispatcher):
 class XfrinConnection(asyncore.dispatcher):
     '''Do xfrin in this class. '''
     '''Do xfrin in this class. '''