Commit 0f06a4fc authored by chenzhengzhang's avatar chenzhengzhang
Browse files

update sqlite3_ds zone_exist() comments and unittest

parent 79ccd983
......@@ -25,17 +25,16 @@ RR_NAME_INDEX = 2
RR_TTL_INDEX = 4
RR_RDATA_INDEX = 7
#########################################################################
# define exceptions
#########################################################################
class Sqlite3DSError(Exception):
""" Define exceptions."""
pass
#########################################################################
# create: set up schema for a newly created zones/records database
#########################################################################
def create(cur):
"""Create new zone database"""
""" Set up schema for a newly created zones/records database.
Arguments:
cur - sqlite3 cursor.
"""
cur.execute("CREATE TABLE schema_version (version INTEGER NOT NULL)")
cur.execute("INSERT INTO schema_version VALUES (1)")
cur.execute("""CREATE TABLE zones (id INTEGER PRIMARY KEY,
......@@ -62,16 +61,17 @@ def create(cur):
rdata STRING NOT NULL)""")
cur.execute("CREATE INDEX nsec3_byhash ON nsec3 (hash)")
#########################################################################
# open: open a database. if the database is not yet set up,
# call create to do so.
# input:
# dbfile - the filename for the sqlite3 database
# returns:
# sqlite3 connection, sqlite3 cursor
#########################################################################
def open(dbfile):
"""Open the database file. If necessary, set it up"""
""" Open a database, if the database is not yet set up, call create
to do so. It may raise Sqlite3DSError if failed to open sqlite3
database file or find bad database schema version in the database.
Arguments:
dbfile - the filename for the sqlite3 database.
Return sqlite3 connection, sqlite3 cursor.
"""
# Open the database file. If necessary, set it up"""
try:
conn = sqlite3.connect(dbfile)
cur = conn.cursor()
......@@ -94,12 +94,14 @@ def open(dbfile):
return conn, cur
#########################################################################
# get_zone_datas
# a generator function producing an iterable set of
# the records in the zone with the given zone name.
#########################################################################
def get_zone_datas(zonename, dbfile):
""" A generator function producing an iterable set of
the records in the zone with the given zone name.
Arguments:
zonename - the zone's origin name.
dbfile - the filename for the sqlite3 database.
"""
conn, cur = open(dbfile)
zone_id = get_zoneid(zonename, cur)
......@@ -113,12 +115,14 @@ def get_zone_datas(zonename, dbfile):
conn.close()
#########################################################################
# get_zone_soa
# returns the soa record of the zone with the given zone name.
# If the zone doesn't exist, return None.
#########################################################################
def get_zone_soa(zonename, dbfile):
"""Return the soa record of the zone with the given zone name.
If the zone doesn't exist, return None.
Arguments:
zonename - the zone's origin name.
dbfile - the filename for the sqlite3 database.
"""
conn, cur = open(dbfile)
id = get_zoneid(zonename, cur)
cur.execute("SELECT * FROM records WHERE zone_id = ? and rdtype = ?", [id, 'SOA'])
......@@ -129,13 +133,17 @@ def get_zone_soa(zonename, dbfile):
return datas
#########################################################################
# get_zone_rrset
# returns the rrset of the zone with the given zone name, rrset name
# and given rd type.
# If the zone doesn't exist or rd type doesn't exist, return an empty list.
#########################################################################
def get_zone_rrset(zonename, rr_name, rdtype, dbfile):
"""Return the rrset of the zone with the given zone name, rrset
name and given rd type. If the zone doesn't exist or rd type
doesn't exist, return an empty list.
Arguments:
zonename - the zone's origin name.
rr_name - rr name.
rdtype - rdata type.
dbfile - the filename for the sqlite3 database.
"""
conn, cur = open(dbfile)
id = get_zoneid(zonename, cur)
cur.execute("SELECT * FROM records WHERE name = ? and zone_id = ? and rdtype = ?",
......@@ -146,11 +154,12 @@ def get_zone_rrset(zonename, rr_name, rdtype, dbfile):
return datas
#########################################################################
# get_zones_info:
# returns all the zones' information.
#########################################################################
def get_zones_info(db_file):
""" Return all the zones' information in the database.
Arguments:
dbfile - the filename for the sqlite3 database.
"""
conn, cur = open(db_file)
cur.execute("SELECT name, rdclass FROM zones")
info = cur.fetchone()
......@@ -162,13 +171,17 @@ def get_zones_info(db_file):
conn.close()
#########################################################################
# get_zoneid:
# returns the zone_id for a given zone name, or an empty
# string if the zone is not found
#########################################################################
def get_zoneid(zone, cur):
cur.execute("SELECT id FROM zones WHERE name = ?", [zone])
def get_zoneid(zonename, cur):
""" Get the zone_id for a given zone name.
Arguments:
zonename - the zone's origin name.
cur - sqlite3 cursor.
Return zone id for the given zone name, or an empty string if the
zone is not found.
"""
cur.execute("SELECT id FROM zones WHERE name = ?", [zonename])
row = cur.fetchone()
if row:
return row[0]
......@@ -176,18 +189,17 @@ def get_zoneid(zone, cur):
return ''
#########################################################################
# zone_exist:
# Search for the zone with the name zonename in databse. This method
# may throw a exception because its underlying methods open() may
# throw exceptions.
# input:
# zonename: the zone's origin name.
# dbfile: the filename for the sqlite3 database.
# returns:
# returns True if the zone is found, otherwise False.
#########################################################################
def zone_exist(zonename, dbfile):
""" Search for the zone with the given zone name in databse. This
method may throw a Sqlite3DSError exception because its underlying
methods open() can throw that exception.
Arguments:
zonename - the zone's origin name.
dbfile - the filename for the sqlite3 database.
Return True if the zone is found, otherwise False.
"""
conn, cur = open(dbfile)
zoneid = get_zoneid(zonename, cur)
cur.close()
......@@ -197,15 +209,14 @@ def zone_exist(zonename, dbfile):
return False
#########################################################################
# reverse_name:
# reverse the labels of a DNS name. (for example,
# "bind10.isc.org." would become "org.isc.bind10.")
#########################################################################
def reverse_name(name):
"""Reverse the labels of a domain name; for example,
given 'www.isc.org.', return 'org.isc.www.' This is needed
for DNSSEC sort order."""
for DNSSEC sort order.
Arguments:
name - the DNS name will be reversed.
"""
new = name.split('.')
new.reverse()
if new[0] == '':
......@@ -213,16 +224,15 @@ def reverse_name(name):
return '.'.join(new)+'.'
#########################################################################
# load:
# load a zone into the SQL database.
# input:
# dbfile: the sqlite3 database fileanme
# zone: the zone origin
# reader: a generator function producing an iterable set of
# name/ttl/class/rrtype/rdata-text tuples
#########################################################################
def load(dbfile, zone, reader):
""" Load a zone into the SQL database.
Arguments:
dbfile - the sqlite3 database filename
zone - the zone origin
reader - a generator function producing an iterable set of
name/ttl/class/rrtype/rdata-text tuples.
"""
# if the zone name doesn't contain the trailing dot, automatically add it.
if zone[-1] != '.':
zone += '.'
......
......@@ -2,10 +2,13 @@ PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
PYTESTS = master_test.py sqlite3_ds_test.py
EXTRA_DIST = $(PYTESTS)
EXTRA_DIST += testdata/brokendb.sqlite3
EXTRA_DIST += testdata/example.com.sqlite3
# test using command-line arguments, so use check-local target instead of TESTS
check-local:
if ENABLE_PYTHON_COVERAGE
touch $(abs_top_srcdir)/.coverage
touch $(abs_top_srcdir)/.coverage
rm -f .coverage
${LN_S} $(abs_top_srcdir)/.coverage .coverage
endif
......@@ -14,3 +17,4 @@ endif
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/python/isc/log \
$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
done
# Copyright (C) 2010 Internet Systems Consortium.
# Copyright (C) 2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
......@@ -17,17 +17,26 @@ from isc.datasrc import sqlite3_ds
import socket
import unittest
TEST_DATA_PATH = "./testdata/"
class TestSqlite3_ds(unittest.TestCase):
def test_zone_exist(self):
def open(db_file):
conn, cur = socket.socketpair()
return conn, cur
def get_zoneid(zone_name, cur):
return zone_name
sqlite3_ds.open = open
sqlite3_ds.get_zoneid = get_zoneid
self.assertTrue(sqlite3_ds.zone_exist("example.com", "sqlite3_db"))
self.assertFalse(sqlite3_ds.zone_exist("", "sqlite3_db"))
# The following file must be non existent and must be non
# "creatable"; the sqlite3 library will try to create a new
# DB file if it doesn't exist, so to test a failure case the
# create operation should also fail. The "nodir", a non
# existent directory, is inserted for this purpose.
nodir = "/nodir/notexist"
self.assertRaises(sqlite3_ds.Sqlite3DSError,
sqlite3_ds.zone_exist, "example.com", nodir)
# Open a broken database file
self.assertRaises(sqlite3_ds.Sqlite3DSError,
sqlite3_ds.zone_exist, "example.com",
TEST_DATA_PATH + "brokendb.sqlite3")
self.assertTrue(sqlite3_ds.zone_exist("example.com.",
TEST_DATA_PATH + "example.com.sqlite3"))
self.assertFalse(sqlite3_ds.zone_exist("example.org.",
TEST_DATA_PATH + "example.com.sqlite3"))
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment