summaryrefslogtreecommitdiff
path: root/ironic_python_agent
diff options
context:
space:
mode:
authorJohn L. Villalovos <john.l.villalovos@intel.com>2015-08-21 18:14:59 -0700
committerJohn L. Villalovos <john.l.villalovos@intel.com>2015-09-11 13:44:09 -0700
commit1285baee1c91eda75984099b6f1fd8244aaa0258 (patch)
tree89fd83cd961ba755406667159b192a02ff5b22e0 /ironic_python_agent
parentf683a783af2898c4753ad2fc2dce29a88a225976 (diff)
downloadironic-python-agent-1285baee1c91eda75984099b6f1fd8244aaa0258.tar.gz
Create a SerializableComparable class
Create a SerializableComparable class derived from the Serializable class. Added the following functions to the SerializableComparable class: '__eq__' '__ne__' Disable the '__hash__' function in the SerializableComparable class as some derived classes are mutable. Use the SerializableComparable class in hardware.py and extensions/base.py This should make unit testing users of the class easier when doing a self.assertEqual() or self.assertNotEqual() Added some initial unit testing for encoding.py Change-Id: If0f14b3bfe7f1391f65dd730a16a534afed0da82
Diffstat (limited to 'ironic_python_agent')
-rw-r--r--ironic_python_agent/encoding.py18
-rw-r--r--ironic_python_agent/extensions/base.py2
-rw-r--r--ironic_python_agent/hardware.py8
-rw-r--r--ironic_python_agent/tests/unit/test_encoding.py62
4 files changed, 85 insertions, 5 deletions
diff --git a/ironic_python_agent/encoding.py b/ironic_python_agent/encoding.py
index 9022afd5..715d1341 100644
--- a/ironic_python_agent/encoding.py
+++ b/ironic_python_agent/encoding.py
@@ -25,6 +25,24 @@ class Serializable(object):
return dict((f, getattr(self, f)) for f in self.serializable_fields)
+class SerializableComparable(Serializable):
+ """A Serializable class which supports some comparison operators
+
+ This class supports the '__eq__' and '__ne__' comparison operators, but
+ intentionally disables the '__hash__' operator as some child classes may be
+ mutable. The addition of these comparison operators is mainly used to
+ assist with unit testing.
+ """
+
+ __hash__ = None
+
+ def __eq__(self, other):
+ return self.serialize() == other.serialize()
+
+ def __ne__(self, other):
+ return self.serialize() != other.serialize()
+
+
class RESTJSONEncoder(json.JSONEncoder):
"""A slightly customized JSON encoder."""
def encode(self, o):
diff --git a/ironic_python_agent/extensions/base.py b/ironic_python_agent/extensions/base.py
index baac978a..6f7de8e7 100644
--- a/ironic_python_agent/extensions/base.py
+++ b/ironic_python_agent/extensions/base.py
@@ -35,7 +35,7 @@ class AgentCommandStatus(object):
CLEAN_VERSION_MISMATCH = u'CLEAN_VERSION_MISMATCH'
-class BaseCommandResult(encoding.Serializable):
+class BaseCommandResult(encoding.SerializableComparable):
"""Base class for command result."""
serializable_fields = ('id', 'command_name', 'command_params',
diff --git a/ironic_python_agent/hardware.py b/ironic_python_agent/hardware.py
index ace35303..69d7e0ab 100644
--- a/ironic_python_agent/hardware.py
+++ b/ironic_python_agent/hardware.py
@@ -99,7 +99,7 @@ class HardwareType(object):
MAC_ADDRESS = 'mac_address'
-class BlockDevice(encoding.Serializable):
+class BlockDevice(encoding.SerializableComparable):
serializable_fields = ('name', 'model', 'size', 'rotational')
def __init__(self, name, model, size, rotational):
@@ -109,7 +109,7 @@ class BlockDevice(encoding.Serializable):
self.rotational = rotational
-class NetworkInterface(encoding.Serializable):
+class NetworkInterface(encoding.SerializableComparable):
serializable_fields = ('name', 'mac_address', 'switch_port_descr',
'switch_chassis_descr', 'ipv4_address')
@@ -122,7 +122,7 @@ class NetworkInterface(encoding.Serializable):
self.switch_chassis_descr = None
-class CPU(encoding.Serializable):
+class CPU(encoding.SerializableComparable):
serializable_fields = ('model_name', 'frequency', 'count', 'architecture')
def __init__(self, model_name, frequency, count, architecture):
@@ -132,7 +132,7 @@ class CPU(encoding.Serializable):
self.architecture = architecture
-class Memory(encoding.Serializable):
+class Memory(encoding.SerializableComparable):
serializable_fields = ('total', 'physical_mb')
# physical = total + kernel binary + reserved space
diff --git a/ironic_python_agent/tests/unit/test_encoding.py b/ironic_python_agent/tests/unit/test_encoding.py
new file mode 100644
index 00000000..522dc968
--- /dev/null
+++ b/ironic_python_agent/tests/unit/test_encoding.py
@@ -0,0 +1,62 @@
+# Copyright (C) 2015 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslotest import base as test_base
+
+from ironic_python_agent import encoding
+
+
+class SerializableTesting(encoding.Serializable):
+ serializable_fields = ('jack', 'jill')
+
+ def __init__(self, jack, jill):
+ self.jack = jack
+ self.jill = jill
+
+
+class SerializableComparableTesting(encoding.SerializableComparable):
+ serializable_fields = ('jack', 'jill')
+
+ def __init__(self, jack, jill):
+ self.jack = jack
+ self.jill = jill
+
+
+class TestSerializable(test_base.BaseTestCase):
+ def test_baseclass_serialize(self):
+ obj = encoding.Serializable()
+ self.assertEqual({}, obj.serialize())
+
+ def test_childclass_serialize(self):
+ expected = {'jack': 'hello', 'jill': 'world'}
+ obj = SerializableTesting('hello', 'world')
+ self.assertEqual(expected, obj.serialize())
+
+
+class TestSerializableComparable(test_base.BaseTestCase):
+
+ def test_childclass_equal(self):
+ obj1 = SerializableComparableTesting('hello', 'world')
+ obj2 = SerializableComparableTesting('hello', 'world')
+ self.assertEqual(obj1, obj2)
+
+ def test_childclass_notequal(self):
+ obj1 = SerializableComparableTesting('hello', 'world')
+ obj2 = SerializableComparableTesting('hello', 'world2')
+ self.assertNotEqual(obj1, obj2)
+
+ def test_childclass_hash(self):
+ # Ensure __hash__ is None
+ obj = SerializableComparableTesting('hello', 'world')
+ self.assertEqual(None, obj.__hash__)