From f6dadbf22ebc541ab8abcb743919a656b2f37149 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 00:16:42 -0400 Subject: [PATCH 01/11] start simple with integer objects, other files are empty placeholders --- tests/test_primitive_data/__init__.py | 7 ++ tests/test_primitive_data/test_bit_string.py | 0 tests/test_primitive_data/test_boolean.py | 0 .../test_character_string.py | 0 tests/test_primitive_data/test_date.py | 0 tests/test_primitive_data/test_double.py | 0 tests/test_primitive_data/test_enumerated.py | 0 tests/test_primitive_data/test_integer.py | 115 ++++++++++++++++++ tests/test_primitive_data/test_null.py | 0 .../test_object_identifier.py | 0 tests/test_primitive_data/test_object_type.py | 0 .../test_primitive_data/test_octet_string.py | 0 tests/test_primitive_data/test_real.py | 0 tests/test_primitive_data/test_tag.py | 0 tests/test_primitive_data/test_time.py | 0 tests/test_primitive_data/test_unsigned.py | 0 16 files changed, 122 insertions(+) create mode 100644 tests/test_primitive_data/__init__.py create mode 100644 tests/test_primitive_data/test_bit_string.py create mode 100644 tests/test_primitive_data/test_boolean.py create mode 100644 tests/test_primitive_data/test_character_string.py create mode 100644 tests/test_primitive_data/test_date.py create mode 100644 tests/test_primitive_data/test_double.py create mode 100644 tests/test_primitive_data/test_enumerated.py create mode 100644 tests/test_primitive_data/test_integer.py create mode 100644 tests/test_primitive_data/test_null.py create mode 100644 tests/test_primitive_data/test_object_identifier.py create mode 100644 tests/test_primitive_data/test_object_type.py create mode 100644 tests/test_primitive_data/test_octet_string.py create mode 100644 tests/test_primitive_data/test_real.py create mode 100644 tests/test_primitive_data/test_tag.py create mode 100644 tests/test_primitive_data/test_time.py create mode 100644 tests/test_primitive_data/test_unsigned.py diff --git a/tests/test_primitive_data/__init__.py b/tests/test_primitive_data/__init__.py new file mode 100644 index 0000000..c0c458a --- /dev/null +++ b/tests/test_primitive_data/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/python + +""" +Test Primitive Data Module +""" + +from . import test_integer diff --git a/tests/test_primitive_data/test_bit_string.py b/tests/test_primitive_data/test_bit_string.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_boolean.py b/tests/test_primitive_data/test_boolean.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_character_string.py b/tests/test_primitive_data/test_character_string.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_date.py b/tests/test_primitive_data/test_date.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_double.py b/tests/test_primitive_data/test_double.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_enumerated.py b/tests/test_primitive_data/test_enumerated.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_integer.py b/tests/test_primitive_data/test_integer.py new file mode 100644 index 0000000..9bb491a --- /dev/null +++ b/tests/test_primitive_data/test_integer.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Test Primitive Data Integer +--------------------------- +""" + +import unittest + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob +from bacpypes.primitivedata import Integer, Tag + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +@bacpypes_debugging +def integer_tag(x): + """Convert a hex string to an integer application tag.""" + if _debug: integer_tag._debug("integer_tag %r", x) + + b = xtob(x) + tag = Tag(Tag.applicationTagClass, Tag.integerAppTag, len(b), b) + if _debug: integer_endec._debug(" - tag: %r", tag) + + return tag + +@bacpypes_debugging +def integer_encode(obj): + """Encode an Integer object into a tag.""" + if _debug: integer_encode._debug("integer_encode %r", obj) + + tag = Tag() + obj.encode(tag) + if _debug: integer_endec._debug(" - tag: %r", tag) + + return tag + + +@bacpypes_debugging +def integer_decode(tag): + """Decode an integer application tag into an integer.""" + if _debug: integer_decode._debug("integer_decode %r", tag) + + obj = Integer(tag) + if _debug: integer_decode._debug(" - obj: %r", obj) + + return obj + + +@bacpypes_debugging +def integer_endec(value, x): + """Pass the value to Integer, construct a tag from the hex string, + and compare results of encode and decoding each other.""" + if _debug: integer_endec._debug("integer_endec %r %r", value, x) + + tag = integer_tag(x) + if _debug: integer_endec._debug(" - tag: %r, %r", tag, tag.tagData) + + obj = Integer(value) + if _debug: integer_endec._debug(" - obj: %r, %r", obj, obj.value) + + assert integer_encode(obj) == tag + assert integer_decode(tag) == obj + + +@bacpypes_debugging +class TestInteger(unittest.TestCase): + + def test_integer(self): + if _debug: TestInteger._debug("test_integer") + + obj = Integer() + assert obj.value == 0 + + def test_integer_int(self): + if _debug: TestInteger._debug("test_integer_int") + + obj = Integer(1) + assert obj.value == 1 + assert str(obj) == "Integer(1)" + + obj = Integer(-1) + assert obj.value == -1 + assert str(obj) == "Integer(-1)" + + def test_integer_integer(self): + if _debug: TestInteger._debug("test_integer_integer") + + obj1 = Integer(12) + obj2 = Integer(obj1) + assert obj2.value == 12 + + def test_integer_endec(self): + if _debug: TestInteger._debug("test_integer_endec") + + with self.assertRaises(IndexError): + obj = Integer(integer_tag('')) + + integer_endec(0, '00') + integer_endec(1, '01') + integer_endec(127, '7f') + integer_endec(-128, '80') + integer_endec(-1, 'ff') + + integer_endec(32767, '7fff') + integer_endec(-32768, '8000') + + integer_endec(8388607, '7fffff') + integer_endec(-8388608, '800000') + + integer_endec(2147483647, '7fffffff') + integer_endec(-2147483648, '80000000') diff --git a/tests/test_primitive_data/test_null.py b/tests/test_primitive_data/test_null.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_object_identifier.py b/tests/test_primitive_data/test_object_identifier.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_object_type.py b/tests/test_primitive_data/test_object_type.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_octet_string.py b/tests/test_primitive_data/test_octet_string.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_real.py b/tests/test_primitive_data/test_real.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_tag.py b/tests/test_primitive_data/test_tag.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_time.py b/tests/test_primitive_data/test_time.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_primitive_data/test_unsigned.py b/tests/test_primitive_data/test_unsigned.py new file mode 100644 index 0000000..e69de29 From a9f12dbfdf17a13817aad3af8dac917c5f4a0c23 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 18:59:12 -0400 Subject: [PATCH 02/11] add some failures and ctor value from tag --- tests/test_primitive_data/test_integer.py | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_primitive_data/test_integer.py b/tests/test_primitive_data/test_integer.py index 9bb491a..e640e2d 100644 --- a/tests/test_primitive_data/test_integer.py +++ b/tests/test_primitive_data/test_integer.py @@ -75,6 +75,11 @@ class TestInteger(unittest.TestCase): obj = Integer() assert obj.value == 0 + with self.assertRaises(TypeError): + Integer("some string") + with self.assertRaises(TypeError): + Integer(1.0) + def test_integer_int(self): if _debug: TestInteger._debug("test_integer_int") @@ -86,6 +91,25 @@ class TestInteger(unittest.TestCase): assert obj.value == -1 assert str(obj) == "Integer(-1)" + def test_integer_tag(self): + if _debug: TestInteger._debug("test_integer_tag") + + tag = Tag(Tag.applicationTagClass, Tag.integerAppTag, 1, xtob('01')) + obj = Integer(tag) + assert obj.value == 1 + + tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob('')) + with self.assertRaises(ValueError): + Integer(tag) + + tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff')) + with self.assertRaises(ValueError): + Integer(tag) + + tag = Tag(Tag.openingTagClass, 0) + with self.assertRaises(ValueError): + Integer(tag) + def test_integer_integer(self): if _debug: TestInteger._debug("test_integer_integer") From bd48ad47886194e77fa69432a8c3c05ad663599e Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 21:28:32 -0400 Subject: [PATCH 03/11] tests for null objects --- tests/test_primitive_data/test_null.py | 106 +++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/tests/test_primitive_data/test_null.py b/tests/test_primitive_data/test_null.py index e69de29..9083904 100644 --- a/tests/test_primitive_data/test_null.py +++ b/tests/test_primitive_data/test_null.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Test Primitive Data Null +------------------------ +""" + +import unittest + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob +from bacpypes.primitivedata import Null, Tag + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +@bacpypes_debugging +def null_tag(x): + """Convert a hex string to an integer application tag.""" + if _debug: null_tag._debug("null_tag %r", x) + + b = xtob(x) + tag = Tag(Tag.applicationTagClass, Tag.nullAppTag, len(b), b) + if _debug: integer_endec._debug(" - tag: %r", tag) + + return tag + +@bacpypes_debugging +def null_encode(obj): + """Encode an Integer object into a tag.""" + if _debug: null_encode._debug("null_encode %r", obj) + + tag = Tag() + obj.encode(tag) + if _debug: null_encode._debug(" - tag: %r", tag) + + return tag + + +@bacpypes_debugging +def null_decode(tag): + """Decode an integer application tag into an integer.""" + if _debug: null_decode._debug("null_decode %r", tag) + + obj = Null(tag) + if _debug: null_decode._debug(" - obj: %r", obj) + + return obj + + +@bacpypes_debugging +def null_endec(value, x): + """Pass the value to Integer, construct a tag from the hex string, + and compare results of encode and decoding each other.""" + if _debug: null_endec._debug("null_endec %r %r", value, x) + + tag = null_tag(x) + if _debug: null_endec._debug(" - tag: %r, %r", tag, tag.tagData) + + obj = Null(value) + if _debug: null_endec._debug(" - obj: %r, %r", obj, obj.value) + + assert null_encode(obj) == tag + assert null_decode(tag) == obj + + +@bacpypes_debugging +class TestNull(unittest.TestCase): + + def test_null(self): + if _debug: TestInteger._debug("test_null") + + obj = Null() + assert obj.value == () + + with self.assertRaises(TypeError): + Null("some string") + with self.assertRaises(TypeError): + Null(1.0) + + def test_null_null(self): + if _debug: TestInteger._debug("test_null_null") + + obj = Null(()) + assert obj.value == () + + def test_null_tag(self): + if _debug: TestInteger._debug("test_null_tag") + + tag = Tag(Tag.applicationTagClass, Tag.nullAppTag, 0, xtob('')) + obj = Null(tag) + assert obj.value == () + + def test_null_null(self): + if _debug: TestInteger._debug("test_null_null") + + obj1 = Null() + obj2 = Null(obj1) + assert obj2.value == () + + def test_null_endec(self): + if _debug: TestInteger._debug("test_null_endec") + + null_endec((), '') From 42cf41e84e78e141f2e3dc338eee22471d3b32b3 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 21:41:43 -0400 Subject: [PATCH 04/11] add boolean tests, sync parameter names so modules read the same --- tests/test_primitive_data/test_boolean.py | 123 ++++++++++++++++++++++ tests/test_primitive_data/test_integer.py | 6 +- tests/test_primitive_data/test_null.py | 6 +- 3 files changed, 129 insertions(+), 6 deletions(-) diff --git a/tests/test_primitive_data/test_boolean.py b/tests/test_primitive_data/test_boolean.py index e69de29..2b4ac3f 100644 --- a/tests/test_primitive_data/test_boolean.py +++ b/tests/test_primitive_data/test_boolean.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Test Primitive Data Boolean +--------------------------- +""" + +import unittest + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob +from bacpypes.primitivedata import Boolean, Tag + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +@bacpypes_debugging +def boolean_tag(value): + """Convert an integer to an boolean application tag.""" + if _debug: boolean_tag._debug("boolean_tag %r", value) + + tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, int(value), xtob('')) + if _debug: boolean_endec._debug(" - tag: %r", tag) + + return tag + +@bacpypes_debugging +def boolean_encode(obj): + """Encode an Boolean object into a tag.""" + if _debug: boolean_encode._debug("boolean_encode %r", obj) + + tag = Tag() + obj.encode(tag) + if _debug: boolean_endec._debug(" - tag: %r", tag) + + return tag + + +@bacpypes_debugging +def boolean_decode(tag): + """Decode an boolean application tag into an boolean.""" + if _debug: boolean_decode._debug("boolean_decode %r", tag) + + obj = Boolean(tag) + if _debug: boolean_decode._debug(" - obj: %r", obj) + + return obj + + +@bacpypes_debugging +def boolean_endec(v, x): + """Pass the value to Boolean, construct a tag from the hex string, + and compare results of encode and decoding each other.""" + if _debug: boolean_endec._debug("boolean_endec %r %r", v, x) + + tag = boolean_tag(x) + if _debug: boolean_endec._debug(" - tag: %r, %r", tag, tag.tagData) + + obj = Boolean(v) + if _debug: boolean_endec._debug(" - obj: %r, %r", obj, obj.value) + + assert boolean_encode(obj) == tag + assert boolean_decode(tag) == obj + + +@bacpypes_debugging +class TestBoolean(unittest.TestCase): + + def test_boolean(self): + if _debug: TestBoolean._debug("test_boolean") + + obj = Boolean() + assert obj.value == False + + with self.assertRaises(TypeError): + Boolean("some string") + with self.assertRaises(TypeError): + Boolean(1.0) + + def test_boolean_bool(self): + if _debug: TestBoolean._debug("test_boolean_bool") + + obj = Boolean(False) + assert obj.value == False + assert str(obj) == "Boolean(False)" + + obj = Boolean(True) + assert obj.value == True + assert str(obj) == "Boolean(True)" + + def test_boolean_tag(self): + if _debug: TestBoolean._debug("test_boolean_tag") + + tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 1, xtob('01')) + obj = Boolean(tag) + assert obj.value == 1 + + tag = Tag(Tag.applicationTagClass, Tag.integerAppTag, 0, xtob('')) + with self.assertRaises(ValueError): + Boolean(tag) + + tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff')) + with self.assertRaises(ValueError): + Boolean(tag) + + tag = Tag(Tag.openingTagClass, 0) + with self.assertRaises(ValueError): + Boolean(tag) + + def test_boolean_boolean(self): + if _debug: TestBoolean._debug("test_boolean_boolean") + + obj1 = Boolean(True) + obj2 = Boolean(obj1) + assert obj2.value == True + + def test_boolean_endec(self): + if _debug: TestBoolean._debug("test_boolean_endec") + + boolean_endec(False, False) + boolean_endec(True, True) diff --git a/tests/test_primitive_data/test_integer.py b/tests/test_primitive_data/test_integer.py index e640e2d..afbbe99 100644 --- a/tests/test_primitive_data/test_integer.py +++ b/tests/test_primitive_data/test_integer.py @@ -51,15 +51,15 @@ def integer_decode(tag): @bacpypes_debugging -def integer_endec(value, x): +def integer_endec(v, x): """Pass the value to Integer, construct a tag from the hex string, and compare results of encode and decoding each other.""" - if _debug: integer_endec._debug("integer_endec %r %r", value, x) + if _debug: integer_endec._debug("integer_endec %r %r", v, x) tag = integer_tag(x) if _debug: integer_endec._debug(" - tag: %r, %r", tag, tag.tagData) - obj = Integer(value) + obj = Integer(v) if _debug: integer_endec._debug(" - obj: %r, %r", obj, obj.value) assert integer_encode(obj) == tag diff --git a/tests/test_primitive_data/test_null.py b/tests/test_primitive_data/test_null.py index 9083904..daefe5d 100644 --- a/tests/test_primitive_data/test_null.py +++ b/tests/test_primitive_data/test_null.py @@ -51,15 +51,15 @@ def null_decode(tag): @bacpypes_debugging -def null_endec(value, x): +def null_endec(v, x): """Pass the value to Integer, construct a tag from the hex string, and compare results of encode and decoding each other.""" - if _debug: null_endec._debug("null_endec %r %r", value, x) + if _debug: null_endec._debug("null_endec %r %r", v, x) tag = null_tag(x) if _debug: null_endec._debug(" - tag: %r, %r", tag, tag.tagData) - obj = Null(value) + obj = Null(v) if _debug: null_endec._debug(" - obj: %r, %r", obj, obj.value) assert null_encode(obj) == tag From 92baf4dd6ed6ffd84c3ae93085c053ace2672d1f Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 21:49:05 -0400 Subject: [PATCH 05/11] add unsigned tests --- tests/test_primitive_data/test_unsigned.py | 138 +++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/tests/test_primitive_data/test_unsigned.py b/tests/test_primitive_data/test_unsigned.py index e69de29..592ebc0 100644 --- a/tests/test_primitive_data/test_unsigned.py +++ b/tests/test_primitive_data/test_unsigned.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Test Primitive Data Unsigned +---------------------------- +""" + +import unittest + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob +from bacpypes.primitivedata import Unsigned, Tag + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +@bacpypes_debugging +def unsigned_tag(x): + """Convert a hex string to an unsigned application tag.""" + if _debug: unsigned_tag._debug("unsigned_tag %r", x) + + b = xtob(x) + tag = Tag(Tag.applicationTagClass, Tag.unsignedAppTag, len(b), b) + if _debug: unsigned_endec._debug(" - tag: %r", tag) + + return tag + +@bacpypes_debugging +def unsigned_encode(obj): + """Encode an Unsigned object into a tag.""" + if _debug: unsigned_encode._debug("unsigned_encode %r", obj) + + tag = Tag() + obj.encode(tag) + if _debug: unsigned_endec._debug(" - tag: %r", tag) + + return tag + + +@bacpypes_debugging +def unsigned_decode(tag): + """Decode an unsigned application tag into an unsigned.""" + if _debug: unsigned_decode._debug("unsigned_decode %r", tag) + + obj = Unsigned(tag) + if _debug: unsigned_decode._debug(" - obj: %r", obj) + + return obj + + +@bacpypes_debugging +def unsigned_endec(v, x): + """Pass the value to Unsigned, construct a tag from the hex string, + and compare results of encode and decoding each other.""" + if _debug: unsigned_endec._debug("unsigned_endec %r %r", v, x) + + tag = unsigned_tag(x) + if _debug: unsigned_endec._debug(" - tag: %r, %r", tag, tag.tagData) + + obj = Unsigned(v) + if _debug: unsigned_endec._debug(" - obj: %r, %r", obj, obj.value) + + assert unsigned_encode(obj) == tag + assert unsigned_decode(tag) == obj + + +@bacpypes_debugging +class TestUnsigned(unittest.TestCase): + + def test_unsigned(self): + if _debug: TestUnsigned._debug("test_unsigned") + + obj = Unsigned() + assert obj.value == 0 + + with self.assertRaises(TypeError): + Unsigned("some string") + with self.assertRaises(TypeError): + Unsigned(1.0) + + def test_unsigned_int(self): + if _debug: TestUnsigned._debug("test_unsigned_int") + + obj = Unsigned(1) + assert obj.value == 1 + assert str(obj) == "Unsigned(1)" + + with self.assertRaises(ValueError): + Unsigned(-1) + + def test_unsigned_tag(self): + if _debug: TestUnsigned._debug("test_unsigned_tag") + + tag = Tag(Tag.applicationTagClass, Tag.unsignedAppTag, 1, xtob('01')) + obj = Unsigned(tag) + assert obj.value == 1 + + tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob('')) + with self.assertRaises(ValueError): + Unsigned(tag) + + tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff')) + with self.assertRaises(ValueError): + Unsigned(tag) + + tag = Tag(Tag.openingTagClass, 0) + with self.assertRaises(ValueError): + Unsigned(tag) + + def test_unsigned_unsigned(self): + if _debug: TestUnsigned._debug("test_unsigned_unsigned") + + obj1 = Unsigned(12) + obj2 = Unsigned(obj1) + assert obj2.value == 12 + + def test_unsigned_endec(self): + if _debug: TestUnsigned._debug("test_unsigned_endec") + +# with self.assertRaises(IndexError): +# obj = Unsigned(unsigned_tag('')) + + unsigned_endec(0, '00') + unsigned_endec(1, '01') + unsigned_endec(127, '7f') + unsigned_endec(128, '80') + unsigned_endec(255, 'ff') + + unsigned_endec(32767, '7fff') + unsigned_endec(32768, '8000') + + unsigned_endec(8388607, '7fffff') + unsigned_endec(8388608, '800000') + + unsigned_endec(2147483647, '7fffffff') + unsigned_endec(2147483648, '80000000') From ef6359c52ee7c6de001336afe40de53520f52250 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 22:23:33 -0400 Subject: [PATCH 06/11] add real tests --- tests/test_primitive_data/test_real.py | 136 +++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/tests/test_primitive_data/test_real.py b/tests/test_primitive_data/test_real.py index e69de29..4373ec1 100644 --- a/tests/test_primitive_data/test_real.py +++ b/tests/test_primitive_data/test_real.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Test Primitive Data Real +------------------------ +""" + +import unittest +import struct + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob +from bacpypes.primitivedata import Real, Tag + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +@bacpypes_debugging +def real_tag(x): + """Convert a hex string to an real application tag.""" + if _debug: real_tag._debug("real_tag %r", x) + + b = xtob(x) + tag = Tag(Tag.applicationTagClass, Tag.realAppTag, len(b), b) + if _debug: real_endec._debug(" - tag: %r", tag) + + return tag + +@bacpypes_debugging +def real_encode(obj): + """Encode an Real object into a tag.""" + if _debug: real_encode._debug("real_encode %r", obj) + + tag = Tag() + obj.encode(tag) + if _debug: real_endec._debug(" - tag: %r", tag) + + return tag + + +@bacpypes_debugging +def real_decode(tag): + """Decode an real application tag into an real.""" + if _debug: real_decode._debug("real_decode %r", tag) + + obj = Real(tag) + if _debug: real_decode._debug(" - obj: %r", obj) + + return obj + + +@bacpypes_debugging +def real_endec(v, x): + """Pass the value to Real, construct a tag from the hex string, + and compare results of encode and decoding each other.""" + if _debug: real_endec._debug("real_endec %r %r", v, x) + + tag = real_tag(x) + if _debug: real_endec._debug(" - tag: %r, %r", tag, tag.tagData) + + obj = Real(v) + if _debug: real_endec._debug(" - obj: %r, %r", obj, obj.value) + + assert real_encode(obj) == tag + assert real_decode(tag) == obj + + +@bacpypes_debugging +class TestReal(unittest.TestCase): + + def test_real(self): + if _debug: TestReal._debug("test_real") + + obj = Real() + assert obj.value == 0.0 + + with self.assertRaises(TypeError): + Real("some string") + + def test_real_real(self): + if _debug: TestReal._debug("test_real_real") + + obj = Real(1.0) + assert obj.value == 1.0 + assert str(obj) == "Real(1)" + + obj = Real(73.5) + assert obj.value == 73.5 + assert str(obj) == "Real(73.5)" + + def test_real_tag(self): + if _debug: TestReal._debug("test_real_tag") + + tag = Tag(Tag.applicationTagClass, Tag.realAppTag, 1, xtob('3f800000')) + obj = Real(tag) + assert obj.value == 1.0 + + tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob('')) + with self.assertRaises(ValueError): + Real(tag) + + tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff')) + with self.assertRaises(ValueError): + Real(tag) + + tag = Tag(Tag.openingTagClass, 0) + with self.assertRaises(ValueError): + Real(tag) + + def test_real_copy(self): + if _debug: TestReal._debug("test_real_copy") + + obj1 = Real(12) + obj2 = Real(obj1) + assert obj2.value == 12 + + def test_real_endec(self): + if _debug: TestReal._debug("test_real_endec") + + with self.assertRaises(struct.error): + obj = Real(real_tag('')) + + real_endec(0, '00000000') + real_endec(1, '3f800000') + real_endec(-1, 'bf800000') + + real_endec(73.5, '42930000') + + inf = float('inf') + real_endec(inf, '7f800000') + real_endec(-inf, 'ff800000') + + nan = float('nan') + real_endec(nan, '7fc00000') \ No newline at end of file From a4ccab87bb5fc5ea3093c600bfbbd82f852e2d13 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 22:23:50 -0400 Subject: [PATCH 07/11] change to the _copy names for copy-constructor-like tests --- tests/test_primitive_data/test_boolean.py | 4 ++-- tests/test_primitive_data/test_integer.py | 4 ++-- tests/test_primitive_data/test_null.py | 4 ++-- tests/test_primitive_data/test_unsigned.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_primitive_data/test_boolean.py b/tests/test_primitive_data/test_boolean.py index 2b4ac3f..cbc537e 100644 --- a/tests/test_primitive_data/test_boolean.py +++ b/tests/test_primitive_data/test_boolean.py @@ -109,8 +109,8 @@ class TestBoolean(unittest.TestCase): with self.assertRaises(ValueError): Boolean(tag) - def test_boolean_boolean(self): - if _debug: TestBoolean._debug("test_boolean_boolean") + def test_boolean_copy(self): + if _debug: TestBoolean._debug("test_boolean_copy") obj1 = Boolean(True) obj2 = Boolean(obj1) diff --git a/tests/test_primitive_data/test_integer.py b/tests/test_primitive_data/test_integer.py index afbbe99..fde04f0 100644 --- a/tests/test_primitive_data/test_integer.py +++ b/tests/test_primitive_data/test_integer.py @@ -110,8 +110,8 @@ class TestInteger(unittest.TestCase): with self.assertRaises(ValueError): Integer(tag) - def test_integer_integer(self): - if _debug: TestInteger._debug("test_integer_integer") + def test_integer_copy(self): + if _debug: TestInteger._debug("test_integer_copy") obj1 = Integer(12) obj2 = Integer(obj1) diff --git a/tests/test_primitive_data/test_null.py b/tests/test_primitive_data/test_null.py index daefe5d..4599475 100644 --- a/tests/test_primitive_data/test_null.py +++ b/tests/test_primitive_data/test_null.py @@ -93,8 +93,8 @@ class TestNull(unittest.TestCase): obj = Null(tag) assert obj.value == () - def test_null_null(self): - if _debug: TestInteger._debug("test_null_null") + def test_null_copy(self): + if _debug: TestInteger._debug("test_null_copy") obj1 = Null() obj2 = Null(obj1) diff --git a/tests/test_primitive_data/test_unsigned.py b/tests/test_primitive_data/test_unsigned.py index 592ebc0..28c567e 100644 --- a/tests/test_primitive_data/test_unsigned.py +++ b/tests/test_primitive_data/test_unsigned.py @@ -109,8 +109,8 @@ class TestUnsigned(unittest.TestCase): with self.assertRaises(ValueError): Unsigned(tag) - def test_unsigned_unsigned(self): - if _debug: TestUnsigned._debug("test_unsigned_unsigned") + def test_unsigned_copy(self): + if _debug: TestUnsigned._debug("test_unsigned_copy") obj1 = Unsigned(12) obj2 = Unsigned(obj1) From 0d14583c419dbaf19bc14f9b658262cdd7689b9b Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 22:35:13 -0400 Subject: [PATCH 08/11] add double tests --- tests/test_primitive_data/test_double.py | 136 +++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/tests/test_primitive_data/test_double.py b/tests/test_primitive_data/test_double.py index e69de29..6753e1d 100644 --- a/tests/test_primitive_data/test_double.py +++ b/tests/test_primitive_data/test_double.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Test Primitive Data Double +-------------------------- +""" + +import unittest +import struct + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob +from bacpypes.primitivedata import Double, Tag + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +@bacpypes_debugging +def double_tag(x): + """Convert a hex string to an double application tag.""" + if _debug: double_tag._debug("double_tag %r", x) + + b = xtob(x) + tag = Tag(Tag.applicationTagClass, Tag.doubleAppTag, len(b), b) + if _debug: double_endec._debug(" - tag: %r", tag) + + return tag + +@bacpypes_debugging +def double_encode(obj): + """Encode an Double object into a tag.""" + if _debug: double_encode._debug("double_encode %r", obj) + + tag = Tag() + obj.encode(tag) + if _debug: double_endec._debug(" - tag: %r", tag) + + return tag + + +@bacpypes_debugging +def double_decode(tag): + """Decode an double application tag into a double.""" + if _debug: double_decode._debug("double_decode %r", tag) + + obj = Double(tag) + if _debug: double_decode._debug(" - obj: %r", obj) + + return obj + + +@bacpypes_debugging +def double_endec(v, x): + """Pass the value to Double, construct a tag from the hex string, + and compare results of encode and decoding each other.""" + if _debug: double_endec._debug("double_endec %r %r", v, x) + + tag = double_tag(x) + if _debug: double_endec._debug(" - tag: %r, %r", tag, tag.tagData) + + obj = Double(v) + if _debug: double_endec._debug(" - obj: %r, %r", obj, obj.value) + + assert double_encode(obj) == tag + assert double_decode(tag) == obj + + +@bacpypes_debugging +class TestDouble(unittest.TestCase): + + def test_double(self): + if _debug: TestDouble._debug("test_double") + + obj = Double() + assert obj.value == 0.0 + + with self.assertRaises(TypeError): + Double("some string") + + def test_double_double(self): + if _debug: TestDouble._debug("test_double_double") + + obj = Double(1.0) + assert obj.value == 1.0 + assert str(obj) == "Double(1)" + + obj = Double(73.5) + assert obj.value == 73.5 + assert str(obj) == "Double(73.5)" + + def test_double_tag(self): + if _debug: TestDouble._debug("test_double_tag") + + tag = Tag(Tag.applicationTagClass, Tag.doubleAppTag, 8, xtob('3ff0000000000000')) + obj = Double(tag) + assert obj.value == 1.0 + + tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob('')) + with self.assertRaises(ValueError): + Double(tag) + + tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff')) + with self.assertRaises(ValueError): + Double(tag) + + tag = Tag(Tag.openingTagClass, 0) + with self.assertRaises(ValueError): + Double(tag) + + def test_double_copy(self): + if _debug: TestDouble._debug("test_double_copy") + + obj1 = Double(12) + obj2 = Double(obj1) + assert obj2.value == 12 + + def test_double_endec(self): + if _debug: TestDouble._debug("test_double_endec") + + with self.assertRaises(struct.error): + obj = Double(double_tag('')) + + double_endec(0, '0000000000000000') + double_endec(1, '3ff0000000000000') + double_endec(-1, 'bff0000000000000') + + double_endec(73.5, '4052600000000000') + + inf = float('inf') + double_endec(inf, '7ff0000000000000') + double_endec(-inf, 'fff0000000000000') + + nan = float('nan') + double_endec(nan, '7ff8000000000000') From 22c5fe48f303bf1431758f259b6ae6a68da0d6ff Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Tue, 11 Aug 2015 22:46:20 -0400 Subject: [PATCH 09/11] add octet string tests --- .../test_primitive_data/test_octet_string.py | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/tests/test_primitive_data/test_octet_string.py b/tests/test_primitive_data/test_octet_string.py index e69de29..7ebe71f 100644 --- a/tests/test_primitive_data/test_octet_string.py +++ b/tests/test_primitive_data/test_octet_string.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Test Primitive Data Octet String +-------------------------------- +""" + +import unittest +import struct + +from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob +from bacpypes.primitivedata import OctetString, Tag + +# some debugging +_debug = 0 +_log = ModuleLogger(globals()) + + +@bacpypes_debugging +def octet_string_tag(x): + """Convert a hex string to an octet_string application tag.""" + if _debug: octet_string_tag._debug("octet_string_tag %r", x) + + b = xtob(x) + tag = Tag(Tag.applicationTagClass, Tag.octetStringAppTag, len(b), b) + if _debug: octet_string_endec._debug(" - tag: %r", tag) + + return tag + +@bacpypes_debugging +def octet_string_encode(obj): + """Encode an OctetString object into a tag.""" + if _debug: octet_string_encode._debug("octet_string_encode %r", obj) + + tag = Tag() + obj.encode(tag) + if _debug: octet_string_endec._debug(" - tag: %r", tag) + + return tag + + +@bacpypes_debugging +def octet_string_decode(tag): + """Decode an octet_string application tag into an octet string.""" + if _debug: octet_string_decode._debug("octet_string_decode %r", tag) + + obj = OctetString(tag) + if _debug: octet_string_decode._debug(" - obj: %r", obj) + + return obj + + +@bacpypes_debugging +def octet_string_endec(x): + """Pass the value to OctetString, construct a tag from the hex string, + and compare results of encode and decoding each other.""" + if _debug: octet_string_endec._debug("octet_string_endec %r", x) + + tag = octet_string_tag(x) + if _debug: octet_string_endec._debug(" - tag: %r, %r", tag, tag.tagData) + + obj = OctetString(xtob(x)) + if _debug: octet_string_endec._debug(" - obj: %r, %r", obj, obj.value) + + assert octet_string_encode(obj) == tag + assert octet_string_decode(tag) == obj + + +@bacpypes_debugging +class TestOctetString(unittest.TestCase): + + def test_octet_string(self): + if _debug: TestOctetString._debug("test_octet_string") + + obj = OctetString() + assert obj.value == xtob('') + + with self.assertRaises(TypeError): + OctetString(1) + + def test_octet_string_octet_string(self): + if _debug: TestOctetString._debug("test_octet_string_octet_string") + + obj = OctetString(xtob('01')) + assert obj.value == xtob('01') + assert str(obj) == "OctetString(X'01')" + + obj = OctetString(xtob('01020304')) + assert obj.value == xtob('01020304') + assert str(obj) == "OctetString(X'01020304')" + + def test_octet_string_tag(self): + if _debug: TestOctetString._debug("test_octet_string_tag") + + tag = Tag(Tag.applicationTagClass, Tag.octetStringAppTag, 1, xtob('00')) + obj = OctetString(tag) + assert obj.value == xtob('00') + + tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob('')) + with self.assertRaises(ValueError): + OctetString(tag) + + tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff')) + with self.assertRaises(ValueError): + OctetString(tag) + + tag = Tag(Tag.openingTagClass, 0) + with self.assertRaises(ValueError): + OctetString(tag) + + def test_octet_string_copy(self): + if _debug: TestOctetString._debug("test_octet_string_copy") + + obj1 = OctetString(xtob('01')) + obj2 = OctetString(obj1) + assert obj2.value == xtob('01') + + def test_octet_string_endec(self): + if _debug: TestOctetString._debug("test_octet_string_endec") + + octet_string_endec('') + octet_string_endec('01') + octet_string_endec('0102') + octet_string_endec('010203') + octet_string_endec('01020304') From 34ed6bd399af49c3cce9dca54287c2300252de01 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Wed, 12 Aug 2015 09:07:11 -0400 Subject: [PATCH 10/11] Python3 no longer uses __cmp__, incorrect initialization for octet strings --- py34/bacpypes/primitivedata.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/py34/bacpypes/primitivedata.py b/py34/bacpypes/primitivedata.py index 6539e3a..591b81d 100755 --- a/py34/bacpypes/primitivedata.py +++ b/py34/bacpypes/primitivedata.py @@ -451,6 +451,8 @@ class Atomic(object): _app_tag = None def __cmp__(self, other): + # sys.stderr.write("__cmp__ %r %r\n" % (self, other)) + # hoop jump it if not isinstance(other, self.__class__): other = self.__class__(other) @@ -463,6 +465,26 @@ class Atomic(object): else: return 0 + def __lt__(self, other): + # sys.stderr.write("__lt__ %r %r\n" % (self, other)) + + # hoop jump it + if not isinstance(other, self.__class__): + other = self.__class__(other) + + # now compare the values + return (self.value < other.value) + + def __eq__(self, other): + sys.stderr.write("__eq__ %r %r\n" % (self, other)) + + # hoop jump it + if not isinstance(other, self.__class__): + other = self.__class__(other) + + # now compare the values + return self.value == other.value + # # Null # @@ -738,7 +760,7 @@ class OctetString(Atomic): _app_tag = Tag.octetStringAppTag def __init__(self, arg=None): - self.value = '' + self.value = bytes() if arg is None: pass From e12523eeeeb09d231798091fc659b73569cfbd6f Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Wed, 12 Aug 2015 09:07:57 -0400 Subject: [PATCH 11/11] explicit checking for NaN --- tests/test_primitive_data/test_double.py | 9 ++++++++- tests/test_primitive_data/test_real.py | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tests/test_primitive_data/test_double.py b/tests/test_primitive_data/test_double.py index 6753e1d..04a66e1 100644 --- a/tests/test_primitive_data/test_double.py +++ b/tests/test_primitive_data/test_double.py @@ -8,6 +8,7 @@ Test Primitive Data Double import unittest import struct +import math from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob from bacpypes.primitivedata import Double, Tag @@ -64,8 +65,14 @@ def double_endec(v, x): if _debug: double_endec._debug(" - obj: %r, %r", obj, obj.value) assert double_encode(obj) == tag - assert double_decode(tag) == obj + if _debug: real_endec._debug(" - tags match") + if math.isnan(v): + assert math.isnan(double_decode(tag).value) + if _debug: double_endec._debug(" - both NaN") + else: + assert double_decode(tag) == obj + if _debug: double_endec._debug(" - objects match") @bacpypes_debugging class TestDouble(unittest.TestCase): diff --git a/tests/test_primitive_data/test_real.py b/tests/test_primitive_data/test_real.py index 4373ec1..7f14710 100644 --- a/tests/test_primitive_data/test_real.py +++ b/tests/test_primitive_data/test_real.py @@ -8,6 +8,7 @@ Test Primitive Data Real import unittest import struct +import math from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob from bacpypes.primitivedata import Real, Tag @@ -24,7 +25,7 @@ def real_tag(x): b = xtob(x) tag = Tag(Tag.applicationTagClass, Tag.realAppTag, len(b), b) - if _debug: real_endec._debug(" - tag: %r", tag) + if _debug: real_tag._debug(" - tag: %r", tag) return tag @@ -35,7 +36,7 @@ def real_encode(obj): tag = Tag() obj.encode(tag) - if _debug: real_endec._debug(" - tag: %r", tag) + if _debug: real_encode._debug(" - tag: %r, %r", tag, tag.tagData) return tag @@ -46,7 +47,7 @@ def real_decode(tag): if _debug: real_decode._debug("real_decode %r", tag) obj = Real(tag) - if _debug: real_decode._debug(" - obj: %r", obj) + if _debug: real_decode._debug(" - obj: %r, %r", obj, obj.value) return obj @@ -64,7 +65,14 @@ def real_endec(v, x): if _debug: real_endec._debug(" - obj: %r, %r", obj, obj.value) assert real_encode(obj) == tag - assert real_decode(tag) == obj + if _debug: real_endec._debug(" - tags match") + + if math.isnan(v): + assert math.isnan(real_decode(tag).value) + if _debug: real_endec._debug(" - both NaN") + else: + assert real_decode(tag) == obj + if _debug: real_endec._debug(" - objects match") @bacpypes_debugging @@ -133,4 +141,4 @@ class TestReal(unittest.TestCase): real_endec(-inf, 'ff800000') nan = float('nan') - real_endec(nan, '7fc00000') \ No newline at end of file + real_endec(nan, '7fc00000')