mirror of
https://github.com/JoelBender/bacpypes
synced 2025-09-28 22:15:23 +08:00
shuffle some pieces around, add some more tests
This commit is contained in:
parent
ef0f012ead
commit
dd0a519021
|
@ -13,8 +13,10 @@ from bacpypes.vlan import Network, Node
|
||||||
from bacpypes.app import Application
|
from bacpypes.app import Application
|
||||||
from bacpypes.appservice import StateMachineAccessPoint, ApplicationServiceAccessPoint
|
from bacpypes.appservice import StateMachineAccessPoint, ApplicationServiceAccessPoint
|
||||||
from bacpypes.netservice import NetworkServiceAccessPoint, NetworkServiceElement
|
from bacpypes.netservice import NetworkServiceAccessPoint, NetworkServiceElement
|
||||||
|
from bacpypes.service.device import LocalDeviceObject
|
||||||
|
|
||||||
from ..state_machine import StateMachine
|
from ..state_machine import StateMachine, StateMachineGroup
|
||||||
|
from ..time_machine import reset_time_machine, run_time_machine
|
||||||
|
|
||||||
|
|
||||||
# some debugging
|
# some debugging
|
||||||
|
@ -22,6 +24,71 @@ _debug = 0
|
||||||
_log = ModuleLogger(globals())
|
_log = ModuleLogger(globals())
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# ApplicationNetwork
|
||||||
|
#
|
||||||
|
|
||||||
|
@bacpypes_debugging
|
||||||
|
class ApplicationNetwork(StateMachineGroup):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
if _debug: ApplicationNetwork._debug("__init__")
|
||||||
|
StateMachineGroup.__init__(self)
|
||||||
|
|
||||||
|
# reset the time machine
|
||||||
|
reset_time_machine()
|
||||||
|
if _debug: ApplicationNetwork._debug(" - time machine reset")
|
||||||
|
|
||||||
|
# make a little LAN
|
||||||
|
self.vlan = Network(broadcast_address=LocalBroadcast())
|
||||||
|
|
||||||
|
# test device object
|
||||||
|
td_device_object = LocalDeviceObject(
|
||||||
|
objectName="td",
|
||||||
|
objectIdentifier=("device", 10),
|
||||||
|
maxApduLengthAccepted=1024,
|
||||||
|
segmentationSupported='noSegmentation',
|
||||||
|
vendorIdentifier=999,
|
||||||
|
)
|
||||||
|
|
||||||
|
# test device
|
||||||
|
self.td = ApplicationNode(td_device_object, self.vlan)
|
||||||
|
self.append(self.td)
|
||||||
|
|
||||||
|
# implementation under test device object
|
||||||
|
iut_device_object = LocalDeviceObject(
|
||||||
|
objectName="iut",
|
||||||
|
objectIdentifier=("device", 20),
|
||||||
|
maxApduLengthAccepted=1024,
|
||||||
|
segmentationSupported='noSegmentation',
|
||||||
|
vendorIdentifier=999,
|
||||||
|
)
|
||||||
|
|
||||||
|
# implementation under test
|
||||||
|
self.iut = ApplicationNode(iut_device_object, self.vlan)
|
||||||
|
self.append(self.iut)
|
||||||
|
|
||||||
|
def run(self, time_limit=60.0):
|
||||||
|
if _debug: ApplicationNetwork._debug("run %r", time_limit)
|
||||||
|
|
||||||
|
# run the group
|
||||||
|
super(ApplicationNetwork, self).run()
|
||||||
|
if _debug: ApplicationNetwork._debug(" - group running")
|
||||||
|
|
||||||
|
# run it for some time
|
||||||
|
run_time_machine(time_limit)
|
||||||
|
if _debug:
|
||||||
|
ApplicationNetwork._debug(" - time machine finished")
|
||||||
|
for state_machine in self.state_machines:
|
||||||
|
ApplicationNetwork._debug(" - machine: %r", state_machine)
|
||||||
|
for direction, pdu in state_machine.transaction_log:
|
||||||
|
ApplicationNetwork._debug(" %s %s", direction, str(pdu))
|
||||||
|
|
||||||
|
# check for success
|
||||||
|
all_success, some_failed = super(ApplicationNetwork, self).check_for_success()
|
||||||
|
assert all_success
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# SnifferNode
|
# SnifferNode
|
||||||
#
|
#
|
||||||
|
@ -29,15 +96,17 @@ _log = ModuleLogger(globals())
|
||||||
@bacpypes_debugging
|
@bacpypes_debugging
|
||||||
class SnifferNode(Client, StateMachine):
|
class SnifferNode(Client, StateMachine):
|
||||||
|
|
||||||
def __init__(self, localAddress, vlan):
|
def __init__(self, vlan):
|
||||||
if _debug: SnifferNode._debug("__init__ %r %r", localAddress, vlan)
|
if _debug: SnifferNode._debug("__init__ %r", vlan)
|
||||||
|
|
||||||
|
# save the name and give it a blank address
|
||||||
|
self.name = "sniffer"
|
||||||
|
self.address = Address()
|
||||||
|
|
||||||
|
# continue with initialization
|
||||||
Client.__init__(self)
|
Client.__init__(self)
|
||||||
StateMachine.__init__(self)
|
StateMachine.__init__(self)
|
||||||
|
|
||||||
# save the name and address
|
|
||||||
self.name = "sniffer"
|
|
||||||
self.address = localAddress
|
|
||||||
|
|
||||||
# create a promiscuous node, added to the network
|
# create a promiscuous node, added to the network
|
||||||
self.node = Node(self.address, vlan, promiscuous=True)
|
self.node = Node(self.address, vlan, promiscuous=True)
|
||||||
if _debug: SnifferNode._debug(" - node: %r", self.node)
|
if _debug: SnifferNode._debug(" - node: %r", self.node)
|
||||||
|
@ -63,14 +132,16 @@ class SnifferNode(Client, StateMachine):
|
||||||
@bacpypes_debugging
|
@bacpypes_debugging
|
||||||
class ApplicationNode(Application, StateMachine):
|
class ApplicationNode(Application, StateMachine):
|
||||||
|
|
||||||
def __init__(self, localDevice, localAddress, vlan):
|
def __init__(self, localDevice, vlan):
|
||||||
if _debug: ApplicationNode._debug("__init__ %r %r %r", localDevice, localAddress, vlan)
|
if _debug: ApplicationNode._debug("__init__ %r %r", localDevice, vlan)
|
||||||
Application.__init__(self, localDevice, localAddress)
|
|
||||||
StateMachine.__init__(self)
|
|
||||||
|
|
||||||
# save the name and address
|
# save the name and address
|
||||||
self.name = localDevice.objectName
|
self.name = localDevice.objectName
|
||||||
self.address = localAddress
|
self.address = Address(localDevice.objectIdentifier[1])
|
||||||
|
|
||||||
|
# continue with initialization
|
||||||
|
Application.__init__(self, localDevice, self.address)
|
||||||
|
StateMachine.__init__(self)
|
||||||
|
|
||||||
# include a application decoder
|
# include a application decoder
|
||||||
self.asap = ApplicationServiceAccessPoint()
|
self.asap = ApplicationServiceAccessPoint()
|
||||||
|
|
|
@ -11,91 +11,18 @@ import unittest
|
||||||
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
from bacpypes.debugging import bacpypes_debugging, ModuleLogger, xtob
|
||||||
|
|
||||||
from bacpypes.pdu import Address, LocalBroadcast, PDU
|
from bacpypes.pdu import Address, LocalBroadcast, PDU
|
||||||
from bacpypes.apdu import WhoIsRequest, IAmRequest
|
from bacpypes.apdu import WhoIsRequest, IAmRequest, \
|
||||||
|
WhoHasRequest, WhoHasLimits, WhoHasObject, IHaveRequest
|
||||||
|
|
||||||
from bacpypes.vlan import Network
|
from bacpypes.service.device import WhoIsIAmServices, WhoHasIHaveServices
|
||||||
from bacpypes.service.device import LocalDeviceObject, WhoIsIAmServices
|
|
||||||
|
|
||||||
from ..state_machine import match_pdu, StateMachineGroup
|
from .helpers import ApplicationNetwork, ApplicationNode
|
||||||
from ..time_machine import reset_time_machine, run_time_machine
|
|
||||||
|
|
||||||
from .helpers import SnifferNode, ApplicationNode
|
|
||||||
|
|
||||||
# some debugging
|
# some debugging
|
||||||
_debug = 0
|
_debug = 0
|
||||||
_log = ModuleLogger(globals())
|
_log = ModuleLogger(globals())
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# TNetwork
|
|
||||||
#
|
|
||||||
|
|
||||||
@bacpypes_debugging
|
|
||||||
class TNetwork(StateMachineGroup):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if _debug: TNetwork._debug("__init__")
|
|
||||||
StateMachineGroup.__init__(self)
|
|
||||||
|
|
||||||
# reset the time machine
|
|
||||||
reset_time_machine()
|
|
||||||
if _debug: TNetwork._debug(" - time machine reset")
|
|
||||||
|
|
||||||
# make a little LAN
|
|
||||||
self.vlan = Network(broadcast_address=LocalBroadcast())
|
|
||||||
|
|
||||||
# test device object
|
|
||||||
td_device_object = LocalDeviceObject(
|
|
||||||
objectName="td",
|
|
||||||
objectIdentifier=("device", 1),
|
|
||||||
maxApduLengthAccepted=1024,
|
|
||||||
segmentationSupported='noSegmentation',
|
|
||||||
vendorIdentifier=999,
|
|
||||||
)
|
|
||||||
|
|
||||||
# test device
|
|
||||||
self.td = ApplicationNode(td_device_object, Address(1), self.vlan)
|
|
||||||
self.append(self.td)
|
|
||||||
|
|
||||||
# implementation under test device object
|
|
||||||
iut_device_object = LocalDeviceObject(
|
|
||||||
objectName="iut",
|
|
||||||
objectIdentifier=("device", 2),
|
|
||||||
maxApduLengthAccepted=1024,
|
|
||||||
segmentationSupported='noSegmentation',
|
|
||||||
vendorIdentifier=999,
|
|
||||||
)
|
|
||||||
|
|
||||||
# implementation under test
|
|
||||||
self.iut = ApplicationNode(iut_device_object, Address(2), self.vlan)
|
|
||||||
self.append(self.iut)
|
|
||||||
|
|
||||||
# sniffer node
|
|
||||||
self.sniffer = SnifferNode(Address(3), self.vlan)
|
|
||||||
self.append(self.sniffer)
|
|
||||||
|
|
||||||
|
|
||||||
def run(self, time_limit=60.0):
|
|
||||||
if _debug: TNetwork._debug("run %r", time_limit)
|
|
||||||
|
|
||||||
# run the group
|
|
||||||
super(TNetwork, self).run()
|
|
||||||
if _debug: TNetwork._debug(" - group running")
|
|
||||||
|
|
||||||
# run it for some time
|
|
||||||
run_time_machine(time_limit)
|
|
||||||
if _debug:
|
|
||||||
TNetwork._debug(" - time machine finished")
|
|
||||||
for state_machine in self.state_machines:
|
|
||||||
TNetwork._debug(" - machine: %r", state_machine)
|
|
||||||
for direction, pdu in state_machine.transaction_log:
|
|
||||||
TNetwork._debug(" %s %s", direction, str(pdu))
|
|
||||||
|
|
||||||
# check for success
|
|
||||||
all_success, some_failed = super(TNetwork, self).check_for_success()
|
|
||||||
assert all_success
|
|
||||||
|
|
||||||
|
|
||||||
@bacpypes_debugging
|
@bacpypes_debugging
|
||||||
class TestBasic(unittest.TestCase):
|
class TestBasic(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -104,41 +31,168 @@ class TestBasic(unittest.TestCase):
|
||||||
if _debug: TestBasic._debug("test_basic")
|
if _debug: TestBasic._debug("test_basic")
|
||||||
|
|
||||||
# create a network
|
# create a network
|
||||||
tnet = TNetwork()
|
anet = ApplicationNetwork()
|
||||||
|
|
||||||
# all start states are successful
|
# all start states are successful
|
||||||
tnet.td.start_state.success()
|
anet.td.start_state.success()
|
||||||
tnet.iut.start_state.success()
|
anet.iut.start_state.success()
|
||||||
tnet.sniffer.start_state.success()
|
|
||||||
|
|
||||||
# run the group
|
# run the group
|
||||||
tnet.run()
|
anet.run()
|
||||||
|
|
||||||
|
|
||||||
@bacpypes_debugging
|
@bacpypes_debugging
|
||||||
class TestWhoIsIAm(unittest.TestCase):
|
class TestWhoIsIAm(unittest.TestCase):
|
||||||
|
|
||||||
def test_whois(self):
|
def test_whois_unconstrained(self):
|
||||||
"""Test an idle network, nothing happens is success."""
|
"""Test an unconstrained WhoIs, all devices respond."""
|
||||||
if _debug: TestWhoIsIAm._debug("test_whois")
|
if _debug: TestWhoIsIAm._debug("test_whois_unconstrained")
|
||||||
|
|
||||||
# create a network
|
# create a network
|
||||||
tnet = TNetwork()
|
anet = ApplicationNetwork()
|
||||||
|
|
||||||
# add the service capability to the iut
|
# add the service capability to the IUT
|
||||||
tnet.iut.add_capability(WhoIsIAmServices)
|
anet.iut.add_capability(WhoIsIAmServices)
|
||||||
|
|
||||||
# all start states are successful
|
# all start states are successful
|
||||||
tnet.td.start_state.doc("1-1-0") \
|
anet.td.start_state.doc("1-1-0") \
|
||||||
.send(WhoIsRequest(destination=tnet.vlan.broadcast_address)).doc("1-1-1") \
|
.send(WhoIsRequest(destination=anet.vlan.broadcast_address)).doc("1-1-1") \
|
||||||
.receive(IAmRequest, pduSource=tnet.iut.address).doc("1-1-2") \
|
.receive(IAmRequest, pduSource=anet.iut.address).doc("1-1-2") \
|
||||||
.success()
|
.success()
|
||||||
|
|
||||||
# application layer above the iut is idle
|
# no IUT application layer matching
|
||||||
tnet.iut.start_state.success()
|
anet.iut.start_state.success()
|
||||||
|
|
||||||
# no sniffing yet
|
|
||||||
tnet.sniffer.start_state.success()
|
|
||||||
|
|
||||||
# run the group
|
# run the group
|
||||||
tnet.run()
|
anet.run()
|
||||||
|
|
||||||
|
def test_whois_range_below(self):
|
||||||
|
"""Test range below."""
|
||||||
|
if _debug: TestWhoIsIAm._debug("test_whois_range_below")
|
||||||
|
|
||||||
|
# create a network
|
||||||
|
anet = ApplicationNetwork()
|
||||||
|
|
||||||
|
# add the service capability to the iut
|
||||||
|
anet.iut.add_capability(WhoIsIAmServices)
|
||||||
|
|
||||||
|
# all start states are successful
|
||||||
|
anet.td.start_state.doc("2-1-0") \
|
||||||
|
.send(WhoIsRequest(
|
||||||
|
destination=anet.vlan.broadcast_address,
|
||||||
|
deviceInstanceRangeLowLimit=0,
|
||||||
|
deviceInstanceRangeHighLimit=9,
|
||||||
|
)).doc("2-1-1") \
|
||||||
|
.success()
|
||||||
|
|
||||||
|
# no IUT application layer matching
|
||||||
|
anet.iut.start_state.success()
|
||||||
|
|
||||||
|
# run the group
|
||||||
|
anet.run()
|
||||||
|
|
||||||
|
def test_whois_range_above(self):
|
||||||
|
"""Test range above."""
|
||||||
|
if _debug: TestWhoIsIAm._debug("test_whois_range_above")
|
||||||
|
|
||||||
|
# create a network
|
||||||
|
anet = ApplicationNetwork()
|
||||||
|
|
||||||
|
# add the service capability to the iut
|
||||||
|
anet.iut.add_capability(WhoIsIAmServices)
|
||||||
|
|
||||||
|
# all start states are successful
|
||||||
|
anet.td.start_state.doc("3-1-0") \
|
||||||
|
.send(WhoIsRequest(
|
||||||
|
destination=anet.vlan.broadcast_address,
|
||||||
|
deviceInstanceRangeLowLimit=21,
|
||||||
|
deviceInstanceRangeHighLimit=29,
|
||||||
|
)).doc("3-1-1") \
|
||||||
|
.success()
|
||||||
|
|
||||||
|
# no IUT application layer matching
|
||||||
|
anet.iut.start_state.success()
|
||||||
|
|
||||||
|
# run the group
|
||||||
|
anet.run()
|
||||||
|
|
||||||
|
def test_whois_range(self):
|
||||||
|
"""Test a WhoIs, included range."""
|
||||||
|
if _debug: TestWhoIsIAm._debug("test_whois_range")
|
||||||
|
|
||||||
|
# create a network
|
||||||
|
anet = ApplicationNetwork()
|
||||||
|
|
||||||
|
# add the service capability to the IUT
|
||||||
|
anet.iut.add_capability(WhoIsIAmServices)
|
||||||
|
|
||||||
|
# all start states are successful
|
||||||
|
anet.td.start_state.doc("4-1-0") \
|
||||||
|
.send(WhoIsRequest(
|
||||||
|
destination=anet.vlan.broadcast_address,
|
||||||
|
deviceInstanceRangeLowLimit=19,
|
||||||
|
deviceInstanceRangeHighLimit=21,
|
||||||
|
)).doc("4-1-1") \
|
||||||
|
.receive(IAmRequest, pduSource=anet.iut.address).doc("4-1-2") \
|
||||||
|
.success()
|
||||||
|
|
||||||
|
# no IUT application layer matching
|
||||||
|
anet.iut.start_state.success()
|
||||||
|
|
||||||
|
# run the group
|
||||||
|
anet.run()
|
||||||
|
|
||||||
|
|
||||||
|
@bacpypes_debugging
|
||||||
|
class TestWhoHasIHave(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_who_has_object_by_name(self):
|
||||||
|
"""Test an unconstrained WhoIs, all devices respond."""
|
||||||
|
if _debug: TestWhoIsIAm._debug("test_who_has_object_by_name")
|
||||||
|
|
||||||
|
# create a network
|
||||||
|
anet = ApplicationNetwork()
|
||||||
|
|
||||||
|
# add the service capability to the IUT
|
||||||
|
anet.iut.add_capability(WhoHasIHaveServices)
|
||||||
|
|
||||||
|
# all start states are successful
|
||||||
|
anet.td.start_state.doc("5-1-0") \
|
||||||
|
.send(WhoHasRequest(
|
||||||
|
destination=anet.vlan.broadcast_address,
|
||||||
|
object=WhoHasObject(objectName="iut"),
|
||||||
|
)).doc("5-1-1") \
|
||||||
|
.receive(IHaveRequest, pduSource=anet.iut.address).doc("5-1-2") \
|
||||||
|
.success()
|
||||||
|
|
||||||
|
# no IUT application layer matching
|
||||||
|
anet.iut.start_state.success()
|
||||||
|
|
||||||
|
# run the group
|
||||||
|
anet.run()
|
||||||
|
|
||||||
|
def test_who_has_object_by_id(self):
|
||||||
|
"""Test an unconstrained WhoIs, all devices respond."""
|
||||||
|
if _debug: TestWhoIsIAm._debug("test_who_has_object_by_id")
|
||||||
|
|
||||||
|
# create a network
|
||||||
|
anet = ApplicationNetwork()
|
||||||
|
|
||||||
|
# add the service capability to the IUT
|
||||||
|
anet.iut.add_capability(WhoHasIHaveServices)
|
||||||
|
|
||||||
|
# all start states are successful
|
||||||
|
anet.td.start_state.doc("6-1-0") \
|
||||||
|
.send(WhoHasRequest(
|
||||||
|
destination=anet.vlan.broadcast_address,
|
||||||
|
object=WhoHasObject(objectIdentifier=('device', 20)),
|
||||||
|
)).doc("6-1-1") \
|
||||||
|
.receive(IHaveRequest, pduSource=anet.iut.address).doc("6-1-2") \
|
||||||
|
.success()
|
||||||
|
|
||||||
|
# no IUT application layer matching
|
||||||
|
anet.iut.start_state.success()
|
||||||
|
|
||||||
|
# run the group
|
||||||
|
anet.run()
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,8 @@ class SampleOneShotTask(OneShotTask):
|
||||||
self.process_task_called = []
|
self.process_task_called = []
|
||||||
|
|
||||||
def process_task(self):
|
def process_task(self):
|
||||||
if _debug: SampleOneShotTask._debug("process_task @ %r", time_machine.current_time)
|
|
||||||
global time_machine
|
global time_machine
|
||||||
|
if _debug: SampleOneShotTask._debug("process_task @ %r", time_machine.current_time)
|
||||||
|
|
||||||
# add the current time
|
# add the current time
|
||||||
self.process_task_called.append(time_machine.current_time)
|
self.process_task_called.append(time_machine.current_time)
|
||||||
|
@ -81,8 +81,8 @@ sample_task_function_called = []
|
||||||
|
|
||||||
@bacpypes_debugging
|
@bacpypes_debugging
|
||||||
def sample_task_function(*args, **kwargs):
|
def sample_task_function(*args, **kwargs):
|
||||||
if _debug: sample_task_function._debug("sample_task_function %r %r @ %r", args, kwargs, time_machine.current_time)
|
|
||||||
global sample_task_function_called, time_machine
|
global sample_task_function_called, time_machine
|
||||||
|
if _debug: sample_task_function._debug("sample_task_function %r %r @ %r", args, kwargs, time_machine.current_time)
|
||||||
|
|
||||||
# bump the counter
|
# bump the counter
|
||||||
sample_task_function_called.append(time_machine.current_time)
|
sample_task_function_called.append(time_machine.current_time)
|
||||||
|
@ -98,8 +98,8 @@ class SampleRecurringTask(RecurringTask):
|
||||||
self.process_task_called = []
|
self.process_task_called = []
|
||||||
|
|
||||||
def process_task(self):
|
def process_task(self):
|
||||||
if _debug: SampleRecurringTask._debug("process_task @ %r", time_machine.current_time)
|
|
||||||
global time_machine
|
global time_machine
|
||||||
|
if _debug: SampleRecurringTask._debug("process_task @ %r", time_machine.current_time)
|
||||||
|
|
||||||
# add the current time
|
# add the current time
|
||||||
self.process_task_called.append(time_machine.current_time)
|
self.process_task_called.append(time_machine.current_time)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user