From 7c3bcafef094d77df698aa0eba8b02e8892ce1c2 Mon Sep 17 00:00:00 2001 From: Martin Basti Date: Jun 03 2016 13:58:21 +0000 Subject: DNS Locations: API tests Tests for location-* commands https://fedorahosted.org/freeipa/ticket/2008 Reviewed-By: Petr Spacek Reviewed-By: Jan Cholasta --- diff --git a/ipatests/test_xmlrpc/test_location_plugin.py b/ipatests/test_xmlrpc/test_location_plugin.py new file mode 100644 index 0000000..1ca3eac --- /dev/null +++ b/ipatests/test_xmlrpc/test_location_plugin.py @@ -0,0 +1,113 @@ +# +# Copyright (C) 2016 FreeIPA Contributors see COPYING for license +# +from __future__ import absolute_import + +import pytest + +from ipalib import errors +from ipatests.test_xmlrpc.tracker.location_plugin import LocationTracker +from ipatests.test_xmlrpc.xmlrpc_test import ( + XMLRPC_test, + raises_exact, +) + + +@pytest.fixture(scope='class', params=[u'location1', u'sk\xfa\u0161ka.idna']) +def location(request): + tracker = LocationTracker(request.param) + return tracker.make_fixture(request) + + +@pytest.fixture(scope='class') +def location_invalid(request): + tracker = LocationTracker(u'invalid..location') + return tracker + + +@pytest.fixture(scope='class') +def location_absolute(request): + tracker = LocationTracker(u'invalid.absolute.') + return tracker.make_fixture(request) + + +@pytest.mark.tier1 +class TestNonexistentIPALocation(XMLRPC_test): + def test_retrieve_nonexistent(self, location): + location.ensure_missing() + command = location.make_retrieve_command() + with raises_exact(errors.NotFound( + reason=u'%s: location not found' % location.idnsname)): + command() + + def test_update_nonexistent(self, location): + location.ensure_missing() + command = location.make_update_command(updates=dict( + description=u'Nope')) + with raises_exact(errors.NotFound( + reason=u'%s: location not found' % location.idnsname)): + command() + + def test_delete_nonexistent(self, location): + location.ensure_missing() + command = location.make_delete_command() + with raises_exact(errors.NotFound( + reason=u'%s: location not found' % location.idnsname)): + command() + +@pytest.mark.tier1 +class TestInvalidIPALocations(XMLRPC_test): + def test_invalid_name(self, location_invalid): + command = location_invalid.make_create_command() + with raises_exact(errors.ConversionError( + name=u'name', + error=u"empty DNS label")): + command() + + def test_invalid_absolute(self, location_absolute): + command = location_absolute.make_create_command() + with raises_exact(errors.ValidationError( + name=u'name', error=u'must be relative')): + command() + + +@pytest.mark.tier1 +class TestCRUD(XMLRPC_test): + def test_create_duplicate(self, location): + location.ensure_exists() + command = location.make_create_command(force=True) + with raises_exact(errors.DuplicateEntry( + message=u'location with name "%s" already exists' % + location.idnsname)): + command() + + def test_retrieve_simple(self, location): + location.retrieve() + + def test_retrieve_all(self, location): + location.retrieve(all=True) + + def test_search_simple(self, location): + location.find() + + def test_search_all(self, location): + location.find(all=True) + + def test_update_simple(self, location): + location.update(dict( + description=u'Updated description', + ), + expected_updates=dict( + description=[u'Updated description'], + )) + location.retrieve() + + def test_try_rename(self, location): + location.ensure_exists() + command = location.make_update_command( + updates=dict(setattr=u'idnsname=changed')) + with raises_exact(errors.NotAllowedOnRDN()): + command() + + def test_delete_location(self, location): + location.delete() diff --git a/ipatests/test_xmlrpc/tracker/location_plugin.py b/ipatests/test_xmlrpc/tracker/location_plugin.py new file mode 100644 index 0000000..c7af097 --- /dev/null +++ b/ipatests/test_xmlrpc/tracker/location_plugin.py @@ -0,0 +1,119 @@ +# +# Copyright (C) 2016 FreeIPA Contributors see COPYING for license +# +from __future__ import absolute_import + +from ipapython.dn import DN +from ipapython.dnsutil import DNSName +from ipatests.util import assert_deepequal +from ipatests.test_xmlrpc.tracker.base import Tracker + + +class LocationTracker(Tracker): + """Tracker for IPA Location tests""" + retrieve_keys = {'idnsname', 'description', 'dn'} + retrieve_all_keys = retrieve_keys | {'objectclass'} + create_keys = retrieve_keys | {'objectclass'} + find_keys = retrieve_keys + find_all_keys = retrieve_all_keys + update_keys = {'idnsname', 'description'} + + def __init__(self, name, description=u"Location description"): + super(LocationTracker, self).__init__(default_version=None) + # ugly hack to allow testing invalid inputs + try: + self.idnsname_obj = DNSName(name) + except Exception: + self.idnsname_obj = DNSName(u"placeholder-for-invalid-value") + + self.idnsname = name + self.description = description + self.dn = DN( + ('idnsname', self.idnsname_obj.ToASCII()), + 'cn=locations', + 'cn=etc', self.api.env.basedn + ) + + def make_create_command(self, force=None): + """Make function that creates this location using location-add""" + return self.make_command( + 'location_add', self.idnsname, description=self.description, + ) + + def make_delete_command(self): + """Make function that removes this location using location-del""" + return self.make_command('location_del', self.idnsname) + + def make_retrieve_command(self, all=False, raw=False): + """Make function that retrieves this location using location-show""" + return self.make_command( + 'location_show', self.idnsname, all=all, raw=raw + ) + + def make_find_command(self, *args, **kwargs): + """Make function that finds locations using location-find""" + return self.make_command('location_find', *args, **kwargs) + + def make_update_command(self, updates): + """Make function that modifies the location using location-mod""" + return self.make_command('location_mod', self.idnsname, **updates) + + def track_create(self): + """Update expected state for location creation""" + + self.attrs = dict( + dn=self.dn, + idnsname=[self.idnsname_obj], + description=[self.description], + objectclass=[u'top', u'ipaLocationObject'], + ) + self.exists = True + + def check_create(self, result): + """Check `location-add` command result""" + assert_deepequal(dict( + value=self.idnsname_obj, + summary=u'Added IPA location "{loc}"'.format(loc=self.idnsname), + result=self.filter_attrs(self.create_keys) + ), result) + + def check_delete(self, result): + """Check `location-del` command result""" + assert_deepequal(dict( + value=[self.idnsname_obj], + summary=u'Deleted IPA location "{loc}"'.format(loc=self.idnsname), + result=dict(failed=[]), + ), result) + + def check_retrieve(self, result, all=False, raw=False): + """Check `location-show` command result""" + if all: + expected = self.filter_attrs(self.retrieve_all_keys) + else: + expected = self.filter_attrs(self.retrieve_keys) + assert_deepequal(dict( + value=self.idnsname_obj, + summary=None, + result=expected, + ), result) + + def check_find(self, result, all=False, raw=False): + """Check `location-find` command result""" + if all: + expected = self.filter_attrs(self.find_all_keys) + else: + expected = self.filter_attrs(self.find_keys) + assert_deepequal(dict( + count=1, + truncated=False, + summary=u'1 IPA location matched', + result=[expected], + ), result) + + def check_update(self, result, extra_keys=()): + """Check `location-update` command result""" + assert_deepequal(dict( + value=self.idnsname_obj, + summary=u'Modified IPA location "{loc}"'.format(loc=self.idnsname), + result=self.filter_attrs(self.update_keys | set(extra_keys)) + ), result)