Browse Source

[2379] test before writing final methods

Jelte Jansen 12 years ago
parent
commit
baa520eb35

+ 10 - 0
src/lib/python/isc/datasrc/tests/testdata/example.com

@@ -0,0 +1,10 @@
+;; This is the source of a zone stored in test.sqlite3.  It's provided
+;; for reference purposes only.
+example.com.         1000  IN  SOA a.dns.example.com. mail.example.com. 1 1 1 1 1
+example.com.         1000  IN  NS  a.dns.example.com.
+example.com.         1000  IN  NS  b.dns.example.com.
+example.com.         1000  IN  NS  c.dns.example.com.
+a.dns.example.com.   1000  IN  A    1.1.1.1
+b.dns.example.com.   1000  IN  A    3.3.3.3
+b.dns.example.com.   1000  IN  AAAA 4:4::4:4
+b.dns.example.com.   1000  IN  AAAA 5:5::5:5

+ 21 - 12
src/lib/python/isc/datasrc/tests/zone_loader_test.py

@@ -19,20 +19,24 @@ import isc.dns
 import os
 import unittest
 
-TESTDATA_PATH = os.environ['TESTDATA_PATH'] + os.sep
-TESTDATA_WRITE_PATH = os.environ['TESTDATA_WRITE_PATH'] + os.sep
+TESTDATA_PATH = os.environ['TESTDATA_PATH']
+TESTDATA_WRITE_PATH = os.environ['TESTDATA_WRITE_PATH']
 
-READ_ZONE_DB_FILE = TESTDATA_PATH + "example.com.sqlite3"
-WRITE_ZONE_DB_FILE = TESTDATA_WRITE_PATH + "rwtest.sqlite3.copied"
+ZONE_FILE = TESTDATA_PATH + '/example.com'
 
-READ_ZONE_DB_CONFIG = "{ \"database_file\": \"" + READ_ZONE_DB_FILE + "\" }"
-WRITE_ZONE_DB_CONFIG = "{ \"database_file\": \"" + WRITE_ZONE_DB_FILE + "\"}"
+DB_FILE = TESTDATA_WRITE_PATH + '/zoneloadertest.sqlite3'
+DB_CLIENT_CONFIG = '{ "database_file": "' + DB_FILE + '"}'
 
 class ZoneLoaderTests(unittest.TestCase):
     def setUp(self):
         self.test_name = isc.dns.Name("example.com")
-        self.test_file = "foo.txt"
-        self.client = isc.datasrc.DataSourceClient("sqlite3", WRITE_ZONE_DB_CONFIG)
+        self.test_file = ZONE_FILE
+        self.client = isc.datasrc.DataSourceClient("sqlite3", DB_CLIENT_CONFIG)
+
+    def tearDown(self):
+        # Delete the database after each test
+        if os.path.exists(DB_FILE):
+            os.unlink(DB_FILE)
 
     def test_bad_constructor(self):
         self.assertRaises(TypeError, isc.datasrc.ZoneLoader)
@@ -48,15 +52,20 @@ class ZoneLoaderTests(unittest.TestCase):
 
     def test_load_file(self):
         #self.assertRaises(TypeError, isc.datasrc.ZoneLoader());
+        result, _ = self.client.find_zone(self.test_name)
+        self.assertEqual(self.client.NOTFOUND, result)
+
+        # Create loader and load the zone
         loader = isc.datasrc.ZoneLoader(self.client, self.test_name, self.test_file)
-        # This would currently loop
-        #loader.load()
+        loader.load()
+        # Not really checking content for now, just check the zone exists now
+        result, _ = self.client.find_zone(self.test_name)
+        self.assertEqual(self.client.SUCCESS, result)
 
     def test_bad_file(self):
         #self.assertRaises(TypeError, isc.datasrc.ZoneLoader());
         loader = isc.datasrc.ZoneLoader(self.client, self.test_name, "no such file")
-        # This would currently loop
-        #loader.load()
+        self.assertRaises(isc.datasrc.MasterFileError, loader.load)
 
     def test_exception(self):
         # Just check if masterfileerror is subclass of datasrc.Error

+ 9 - 1
src/lib/python/isc/datasrc/zone_loader_python.cc

@@ -50,8 +50,11 @@ namespace {
 // The s_* Class simply covers one instantiation of the object
 class s_ZoneLoader : public PyObject {
 public:
-    s_ZoneLoader() : cppobj(NULL) {};
+    s_ZoneLoader() : cppobj(NULL), client(NULL) {};
     ZoneLoader* cppobj;
+    // a zoneloader should not survive its associated client,
+    // so add a ref to it at init
+    PyObject* client;
 };
 
 // Shortcut type which would be convenient for adding class variables safely.
@@ -66,6 +69,8 @@ ZoneLoader_init(PyObject* po_self, PyObject* args, PyObject*) {
     char* master_file;
     if (PyArg_ParseTuple(args, "O!O!s", &datasourceclient_type, &po_ds_client, &name_type, &po_name, &master_file)) {
         try {
+            Py_INCREF(po_ds_client);
+            self->client = po_ds_client;
             self->cppobj = new ZoneLoader(PyDataSourceClient_ToDataSourceClient(po_ds_client), PyName_ToName(po_name), master_file);
             return (0);
         } catch (const isc::datasrc::MasterFileError& mfe) {
@@ -89,6 +94,9 @@ ZoneLoader_destroy(PyObject* po_self) {
     s_ZoneLoader* self = static_cast<s_ZoneLoader*>(po_self);
     delete self->cppobj;
     self->cppobj = NULL;
+    if (self->client != NULL) {
+        Py_DECREF(self->client);
+    }
     Py_TYPE(self)->tp_free(self);
 }