mirror of
https://github.com/JoelBender/bacpypes
synced 2025-09-28 22:15:23 +08:00
merging in stage for bugs that have already been fixed
This commit is contained in:
commit
ec832663bf
|
@ -92,17 +92,13 @@ class Tag(object):
|
|||
self.tagData = tdata
|
||||
|
||||
def encode(self, pdu):
|
||||
# check for special encoding of open and close tags
|
||||
if (self.tagClass == Tag.openingTagClass):
|
||||
pdu.put(((self.tagNumber & 0x0F) << 4) + 0x0E)
|
||||
return
|
||||
if (self.tagClass == Tag.closingTagClass):
|
||||
pdu.put(((self.tagNumber & 0x0F) << 4) + 0x0F)
|
||||
return
|
||||
|
||||
# check for context encoding
|
||||
# check for special encoding
|
||||
if (self.tagClass == Tag.contextTagClass):
|
||||
data = 0x08
|
||||
elif (self.tagClass == Tag.openingTagClass):
|
||||
data = 0x0E
|
||||
elif (self.tagClass == Tag.closingTagClass):
|
||||
data = 0x0F
|
||||
else:
|
||||
data = 0x00
|
||||
|
||||
|
@ -1051,7 +1047,7 @@ class Enumerated(Atomic):
|
|||
def encode(self, tag):
|
||||
if isinstance(self.value, int):
|
||||
value = long(self.value)
|
||||
if isinstance(self.value, long):
|
||||
elif isinstance(self.value, long):
|
||||
value = self.value
|
||||
elif isinstance(self.value, str):
|
||||
value = self._xlate_table[self.value]
|
||||
|
@ -1084,7 +1080,7 @@ class Enumerated(Atomic):
|
|||
self.value = rslt
|
||||
|
||||
def __str__(self):
|
||||
return "Enumerated(%s)" % (self.value,)
|
||||
return "%s(%s)" % (self.__class__.__name__, self.value)
|
||||
|
||||
#
|
||||
# expand_enumerations
|
||||
|
@ -1093,13 +1089,17 @@ class Enumerated(Atomic):
|
|||
def expand_enumerations(klass):
|
||||
# build a value dictionary
|
||||
xlateTable = {}
|
||||
for name, value in klass.enumerations.items():
|
||||
# save the results
|
||||
xlateTable[name] = value
|
||||
xlateTable[value] = name
|
||||
|
||||
# save the name in the class
|
||||
setattr(klass, name, value)
|
||||
for c in klass.__mro__:
|
||||
enumerations = getattr(c, 'enumerations', {})
|
||||
if enumerations:
|
||||
for name, value in enumerations.items():
|
||||
# save the results
|
||||
xlateTable[name] = value
|
||||
xlateTable[value] = name
|
||||
|
||||
# save the name in the class
|
||||
setattr(klass, name, value)
|
||||
|
||||
# save the dictionary in the class
|
||||
setattr(klass, '_xlate_table', xlateTable)
|
||||
|
@ -1248,11 +1248,15 @@ class Time(Atomic):
|
|||
raise ValueError("invalid time pattern")
|
||||
|
||||
tup_list = []
|
||||
for s in tup_match:
|
||||
tup_items = list(tup_match.groups())
|
||||
for s in tup_items:
|
||||
if s == '*':
|
||||
tup_list.append(255)
|
||||
elif s in None:
|
||||
tup_list.append(0)
|
||||
elif s is None:
|
||||
if '*' in tup_items:
|
||||
tup_list.append(255)
|
||||
else:
|
||||
tup_list.append(0)
|
||||
else:
|
||||
tup_list.append(int(s))
|
||||
|
||||
|
@ -1393,12 +1397,12 @@ class ObjectIdentifier(Atomic):
|
|||
self.set_long(arg)
|
||||
elif isinstance(arg, tuple):
|
||||
self.set_tuple(*arg)
|
||||
elif isinstance(arg, ObjectIdentifier):
|
||||
self.value = arg.value
|
||||
else:
|
||||
raise TypeError("invalid constructor datatype")
|
||||
elif len(args) == 2:
|
||||
self.set_tuple(*args)
|
||||
elif isinstance(arg, ObjectIdentifier):
|
||||
self.value = arg.value
|
||||
else:
|
||||
raise ValueError("invalid constructor parameters")
|
||||
|
||||
|
|
|
@ -92,17 +92,13 @@ class Tag(object):
|
|||
self.tagData = tdata
|
||||
|
||||
def encode(self, pdu):
|
||||
# check for special encoding of open and close tags
|
||||
if (self.tagClass == Tag.openingTagClass):
|
||||
pdu.put(((self.tagNumber & 0x0F) << 4) + 0x0E)
|
||||
return
|
||||
if (self.tagClass == Tag.closingTagClass):
|
||||
pdu.put(((self.tagNumber & 0x0F) << 4) + 0x0F)
|
||||
return
|
||||
|
||||
# check for context encoding
|
||||
# check for special encoding
|
||||
if (self.tagClass == Tag.contextTagClass):
|
||||
data = 0x08
|
||||
elif (self.tagClass == Tag.openingTagClass):
|
||||
data = 0x0E
|
||||
elif (self.tagClass == Tag.closingTagClass):
|
||||
data = 0x0F
|
||||
else:
|
||||
data = 0x00
|
||||
|
||||
|
@ -1051,7 +1047,7 @@ class Enumerated(Atomic):
|
|||
def encode(self, tag):
|
||||
if isinstance(self.value, int):
|
||||
value = long(self.value)
|
||||
if isinstance(self.value, long):
|
||||
elif isinstance(self.value, long):
|
||||
value = self.value
|
||||
elif isinstance(self.value, str):
|
||||
value = self._xlate_table[self.value]
|
||||
|
@ -1084,7 +1080,7 @@ class Enumerated(Atomic):
|
|||
self.value = rslt
|
||||
|
||||
def __str__(self):
|
||||
return "Enumerated(%s)" % (self.value,)
|
||||
return "%s(%s)" % (self.__class__.__name__, self.value)
|
||||
|
||||
#
|
||||
# expand_enumerations
|
||||
|
@ -1093,13 +1089,17 @@ class Enumerated(Atomic):
|
|||
def expand_enumerations(klass):
|
||||
# build a value dictionary
|
||||
xlateTable = {}
|
||||
for name, value in klass.enumerations.items():
|
||||
# save the results
|
||||
xlateTable[name] = value
|
||||
xlateTable[value] = name
|
||||
|
||||
# save the name in the class
|
||||
setattr(klass, name, value)
|
||||
for c in klass.__mro__:
|
||||
enumerations = getattr(c, 'enumerations', {})
|
||||
if enumerations:
|
||||
for name, value in enumerations.items():
|
||||
# save the results
|
||||
xlateTable[name] = value
|
||||
xlateTable[value] = name
|
||||
|
||||
# save the name in the class
|
||||
setattr(klass, name, value)
|
||||
|
||||
# save the dictionary in the class
|
||||
setattr(klass, '_xlate_table', xlateTable)
|
||||
|
@ -1248,11 +1248,15 @@ class Time(Atomic):
|
|||
raise ValueError("invalid time pattern")
|
||||
|
||||
tup_list = []
|
||||
for s in tup_match:
|
||||
tup_items = list(tup_match.groups())
|
||||
for s in tup_items:
|
||||
if s == '*':
|
||||
tup_list.append(255)
|
||||
elif s in None:
|
||||
tup_list.append(0)
|
||||
elif s is None:
|
||||
if '*' in tup_items:
|
||||
tup_list.append(255)
|
||||
else:
|
||||
tup_list.append(0)
|
||||
else:
|
||||
tup_list.append(int(s))
|
||||
|
||||
|
@ -1393,12 +1397,12 @@ class ObjectIdentifier(Atomic):
|
|||
self.set_long(arg)
|
||||
elif isinstance(arg, tuple):
|
||||
self.set_tuple(*arg)
|
||||
elif isinstance(arg, ObjectIdentifier):
|
||||
self.value = arg.value
|
||||
else:
|
||||
raise TypeError("invalid constructor datatype")
|
||||
elif len(args) == 2:
|
||||
self.set_tuple(*args)
|
||||
elif isinstance(arg, ObjectIdentifier):
|
||||
self.value = arg.value
|
||||
else:
|
||||
raise ValueError("invalid constructor parameters")
|
||||
|
||||
|
|
|
@ -92,17 +92,13 @@ class Tag(object):
|
|||
self.tagData = tdata
|
||||
|
||||
def encode(self, pdu):
|
||||
# check for special encoding of open and close tags
|
||||
if (self.tagClass == Tag.openingTagClass):
|
||||
pdu.put(((self.tagNumber & 0x0F) << 4) + 0x0E)
|
||||
return
|
||||
if (self.tagClass == Tag.closingTagClass):
|
||||
pdu.put(((self.tagNumber & 0x0F) << 4) + 0x0F)
|
||||
return
|
||||
|
||||
# check for context encoding
|
||||
# check for special encoding
|
||||
if (self.tagClass == Tag.contextTagClass):
|
||||
data = 0x08
|
||||
elif (self.tagClass == Tag.openingTagClass):
|
||||
data = 0x0E
|
||||
elif (self.tagClass == Tag.closingTagClass):
|
||||
data = 0x0F
|
||||
else:
|
||||
data = 0x00
|
||||
|
||||
|
@ -797,14 +793,15 @@ class CharacterString(Atomic):
|
|||
def __init__(self, arg=None):
|
||||
self.value = ''
|
||||
self.strEncoding = 0
|
||||
self.strValue = ''
|
||||
self.strValue = b''
|
||||
|
||||
if arg is None:
|
||||
pass
|
||||
elif isinstance(arg, Tag):
|
||||
self.decode(arg)
|
||||
elif isinstance(arg, str):
|
||||
self.strValue = self.value = arg
|
||||
self.value = arg
|
||||
self.strValue = arg.encode('utf-8')
|
||||
elif isinstance(arg, CharacterString):
|
||||
self.value = arg.value
|
||||
self.strEncoding = arg.strEncoding
|
||||
|
@ -814,7 +811,7 @@ class CharacterString(Atomic):
|
|||
|
||||
def encode(self, tag):
|
||||
# encode the tag
|
||||
tag.set_app_data(Tag.characterStringAppTag, (chr(self.strEncoding)+self.strValue.encode('latin-1')))
|
||||
tag.set_app_data(Tag.characterStringAppTag, bytes([self.strEncoding]) + self.strValue)
|
||||
|
||||
def decode(self, tag):
|
||||
if (tag.tagClass != Tag.applicationTagClass) or (tag.tagNumber != Tag.characterStringAppTag):
|
||||
|
@ -829,26 +826,18 @@ class CharacterString(Atomic):
|
|||
|
||||
# normalize the value
|
||||
if (self.strEncoding == 0):
|
||||
udata = self.strValue.decode('utf-8')
|
||||
self.value = str(udata)
|
||||
#self.value = str(udata.encode('ascii', 'backslashreplace'))
|
||||
self.value = self.strValue.decode('utf-8')
|
||||
elif (self.strEncoding == 3):
|
||||
udata = self.strValue.decode('utf_32be')
|
||||
self.value = str(udata)
|
||||
#self.value = str(udata.encode('ascii', 'backslashreplace'))
|
||||
self.value = self.strValue.decode('utf_32be')
|
||||
elif (self.strEncoding == 4):
|
||||
udata = self.strValue.decode('utf_16be')
|
||||
self.value = str(udata)
|
||||
#self.value = str(udata.encode('ascii', 'backslashreplace'))
|
||||
self.value = self.strValue.decode('utf_16be')
|
||||
elif (self.strEncoding == 5):
|
||||
udata = self.strValue.decode('latin_1')
|
||||
self.value = str(udata)
|
||||
#self.value = str(udata.encode('ascii', 'backslashreplace'))
|
||||
self.value = self.strValue.decode('latin_1')
|
||||
else:
|
||||
self.value = '### unknown encoding: %d ###' % (self.strEncoding,)
|
||||
|
||||
def __str__(self):
|
||||
return "CharacterString(%d," % (self.strEncoding,) + repr(self.strValue) + ")"
|
||||
return "CharacterString(%d," % (self.strEncoding,) + repr(self.value) + ")"
|
||||
|
||||
#
|
||||
# BitString
|
||||
|
@ -1102,7 +1091,7 @@ class Enumerated(Atomic):
|
|||
self.value = rslt
|
||||
|
||||
def __str__(self):
|
||||
return "Enumerated(%s)" % (self.value,)
|
||||
return "%s(%s)" % (self.__class__.__name__, self.value)
|
||||
|
||||
#
|
||||
# expand_enumerations
|
||||
|
@ -1111,13 +1100,17 @@ class Enumerated(Atomic):
|
|||
def expand_enumerations(klass):
|
||||
# build a value dictionary
|
||||
xlateTable = {}
|
||||
for name, value in klass.enumerations.items():
|
||||
# save the results
|
||||
xlateTable[name] = value
|
||||
xlateTable[value] = name
|
||||
|
||||
# save the name in the class
|
||||
setattr(klass, name, value)
|
||||
for c in klass.__mro__:
|
||||
enumerations = getattr(c, 'enumerations', {})
|
||||
if enumerations:
|
||||
for name, value in enumerations.items():
|
||||
# save the results
|
||||
xlateTable[name] = value
|
||||
xlateTable[value] = name
|
||||
|
||||
# save the name in the class
|
||||
setattr(klass, name, value)
|
||||
|
||||
# save the dictionary in the class
|
||||
setattr(klass, '_xlate_table', xlateTable)
|
||||
|
@ -1266,11 +1259,15 @@ class Time(Atomic):
|
|||
raise ValueError("invalid time pattern")
|
||||
|
||||
tup_list = []
|
||||
for s in tup_match:
|
||||
tup_items = list(tup_match.groups())
|
||||
for s in tup_items:
|
||||
if s == '*':
|
||||
tup_list.append(255)
|
||||
elif s in None:
|
||||
tup_list.append(0)
|
||||
elif s is None:
|
||||
if '*' in tup_items:
|
||||
tup_list.append(255)
|
||||
else:
|
||||
tup_list.append(0)
|
||||
else:
|
||||
tup_list.append(int(s))
|
||||
|
||||
|
@ -1409,12 +1406,12 @@ class ObjectIdentifier(Atomic):
|
|||
self.set_long(arg)
|
||||
elif isinstance(arg, tuple):
|
||||
self.set_tuple(*arg)
|
||||
elif isinstance(arg, ObjectIdentifier):
|
||||
self.value = arg.value
|
||||
else:
|
||||
raise TypeError("invalid constructor datatype")
|
||||
elif len(args) == 2:
|
||||
self.set_tuple(*args)
|
||||
elif isinstance(arg, ObjectIdentifier):
|
||||
self.value = arg.value
|
||||
else:
|
||||
raise ValueError("invalid constructor parameters")
|
||||
|
||||
|
|
2
setup.py
2
setup.py
|
@ -25,7 +25,7 @@ test_requirements = [
|
|||
|
||||
setup(
|
||||
name='bacpypes',
|
||||
version="0.13.1",
|
||||
version="0.13.2",
|
||||
description="Testing multiple versions of python",
|
||||
long_description="This is a long line of text",
|
||||
author="Joel Bender",
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Bit String
|
||||
-------------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import BitString, Tag
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
class SampleBitString(BitString):
|
||||
bitLen = 13
|
||||
bitNames = {
|
||||
'b0': 0,
|
||||
'b1': 1,
|
||||
'b4': 4,
|
||||
'b7': 7,
|
||||
'b8': 8,
|
||||
'b12': 12,
|
||||
}
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def bit_string_tag(x):
|
||||
"""Convert a hex string to an bit_string application tag."""
|
||||
if _debug: bit_string_tag._debug("bit_string_tag %r", x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(Tag.applicationTagClass, Tag.bitStringAppTag, len(b), b)
|
||||
if _debug: bit_string_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
@bacpypes_debugging
|
||||
def bit_string_encode(obj):
|
||||
"""Encode an BitString object into a tag."""
|
||||
if _debug: bit_string_encode._debug("bit_string_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
if _debug: bit_string_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def bit_string_decode(tag):
|
||||
"""Decode an bit_string application tag into an bit_string."""
|
||||
if _debug: bit_string_decode._debug("bit_string_decode %r", tag)
|
||||
|
||||
obj = BitString(tag)
|
||||
if _debug: bit_string_decode._debug(" - obj: %r", obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def bit_string_endec(v, x):
|
||||
"""Pass the value to BitString, construct a tag from the hex string,
|
||||
and compare results of encode and decoding each other."""
|
||||
if _debug: bit_string_endec._debug("bit_string_endec %r %r", v, x)
|
||||
|
||||
tag = bit_string_tag(x)
|
||||
if _debug: bit_string_endec._debug(" - tag: %r, %r", tag, tag.tagData)
|
||||
|
||||
obj = BitString(v)
|
||||
if _debug: bit_string_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
assert bit_string_encode(obj) == tag
|
||||
assert bit_string_decode(tag) == obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestBitString(unittest.TestCase):
|
||||
|
||||
def test_bit_string(self):
|
||||
if _debug: TestBitString._debug("test_bit_string")
|
||||
|
||||
obj = BitString()
|
||||
assert obj.value == []
|
||||
assert str(obj) == "BitString()"
|
||||
|
||||
obj = BitString([0])
|
||||
assert obj.value == [0]
|
||||
assert str(obj) == "BitString(0)"
|
||||
|
||||
obj = BitString([0, 1])
|
||||
assert obj.value == [0, 1]
|
||||
assert str(obj) == "BitString(0,1)"
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
BitString("some string")
|
||||
with self.assertRaises(TypeError):
|
||||
BitString(1.0)
|
||||
|
||||
def test_bit_string_sample(self):
|
||||
if _debug: TestBitString._debug("test_bit_string_sample")
|
||||
|
||||
obj = SampleBitString()
|
||||
assert obj.value == [0] * SampleBitString.bitLen
|
||||
|
||||
obj = SampleBitString([1])
|
||||
assert str(obj) == "BitString(b0)"
|
||||
|
||||
obj = SampleBitString(['b4'])
|
||||
assert str(obj) == "BitString(!b0,!b1,0,0,b4,0,0,!b7,!b8,0,0,0,!b12)"
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
SampleBitString(["x1"])
|
||||
|
||||
def test_bit_string_tag(self):
|
||||
if _debug: TestBitString._debug("test_bit_string_tag")
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.bitStringAppTag, 1, xtob('08'))
|
||||
obj = BitString(tag)
|
||||
if _debug: TestBitString._debug(" - obj.value: %r", obj.value)
|
||||
assert obj.value == []
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.bitStringAppTag, 2, xtob('0102'))
|
||||
obj = BitString(tag)
|
||||
if _debug: TestBitString._debug(" - obj.value: %r", obj.value)
|
||||
assert obj.value == [0, 0, 0, 0, 0, 0, 1]
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
BitString(tag)
|
||||
|
||||
tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff'))
|
||||
with self.assertRaises(ValueError):
|
||||
BitString(tag)
|
||||
|
||||
tag = Tag(Tag.openingTagClass, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
BitString(tag)
|
||||
|
||||
def test_bit_string_copy(self):
|
||||
if _debug: TestBitString._debug("test_bit_string_copy")
|
||||
|
||||
sample_value = [0, 1, 0, 1]
|
||||
obj1 = BitString(sample_value)
|
||||
obj2 = BitString(obj1)
|
||||
assert obj2.value == sample_value
|
||||
|
||||
def test_bit_string_endec(self):
|
||||
if _debug: TestBitString._debug("test_bit_string_endec")
|
||||
|
||||
bit_string_endec([], '00')
|
||||
bit_string_endec([0], '0700')
|
||||
bit_string_endec([1], '0780')
|
||||
bit_string_endec([0] * 2, '0600')
|
||||
bit_string_endec([1] * 2, '06c0')
|
||||
bit_string_endec([0] * 10, '060000')
|
||||
bit_string_endec([1] * 10, '06ffc0')
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Data Character String
|
||||
------------------------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import CharacterString, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
# globals
|
||||
fox_message = "the quick brown fox jumped over the lazy dog"
|
||||
|
||||
@bacpypes_debugging
|
||||
def character_string_tag(x):
|
||||
"""Convert a hex string to an character_string application tag."""
|
||||
if _debug: character_string_tag._debug("character_string_tag %r", x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(Tag.applicationTagClass, Tag.characterStringAppTag, len(b), b)
|
||||
if _debug: character_string_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
@bacpypes_debugging
|
||||
def character_string_encode(obj):
|
||||
"""Encode an CharacterString object into a tag."""
|
||||
if _debug: character_string_encode._debug("character_string_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
if _debug: character_string_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def character_string_decode(tag):
|
||||
"""Decode an character_string application tag into an character_string."""
|
||||
if _debug: character_string_decode._debug("character_string_decode %r", tag)
|
||||
|
||||
obj = CharacterString(tag)
|
||||
if _debug: character_string_decode._debug(" - obj: %r", obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def character_string_endec(v, x):
|
||||
"""Pass the value to CharacterString, construct a tag from the hex string,
|
||||
and compare results of encode and decoding each other."""
|
||||
if _debug: character_string_endec._debug("character_string_endec %r %r", v, x)
|
||||
|
||||
tag = character_string_tag(x)
|
||||
if _debug: character_string_endec._debug(" - tag: %r, %r", tag, tag.tagData)
|
||||
|
||||
obj = CharacterString(v)
|
||||
if _debug: character_string_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
assert character_string_encode(obj) == tag
|
||||
assert character_string_decode(tag) == obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestCharacterString(unittest.TestCase):
|
||||
|
||||
def test_character_string(self):
|
||||
if _debug: TestCharacterString._debug("test_character_string")
|
||||
|
||||
obj = CharacterString()
|
||||
assert obj.value == ''
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
CharacterString(1)
|
||||
with self.assertRaises(TypeError):
|
||||
CharacterString(1.0)
|
||||
|
||||
def test_character_string_str(self):
|
||||
if _debug: TestCharacterString._debug("test_character_string_str")
|
||||
|
||||
obj = CharacterString("hello")
|
||||
assert obj.value == "hello"
|
||||
assert str(obj) == "CharacterString(0,'hello')"
|
||||
|
||||
def test_character_string_tag(self):
|
||||
if _debug: TestCharacterString._debug("test_character_string_tag")
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.characterStringAppTag, 1, xtob('00'))
|
||||
obj = CharacterString(tag)
|
||||
assert obj.value == ''
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
CharacterString(tag)
|
||||
|
||||
tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff'))
|
||||
with self.assertRaises(ValueError):
|
||||
CharacterString(tag)
|
||||
|
||||
tag = Tag(Tag.openingTagClass, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
CharacterString(tag)
|
||||
|
||||
def test_character_string_copy(self):
|
||||
if _debug: TestCharacterString._debug("test_character_string_copy")
|
||||
|
||||
obj1 = CharacterString(fox_message)
|
||||
obj2 = CharacterString(obj1)
|
||||
assert obj2.value == fox_message
|
||||
|
||||
def test_character_string_endec(self):
|
||||
if _debug: TestCharacterString._debug("test_character_string_endec")
|
||||
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = CharacterString(character_string_tag(''))
|
||||
|
||||
character_string_endec("", '00')
|
||||
character_string_endec("abc", '00616263')
|
|
@ -0,0 +1,150 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Data Date
|
||||
---------------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import Date, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def date_tag(x):
|
||||
"""Convert a hex string to an date application tag."""
|
||||
if _debug: date_tag._debug("date_tag %r", x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(Tag.applicationTagClass, Tag.dateAppTag, len(b), b)
|
||||
if _debug: date_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
@bacpypes_debugging
|
||||
def date_encode(obj):
|
||||
"""Encode an Date object into a tag."""
|
||||
if _debug: date_encode._debug("date_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
if _debug: date_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def date_decode(tag):
|
||||
"""Decode an date application tag into an date."""
|
||||
if _debug: date_decode._debug("date_decode %r", tag)
|
||||
|
||||
obj = Date(tag)
|
||||
if _debug: date_decode._debug(" - obj: %r", obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def date_endec(v, x):
|
||||
"""Pass the value to Date, construct a tag from the hex string,
|
||||
and compare results of encode and decoding each other."""
|
||||
if _debug: date_endec._debug("date_endec %r %r", v, x)
|
||||
|
||||
tag = date_tag(x)
|
||||
if _debug: date_endec._debug(" - tag: %r, %r", tag, tag.tagData)
|
||||
|
||||
obj = Date(v)
|
||||
if _debug: date_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
assert date_encode(obj) == tag
|
||||
assert date_decode(tag) == obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestDate(unittest.TestCase):
|
||||
|
||||
def test_date(self):
|
||||
if _debug: TestDate._debug("test_date")
|
||||
|
||||
# default values is all dont care
|
||||
obj = Date()
|
||||
assert obj.value == (255, 255, 255, 255)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Date("some string")
|
||||
with self.assertRaises(TypeError):
|
||||
Date(1.0)
|
||||
|
||||
def test_date_tuple(self):
|
||||
if _debug: TestDate._debug("test_date_tuple")
|
||||
|
||||
obj = Date((1,2,3,4))
|
||||
assert obj.value == (1, 2, 3, 4)
|
||||
assert str(obj) == "Date(2/3/1901 Thu)"
|
||||
|
||||
### issue-48
|
||||
# obj = Date("1/2/3")
|
||||
# assert obj.value == (1, 2, x, y)
|
||||
|
||||
# obj = Date("*/2/3")
|
||||
# assert obj.value == (255, 2, x, 255)
|
||||
|
||||
# obj = Date("1/*/3")
|
||||
# assert obj.value == (1, 255, x, 255)
|
||||
|
||||
# obj = Date("1/2/*")
|
||||
# assert obj.value == (1, 2, 255, 255)
|
||||
|
||||
# obj = Date("1/2/3 *")
|
||||
# assert obj.value == (1, 2, 3, 255)
|
||||
|
||||
def test_date_tag(self):
|
||||
if _debug: TestDate._debug("test_date_tag")
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.dateAppTag, 1, xtob('01020304'))
|
||||
obj = Date(tag)
|
||||
assert obj.value == (1, 2, 3, 4)
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
Date(tag)
|
||||
|
||||
tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff'))
|
||||
with self.assertRaises(ValueError):
|
||||
Date(tag)
|
||||
|
||||
tag = Tag(Tag.openingTagClass, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
Date(tag)
|
||||
|
||||
def test_date_copy(self):
|
||||
if _debug: TestDate._debug("test_date_copy")
|
||||
|
||||
date_value = (2, 3, 4, 5)
|
||||
obj1 = Date(date_value)
|
||||
obj2 = Date(obj1)
|
||||
assert obj2.value == date_value
|
||||
|
||||
def test_date_now(self):
|
||||
if _debug: TestDate._debug("test_date_now")
|
||||
|
||||
# obj = Date().now()
|
||||
### how to test?
|
||||
|
||||
def test_date_endec(self):
|
||||
if _debug: TestDate._debug("test_date_endec")
|
||||
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = Date(date_tag(''))
|
||||
|
||||
date_endec((0, 0, 0, 0), '00000000')
|
||||
date_endec((1, 0, 0, 0), '01000000')
|
||||
date_endec((0, 2, 0, 0), '00020000')
|
||||
date_endec((0, 0, 3, 0), '00000300')
|
||||
date_endec((0, 0, 0, 4), '00000004')
|
|
@ -11,7 +11,7 @@ import struct
|
|||
import math
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import Double, Tag
|
||||
from bacpypes.primitivedata import Double, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -126,8 +126,8 @@ class TestDouble(unittest.TestCase):
|
|||
def test_double_endec(self):
|
||||
if _debug: TestDouble._debug("test_double_endec")
|
||||
|
||||
with self.assertRaises(struct.error):
|
||||
obj = Double(double_tag(''))
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = Double(double_tag(''))
|
||||
|
||||
double_endec(0, '0000000000000000')
|
||||
double_endec(1, '3ff0000000000000')
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Data Enumerated
|
||||
------------------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import Enumerated, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def enumerated_tag(x):
|
||||
"""Convert a hex string to an enumerated application tag."""
|
||||
if _debug: enumerated_tag._debug("enumerated_tag %r", x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(Tag.applicationTagClass, Tag.enumeratedAppTag, len(b), b)
|
||||
if _debug: enumerated_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
@bacpypes_debugging
|
||||
def enumerated_encode(obj):
|
||||
"""Encode an Enumerated object into a tag."""
|
||||
if _debug: enumerated_encode._debug("enumerated_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
if _debug: enumerated_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def enumerated_decode(tag):
|
||||
"""Decode an enumerated application tag into an enumerated."""
|
||||
if _debug: enumerated_decode._debug("enumerated_decode %r", tag)
|
||||
|
||||
obj = Enumerated(tag)
|
||||
if _debug: enumerated_decode._debug(" - obj: %r", obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def enumerated_endec(v, x):
|
||||
"""Pass the value to Enumerated, construct a tag from the hex string,
|
||||
and compare results of encode and decoding each other."""
|
||||
if _debug: enumerated_endec._debug("enumerated_endec %r %r", v, x)
|
||||
|
||||
tag = enumerated_tag(x)
|
||||
if _debug: enumerated_endec._debug(" - tag: %r, %r", tag, tag.tagData)
|
||||
|
||||
obj = Enumerated(v)
|
||||
if _debug: enumerated_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
assert enumerated_encode(obj) == tag
|
||||
assert enumerated_decode(tag) == obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestEnumerated(unittest.TestCase):
|
||||
|
||||
def test_enumerated(self):
|
||||
if _debug: TestEnumerated._debug("test_enumerated")
|
||||
|
||||
obj = Enumerated()
|
||||
assert obj.value == 0
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Enumerated("label")
|
||||
with self.assertRaises(TypeError):
|
||||
Enumerated(1.0)
|
||||
|
||||
def test_enumerated_int(self):
|
||||
if _debug: TestEnumerated._debug("test_enumerated_int")
|
||||
|
||||
obj = Enumerated(1)
|
||||
assert obj.value == 1
|
||||
assert str(obj) == "Enumerated(1)"
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Enumerated(-1)
|
||||
|
||||
def test_enumerated_tag(self):
|
||||
if _debug: TestEnumerated._debug("test_enumerated_tag")
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.enumeratedAppTag, 1, xtob('01'))
|
||||
obj = Enumerated(tag)
|
||||
assert obj.value == 1
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
Enumerated(tag)
|
||||
|
||||
tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff'))
|
||||
with self.assertRaises(ValueError):
|
||||
Enumerated(tag)
|
||||
|
||||
tag = Tag(Tag.openingTagClass, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
Enumerated(tag)
|
||||
|
||||
def test_enumerated_copy(self):
|
||||
if _debug: TestEnumerated._debug("test_enumerated_copy")
|
||||
|
||||
obj1 = Enumerated(12)
|
||||
obj2 = Enumerated(obj1)
|
||||
assert obj2.value == 12
|
||||
|
||||
def test_enumerated_endec(self):
|
||||
if _debug: TestEnumerated._debug("test_enumerated_endec")
|
||||
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = Enumerated(enumerated_tag(''))
|
||||
|
||||
enumerated_endec(0, '00')
|
||||
enumerated_endec(1, '01')
|
||||
enumerated_endec(127, '7f')
|
||||
enumerated_endec(128, '80')
|
||||
enumerated_endec(255, 'ff')
|
||||
|
||||
enumerated_endec(32767, '7fff')
|
||||
enumerated_endec(32768, '8000')
|
||||
|
||||
enumerated_endec(8388607, '7fffff')
|
||||
enumerated_endec(8388608, '800000')
|
||||
|
||||
enumerated_endec(2147483647, '7fffffff')
|
||||
enumerated_endec(2147483648, '80000000')
|
|
@ -9,7 +9,7 @@ Test Primitive Data Integer
|
|||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import Integer, Tag
|
||||
from bacpypes.primitivedata import Integer, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -120,8 +120,8 @@ class TestInteger(unittest.TestCase):
|
|||
def test_integer_endec(self):
|
||||
if _debug: TestInteger._debug("test_integer_endec")
|
||||
|
||||
with self.assertRaises(IndexError):
|
||||
obj = Integer(integer_tag(''))
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = Integer(integer_tag(''))
|
||||
|
||||
integer_endec(0, '00')
|
||||
integer_endec(1, '01')
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Data Object Identifier
|
||||
-------------------------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import ObjectIdentifier, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_identifier_tag(x):
|
||||
"""Convert a hex string to an object_identifier application tag."""
|
||||
if _debug: object_identifier_tag._debug("object_identifier_tag %r", x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(Tag.applicationTagClass, Tag.objectIdentifierAppTag, len(b), b)
|
||||
if _debug: object_identifier_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_identifier_encode(obj):
|
||||
"""Encode an ObjectIdentifier object into a tag."""
|
||||
if _debug: object_identifier_encode._debug("object_identifier_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
if _debug: object_identifier_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_identifier_decode(tag):
|
||||
"""Decode an object_identifier application tag into an object_identifier."""
|
||||
if _debug: object_identifier_decode._debug("object_identifier_decode %r", tag)
|
||||
|
||||
obj = ObjectIdentifier(tag)
|
||||
if _debug: object_identifier_decode._debug(" - obj: %r", obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_identifier_endec(v, x):
|
||||
"""Pass the value to ObjectIdentifier, construct a tag from the hex string,
|
||||
and compare results of encode and decoding each other."""
|
||||
if _debug: object_identifier_endec._debug("object_identifier_endec %r %r", v, x)
|
||||
|
||||
tag = object_identifier_tag(x)
|
||||
if _debug: object_identifier_endec._debug(" - tag: %r, %r", tag, tag.tagData)
|
||||
|
||||
obj = ObjectIdentifier(v)
|
||||
if _debug: object_identifier_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
assert object_identifier_encode(obj) == tag
|
||||
assert object_identifier_decode(tag) == obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestObjectIdentifier(unittest.TestCase):
|
||||
|
||||
def test_object_identifier(self):
|
||||
if _debug: TestObjectIdentifier._debug("test_object_identifier")
|
||||
|
||||
obj = ObjectIdentifier()
|
||||
assert obj.value == ('analogInput', 0)
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
ObjectIdentifier("some string")
|
||||
with self.assertRaises(TypeError):
|
||||
ObjectIdentifier(1.0)
|
||||
|
||||
def test_object_identifier_int(self):
|
||||
if _debug: TestObjectIdentifier._debug("test_object_identifier_int")
|
||||
|
||||
obj = ObjectIdentifier(1)
|
||||
assert obj.value == ('analogInput', 1)
|
||||
assert str(obj) == "ObjectIdentifier(analogInput,1)"
|
||||
|
||||
obj = ObjectIdentifier(0x0400002)
|
||||
assert obj.value == ('analogOutput', 2)
|
||||
assert str(obj) == "ObjectIdentifier(analogOutput,2)"
|
||||
|
||||
def test_object_identifier_tag(self):
|
||||
if _debug: TestObjectIdentifier._debug("test_object_identifier_tag")
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.objectIdentifierAppTag, 1, xtob('06000003'))
|
||||
obj = ObjectIdentifier(tag)
|
||||
assert obj.value == ('pulseConverter', 3)
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
ObjectIdentifier(tag)
|
||||
|
||||
tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff'))
|
||||
with self.assertRaises(ValueError):
|
||||
ObjectIdentifier(tag)
|
||||
|
||||
tag = Tag(Tag.openingTagClass, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
ObjectIdentifier(tag)
|
||||
|
||||
def test_object_identifier_copy(self):
|
||||
if _debug: TestObjectIdentifier._debug("test_object_identifier_copy")
|
||||
|
||||
obj1 = ObjectIdentifier(('analogInput', 1))
|
||||
obj2 = ObjectIdentifier(obj1)
|
||||
assert obj2.value == ('analogInput', 1)
|
||||
|
||||
def test_object_identifier_endec(self):
|
||||
if _debug: TestObjectIdentifier._debug("test_object_identifier_endec")
|
||||
|
||||
### this should raise a DecodingError
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = ObjectIdentifier(object_identifier_tag(''))
|
||||
|
||||
# test standard types
|
||||
object_identifier_endec(('analogInput', 0), '00000000')
|
||||
|
||||
# test vendor types
|
|
@ -0,0 +1,175 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Data ObjectType
|
||||
------------------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import ObjectType, Tag, DecodingError, \
|
||||
expand_enumerations
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
class MyObjectType(ObjectType):
|
||||
enumerations = {
|
||||
'myAnalogInput': 128,
|
||||
'myAnalogOutput': 129,
|
||||
'myAnalogValue': 130,
|
||||
}
|
||||
|
||||
expand_enumerations(MyObjectType)
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_type_tag(x):
|
||||
"""Convert a hex string to an enumerated application tag."""
|
||||
if _debug: object_type_tag._debug("object_type_tag %r", x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(Tag.applicationTagClass, Tag.enumeratedAppTag, len(b), b)
|
||||
if _debug: object_type_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_type_encode(obj):
|
||||
"""Encode an ObjectType object into a tag."""
|
||||
if _debug: object_type_encode._debug("object_type_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
if _debug: object_type_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_type_decode(tag):
|
||||
"""Decode an enumerated application tag into an object_type."""
|
||||
if _debug: object_type_decode._debug("object_type_decode %r", tag)
|
||||
|
||||
obj = ObjectType(tag)
|
||||
if _debug: object_type_decode._debug(" - obj: %r", obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def object_type_endec(v, x):
|
||||
"""Pass the value to ObjectType, construct a tag from the hex string,
|
||||
and compare results of encode and decoding each other."""
|
||||
if _debug: object_type_endec._debug("object_type_endec %r %r", v, x)
|
||||
|
||||
tag = object_type_tag(x)
|
||||
if _debug: object_type_endec._debug(" - tag: %r, %r", tag, tag.tagData)
|
||||
|
||||
obj = ObjectType(v)
|
||||
if _debug: object_type_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
assert object_type_encode(obj) == tag
|
||||
assert object_type_decode(tag) == obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestObjectType(unittest.TestCase):
|
||||
|
||||
def test_object_type(self):
|
||||
if _debug: TestObjectType._debug("test_object_type")
|
||||
|
||||
obj = ObjectType()
|
||||
assert obj.value == 0
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
ObjectType("unknownType")
|
||||
with self.assertRaises(TypeError):
|
||||
ObjectType(1.0)
|
||||
|
||||
def test_object_type_int(self):
|
||||
if _debug: TestObjectType._debug("test_object_type_int")
|
||||
|
||||
# known values are translated into strings
|
||||
obj = ObjectType(0)
|
||||
assert obj.value == 'analogInput'
|
||||
assert str(obj) == "ObjectType(analogInput)"
|
||||
|
||||
# unknown values are kept as integers
|
||||
obj = ObjectType(127)
|
||||
assert obj.value == 127
|
||||
assert str(obj) == "ObjectType(127)"
|
||||
|
||||
def test_object_type_str(self):
|
||||
if _debug: TestObjectType._debug("test_object_type_str")
|
||||
|
||||
# known strings are accepted
|
||||
obj = ObjectType('analogInput')
|
||||
assert obj.value == 'analogInput'
|
||||
|
||||
def test_extended_object_type_int(self):
|
||||
if _debug: TestObjectType._debug("test_extended_object_type_int")
|
||||
|
||||
# known values are translated into strings
|
||||
obj = MyObjectType(0)
|
||||
assert obj.value == 'analogInput'
|
||||
assert str(obj) == "MyObjectType(analogInput)"
|
||||
|
||||
# unknown values are kept as integers
|
||||
obj = MyObjectType(128)
|
||||
assert obj.value == 'myAnalogInput'
|
||||
assert str(obj) == "MyObjectType(myAnalogInput)"
|
||||
|
||||
def test_extended_object_type_str(self):
|
||||
if _debug: TestObjectType._debug("test_extended_object_type_str")
|
||||
|
||||
# known strings are accepted
|
||||
obj = MyObjectType('myAnalogInput')
|
||||
assert obj.value == 'myAnalogInput'
|
||||
|
||||
# unknown strings are rejected
|
||||
with self.assertRaises(ValueError):
|
||||
MyObjectType('snork')
|
||||
|
||||
def test_object_type_tag(self):
|
||||
if _debug: TestObjectType._debug("test_object_type_tag")
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.enumeratedAppTag, 1, xtob('01'))
|
||||
obj = ObjectType(tag)
|
||||
assert obj.value == 'analogOutput'
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
ObjectType(tag)
|
||||
|
||||
tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff'))
|
||||
with self.assertRaises(ValueError):
|
||||
ObjectType(tag)
|
||||
|
||||
tag = Tag(Tag.openingTagClass, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
ObjectType(tag)
|
||||
|
||||
def test_object_type_copy(self):
|
||||
if _debug: TestObjectType._debug("test_object_type_copy")
|
||||
|
||||
# known values are translated into strings
|
||||
obj1 = ObjectType(12)
|
||||
obj2 = ObjectType(obj1)
|
||||
assert obj2.value == 'loop'
|
||||
|
||||
def test_object_type_endec(self):
|
||||
if _debug: TestObjectType._debug("test_object_type_endec")
|
||||
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = ObjectType(object_type_tag(''))
|
||||
|
||||
object_type_endec('analogInput', '00')
|
||||
object_type_endec('analogOutput', '01')
|
||||
|
||||
object_type_endec(127, '7f')
|
||||
object_type_endec(128, '80')
|
|
@ -11,7 +11,7 @@ import struct
|
|||
import math
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import Real, Tag
|
||||
from bacpypes.primitivedata import Real, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -127,8 +127,8 @@ class TestReal(unittest.TestCase):
|
|||
def test_real_endec(self):
|
||||
if _debug: TestReal._debug("test_real_endec")
|
||||
|
||||
with self.assertRaises(struct.error):
|
||||
obj = Real(real_tag(''))
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = Real(real_tag(''))
|
||||
|
||||
real_endec(0, '00000000')
|
||||
real_endec(1, '3f800000')
|
||||
|
|
|
@ -0,0 +1,595 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Data Tag
|
||||
-----------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob, btox
|
||||
from bacpypes.primitivedata import Tag, ApplicationTag, ContextTag, \
|
||||
OpeningTag, ClosingTag, TagList, \
|
||||
Null, Boolean, Unsigned, Integer, Real, Double, OctetString, \
|
||||
CharacterString, BitString, Enumerated, Date, Time, ObjectIdentifier, \
|
||||
DecodingError
|
||||
from bacpypes.pdu import PDUData
|
||||
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
def tag_tuple(tag):
|
||||
"""Simple function to decompose a tag for debugging."""
|
||||
return (tag.tagClass, tag.tagNumber, tag.tagLVT, tag.tagData)
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def IntegerTag(v):
|
||||
"""Return an application encoded integer tag with the appropriate value.
|
||||
"""
|
||||
obj = Integer(v)
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def obj_decode(blob):
|
||||
"""Build PDU from the string, decode the tag, convert to an object."""
|
||||
if _debug: obj_decode._debug("obj_decode %r", blob)
|
||||
|
||||
data = PDUData(blob)
|
||||
tag = Tag(data)
|
||||
obj = tag.app_to_object()
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def obj_encode(obj):
|
||||
"""Encode the object into a tag, encode it in a PDU, return the data."""
|
||||
if _debug: obj_encode._debug("obj_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
data = PDUData()
|
||||
tag.encode(data)
|
||||
return data.pduData
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def obj_endec(obj, x):
|
||||
"""Convert the value (a primitive object) to a hex encoded string,
|
||||
convert the hex encoded string to and object, and compare the results to
|
||||
each other."""
|
||||
if _debug: obj_endec._debug("obj_endec %r %r", obj, x)
|
||||
|
||||
# convert the hex string to a blob
|
||||
blob = xtob(x)
|
||||
|
||||
# decode the blob into an object
|
||||
obj2 = obj_decode(blob)
|
||||
if _debug: obj_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
# encode the object into a blob
|
||||
blob2 = obj_encode(obj)
|
||||
if _debug: obj_endec._debug(" - blob2: %r", blob2)
|
||||
|
||||
# compare the results
|
||||
assert obj == obj2
|
||||
assert blob == blob2
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def context_decode(blob):
|
||||
"""Build PDU from the string, decode the tag, convert to an object."""
|
||||
if _debug: context_decode._debug("context_decode %r", blob)
|
||||
|
||||
data = PDUData(blob)
|
||||
tag = ContextTag(data)
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def context_encode(tag):
|
||||
"""Encode the object into a tag, encode it in a PDU, return the data."""
|
||||
if _debug: context_encode._debug("context_encode %r", tag)
|
||||
|
||||
data = PDUData()
|
||||
tag.encode(data)
|
||||
return data.pduData
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def context_endec(tnum, x, y):
|
||||
"""Convert the value (a primitive object) to a hex encoded string,
|
||||
convert the hex encoded string to and object, and compare the results to
|
||||
each other."""
|
||||
if _debug: context_endec._debug("context_endec %r %r %r", tnum, x, y)
|
||||
|
||||
# convert the hex strings to a blobs
|
||||
tdata = xtob(x)
|
||||
blob1 = xtob(y)
|
||||
|
||||
# make a context tag
|
||||
tag1 = ContextTag(tnum, tdata)
|
||||
|
||||
# decode the blob into a tag
|
||||
tag2 = context_decode(blob1)
|
||||
if _debug: context_endec._debug(" - tag: %r", tag)
|
||||
|
||||
# encode the tag into a blob
|
||||
blob2 = context_encode(tag1)
|
||||
if _debug: context_endec._debug(" - blob2: %r", blob2)
|
||||
|
||||
# compare the results
|
||||
assert tag1 == tag2
|
||||
assert blob1 == blob2
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def opening_decode(blob):
|
||||
"""Build PDU from the string, decode the tag, convert to an object."""
|
||||
if _debug: opening_decode._debug("opening_decode %r", blob)
|
||||
|
||||
data = PDUData(blob)
|
||||
tag = OpeningTag(data)
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def opening_encode(tag):
|
||||
"""Encode the object into a tag, encode it in a PDU, return the data."""
|
||||
if _debug: opening_encode._debug("opening_encode %r", tag)
|
||||
|
||||
data = PDUData()
|
||||
tag.encode(data)
|
||||
return data.pduData
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def opening_endec(tnum, x):
|
||||
"""Convert the value (a primitive object) to a hex encoded string,
|
||||
convert the hex encoded string to and object, and compare the results to
|
||||
each other."""
|
||||
if _debug: opening_endec._debug("opening_endec %r %r", tnum, x)
|
||||
|
||||
# convert the hex string to a blob
|
||||
blob1 = xtob(x)
|
||||
|
||||
# make a context tag
|
||||
tag1 = OpeningTag(tnum)
|
||||
if _debug: opening_endec._debug(" - tag1: %r", tag1)
|
||||
|
||||
# decode the blob into a tag
|
||||
tag2 = opening_decode(blob1)
|
||||
if _debug: opening_endec._debug(" - tag2: %r", tag2)
|
||||
|
||||
# encode the tag into a blob
|
||||
blob2 = opening_encode(tag1)
|
||||
if _debug: opening_endec._debug(" - blob2: %r", blob2)
|
||||
|
||||
# compare the results
|
||||
assert tag1 == tag2
|
||||
assert blob1 == blob2
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def closing_decode(blob):
|
||||
"""Build PDU from the string, decode the tag, convert to an object."""
|
||||
if _debug: closing_decode._debug("closing_decode %r", blob)
|
||||
|
||||
data = PDUData(blob)
|
||||
tag = ClosingTag(data)
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def closing_encode(tag):
|
||||
"""Encode the object into a tag, encode it in a PDU, return the data."""
|
||||
if _debug: closing_encode._debug("closing_encode %r", tag)
|
||||
|
||||
data = PDUData()
|
||||
tag.encode(data)
|
||||
return data.pduData
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def closing_endec(tnum, x):
|
||||
"""Convert the value (a primitive object) to a hex encoded string,
|
||||
convert the hex encoded string to and object, and compare the results to
|
||||
each other."""
|
||||
if _debug: closing_endec._debug("closing_endec %r %r", tnum, x)
|
||||
|
||||
# convert the hex string to a blob
|
||||
blob1 = xtob(x)
|
||||
|
||||
# make a context tag
|
||||
tag1 = ClosingTag(tnum)
|
||||
if _debug: closing_endec._debug(" - tag1: %r", tag1)
|
||||
|
||||
# decode the blob into a tag
|
||||
tag2 = closing_decode(blob1)
|
||||
if _debug: closing_endec._debug(" - tag2: %r", tag2)
|
||||
|
||||
# encode the tag into a blob
|
||||
blob2 = closing_encode(tag1)
|
||||
if _debug: closing_endec._debug(" - blob2: %r", blob2)
|
||||
|
||||
# compare the results
|
||||
assert tag1 == tag2
|
||||
assert blob1 == blob2
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def tag(tag_class, tag_number, x):
|
||||
"""Create a tag object with the given class, number, and data."""
|
||||
if _debug: tag._debug("tag %r %r %r", tag_class, tag_number, x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(tag_class, tag_number, len(b), b)
|
||||
if _debug: tag_tuple._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestTag(unittest.TestCase):
|
||||
|
||||
def test_tag(self):
|
||||
if _debug: TestTag._debug("test_tag")
|
||||
|
||||
# test tag construction
|
||||
tag = Tag()
|
||||
assert (tag.tagClass, tag.tagNumber) == (None, None)
|
||||
|
||||
# must have a valid encoded tag to extract from the data
|
||||
data = PDUData(xtob(''))
|
||||
with self.assertRaises(DecodingError):
|
||||
tag = Tag(data)
|
||||
|
||||
# must have two values, class and number
|
||||
with self.assertRaises(ValueError):
|
||||
tag = Tag(0)
|
||||
|
||||
tag = Tag(0, 1)
|
||||
assert (tag.tagClass, tag.tagNumber) == (0, 1)
|
||||
|
||||
tag = Tag(0, 1, 2)
|
||||
assert (tag.tagClass, tag.tagNumber, tag.tagLVT) == (0, 1, 2)
|
||||
|
||||
# tag data must be bytes or bytearray
|
||||
with self.assertRaises(TypeError):
|
||||
tag = Tag(0, 1, 2, 3)
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestApplicationTag(unittest.TestCase):
|
||||
|
||||
def test_application_tag(self):
|
||||
if _debug: TestApplicationTag._debug("test_application_tag")
|
||||
|
||||
# application tag construction, encoding, and decoding
|
||||
tag = ApplicationTag(0, xtob(''))
|
||||
if _debug: TestApplicationTag._debug(" - tag: %r", tag_tuple(tag))
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
tag = ApplicationTag(0)
|
||||
|
||||
def test_generic_application_to_context(self):
|
||||
if _debug: TestApplicationTag._debug("test_generic_application_to_context")
|
||||
|
||||
# create an application
|
||||
tag = ApplicationTag(0, xtob('01'))
|
||||
if _debug: TestApplicationTag._debug(" - tag: %r", tag_tuple(tag))
|
||||
|
||||
# convert it to context tagged, context 0
|
||||
ctag = tag.app_to_context(0)
|
||||
if _debug: TestApplicationTag._debug(" - ctag: %r", tag_tuple(ctag))
|
||||
|
||||
# create a context tag with the same shape
|
||||
ttag = ContextTag(0, xtob('01'))
|
||||
if _debug: TestApplicationTag._debug(" - ttag: %r", tag_tuple(ttag))
|
||||
|
||||
# check to see they are the same
|
||||
assert ctag == ttag
|
||||
|
||||
# convert the context tag back to an application tag
|
||||
dtag = ctag.context_to_app(0)
|
||||
if _debug: TestApplicationTag._debug(" - dtag: %r", tag_tuple(dtag))
|
||||
|
||||
# check to see it round-tripped
|
||||
assert dtag == tag
|
||||
|
||||
def test_boolean_application_to_context(self):
|
||||
if _debug: TestApplicationTag._debug("test_boolean_application_to_context")
|
||||
|
||||
# create an application
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0)
|
||||
if _debug: TestApplicationTag._debug(" - tag: %r", tag_tuple(tag))
|
||||
|
||||
# convert it to context tagged, context 0
|
||||
ctag = tag.app_to_context(0)
|
||||
if _debug: TestApplicationTag._debug(" - ctag: %r", tag_tuple(ctag))
|
||||
|
||||
# create a context tag with the same shape
|
||||
ttag = ContextTag(0, xtob('00'))
|
||||
if _debug: TestApplicationTag._debug(" - ttag: %r", tag_tuple(ttag))
|
||||
|
||||
# check to see they are the same
|
||||
assert ctag == ttag
|
||||
|
||||
# convert the context tag back to an application tag
|
||||
dtag = ctag.context_to_app(Tag.booleanAppTag)
|
||||
if _debug: TestApplicationTag._debug(" - dtag: %r", tag_tuple(dtag))
|
||||
|
||||
# check to see it round-tripped
|
||||
assert dtag == tag
|
||||
|
||||
def test_boolean_application_to_object(self):
|
||||
if _debug: TestApplicationTag._debug("test_boolean_application_to_object")
|
||||
|
||||
# null
|
||||
obj_endec(Null(), '00')
|
||||
|
||||
# boolean
|
||||
obj_endec(Boolean(True), '11')
|
||||
obj_endec(Boolean(False), '10')
|
||||
|
||||
# unsigned
|
||||
obj_endec(Unsigned(0), '2100')
|
||||
obj_endec(Unsigned(1), '2101')
|
||||
obj_endec(Unsigned(127), '217F')
|
||||
obj_endec(Unsigned(128), '2180')
|
||||
|
||||
# integer
|
||||
obj_endec(Integer(0), '3100')
|
||||
obj_endec(Integer(1), '3101')
|
||||
obj_endec(Integer(-1), '31FF')
|
||||
obj_endec(Integer(128), '320080')
|
||||
obj_endec(Integer(-128), '3180')
|
||||
|
||||
# real
|
||||
obj_endec(Real(0), '4400000000')
|
||||
obj_endec(Real(1), '443F800000')
|
||||
obj_endec(Real(-1), '44BF800000')
|
||||
obj_endec(Real(73.5), '4442930000')
|
||||
|
||||
# double
|
||||
obj_endec(Double(0), '55080000000000000000')
|
||||
obj_endec(Double(1), '55083FF0000000000000')
|
||||
obj_endec(Double(-1), '5508BFF0000000000000')
|
||||
obj_endec(Double(73.5), '55084052600000000000')
|
||||
|
||||
# octet string
|
||||
obj_endec(OctetString(xtob('')), '60')
|
||||
obj_endec(OctetString(xtob('01')), '6101')
|
||||
obj_endec(OctetString(xtob('0102')), '620102')
|
||||
obj_endec(OctetString(xtob('010203040506')), '6506010203040506')
|
||||
|
||||
# character string
|
||||
obj_endec(CharacterString(''), '7100')
|
||||
obj_endec(CharacterString('a'), '720061')
|
||||
obj_endec(CharacterString('abcde'), '7506006162636465')
|
||||
|
||||
# bit string
|
||||
obj_endec(BitString([]), '8100')
|
||||
obj_endec(BitString([0]), '820700')
|
||||
obj_endec(BitString([1]), '820780')
|
||||
obj_endec(BitString([1, 1, 1, 1, 1]), '8203F8')
|
||||
obj_endec(BitString([1] * 10), '8306FFC0')
|
||||
|
||||
# enumerated
|
||||
obj_endec(Enumerated(0), '9100')
|
||||
obj_endec(Enumerated(1), '9101')
|
||||
obj_endec(Enumerated(127), '917F')
|
||||
obj_endec(Enumerated(128), '9180')
|
||||
|
||||
# date
|
||||
obj_endec(Date((1,2,3,4)), 'A401020304')
|
||||
obj_endec(Date((255,2,3,4)), 'A4FF020304')
|
||||
obj_endec(Date((1,255,3,4)), 'A401FF0304')
|
||||
obj_endec(Date((1,2,255,4)), 'A40102FF04')
|
||||
obj_endec(Date((1,2,3,255)), 'A4010203FF')
|
||||
|
||||
# time
|
||||
obj_endec(Time((1,2,3,4)), 'B401020304')
|
||||
obj_endec(Time((255,2,3,4)), 'B4FF020304')
|
||||
obj_endec(Time((1,255,3,4)), 'B401FF0304')
|
||||
obj_endec(Time((1,2,255,4)), 'B40102FF04')
|
||||
obj_endec(Time((1,2,3,255)), 'B4010203FF')
|
||||
|
||||
# object identifier
|
||||
obj_endec(ObjectIdentifier(0,0), 'C400000000')
|
||||
obj_endec(ObjectIdentifier(1,0), 'C400400000')
|
||||
obj_endec(ObjectIdentifier(0,2), 'C400000002')
|
||||
obj_endec(ObjectIdentifier(3,4), 'C400C00004')
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestContextTag(unittest.TestCase):
|
||||
|
||||
def test_context_tag(self):
|
||||
if _debug: TestContextTag._debug("test_context_tag")
|
||||
|
||||
# test context tag construction
|
||||
tag = ContextTag(0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
tag = ContextTag()
|
||||
|
||||
# test encoding and decoding
|
||||
context_endec(0, '', '08')
|
||||
context_endec(1, '01', '1901')
|
||||
context_endec(2, '0102', '2A0102')
|
||||
context_endec(3, '010203', '3B010203')
|
||||
context_endec(14, '010203', 'EB010203')
|
||||
context_endec(15, '010203', 'FB0F010203')
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestOpeningTag(unittest.TestCase):
|
||||
|
||||
def test_opening_tag(self):
|
||||
if _debug: TestOpeningTag._debug("test_opening_tag")
|
||||
|
||||
# test opening tag construction
|
||||
tag = OpeningTag(0)
|
||||
with self.assertRaises(TypeError):
|
||||
tag = OpeningTag()
|
||||
|
||||
# test encoding, and decoding
|
||||
opening_endec(0, '0E')
|
||||
opening_endec(1, '1E')
|
||||
opening_endec(2, '2E')
|
||||
opening_endec(3, '3E')
|
||||
opening_endec(14, 'EE')
|
||||
opening_endec(15, 'FE0F')
|
||||
opening_endec(254, 'FEFE')
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestClosingTag(unittest.TestCase):
|
||||
|
||||
def test_closing_tag(self):
|
||||
if _debug: TestClosingTag._debug("test_closing_tag")
|
||||
|
||||
# test closing tag construction
|
||||
tag = ClosingTag(0)
|
||||
with self.assertRaises(TypeError):
|
||||
tag = ClosingTag()
|
||||
|
||||
# test encoding, and decoding
|
||||
closing_endec(0, '0F')
|
||||
closing_endec(1, '1F')
|
||||
closing_endec(2, '2F')
|
||||
closing_endec(3, '3F')
|
||||
closing_endec(14, 'EF')
|
||||
closing_endec(15, 'FF0F')
|
||||
closing_endec(254, 'FFFE')
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestTagList(unittest.TestCase):
|
||||
|
||||
def test_tag_list(self):
|
||||
if _debug: TestTagList._debug("test_tag_list")
|
||||
|
||||
# test tag list construction
|
||||
tag_list = TagList()
|
||||
tag_list = TagList([])
|
||||
|
||||
def test_peek(self):
|
||||
if _debug: TestTagList._debug("test_peek")
|
||||
|
||||
tag0 = IntegerTag(0)
|
||||
taglist = TagList([tag0])
|
||||
|
||||
# peek at the first tag
|
||||
assert tag0 == taglist.Peek()
|
||||
|
||||
# pop of the front
|
||||
tag1 = taglist.Pop()
|
||||
assert taglist.tagList == []
|
||||
|
||||
# push it back on the front
|
||||
taglist.push(tag1)
|
||||
assert taglist.tagList == [tag1]
|
||||
|
||||
def test_get_context(self):
|
||||
"""Test extracting specific context encoded content.
|
||||
"""
|
||||
if _debug: TestTagList._debug("test_get_context")
|
||||
|
||||
tag_list_data = [
|
||||
ContextTag(0, xtob('00')),
|
||||
ContextTag(1, xtob('01')),
|
||||
OpeningTag(2),
|
||||
IntegerTag(3),
|
||||
OpeningTag(0),
|
||||
IntegerTag(4),
|
||||
ClosingTag(0),
|
||||
ClosingTag(2),
|
||||
]
|
||||
taglist = TagList(tag_list_data)
|
||||
|
||||
# known to be a simple context encoded element
|
||||
context_0 = taglist.get_context(0)
|
||||
if _debug: TestTagList._debug(" - context_0: %r", context_0)
|
||||
assert context_0 == tag_list_data[0]
|
||||
|
||||
# known to be a simple context encoded list of element(s)
|
||||
context_2 = taglist.get_context(2)
|
||||
if _debug: TestTagList._debug(" - context_2: %r", context_2)
|
||||
assert context_2.tagList == tag_list_data[3:7]
|
||||
|
||||
# known missing context
|
||||
context_3 = taglist.get_context(3)
|
||||
if _debug: TestTagList._debug(" - context_3: %r", context_3)
|
||||
assert taglist.get_context(3) is None
|
||||
|
||||
def test_endec_0(self):
|
||||
"""Test empty tag list encoding and decoding.
|
||||
"""
|
||||
if _debug: TestTagList._debug("test_endec_0")
|
||||
|
||||
taglist = TagList([])
|
||||
|
||||
data = PDUData()
|
||||
taglist.encode(data)
|
||||
assert data.pduData == xtob('')
|
||||
|
||||
taglist = TagList()
|
||||
taglist.decode(data)
|
||||
assert taglist.tagList == []
|
||||
|
||||
def test_endec_1(self):
|
||||
"""Test short tag list encoding and decoding, application tags.
|
||||
"""
|
||||
if _debug: TestTagList._debug("test_endec_1")
|
||||
|
||||
tag0 = IntegerTag(0x00)
|
||||
tag1 = IntegerTag(0x01)
|
||||
taglist = TagList([tag0, tag1])
|
||||
|
||||
data = PDUData()
|
||||
taglist.encode(data)
|
||||
assert data.pduData == xtob('31003101')
|
||||
|
||||
taglist = TagList()
|
||||
taglist.decode(data)
|
||||
assert taglist.tagList == [tag0, tag1]
|
||||
|
||||
def test_endec_2(self):
|
||||
"""Test short tag list encoding and decoding, context tags.
|
||||
"""
|
||||
if _debug: TestTagList._debug("test_endec_2")
|
||||
|
||||
tag0 = ContextTag(0, xtob('00'))
|
||||
tag1 = ContextTag(1, xtob('01'))
|
||||
taglist = TagList([tag0, tag1])
|
||||
|
||||
data = PDUData()
|
||||
taglist.encode(data)
|
||||
assert data.pduData == xtob('09001901')
|
||||
|
||||
taglist = TagList()
|
||||
taglist.decode(data)
|
||||
assert taglist.tagList == [tag0, tag1]
|
||||
|
||||
def test_endec_3(self):
|
||||
"""Test bracketed application tagged integer encoding and decoding."""
|
||||
if _debug: TestTagList._debug("test_endec_2")
|
||||
|
||||
tag0 = OpeningTag(0)
|
||||
tag1 = IntegerTag(0x0102)
|
||||
tag2 = ClosingTag(0)
|
||||
taglist = TagList([tag0, tag1, tag2])
|
||||
|
||||
data = PDUData()
|
||||
taglist.encode(data)
|
||||
assert data.pduData == xtob('0E3201020F')
|
||||
|
||||
taglist = TagList()
|
||||
taglist.decode(data)
|
||||
assert taglist.tagList == [tag0, tag1, tag2]
|
|
@ -0,0 +1,142 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Test Primitive Data Time
|
||||
---------------------------
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import Time, Tag
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
_log = ModuleLogger(globals())
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def time_tag(x):
|
||||
"""Convert a hex string to an time application tag."""
|
||||
if _debug: time_tag._debug("time_tag %r", x)
|
||||
|
||||
b = xtob(x)
|
||||
tag = Tag(Tag.applicationTagClass, Tag.timeAppTag, len(b), b)
|
||||
if _debug: time_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
@bacpypes_debugging
|
||||
def time_encode(obj):
|
||||
"""Encode an Time object into a tag."""
|
||||
if _debug: time_encode._debug("time_encode %r", obj)
|
||||
|
||||
tag = Tag()
|
||||
obj.encode(tag)
|
||||
if _debug: time_endec._debug(" - tag: %r", tag)
|
||||
|
||||
return tag
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def time_decode(tag):
|
||||
"""Decode an time application tag into an time."""
|
||||
if _debug: time_decode._debug("time_decode %r", tag)
|
||||
|
||||
obj = Time(tag)
|
||||
if _debug: time_decode._debug(" - obj: %r", obj)
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
def time_endec(v, x):
|
||||
"""Pass the value to Time, construct a tag from the hex string,
|
||||
and compare results of encode and decoding each other."""
|
||||
if _debug: time_endec._debug("time_endec %r %r", v, x)
|
||||
|
||||
tag = time_tag(x)
|
||||
if _debug: time_endec._debug(" - tag: %r, %r", tag, tag.tagData)
|
||||
|
||||
obj = Time(v)
|
||||
if _debug: time_endec._debug(" - obj: %r, %r", obj, obj.value)
|
||||
|
||||
assert time_encode(obj) == tag
|
||||
assert time_decode(tag) == obj
|
||||
|
||||
|
||||
@bacpypes_debugging
|
||||
class TestTime(unittest.TestCase):
|
||||
|
||||
def test_time(self):
|
||||
if _debug: TestTime._debug("test_time")
|
||||
|
||||
# default values is all dont care
|
||||
obj = Time()
|
||||
assert obj.value == (255, 255, 255, 255)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
Time("some string")
|
||||
with self.assertRaises(TypeError):
|
||||
Time(1.0)
|
||||
|
||||
def test_time_tuple(self):
|
||||
if _debug: TestTime._debug("test_time_tuple")
|
||||
|
||||
obj = Time((1,2,3,4))
|
||||
assert obj.value == (1, 2, 3, 4)
|
||||
assert str(obj) == "Time(01:02:03.04)"
|
||||
|
||||
assert Time("1:2").value == (1, 2, 0, 0)
|
||||
assert Time("1:2:3").value == (1, 2, 3, 0)
|
||||
assert Time("1:2:3.4").value == (1, 2, 3, 40)
|
||||
assert Time("1:*").value == (1, 255, 255, 255)
|
||||
assert Time("1:2:*").value == (1, 2, 255, 255)
|
||||
assert Time("1:2:3.*").value == (1, 2, 3, 255)
|
||||
|
||||
def test_time_tag(self):
|
||||
if _debug: TestTime._debug("test_time_tag")
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.timeAppTag, 1, xtob('01020304'))
|
||||
obj = Time(tag)
|
||||
assert obj.value == (1, 2, 3, 4)
|
||||
|
||||
tag = Tag(Tag.applicationTagClass, Tag.booleanAppTag, 0, xtob(''))
|
||||
with self.assertRaises(ValueError):
|
||||
Time(tag)
|
||||
|
||||
tag = Tag(Tag.contextTagClass, 0, 1, xtob('ff'))
|
||||
with self.assertRaises(ValueError):
|
||||
Time(tag)
|
||||
|
||||
tag = Tag(Tag.openingTagClass, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
Time(tag)
|
||||
|
||||
def test_time_copy(self):
|
||||
if _debug: TestTime._debug("test_time_copy")
|
||||
|
||||
time_value = (2, 3, 4, 5)
|
||||
obj1 = Time(time_value)
|
||||
obj2 = Time(obj1)
|
||||
assert obj2.value == time_value
|
||||
|
||||
def test_time_now(self):
|
||||
if _debug: TestTime._debug("test_time_now")
|
||||
|
||||
# obj = Time().now()
|
||||
### how to test?
|
||||
|
||||
def test_time_endec(self):
|
||||
if _debug: TestTime._debug("test_time_endec")
|
||||
|
||||
### this should raise a decoding error
|
||||
# with self.assertRaises(IndexError):
|
||||
# obj = Time(time_tag(''))
|
||||
|
||||
time_endec((0, 0, 0, 0), '00000000')
|
||||
time_endec((1, 0, 0, 0), '01000000')
|
||||
time_endec((0, 2, 0, 0), '00020000')
|
||||
time_endec((0, 0, 3, 0), '00000300')
|
||||
time_endec((0, 0, 0, 4), '00000004')
|
|
@ -9,7 +9,7 @@ Test Primitive Data Unsigned
|
|||
import unittest
|
||||
|
||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||
from bacpypes.primitivedata import Unsigned, Tag
|
||||
from bacpypes.primitivedata import Unsigned, Tag, DecodingError
|
||||
|
||||
# some debugging
|
||||
_debug = 0
|
||||
|
@ -119,7 +119,7 @@ class TestUnsigned(unittest.TestCase):
|
|||
def test_unsigned_endec(self):
|
||||
if _debug: TestUnsigned._debug("test_unsigned_endec")
|
||||
|
||||
# with self.assertRaises(IndexError):
|
||||
# with self.assertRaises(DecodingError):
|
||||
# obj = Unsigned(unsigned_tag(''))
|
||||
|
||||
unsigned_endec(0, '00')
|
||||
|
|
Loading…
Reference in New Issue
Block a user