예제 #1
0
class NipapTest(unittest.TestCase):
    """ Tests the NIPAP class
    """

    nipap = None

    def setUp(self):
        """ Better start from a clean slate!
        """

        cfg = NipapConfig('/etc/nipap/nipap.conf')
        self.nipap = Nipap()

        # create dummy auth object
        # As the authentication is performed before the query hits the Nipap
        # class, it does not matter what user we use here
        self.auth = SqliteAuth('local', 'unittest', 'unittest', 'unittest')
        self.auth.authenticated_as = 'unittest'
        self.auth.full_name = 'Unit test'

        self.nipap._execute("TRUNCATE ip_net_plan, ip_net_pool, ip_net_vrf, ip_net_log, ip_net_asn")

        self.schema_attrs = {
                'name': 'test-schema1',
                'description': 'Test schema numero uno!'
                }
        self.schema_attrs['id'] = self.nipap.add_schema(self.auth, self.schema_attrs)
        self.schema_attrs2 = {
                'name': 'test-schema2',
                'description': 'Test schema numero dos!'
                }
        self.schema_attrs2['id'] = self.nipap.add_schema(self.auth, self.schema_attrs2)
        self.pool_attrs = {
                'name': 'test-pool1',
                'description': 'Test pool numero uno!',
                'default_type': 'assignment',
                'ipv4_default_prefix_length': 30,
                'ipv6_default_prefix_length': 112
                }
        self.pool_attrs['id'] = self.nipap.add_pool(self.auth, {'id': self.schema_attrs['id']}, self.pool_attrs)
        self.prefix_attrs1 = {
                'authoritative_source': 'nipaptest',
                'prefix': '1.3.3.0/24',
                'type': 'assignment',
                'description': ''
                }
        self.prefix_attrs1['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs1)
        self.prefix_attrs = {
                'authoritative_source': 'nipaptest',
                'prefix': '1.3.3.1/32',
                'type': 'host',
                'description': 'Test prefix numero uno!'
                }
        self.prefix_attrs['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs)
        self.prefix_attrs2 = {
                'authoritative_source': 'nipaptest',
                'prefix': '1.3.2.0/23',
                'type': 'reservation',
                'description': ''
                }
        self.prefix_attrs2['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs2)
        self.prefix_attrs3 = {
                'authoritative_source': 'nipaptest',
                'prefix': '1.3.0.0/16',
                'type': 'reservation',
                'description': ''
                }
        self.prefix_attrs3['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs3)
        self.prefix_attrs4 = {
                'authoritative_source': 'nipaptest',
                'prefix': '1.3.0.0/17',
                'type': 'reservation',
                'description': ''
                }
        self.prefix_attrs4['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs2['id']}, self.prefix_attrs4)

        self.prefix6_attrs1 = {
                'authoritative_source': 'nipaptest',
                'prefix': '2001:0db8:3:3::/112',
                'type': 'assignment',
                'description': ''
                }
        self.prefix6_attrs1['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs1)
        self.prefix6_attrs = {
                'authoritative_source': 'nipaptest',
                'prefix': '2001:0db8:3:3::1/128',
                'type': 'host',
                'description': 'Test prefix numero uno!'
                }
        self.prefix6_attrs['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs)
        self.prefix6_attrs2 = {
                'authoritative_source': 'nipaptest',
                'prefix': '2001:0db8:3:3::/64',
                'type': 'reservation',
                'description': ''
                }
        self.prefix6_attrs2['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs2)
        self.prefix6_attrs3 = {
                'authoritative_source': 'nipaptest',
                'prefix': '2001:0db8:3:0::/48',
                'type': 'reservation',
                'description': ''
                }
        self.prefix6_attrs3['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs3)
        self.prefix6_attrs4 = {
                'authoritative_source': 'nipaptest',
                'prefix': '2001:0db8:3:0::/56',
                'type': 'reservation',
                'description': ''
                }
        self.prefix6_attrs4['id'] = self.nipap.add_prefix(self.auth, {'id': self.schema_attrs2['id']}, self.prefix6_attrs4)


    def test_schema_basic(self):
        """ Basic schema test

            1. Add a new schema
            2. List with filters to get newly created schema
            3. Verify listed schema coincides with input args for added schema
            4. Remove schema
        """
        attrs = {
                'name': 'test-schema-wrong',
                'description': 'A simple test schema with incorrect name!'
                }
        attrs['id'] = self.nipap.add_schema(self.auth, attrs)
        schema = self.nipap.list_schema(self.auth, { 'id': attrs['id'] })
        for a in attrs:
            self.assertEqual(schema[0][a], attrs[a], 'Added object differ from listed on attribute: ' + a)



    def test_schema_add_crap_input(self):
        """ Try to input junk into add_schema and expect error

        """
        attrs = {
                'name': 'test-schema-crap',
                'description': 'A simple test schema with incorrect name!',
                'crap': 'this is just some crap'
                }
        # missing everything
        self.assertRaises(NipapMissingInputError, self.nipap.add_schema, self.auth, { })
        # missing description
        self.assertRaises(NipapMissingInputError, self.nipap.add_schema, self.auth, { 'name': 'crapson' })
        # have required and extra crap
        self.assertRaises(NipapExtraneousInputError, self.nipap.add_schema, self.auth, attrs)



    def test_expand_schema_spec(self):
        """ Test the expand_schema_spec()

            The _expand_schema_spec() function is used throughout the schema
            functions to expand the schema specification input and so we test
            the separately.
        """
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_schema_spec, 'string')
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_schema_spec, 1)
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_schema_spec, [])
        # missing keys
        self.assertRaises(NipapMissingInputError, self.nipap._expand_schema_spec, { })
        # crap key
        self.assertRaises(NipapExtraneousInputError, self.nipap._expand_schema_spec, { 'crap': self.schema_attrs['name'] })
        # required keys and extra crap
        self.assertRaises(NipapExtraneousInputError, self.nipap._expand_schema_spec, { 'name': self.schema_attrs['name'], 'crap': 'crap' })
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_schema_spec, { 'id': '3' })
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_schema_spec, { 'name': 3 })
        # both id and name
        self.assertRaises(NipapExtraneousInputError, self.nipap._expand_schema_spec, { 'id': 3, 'name': '3' })
        # proper key - id
        where, params = self.nipap._expand_schema_spec({ 'id': 3 })
        self.assertEqual(where, 'id = %(spec_id)s', "Improperly expanded WHERE clause")
        self.assertEqual(params, {'spec_id': 3}, "Improperly expanded params dict")
        # proper spec - name
        where, params = self.nipap._expand_schema_spec({ 'name': 'test' })



    def test_schema_edit_crap_input(self):
        """ Try to input junk into edit_schema and expect error

        """
        attrs = {
                'name': 'test-schema-crap',
                'description': 'A simple test schema with incorrect name!'
                }
        crap_attrs = {
                'name': 'test-schema-crap',
                'description': 'A simple test schema with incorrect name!',
                'crap': 'this is just some crap'
                }
        # spec is tested elsewhere, just test attrs part
        self.assertRaises(NipapExtraneousInputError, self.nipap.edit_schema, self.auth, { 'name': self.schema_attrs['name'] }, crap_attrs)



    def test_schema_list_crap_input(self):
        """ Try to input junk into list_schema and expect error

        """
        # TODO: what do we really expect?
        self.assertRaises(NipapExtraneousInputError, self.nipap.list_schema, self.auth, { 'crap': 'crap crap' })



    def test_schema_dupe(self):
        """ Check so we can't create duplicate schemas

            There are unique indices in the database that should prevent us
            from creating duplicate schema (ie, with the same name).
        """
        schema_attrs = {
                'name': 'test-schema-dupe',
                'description': 'Testing dupe'
                }
        self.nipap.add_schema(self.auth, schema_attrs)
        self.assertRaises(NipapDuplicateError, self.nipap.add_schema, self.auth, schema_attrs)



    def test_schema_rename(self):
        """ Rename a schema

            Uses the edit_schema() functionality to rename our previously
            created and incorrectly named schema so it hereafter has the
            correct name. Also tests the list_schema() functionality since we
            use that to list the modified schema.
        """
        spec = { 'name': 'test-schema1' }
        attrs = {
                'name': 'test-schema',
                'description': 'A simple test schema with correct name!'
                }
        self.nipap.edit_schema(self.auth, spec, attrs)
        # check that search for old record doesn't return anything
        schema = self.nipap.list_schema(self.auth, spec)
        self.assertEqual(schema, [], 'Old entry still exists')
        schema = self.nipap.list_schema(self.auth, { 'name': 'test-schema' })
        for a in attrs:
            self.assertEqual(schema[0][a], attrs[a], 'Modified schema differ from listed on attribute: ' + a)



    def test_schema_remove(self):
        """ Remove a schema

            Remove the schema previously modified and make sure it's not there.
        """
        spec = { 'name': 'test-schema' }
        self.nipap.remove_schema(self.auth, spec)
        # check that search for old record doesn't return anything
        schema = self.nipap.list_schema(self.auth, spec)
        self.assertEqual(schema, [], 'Old entry still exists')



    def test_expand_pool_spec(self):
        """ Test the function which expands pool spec to SQL.
        """

        schema = {'id': self.schema_attrs['id']}

        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_pool_spec, 'string')
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_pool_spec, 1)
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_pool_spec, [])
        # missing keys
        self.assertRaises(NipapMissingInputError, self.nipap._expand_pool_spec, { })
        # crap key
        self.assertRaises(NipapExtraneousInputError, self.nipap._expand_pool_spec, { 'crap': self.pool_attrs['name'] })
        # required keys and extra crap
        self.assertRaises(NipapExtraneousInputError, self.nipap._expand_pool_spec, { 'id': self.pool_attrs['id'], 'schema': self.schema_attrs['id'], 'crap': 'crap' })
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_pool_spec, { 'id': '3', 'schema': self.schema_attrs['id'] })
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_pool_spec, { 'name': 3, 'schema': self.schema_attrs['id'] })
        # both id and name
        self.assertRaises(NipapExtraneousInputError, self.nipap._expand_pool_spec, { 'id': 3, 'name': '3', 'schema': self.schema_attrs['id'] })
        # proper key - id
        where, params = self.nipap._expand_pool_spec({ 'id': 3, 'schema': self.schema_attrs['id'] })
        self.assertEqual(where, 'po.id = %(spec_id)s AND po.schema = %(spec_schema)s', "Improperly expanded WHERE clause")
        self.assertEqual(params, {'spec_id': 3, 'spec_schema': self.schema_attrs['id']}, "Improperly expanded params dict")
        # proper spec - name
        where, params = self.nipap._expand_pool_spec({ 'name': 'test', 'schema': self.schema_attrs['id'] })
        self.assertEqual(where, 'po.name = %(spec_name)s AND po.schema = %(spec_schema)s', "Improperly expanded WHERE clause")
        self.assertEqual(params, {'spec_name': 'test', 'spec_schema': self.schema_attrs['id'] }, "Improperly expanded params dict")



    def test_pool_add1(self):
        """ Add a pool and check it's there using list functions

            Refer to schema by id
        """
        attrs = {
                'name': 'test-pool-wrong',
                'description': 'A simple test pool with incorrect name!',
                'default_type': 'reservation',
                'ipv4_default_prefix_length': 30,
                'ipv6_default_prefix_length': 112
                }
        schema = {'id': self.schema_attrs['id']}
        pool_id = self.nipap.add_pool(self.auth, schema, attrs)
        pool = self.nipap.list_pool(self.auth, schema, { 'id': pool_id })
        for a in attrs:
            self.assertEqual(pool[0][a], attrs[a], 'Added object differ from listed on attribute: %s  %s!=%s' % (a, attrs[a], pool[0][a]))



    def test_pool_add2(self):
        """ Add a pool and check it's there using list functions

            Refer to schema by name
        """
        schema = {'id': self.schema_attrs['id']}
        attrs = {
                'name': 'test-pool-wrong',
                'default_type': 'reservation',
                'description': 'A simple test pool with incorrect name!'
                }
        pool_id = self.nipap.add_pool(self.auth, schema, attrs)
        pool = self.nipap.list_pool(self.auth, schema, { 'id': pool_id })
        for a in attrs:
            self.assertEqual(pool[0][a], attrs[a], 'Added object differ from listed on attribute: ' + a)



    def test_edit_pool_by_name(self):
        """ Try to rename a pool using edit_pool() function

            Pool is not uniquely identified (empty spec) so this should raise an error
        """
        schema = {'id': self.schema_attrs['id']}
        spec = {  }
        attrs = {
                'name': self.pool_attrs['name'],
                'default_type': 'assignment',
                'description': 'A simple test pool with correct name!'
                }
        self.assertRaises(NipapInputError, self.nipap.edit_pool, self.auth, schema, spec, attrs)



    def test_edit_pool(self):
        """ Rename a pool using edit_pool() function
        """
        schema = {'id': self.schema_attrs['id']}
        spec = { 'id': self.pool_attrs['id'] }
        attrs = {
                'name': 'test-pool',
                'default_type': 'assignment',
                'description': 'A simple test pool with correct name!',
                'ipv4_default_prefix_length': 32,
                'ipv6_default_prefix_length': 128
                }
        self.nipap.edit_pool(self.auth, schema, spec, attrs)
        # check that search for old record doesn't return anything
        pool = self.nipap.list_pool(self.auth, schema, { 'name': self.pool_attrs['name'] })
        self.assertEqual(pool, [], 'Old entry still exists')
        pool = self.nipap.list_pool(self.auth, schema, { 'name': attrs['name'] })
        for a in attrs:
            self.assertEqual(pool[0][a], attrs[a], 'Added object differ from listed on attribute: ' + a)



    def test_remove_pool_by_id(self):
        """ Remove a pool by id
        """
        schema = {'id': self.schema_attrs['id']}
        pool = self.nipap.list_pool(self.auth, schema, { 'id': self.pool_attrs['id'] })
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [], 'Record must exist before we can delete it')
        for a in self.pool_attrs:
            self.assertEqual(pool[0][a], self.pool_attrs[a], 'Listed attribute differ from original')
        # remove the pool
        self.nipap.remove_pool(self.auth, schema, { 'id': self.pool_attrs['id'] })
        # check that search for old record doesn't return anything
        pool = self.nipap.list_pool(self.auth, schema, { 'id': self.pool_attrs['id'] })
        self.assertEqual(pool, [], 'Old entry still exists')



    def test_prefix_in_a_pool(self):
        """ Add prefixes to a poll and list!
        """
        schema = {'id': self.schema_attrs['id']}
        pool = self.nipap.list_pool(self.auth, schema, { 'id': self.pool_attrs['id'] })
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        pfxs = [
                '1.2.2.0/32',
                '1.2.2.1/32',
                '1.2.2.2/32',
                '1.2.2.3/32',
                '1.2.2.4/32',
                '1.2.2.5/32'
                ]
        for p in pfxs:
            prefix_attrs = {
                    'authoritative_source': 'nipap-test',
                    'prefix': p,
                    'type': 'host',
                    'description': 'test prefix',
                    'pool_id': self.pool_attrs['id'],
                    'comment': 'test comment, please remove! ;)'
                    }
            self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # list again
        pool = self.nipap.list_pool(self.auth, schema, { 'id': self.pool_attrs['id'] })
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        self.assertEqual(set(pfxs), set(pool[0]['prefixes']), 'Returned prefixes do not match added ones')



    def test_prefix_basic(self):
        """ Test basic prefix functions
        """
        schema = {'id': self.schema_attrs['id']}
        prefix_attrs = {
                'authoritative_source': 'nipap-test',
                'prefix': '1.3.3.7/32',
                'type': 'host',
                'description': 'test prefix',
                'comment': 'test comment, please remove! ;)'
                }
        self.nipap.add_prefix(self.auth, schema, prefix_attrs)
        prefix = self.nipap.list_prefix(self.auth, schema, { 'prefix': prefix_attrs['prefix'] })
        for a in prefix_attrs:
            self.assertEqual(prefix[0][a], prefix_attrs[a], 'Added object differ from listed on attribute: ' + a)

        # fetch many prefixes - all in a schema
        prefix = self.nipap.list_prefix(self.auth, schema, {})
        self.assertNotEqual(len(prefix), 0, 'Found 0 prefixes in schema ' + self.schema_attrs['name'])



    def test_add_prefix(self):
        """ Test add_prefix in a bit more detail
        """
        schema = {'id': self.schema_attrs['id']}
        # we need a bloody pool first!
        pool = self.nipap.list_pool(self.auth, schema, { 'id': self.pool_attrs['id'] })
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        pfxs = [
                '10.0.0.0/24',
                '10.0.1.0/24',
                '10.0.2.0/24',
                '10.0.3.0/24',
                '10.0.4.0/24'
                ]
        for p in pfxs:
            prefix_attrs = {
                    'authoritative_source': 'nipap-test',
                    'prefix': p,
                    'type': 'reservation',
                    'description': 'test prefix',
                    'pool_id': self.pool_attrs['id'],
                    'comment': 'test comment, please remove! ;)'
                    }
            self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # get an address based on from-prefix
        prefix_attrs = {
                'type': 'assignment',
                'authoritative_source': 'nipap-test',
                'description': 'test prefix',
                'comment': 'test comment, please remove! ;)'
                }
        res = self.nipap.add_prefix(self.auth, schema, prefix_attrs, { 'from-prefix': ['10.0.0.0/24'], 'prefix_length': 30 })
        p = self.nipap.list_prefix(self.auth, schema, { 'id': res })
        self.assertEqual(p[0]['prefix'], '10.0.0.0/30', "New prefix differ from what it should be!")

        self.nipap.add_schema(self.auth, { 'name': 'testtest', 'description': 'another test schema!' })
        # pass different schemas in attr and args
        # TODO: Find something similar?
        #self.assertRaises(NipapInputError, self.nipap.add_prefix, schema, { 'authoritative_source': 'nipap-test', 'description': 'tjong' }, { 'from-prefix': ['10.0.0.0/24'], 'prefix_length': 30 })



    def test_prefix_search_simple(self):
        """ Test the simple prefix search function.
        """

        schema = {'id': self.schema_attrs['id']}

        # First, perform e few tests to verify search string expansion.
        query_keys = dict()
        query_keys['testing testing'] = "description"
        query_keys['1.2.3.4'] = "prefix"

        # build query string
        query_str = ""
        for key, val in query_keys.items():
            if val == "description":
                query_str += "\"%s\" " % key
            else:
                query_str += "%s " % key

        res = self.nipap.smart_search_prefix(self.auth, schema, query_str)
        for interp in res['interpretation']:
            self.assertEqual(interp['string'] in query_keys, True, "Function returned unknown interpreted string %s" % interp['string'])

        prefix_attrs = {
                'authoritative_source': 'nipap-test',
                'prefix': '1.3.3.77/32',
                'type': 'host',
                'description': 'test-ish prefix',
                'comment': 'Test prefix #77! ;)'
                }

        self.nipap.add_prefix(self.auth, schema, prefix_attrs)
        res = self.nipap.smart_search_prefix(self.auth, schema, r"""1.3.3.77 "-ish" """)
        self.assertEqual(res['result'][-1]['prefix'], '1.3.3.77/32', 'Prefix not found')



    def test_prefix_search_smart(self):
        """ Test the smart prefix search function.
        """
        schema = {'id': self.schema_attrs['id']}

        # test full ipv4 address
        res = self.nipap.smart_search_prefix(self.auth, schema, '1.3.3.7')
        self.assertEqual(res['interpretation'][0]['interpretation'], 'IPv4 address')

        res = self.nipap.smart_search_prefix(self.auth, schema, '1.1')
        self.assertEqual(res['interpretation'][0]['interpretation'], 'text', "Incorrectly interpreted '1.1' as : " + res['interpretation'][0]['interpretation'])

        res = self.nipap.smart_search_prefix(self.auth, schema, '10/8')
        self.assertEqual(res['interpretation'][0]['interpretation'], 'IPv4 prefix')

        res = self.nipap.smart_search_prefix(self.auth, schema, '2000:0::01')
        self.assertEqual(res['interpretation'][0]['interpretation'], 'IPv6 address')



    def test_prefix_remove(self):
        """ Remove a prefix
        """
        schema = {'id': self.schema_attrs['id']}
        prefix = self.nipap.list_prefix(self.auth, schema, { 'id': self.prefix_attrs['id'] })
        # first make sure our prefix exists
        self.assertEqual(prefix[0]['id'], self.prefix_attrs['id'], 'Record must exist before we can delete it')
        # remove the prefix, by id
        self.nipap.remove_prefix(self.auth, schema, { 'id': self.prefix_attrs['id'] })
        # check that search for old record doesn't return anything
        prefix = self.nipap.list_prefix(self.auth, schema, { 'id': self.prefix_attrs['id'] })
        self.assertEqual(prefix, [], 'Old entry still exists')



    def test_prefix_indent_ipv4(self):
        """ Check that our indentation calculation is working for IPv4

            Prefixes gets an indent value automatically assigned to help in
            displaying prefix information. The indent value is written on
            updates to the table and this test is to make sure it is correctly
            calculated.
        """
        schema = {'id': self.schema_attrs['id']}
        p1 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '1.3.3.1/32' })[0]
        p2 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '1.3.3.0/24' })[0]
        p3 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '1.3.0.0/16' })[0]
        self.assertEqual(p1['indent'], 4, "Indent calc on add failed")
        self.assertEqual(p2['indent'], 3, "Indent calc on add failed")
        self.assertEqual(p3['indent'], 0, "Indent calc on add failed")
        # remove middle prefix
        self.nipap.remove_prefix(self.auth, schema, { 'id': self.prefix_attrs2['id'] })
        # check that child prefix indent level has decreased
        p1 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '1.3.3.1/32' })[0]
        p3 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '1.3.0.0/16' })[0]
        self.assertEqual(p1['indent'], 3, "Indent calc on remove failed")
        self.assertEqual(p3['indent'], 0, "Indent calc on remove failed")



    def test_prefix_indent_ipv6(self):
        """ Check that our indentation calculation is working for IPv6

            Prefixes gets an indent value automatically assigned to help in
            displaying prefix information. The indent value is written on
            updates to the table and this test is to make sure it is correctly
            calculated.
        """
        schema = {'id': self.schema_attrs['id']}
        p1 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '2001:0db8:3:3::1/128' })[0]
        p2 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '2001:0db8:3:3::/64' })[0]
        p3 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '2001:0db8:3:0::/48' })[0]
        self.assertEqual(p1['indent'], 4, "Indent calc on add failed")
        self.assertEqual(p2['indent'], 2, "Indent calc on add failed")
        self.assertEqual(p3['indent'], 0, "Indent calc on add failed")
        # remove middle prefix
        self.nipap.remove_prefix(self.auth, schema, { 'id': self.prefix6_attrs2['id'] })
        # check that child prefix indent level has decreased
        p1 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '2001:0db8:3:3::1/128' })[0]
        p3 = self.nipap.list_prefix(self.auth, schema, { 'prefix': '2001:0db8:3:0::/48' })[0]
        self.assertEqual(p1['indent'], 3, "Indent calc on remove failed for " + p1['prefix'] + " indent: " + str(p1['indent']))
        self.assertEqual(p3['indent'], 0, "Indent calc on remove failed for " + p3['prefix'] + " indent: " + str(p3['indent']))



    def test_find_free_prefix_input(self):
        """ Mostly input testing of find_free_prefix

            Try to stress find_free_prefix and send a lot of junk..
        """
        schema = {'id': self.schema_attrs['id']}
        # set up a prefix not used elsewhere so we have a known good state
        prefix_attrs = {
                'authoritative_source': 'nipap-test',
                'prefix': '100.0.0.0/16',
                'type': 'reservation',
                'description': 'test prefix',
                'comment': 'test comment, please remove! ;)'
                }
        self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # no schema, should raise error!
        self.assertRaises(NipapInputError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': ['100.0.0.0/16'] })

        # incorrect from-prefix type, string instead of list of strings (looking like an IP address)
        self.assertRaises(NipapInputError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': '100.0.0.0/16' })

        # missing prefix_length
        self.assertRaises(NipapMissingInputError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': [ '100.0.0.0/16' ], 'count': 1 })

        # try giving both IPv4 and IPv6 in from-prefix which shouldn't work
        self.assertRaises(NipapInputError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': [ '100.0.0.0/16', '2a00:800::0/25' ], 'prefix_length': 24, 'count': 1 })

        # try giving non-integer as wanted prefix length
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': [ '100.0.0.0/16'], 'prefix_length': '24', 'count': 1 })

        # try giving to high a number as wanted prefix length for IPv4
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': [ '100.0.0.0/16'], 'prefix_length': 35, 'count': 1 })

        # try giving to high a number as wanted prefix length for IPv6
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': [ '2a00:800::1/25'], 'prefix_length': 150, 'count': 1 })

        # try giving a high number for result count (max is 1000)
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix, self.auth, schema, { 'from-prefix': [ '100.0.0.0/16'], 'prefix_length': 30, 'count': 55555 })

        # don't pass 'family', which is required when specifying 'from-pool'
        self.assertRaises(NipapMissingInputError, self.nipap.find_free_prefix, self.auth, schema, { 'from-pool': { 'name': self.pool_attrs['name'] }, 'prefix_length': 24, 'count': 1 })

        # pass crap as family, wrong type even
        self.assertRaises(ValueError, self.nipap.find_free_prefix, self.auth, schema, { 'from-pool': { 'name': self.pool_attrs['name'] }, 'prefix_length': 24, 'count': 1, 'family': 'crap' })

        # pass 7 as family
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix, self.auth, schema, { 'from-pool': { 'name': self.pool_attrs['name'] }, 'prefix_length': 24, 'count': 1, 'family': 7 })

        # pass non existent pool
        self.assertRaises(NipapNonExistentError, self.nipap.find_free_prefix, self.auth, schema, { 'from-pool': { 'name': 'crap' }, 'prefix_length': 24, 'count': 1, 'family': 4 })



    def test_find_free_prefix1(self):
        """ Functionality testing of find_free_prefix

            Mostly based on 'from-prefix'
        """
        schema = { 'id': self.schema_attrs['id'] }
        # set up a prefix not used elsewhere so we have a known good state
        prefix_attrs = {
                'authoritative_source': 'nipap-test',
                'prefix': '100.0.0.0/16',
                'type': 'assignment',
                'description': 'test prefix',
                'comment': 'test comment, please remove! ;)'
                }
        self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # simple test
        res = self.nipap.find_free_prefix(self.auth, schema, { 'from-prefix': [ '100.0.0.0/16', '1.3.3.0/24' ], 'prefix_length': 24, 'count': 1 })
        self.assertEqual(res, ['100.0.0.0/24'], "Incorrect prefix set returned")

        # simple test - only one input prefix (which did cause a bug, thus keeping it)
        res = self.nipap.find_free_prefix(self.auth, schema, { 'from-prefix': [ '100.0.0.0/16' ], 'prefix_length': 24, 'count': 1 })
        self.assertEqual(res, ['100.0.0.0/24'], "Incorrect prefix set returned")

        res = self.nipap.find_free_prefix(self.auth, schema, { 'from-prefix': [ '100.0.0.0/16', '1.3.3.0/24' ], 'prefix_length': 24, 'count': 999 })
        self.assertEqual(len(res), 256, "Incorrect prefix set returned")



    def test_find_free_prefix2(self):
        """ Functionality testing of find_free_prefix

            Mostly based on 'from-pool'
        """
        schema = { 'id': self.schema_attrs['id'] }
        # we need a bloody pool first!
        pool = self.nipap.list_pool(self.auth, schema, { 'id': self.pool_attrs['id'] })
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        pfxs = [
                '10.0.0.0/24',
                '10.0.1.0/24',
                '10.0.2.0/24',
                '10.0.3.0/24',
                '10.0.4.0/24'
                ]
        for p in pfxs:
            prefix_attrs = {
                    'type': 'reservation',
                    'authoritative_source': 'nipap-test',
                    'prefix': p,
                    'description': 'test prefix',
                    'pool_id': self.pool_attrs['id'],
                    'comment': 'test comment, please remove! ;)'
                    }
            self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # from-pool test
        res = self.nipap.find_free_prefix(self.auth, schema, { 'from-pool': { 'name': self.pool_attrs['name'] }, 'count': 1, 'family': 4})
        self.assertEqual(res, ['10.0.1.0/30'], "Incorrect prefix set returned when requesting default prefix-length")

        # from-pool test, specify wanted prefix length
        res = self.nipap.find_free_prefix(self.auth, schema, { 'from-pool': { 'name': self.pool_attrs['name'] }, 'count': 1, 'family': 4, 'prefix_length': 31})
        self.assertEqual(res, ['10.0.1.0/31'], "Incorrect prefix set returned with explicit prefix-length")



    def test_edit_prefix(self):
        """ Functionality testing of edit_prefix.
        """

        schema = { 'id': self.schema_attrs['id'] }
        data = {
            'prefix': '192.0.2.0/24',
            'description': 'foo',
            'comment': 'bar',
            'order_id': '0xBEEF',
            'customer_id': 'CUST-EEF-DERP',
            'alarm_priority': 'low',
            'type': 'assignment',
            'node': 'TOK-CORE-1',
            'country': 'EE',
            'authoritative_source': 'unittest',
            'pool': self.pool_attrs['id']
            }

        # basic edit
        self.nipap.edit_prefix(self.auth, schema, { 'id': self.prefix_attrs['id'] }, data)
        p = self.nipap.list_prefix(self.auth, schema, {'id': self.prefix_attrs['id']})[0]
        # remove what we did not touch
        for k, v in data.keys():
            if k not in p:
                del p[k]
        self.assertEqual(data, p, "Prefix data incorrect after edit.")

        # create a collision
        self.assertRaises(NipapError, self.nipap.edit_prefix, self.auth, schema, {'id': self.prefix_attrs2['id']}, {'prefix': data['prefix']})

        # try to change schema - disallowed
        self.assertRaises(NipapExtraneousInputError, self.nipap_edit_prefix, self.auth, schema, {'id': self.prefix_attrs2['id']}, {'schema': self.schema_attrs2['id']})



    def test_add_asn(self):
        """ Test adding ASNs to NIPAP.
        """

        data = {
            'asn': 1,
            'name': 'Test ASN #1'
        }

        self.assertEqual(self.nipap.add_asn(self.auth, data), 1, "add_asn did not return correct ASN.")
        asn = self.nipap.list_asn(self.auth, { 'asn': 1 })[0]
        self.assertEquals(data, asn, "ASN in database not equal to what was added.")
        self.assertRaises(NipapDuplicateError, self.nipap.add_asn, self.auth, data)


    def test_remove_asn(self):
        """ Test removing ASNs from NIPAP.
        """

        data = {
            'asn': 2,
            'name': 'Test ASN #2'
        }

        asn = self.nipap.add_asn(self.auth, data)
        self.nipap.remove_asn(self.auth, asn)
        self.assertEquals(0, len(self.nipap.list_asn(self.auth, { 'asn': 2 })), "Removed ASN still in database")



    def test_edit_asn(self):
        """ Test editing ASNs.
        """

        data = {
            'asn': 3,
            'name': 'Test ASN #3'
        }

        asn = self.nipap.add_asn(self.auth, data)
        self.nipap.edit_asn(self.auth, data['asn'], { 'name': 'b0rk' })
        self.assertEquals(self.nipap.list_asn(self.auth, { 'asn': 3 })[0]['name'], 'b0rk', "Edited ASN still has it's old name.")
        self.assertRaises(NipapExtraneousInputError, self.nipap.edit_asn, self.auth, {'asn': 3}, {'asn': 4, 'name': 'Test ASN #4'})



    def test_search_asn(self):
        """ Test searching ASNs.
        """

        data = {
            'asn': 4,
            'name': 'This is AS number 4'
        }

        asn = self.nipap.add_asn(self.auth, data)
        q = {
            'operator': 'equals',
            'val1': 'asn',
            'val2': data['asn']
        }
        res = self.nipap.search_asn(self.auth, q)
        self.assertEquals(len(res['result']), 1, "equal search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['name'], data['name'], "search hit got wrong name")

        q = {
            'operator': 'regex_match',
            'val1': 'name',
            'val2': 'number'
        }
        res = self.nipap.search_asn(self.auth, q)
        self.assertEquals(len(res['result']), 1, "regex search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['asn'], data['asn'], "search hit got wrong asn")



    def test_smart_search_asn(self):
        """ Test smart_search_asn function.
        """

        data = {
            'asn': 5,
            'name': 'Autonomous System Number 5'
        }

        asn = self.nipap.add_asn(self.auth, data)
        res = self.nipap.smart_search_asn(self.auth, "Autonomous")
        self.assertEquals(len(res['result']), 1, "search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['asn'], data['asn'], "search hit got wrong asn")
        self.assertEquals(res['interpretation'][0]['attribute'], 'name', "search term interpretated as wrong type")

        res = self.nipap.smart_search_asn(self.auth, "5")
        self.assertEquals(len(res['result']), 1, "search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['asn'], data['asn'], "search hit got wrong asn")
        self.assertEquals(res['interpretation'][0]['attribute'], 'asn', "search term interpretated as wrong type")
예제 #2
0
class NipapTest(unittest.TestCase):
    """ Tests the NIPAP class
    """

    nipap = None

    def setUp(self):
        """ Better start from a clean slate!
        """

        cfg = NipapConfig('/etc/nipap/nipap.conf')
        self.nipap = Nipap()

        # create dummy auth object
        # As the authentication is performed before the query hits the Nipap
        # class, it does not matter what user we use here
        self.auth = SqliteAuth('local', 'unittest', 'unittest', 'unittest')
        self.auth.authenticated_as = 'unittest'
        self.auth.full_name = 'Unit test'

        self.nipap._execute(
            "TRUNCATE ip_net_plan, ip_net_pool, ip_net_vrf, ip_net_log, ip_net_asn"
        )

        self.schema_attrs = {
            'name': 'test-schema1',
            'description': 'Test schema numero uno!'
        }
        self.schema_attrs['id'] = self.nipap.add_schema(
            self.auth, self.schema_attrs)
        self.schema_attrs2 = {
            'name': 'test-schema2',
            'description': 'Test schema numero dos!'
        }
        self.schema_attrs2['id'] = self.nipap.add_schema(
            self.auth, self.schema_attrs2)
        self.pool_attrs = {
            'name': 'test-pool1',
            'description': 'Test pool numero uno!',
            'default_type': 'assignment',
            'ipv4_default_prefix_length': 30,
            'ipv6_default_prefix_length': 112
        }
        self.pool_attrs['id'] = self.nipap.add_pool(
            self.auth, {'id': self.schema_attrs['id']}, self.pool_attrs)
        self.prefix_attrs1 = {
            'authoritative_source': 'nipaptest',
            'prefix': '1.3.3.0/24',
            'type': 'assignment',
            'description': ''
        }
        self.prefix_attrs1['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs1)
        self.prefix_attrs = {
            'authoritative_source': 'nipaptest',
            'prefix': '1.3.3.1/32',
            'type': 'host',
            'description': 'Test prefix numero uno!'
        }
        self.prefix_attrs['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs)
        self.prefix_attrs2 = {
            'authoritative_source': 'nipaptest',
            'prefix': '1.3.2.0/23',
            'type': 'reservation',
            'description': ''
        }
        self.prefix_attrs2['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs2)
        self.prefix_attrs3 = {
            'authoritative_source': 'nipaptest',
            'prefix': '1.3.0.0/16',
            'type': 'reservation',
            'description': ''
        }
        self.prefix_attrs3['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix_attrs3)
        self.prefix_attrs4 = {
            'authoritative_source': 'nipaptest',
            'prefix': '1.3.0.0/17',
            'type': 'reservation',
            'description': ''
        }
        self.prefix_attrs4['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs2['id']}, self.prefix_attrs4)

        self.prefix6_attrs1 = {
            'authoritative_source': 'nipaptest',
            'prefix': '2001:0db8:3:3::/112',
            'type': 'assignment',
            'description': ''
        }
        self.prefix6_attrs1['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs1)
        self.prefix6_attrs = {
            'authoritative_source': 'nipaptest',
            'prefix': '2001:0db8:3:3::1/128',
            'type': 'host',
            'description': 'Test prefix numero uno!'
        }
        self.prefix6_attrs['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs)
        self.prefix6_attrs2 = {
            'authoritative_source': 'nipaptest',
            'prefix': '2001:0db8:3:3::/64',
            'type': 'reservation',
            'description': ''
        }
        self.prefix6_attrs2['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs2)
        self.prefix6_attrs3 = {
            'authoritative_source': 'nipaptest',
            'prefix': '2001:0db8:3:0::/48',
            'type': 'reservation',
            'description': ''
        }
        self.prefix6_attrs3['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs['id']}, self.prefix6_attrs3)
        self.prefix6_attrs4 = {
            'authoritative_source': 'nipaptest',
            'prefix': '2001:0db8:3:0::/56',
            'type': 'reservation',
            'description': ''
        }
        self.prefix6_attrs4['id'] = self.nipap.add_prefix(
            self.auth, {'id': self.schema_attrs2['id']}, self.prefix6_attrs4)

    def test_schema_basic(self):
        """ Basic schema test

            1. Add a new schema
            2. List with filters to get newly created schema
            3. Verify listed schema coincides with input args for added schema
            4. Remove schema
        """
        attrs = {
            'name': 'test-schema-wrong',
            'description': 'A simple test schema with incorrect name!'
        }
        attrs['id'] = self.nipap.add_schema(self.auth, attrs)
        schema = self.nipap.list_schema(self.auth, {'id': attrs['id']})
        for a in attrs:
            self.assertEqual(
                schema[0][a], attrs[a],
                'Added object differ from listed on attribute: ' + a)

    def test_schema_add_crap_input(self):
        """ Try to input junk into add_schema and expect error

        """
        attrs = {
            'name': 'test-schema-crap',
            'description': 'A simple test schema with incorrect name!',
            'crap': 'this is just some crap'
        }
        # missing everything
        self.assertRaises(NipapMissingInputError, self.nipap.add_schema,
                          self.auth, {})
        # missing description
        self.assertRaises(NipapMissingInputError, self.nipap.add_schema,
                          self.auth, {'name': 'crapson'})
        # have required and extra crap
        self.assertRaises(NipapExtraneousInputError, self.nipap.add_schema,
                          self.auth, attrs)

    def test_expand_schema_spec(self):
        """ Test the expand_schema_spec()

            The _expand_schema_spec() function is used throughout the schema
            functions to expand the schema specification input and so we test
            the separately.
        """
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_schema_spec,
                          'string')
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_schema_spec, 1)
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_schema_spec, [])
        # missing keys
        self.assertRaises(NipapMissingInputError,
                          self.nipap._expand_schema_spec, {})
        # crap key
        self.assertRaises(NipapExtraneousInputError,
                          self.nipap._expand_schema_spec,
                          {'crap': self.schema_attrs['name']})
        # required keys and extra crap
        self.assertRaises(NipapExtraneousInputError,
                          self.nipap._expand_schema_spec, {
                              'name': self.schema_attrs['name'],
                              'crap': 'crap'
                          })
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_schema_spec,
                          {'id': '3'})
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_schema_spec,
                          {'name': 3})
        # both id and name
        self.assertRaises(NipapExtraneousInputError,
                          self.nipap._expand_schema_spec, {
                              'id': 3,
                              'name': '3'
                          })
        # proper key - id
        where, params = self.nipap._expand_schema_spec({'id': 3})
        self.assertEqual(where, 'id = %(spec_id)s',
                         "Improperly expanded WHERE clause")
        self.assertEqual(params, {'spec_id': 3},
                         "Improperly expanded params dict")
        # proper spec - name
        where, params = self.nipap._expand_schema_spec({'name': 'test'})

    def test_schema_edit_crap_input(self):
        """ Try to input junk into edit_schema and expect error

        """
        attrs = {
            'name': 'test-schema-crap',
            'description': 'A simple test schema with incorrect name!'
        }
        crap_attrs = {
            'name': 'test-schema-crap',
            'description': 'A simple test schema with incorrect name!',
            'crap': 'this is just some crap'
        }
        # spec is tested elsewhere, just test attrs part
        self.assertRaises(NipapExtraneousInputError, self.nipap.edit_schema,
                          self.auth, {'name': self.schema_attrs['name']},
                          crap_attrs)

    def test_schema_list_crap_input(self):
        """ Try to input junk into list_schema and expect error

        """
        # TODO: what do we really expect?
        self.assertRaises(NipapExtraneousInputError, self.nipap.list_schema,
                          self.auth, {'crap': 'crap crap'})

    def test_schema_dupe(self):
        """ Check so we can't create duplicate schemas

            There are unique indices in the database that should prevent us
            from creating duplicate schema (ie, with the same name).
        """
        schema_attrs = {
            'name': 'test-schema-dupe',
            'description': 'Testing dupe'
        }
        self.nipap.add_schema(self.auth, schema_attrs)
        self.assertRaises(NipapDuplicateError, self.nipap.add_schema,
                          self.auth, schema_attrs)

    def test_schema_rename(self):
        """ Rename a schema

            Uses the edit_schema() functionality to rename our previously
            created and incorrectly named schema so it hereafter has the
            correct name. Also tests the list_schema() functionality since we
            use that to list the modified schema.
        """
        spec = {'name': 'test-schema1'}
        attrs = {
            'name': 'test-schema',
            'description': 'A simple test schema with correct name!'
        }
        self.nipap.edit_schema(self.auth, spec, attrs)
        # check that search for old record doesn't return anything
        schema = self.nipap.list_schema(self.auth, spec)
        self.assertEqual(schema, [], 'Old entry still exists')
        schema = self.nipap.list_schema(self.auth, {'name': 'test-schema'})
        for a in attrs:
            self.assertEqual(
                schema[0][a], attrs[a],
                'Modified schema differ from listed on attribute: ' + a)

    def test_schema_remove(self):
        """ Remove a schema

            Remove the schema previously modified and make sure it's not there.
        """
        spec = {'name': 'test-schema'}
        self.nipap.remove_schema(self.auth, spec)
        # check that search for old record doesn't return anything
        schema = self.nipap.list_schema(self.auth, spec)
        self.assertEqual(schema, [], 'Old entry still exists')

    def test_expand_pool_spec(self):
        """ Test the function which expands pool spec to SQL.
        """

        schema = {'id': self.schema_attrs['id']}

        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_pool_spec,
                          'string')
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_pool_spec, 1)
        # wrong type
        self.assertRaises(NipapInputError, self.nipap._expand_pool_spec, [])
        # missing keys
        self.assertRaises(NipapMissingInputError, self.nipap._expand_pool_spec,
                          {})
        # crap key
        self.assertRaises(NipapExtraneousInputError,
                          self.nipap._expand_pool_spec,
                          {'crap': self.pool_attrs['name']})
        # required keys and extra crap
        self.assertRaises(
            NipapExtraneousInputError, self.nipap._expand_pool_spec, {
                'id': self.pool_attrs['id'],
                'schema': self.schema_attrs['id'],
                'crap': 'crap'
            })
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_pool_spec, {
            'id': '3',
            'schema': self.schema_attrs['id']
        })
        # proper key but incorrect value (int vs string)
        self.assertRaises(NipapValueError, self.nipap._expand_pool_spec, {
            'name': 3,
            'schema': self.schema_attrs['id']
        })
        # both id and name
        self.assertRaises(NipapExtraneousInputError,
                          self.nipap._expand_pool_spec, {
                              'id': 3,
                              'name': '3',
                              'schema': self.schema_attrs['id']
                          })
        # proper key - id
        where, params = self.nipap._expand_pool_spec({
            'id':
            3,
            'schema':
            self.schema_attrs['id']
        })
        self.assertEqual(
            where, 'po.id = %(spec_id)s AND po.schema = %(spec_schema)s',
            "Improperly expanded WHERE clause")
        self.assertEqual(params, {
            'spec_id': 3,
            'spec_schema': self.schema_attrs['id']
        }, "Improperly expanded params dict")
        # proper spec - name
        where, params = self.nipap._expand_pool_spec({
            'name':
            'test',
            'schema':
            self.schema_attrs['id']
        })
        self.assertEqual(
            where, 'po.name = %(spec_name)s AND po.schema = %(spec_schema)s',
            "Improperly expanded WHERE clause")
        self.assertEqual(params, {
            'spec_name': 'test',
            'spec_schema': self.schema_attrs['id']
        }, "Improperly expanded params dict")

    def test_pool_add1(self):
        """ Add a pool and check it's there using list functions

            Refer to schema by id
        """
        attrs = {
            'name': 'test-pool-wrong',
            'description': 'A simple test pool with incorrect name!',
            'default_type': 'reservation',
            'ipv4_default_prefix_length': 30,
            'ipv6_default_prefix_length': 112
        }
        schema = {'id': self.schema_attrs['id']}
        pool_id = self.nipap.add_pool(self.auth, schema, attrs)
        pool = self.nipap.list_pool(self.auth, schema, {'id': pool_id})
        for a in attrs:
            self.assertEqual(
                pool[0][a], attrs[a],
                'Added object differ from listed on attribute: %s  %s!=%s' %
                (a, attrs[a], pool[0][a]))

    def test_pool_add2(self):
        """ Add a pool and check it's there using list functions

            Refer to schema by name
        """
        schema = {'id': self.schema_attrs['id']}
        attrs = {
            'name': 'test-pool-wrong',
            'default_type': 'reservation',
            'description': 'A simple test pool with incorrect name!'
        }
        pool_id = self.nipap.add_pool(self.auth, schema, attrs)
        pool = self.nipap.list_pool(self.auth, schema, {'id': pool_id})
        for a in attrs:
            self.assertEqual(
                pool[0][a], attrs[a],
                'Added object differ from listed on attribute: ' + a)

    def test_edit_pool_by_name(self):
        """ Try to rename a pool using edit_pool() function

            Pool is not uniquely identified (empty spec) so this should raise an error
        """
        schema = {'id': self.schema_attrs['id']}
        spec = {}
        attrs = {
            'name': self.pool_attrs['name'],
            'default_type': 'assignment',
            'description': 'A simple test pool with correct name!'
        }
        self.assertRaises(NipapInputError, self.nipap.edit_pool, self.auth,
                          schema, spec, attrs)

    def test_edit_pool(self):
        """ Rename a pool using edit_pool() function
        """
        schema = {'id': self.schema_attrs['id']}
        spec = {'id': self.pool_attrs['id']}
        attrs = {
            'name': 'test-pool',
            'default_type': 'assignment',
            'description': 'A simple test pool with correct name!',
            'ipv4_default_prefix_length': 32,
            'ipv6_default_prefix_length': 128
        }
        self.nipap.edit_pool(self.auth, schema, spec, attrs)
        # check that search for old record doesn't return anything
        pool = self.nipap.list_pool(self.auth, schema,
                                    {'name': self.pool_attrs['name']})
        self.assertEqual(pool, [], 'Old entry still exists')
        pool = self.nipap.list_pool(self.auth, schema, {'name': attrs['name']})
        for a in attrs:
            self.assertEqual(
                pool[0][a], attrs[a],
                'Added object differ from listed on attribute: ' + a)

    def test_remove_pool_by_id(self):
        """ Remove a pool by id
        """
        schema = {'id': self.schema_attrs['id']}
        pool = self.nipap.list_pool(self.auth, schema,
                                    {'id': self.pool_attrs['id']})
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [],
                            'Record must exist before we can delete it')
        for a in self.pool_attrs:
            self.assertEqual(pool[0][a], self.pool_attrs[a],
                             'Listed attribute differ from original')
        # remove the pool
        self.nipap.remove_pool(self.auth, schema,
                               {'id': self.pool_attrs['id']})
        # check that search for old record doesn't return anything
        pool = self.nipap.list_pool(self.auth, schema,
                                    {'id': self.pool_attrs['id']})
        self.assertEqual(pool, [], 'Old entry still exists')

    def test_prefix_in_a_pool(self):
        """ Add prefixes to a poll and list!
        """
        schema = {'id': self.schema_attrs['id']}
        pool = self.nipap.list_pool(self.auth, schema,
                                    {'id': self.pool_attrs['id']})
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        pfxs = [
            '1.2.2.0/32', '1.2.2.1/32', '1.2.2.2/32', '1.2.2.3/32',
            '1.2.2.4/32', '1.2.2.5/32'
        ]
        for p in pfxs:
            prefix_attrs = {
                'authoritative_source': 'nipap-test',
                'prefix': p,
                'type': 'host',
                'description': 'test prefix',
                'pool_id': self.pool_attrs['id'],
                'comment': 'test comment, please remove! ;)'
            }
            self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # list again
        pool = self.nipap.list_pool(self.auth, schema,
                                    {'id': self.pool_attrs['id']})
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        self.assertEqual(set(pfxs), set(pool[0]['prefixes']),
                         'Returned prefixes do not match added ones')

    def test_prefix_basic(self):
        """ Test basic prefix functions
        """
        schema = {'id': self.schema_attrs['id']}
        prefix_attrs = {
            'authoritative_source': 'nipap-test',
            'prefix': '1.3.3.7/32',
            'type': 'host',
            'description': 'test prefix',
            'comment': 'test comment, please remove! ;)'
        }
        self.nipap.add_prefix(self.auth, schema, prefix_attrs)
        prefix = self.nipap.list_prefix(self.auth, schema,
                                        {'prefix': prefix_attrs['prefix']})
        for a in prefix_attrs:
            self.assertEqual(
                prefix[0][a], prefix_attrs[a],
                'Added object differ from listed on attribute: ' + a)

        # fetch many prefixes - all in a schema
        prefix = self.nipap.list_prefix(self.auth, schema, {})
        self.assertNotEqual(
            len(prefix), 0,
            'Found 0 prefixes in schema ' + self.schema_attrs['name'])

    def test_add_prefix(self):
        """ Test add_prefix in a bit more detail
        """
        schema = {'id': self.schema_attrs['id']}
        # we need a bloody pool first!
        pool = self.nipap.list_pool(self.auth, schema,
                                    {'id': self.pool_attrs['id']})
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        pfxs = [
            '10.0.0.0/24', '10.0.1.0/24', '10.0.2.0/24', '10.0.3.0/24',
            '10.0.4.0/24'
        ]
        for p in pfxs:
            prefix_attrs = {
                'authoritative_source': 'nipap-test',
                'prefix': p,
                'type': 'reservation',
                'description': 'test prefix',
                'pool_id': self.pool_attrs['id'],
                'comment': 'test comment, please remove! ;)'
            }
            self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # get an address based on from-prefix
        prefix_attrs = {
            'type': 'assignment',
            'authoritative_source': 'nipap-test',
            'description': 'test prefix',
            'comment': 'test comment, please remove! ;)'
        }
        res = self.nipap.add_prefix(self.auth, schema, prefix_attrs, {
            'from-prefix': ['10.0.0.0/24'],
            'prefix_length': 30
        })
        p = self.nipap.list_prefix(self.auth, schema, {'id': res})
        self.assertEqual(p[0]['prefix'], '10.0.0.0/30',
                         "New prefix differ from what it should be!")

        self.nipap.add_schema(self.auth, {
            'name': 'testtest',
            'description': 'another test schema!'
        })
        # pass different schemas in attr and args
        # TODO: Find something similar?
        #self.assertRaises(NipapInputError, self.nipap.add_prefix, schema, { 'authoritative_source': 'nipap-test', 'description': 'tjong' }, { 'from-prefix': ['10.0.0.0/24'], 'prefix_length': 30 })

    def test_prefix_search_simple(self):
        """ Test the simple prefix search function.
        """

        schema = {'id': self.schema_attrs['id']}

        # First, perform e few tests to verify search string expansion.
        query_keys = dict()
        query_keys['testing testing'] = "description"
        query_keys['1.2.3.4'] = "prefix"

        # build query string
        query_str = ""
        for key, val in query_keys.items():
            if val == "description":
                query_str += "\"%s\" " % key
            else:
                query_str += "%s " % key

        res = self.nipap.smart_search_prefix(self.auth, schema, query_str)
        for interp in res['interpretation']:
            self.assertEqual(
                interp['string'] in query_keys, True,
                "Function returned unknown interpreted string %s" %
                interp['string'])

        prefix_attrs = {
            'authoritative_source': 'nipap-test',
            'prefix': '1.3.3.77/32',
            'type': 'host',
            'description': 'test-ish prefix',
            'comment': 'Test prefix #77! ;)'
        }

        self.nipap.add_prefix(self.auth, schema, prefix_attrs)
        res = self.nipap.smart_search_prefix(self.auth, schema,
                                             r"""1.3.3.77 "-ish" """)
        self.assertEqual(res['result'][-1]['prefix'], '1.3.3.77/32',
                         'Prefix not found')

    def test_prefix_search_smart(self):
        """ Test the smart prefix search function.
        """
        schema = {'id': self.schema_attrs['id']}

        # test full ipv4 address
        res = self.nipap.smart_search_prefix(self.auth, schema, '1.3.3.7')
        self.assertEqual(res['interpretation'][0]['interpretation'],
                         'IPv4 address')

        res = self.nipap.smart_search_prefix(self.auth, schema, '1.1')
        self.assertEqual(
            res['interpretation'][0]['interpretation'], 'text',
            "Incorrectly interpreted '1.1' as : " +
            res['interpretation'][0]['interpretation'])

        res = self.nipap.smart_search_prefix(self.auth, schema, '10/8')
        self.assertEqual(res['interpretation'][0]['interpretation'],
                         'IPv4 prefix')

        res = self.nipap.smart_search_prefix(self.auth, schema, '2000:0::01')
        self.assertEqual(res['interpretation'][0]['interpretation'],
                         'IPv6 address')

    def test_prefix_remove(self):
        """ Remove a prefix
        """
        schema = {'id': self.schema_attrs['id']}
        prefix = self.nipap.list_prefix(self.auth, schema,
                                        {'id': self.prefix_attrs['id']})
        # first make sure our prefix exists
        self.assertEqual(prefix[0]['id'], self.prefix_attrs['id'],
                         'Record must exist before we can delete it')
        # remove the prefix, by id
        self.nipap.remove_prefix(self.auth, schema,
                                 {'id': self.prefix_attrs['id']})
        # check that search for old record doesn't return anything
        prefix = self.nipap.list_prefix(self.auth, schema,
                                        {'id': self.prefix_attrs['id']})
        self.assertEqual(prefix, [], 'Old entry still exists')

    def test_prefix_indent_ipv4(self):
        """ Check that our indentation calculation is working for IPv4

            Prefixes gets an indent value automatically assigned to help in
            displaying prefix information. The indent value is written on
            updates to the table and this test is to make sure it is correctly
            calculated.
        """
        schema = {'id': self.schema_attrs['id']}
        p1 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '1.3.3.1/32'})[0]
        p2 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '1.3.3.0/24'})[0]
        p3 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '1.3.0.0/16'})[0]
        self.assertEqual(p1['indent'], 4, "Indent calc on add failed")
        self.assertEqual(p2['indent'], 3, "Indent calc on add failed")
        self.assertEqual(p3['indent'], 0, "Indent calc on add failed")
        # remove middle prefix
        self.nipap.remove_prefix(self.auth, schema,
                                 {'id': self.prefix_attrs2['id']})
        # check that child prefix indent level has decreased
        p1 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '1.3.3.1/32'})[0]
        p3 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '1.3.0.0/16'})[0]
        self.assertEqual(p1['indent'], 3, "Indent calc on remove failed")
        self.assertEqual(p3['indent'], 0, "Indent calc on remove failed")

    def test_prefix_indent_ipv6(self):
        """ Check that our indentation calculation is working for IPv6

            Prefixes gets an indent value automatically assigned to help in
            displaying prefix information. The indent value is written on
            updates to the table and this test is to make sure it is correctly
            calculated.
        """
        schema = {'id': self.schema_attrs['id']}
        p1 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '2001:0db8:3:3::1/128'})[0]
        p2 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '2001:0db8:3:3::/64'})[0]
        p3 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '2001:0db8:3:0::/48'})[0]
        self.assertEqual(p1['indent'], 4, "Indent calc on add failed")
        self.assertEqual(p2['indent'], 2, "Indent calc on add failed")
        self.assertEqual(p3['indent'], 0, "Indent calc on add failed")
        # remove middle prefix
        self.nipap.remove_prefix(self.auth, schema,
                                 {'id': self.prefix6_attrs2['id']})
        # check that child prefix indent level has decreased
        p1 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '2001:0db8:3:3::1/128'})[0]
        p3 = self.nipap.list_prefix(self.auth, schema,
                                    {'prefix': '2001:0db8:3:0::/48'})[0]
        self.assertEqual(
            p1['indent'], 3, "Indent calc on remove failed for " +
            p1['prefix'] + " indent: " + str(p1['indent']))
        self.assertEqual(
            p3['indent'], 0, "Indent calc on remove failed for " +
            p3['prefix'] + " indent: " + str(p3['indent']))

    def test_find_free_prefix_input(self):
        """ Mostly input testing of find_free_prefix

            Try to stress find_free_prefix and send a lot of junk..
        """
        schema = {'id': self.schema_attrs['id']}
        # set up a prefix not used elsewhere so we have a known good state
        prefix_attrs = {
            'authoritative_source': 'nipap-test',
            'prefix': '100.0.0.0/16',
            'type': 'reservation',
            'description': 'test prefix',
            'comment': 'test comment, please remove! ;)'
        }
        self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # no schema, should raise error!
        self.assertRaises(NipapInputError, self.nipap.find_free_prefix,
                          self.auth, schema, {'from-prefix': ['100.0.0.0/16']})

        # incorrect from-prefix type, string instead of list of strings (looking like an IP address)
        self.assertRaises(NipapInputError, self.nipap.find_free_prefix,
                          self.auth, schema, {'from-prefix': '100.0.0.0/16'})

        # missing prefix_length
        self.assertRaises(NipapMissingInputError, self.nipap.find_free_prefix,
                          self.auth, schema, {
                              'from-prefix': ['100.0.0.0/16'],
                              'count': 1
                          })

        # try giving both IPv4 and IPv6 in from-prefix which shouldn't work
        self.assertRaises(
            NipapInputError, self.nipap.find_free_prefix, self.auth, schema, {
                'from-prefix': ['100.0.0.0/16', '2a00:800::0/25'],
                'prefix_length': 24,
                'count': 1
            })

        # try giving non-integer as wanted prefix length
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix,
                          self.auth, schema, {
                              'from-prefix': ['100.0.0.0/16'],
                              'prefix_length': '24',
                              'count': 1
                          })

        # try giving to high a number as wanted prefix length for IPv4
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix,
                          self.auth, schema, {
                              'from-prefix': ['100.0.0.0/16'],
                              'prefix_length': 35,
                              'count': 1
                          })

        # try giving to high a number as wanted prefix length for IPv6
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix,
                          self.auth, schema, {
                              'from-prefix': ['2a00:800::1/25'],
                              'prefix_length': 150,
                              'count': 1
                          })

        # try giving a high number for result count (max is 1000)
        self.assertRaises(NipapValueError, self.nipap.find_free_prefix,
                          self.auth, schema, {
                              'from-prefix': ['100.0.0.0/16'],
                              'prefix_length': 30,
                              'count': 55555
                          })

        # don't pass 'family', which is required when specifying 'from-pool'
        self.assertRaises(
            NipapMissingInputError, self.nipap.find_free_prefix, self.auth,
            schema, {
                'from-pool': {
                    'name': self.pool_attrs['name']
                },
                'prefix_length': 24,
                'count': 1
            })

        # pass crap as family, wrong type even
        self.assertRaises(
            ValueError, self.nipap.find_free_prefix, self.auth, schema, {
                'from-pool': {
                    'name': self.pool_attrs['name']
                },
                'prefix_length': 24,
                'count': 1,
                'family': 'crap'
            })

        # pass 7 as family
        self.assertRaises(
            NipapValueError, self.nipap.find_free_prefix, self.auth, schema, {
                'from-pool': {
                    'name': self.pool_attrs['name']
                },
                'prefix_length': 24,
                'count': 1,
                'family': 7
            })

        # pass non existent pool
        self.assertRaises(
            NipapNonExistentError, self.nipap.find_free_prefix, self.auth,
            schema, {
                'from-pool': {
                    'name': 'crap'
                },
                'prefix_length': 24,
                'count': 1,
                'family': 4
            })

    def test_find_free_prefix1(self):
        """ Functionality testing of find_free_prefix

            Mostly based on 'from-prefix'
        """
        schema = {'id': self.schema_attrs['id']}
        # set up a prefix not used elsewhere so we have a known good state
        prefix_attrs = {
            'authoritative_source': 'nipap-test',
            'prefix': '100.0.0.0/16',
            'type': 'assignment',
            'description': 'test prefix',
            'comment': 'test comment, please remove! ;)'
        }
        self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # simple test
        res = self.nipap.find_free_prefix(
            self.auth, schema, {
                'from-prefix': ['100.0.0.0/16', '1.3.3.0/24'],
                'prefix_length': 24,
                'count': 1
            })
        self.assertEqual(res, ['100.0.0.0/24'],
                         "Incorrect prefix set returned")

        # simple test - only one input prefix (which did cause a bug, thus keeping it)
        res = self.nipap.find_free_prefix(self.auth, schema, {
            'from-prefix': ['100.0.0.0/16'],
            'prefix_length': 24,
            'count': 1
        })
        self.assertEqual(res, ['100.0.0.0/24'],
                         "Incorrect prefix set returned")

        res = self.nipap.find_free_prefix(
            self.auth, schema, {
                'from-prefix': ['100.0.0.0/16', '1.3.3.0/24'],
                'prefix_length': 24,
                'count': 999
            })
        self.assertEqual(len(res), 256, "Incorrect prefix set returned")

    def test_find_free_prefix2(self):
        """ Functionality testing of find_free_prefix

            Mostly based on 'from-pool'
        """
        schema = {'id': self.schema_attrs['id']}
        # we need a bloody pool first!
        pool = self.nipap.list_pool(self.auth, schema,
                                    {'id': self.pool_attrs['id']})
        # first make sure our pool exists
        self.assertNotEqual(pool[0], [], 'Pool must exist!')
        pfxs = [
            '10.0.0.0/24', '10.0.1.0/24', '10.0.2.0/24', '10.0.3.0/24',
            '10.0.4.0/24'
        ]
        for p in pfxs:
            prefix_attrs = {
                'type': 'reservation',
                'authoritative_source': 'nipap-test',
                'prefix': p,
                'description': 'test prefix',
                'pool_id': self.pool_attrs['id'],
                'comment': 'test comment, please remove! ;)'
            }
            self.nipap.add_prefix(self.auth, schema, prefix_attrs)

        # from-pool test
        res = self.nipap.find_free_prefix(
            self.auth, schema, {
                'from-pool': {
                    'name': self.pool_attrs['name']
                },
                'count': 1,
                'family': 4
            })
        self.assertEqual(
            res, ['10.0.1.0/30'],
            "Incorrect prefix set returned when requesting default prefix-length"
        )

        # from-pool test, specify wanted prefix length
        res = self.nipap.find_free_prefix(
            self.auth, schema, {
                'from-pool': {
                    'name': self.pool_attrs['name']
                },
                'count': 1,
                'family': 4,
                'prefix_length': 31
            })
        self.assertEqual(
            res, ['10.0.1.0/31'],
            "Incorrect prefix set returned with explicit prefix-length")

    def test_edit_prefix(self):
        """ Functionality testing of edit_prefix.
        """

        schema = {'id': self.schema_attrs['id']}
        data = {
            'prefix': '192.0.2.0/24',
            'description': 'foo',
            'comment': 'bar',
            'order_id': '0xBEEF',
            'customer_id': 'CUST-EEF-DERP',
            'alarm_priority': 'low',
            'type': 'assignment',
            'node': 'TOK-CORE-1',
            'country': 'EE',
            'authoritative_source': 'unittest',
            'pool': self.pool_attrs['id']
        }

        # basic edit
        self.nipap.edit_prefix(self.auth, schema,
                               {'id': self.prefix_attrs['id']}, data)
        p = self.nipap.list_prefix(self.auth, schema,
                                   {'id': self.prefix_attrs['id']})[0]
        # remove what we did not touch
        for k, v in data.keys():
            if k not in p:
                del p[k]
        self.assertEqual(data, p, "Prefix data incorrect after edit.")

        # create a collision
        self.assertRaises(NipapError, self.nipap.edit_prefix, self.auth,
                          schema, {'id': self.prefix_attrs2['id']},
                          {'prefix': data['prefix']})

        # try to change schema - disallowed
        self.assertRaises(NipapExtraneousInputError, self.nipap_edit_prefix,
                          self.auth, schema, {'id': self.prefix_attrs2['id']},
                          {'schema': self.schema_attrs2['id']})

    def test_add_asn(self):
        """ Test adding ASNs to NIPAP.
        """

        data = {'asn': 1, 'name': 'Test ASN #1'}

        self.assertEqual(self.nipap.add_asn(self.auth, data), 1,
                         "add_asn did not return correct ASN.")
        asn = self.nipap.list_asn(self.auth, {'asn': 1})[0]
        self.assertEquals(data, asn,
                          "ASN in database not equal to what was added.")
        self.assertRaises(NipapDuplicateError, self.nipap.add_asn, self.auth,
                          data)

    def test_remove_asn(self):
        """ Test removing ASNs from NIPAP.
        """

        data = {'asn': 2, 'name': 'Test ASN #2'}

        asn = self.nipap.add_asn(self.auth, data)
        self.nipap.remove_asn(self.auth, asn)
        self.assertEquals(0, len(self.nipap.list_asn(self.auth, {'asn': 2})),
                          "Removed ASN still in database")

    def test_edit_asn(self):
        """ Test editing ASNs.
        """

        data = {'asn': 3, 'name': 'Test ASN #3'}

        asn = self.nipap.add_asn(self.auth, data)
        self.nipap.edit_asn(self.auth, data['asn'], {'name': 'b0rk'})
        self.assertEquals(
            self.nipap.list_asn(self.auth, {'asn': 3})[0]['name'], 'b0rk',
            "Edited ASN still has it's old name.")
        self.assertRaises(NipapExtraneousInputError, self.nipap.edit_asn,
                          self.auth, {'asn': 3}, {
                              'asn': 4,
                              'name': 'Test ASN #4'
                          })

    def test_search_asn(self):
        """ Test searching ASNs.
        """

        data = {'asn': 4, 'name': 'This is AS number 4'}

        asn = self.nipap.add_asn(self.auth, data)
        q = {'operator': 'equals', 'val1': 'asn', 'val2': data['asn']}
        res = self.nipap.search_asn(self.auth, q)
        self.assertEquals(len(res['result']), 1,
                          "equal search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['name'], data['name'],
                          "search hit got wrong name")

        q = {'operator': 'regex_match', 'val1': 'name', 'val2': 'number'}
        res = self.nipap.search_asn(self.auth, q)
        self.assertEquals(len(res['result']), 1,
                          "regex search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['asn'], data['asn'],
                          "search hit got wrong asn")

    def test_smart_search_asn(self):
        """ Test smart_search_asn function.
        """

        data = {'asn': 5, 'name': 'Autonomous System Number 5'}

        asn = self.nipap.add_asn(self.auth, data)
        res = self.nipap.smart_search_asn(self.auth, "Autonomous")
        self.assertEquals(len(res['result']), 1,
                          "search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['asn'], data['asn'],
                          "search hit got wrong asn")
        self.assertEquals(res['interpretation'][0]['attribute'], 'name',
                          "search term interpretated as wrong type")

        res = self.nipap.smart_search_asn(self.auth, "5")
        self.assertEquals(len(res['result']), 1,
                          "search resulted in wrong number of hits")
        self.assertEquals(res['result'][0]['asn'], data['asn'],
                          "search hit got wrong asn")
        self.assertEquals(res['interpretation'][0]['attribute'], 'asn',
                          "search term interpretated as wrong type")