From 7a9612411834649cac2089afc6c19942d8062ab7 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 26 Feb 2016 17:18:57 +0100 Subject: Implement total ordering for PKISubsystem and PKIInstance In Python 3 subclasses no longer implement automatic ordering. To provide ordering for sort() and custom comparison, __eq__ and __lt__ are required. https://fedorahosted.org/pki/ticket/2216 --- base/server/python/pki/server/__init__.py | 45 +++++++++++++++++++++++ tests/python/server/test_server.py | 61 +++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 tests/python/server/test_server.py diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py index 5803f3f52..2c735f0ef 100644 --- a/base/server/python/pki/server/__init__.py +++ b/base/server/python/pki/server/__init__.py @@ -21,6 +21,7 @@ from __future__ import absolute_import from lxml import etree +import functools import getpass import grp import io @@ -59,6 +60,7 @@ class PKIServer(object): return instances +@functools.total_ordering class PKISubsystem(object): def __init__(self, instance, subsystem_name): @@ -87,6 +89,29 @@ class PKISubsystem(object): # custom subsystem location self.doc_base = os.path.join(self.base_dir, 'webapps', self.name) + def __eq__(self, other): + if not isinstance(other, PKISubsystem): + return NotImplemented + return (self.name == other.name and + self.instance == other.instance and + self.type == other.type) + + def __ne__(self, other): + if not isinstance(other, PKISubsystem): + return NotImplemented + return not self.__eq__(other) + + def __lt__(self, other): + if not isinstance(other, PKISubsystem): + return NotImplemented + self_type = self.type if self.type is not None else '' + other_type = other.type if other.type is not None else '' + return (self.name < other.name or + self.instance < other.instance or + self_type < other_type) + + __hash__ = None + def load(self): self.config.clear() @@ -317,6 +342,7 @@ class PKISubsystem(object): return str(self.instance) + '/' + self.name +@functools.total_ordering class PKIInstance(object): def __init__(self, name, instanceType=10): @@ -350,6 +376,25 @@ class PKIInstance(object): self.subsystems = [] + def __eq__(self, other): + if not isinstance(other, PKIInstance): + return NotImplemented + return (self.name == other.name and + self.type == other.type) + + def __ne__(self, other): + if not isinstance(other, PKIInstance): + return NotImplemented + return not self.__eq__(other) + + def __lt__(self, other): + if not isinstance(other, PKIInstance): + return NotImplemented + return (self.name < other.name or + self.type < other.type) + + __hash__ = None + def is_valid(self): return os.path.exists(self.conf_dir) diff --git a/tests/python/server/test_server.py b/tests/python/server/test_server.py new file mode 100644 index 000000000..646e6826f --- /dev/null +++ b/tests/python/server/test_server.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Authors: +# Christian Heimes +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2016 Red Hat, Inc. +# All rights reserved. +# + +import unittest + +from pki.server import PKISubsystem, PKIInstance + + +class PKIServerTests(unittest.TestCase): + def test_instance_ordering(self): + ca = PKIInstance('ca') + ca9 = PKIInstance('ca', 9) + kra = PKIInstance('kra') + instances = [kra, ca, ca9] + self.assertEqual(sorted(instances), [ca9, ca, kra]) + self.assertEqual(sorted(instances, reverse=True), [kra, ca, ca9]) + self.assertTrue(ca == ca) + self.assertFalse(ca != ca) + self.assertFalse(ca == ca9) + self.assertTrue(ca != ca9) + with self.assertRaises(TypeError): + hash(ca) + + def test_subsystem(self): + ca = PKIInstance('ca') + kra = PKIInstance('kra') + casub = PKISubsystem(ca, 'ca sub') + krasub = PKISubsystem(kra, 'kra sub') + subs = [casub, krasub] + self.assertEqual(sorted(subs), [casub, krasub]) + self.assertEqual(sorted(subs, reverse=True), [krasub, casub]) + self.assertTrue(casub == casub) + self.assertFalse(casub != casub) + self.assertFalse(casub == krasub) + self.assertTrue(casub != krasub) + self.assertFalse(ca == casub) + self.assertTrue(ca != casub) + with self.assertRaises(TypeError): + hash(casub) + + +if __name__ == '__main__': + unittest.main() -- cgit