test suite: fixed issues, started working on nodo

This commit is contained in:
Edwin Eefting
2018-01-21 01:53:22 +01:00
parent 1250e09fef
commit f69b84d24b
7 changed files with 137 additions and 58 deletions
+4 -1
View File
@@ -27,8 +27,11 @@ nodes=[
]
#an mqtt broker that both ESPEasy and the test suite are connecting to
mqtt_broker="192.168.13.236"
mqtt_port=1883
#ip of the server running this script
http_server="192.168.13.236"
test_server="192.168.13.236"
http_port=8080
linebased_port=8181
+56 -7
View File
@@ -5,7 +5,7 @@ import threading
from queue import Queue
from logging import getLogger
import time
import re
SENSOR_TYPE_SINGLE = 1
SENSOR_TYPE_TEMP_HUM = 2
@@ -28,6 +28,7 @@ class ControllerEmu:
self.log=logging.getLogger("controller")
self.start_mqtt()
self.start_http()
self.start_linebased()
def start_mqtt(self):
@@ -67,6 +68,8 @@ class ControllerEmu:
logging.getLogger("http").debug(bottle.request.method+" "+str(dict(bottle.request.params)))
self.http_requests.put(bottle.request.copy())
http_thread=threading.Thread(target=bottle.run, kwargs=dict(host='0.0.0.0', port=config.http_port, reloader=False))
http_thread.daemon=True
http_thread.start()
@@ -78,6 +81,49 @@ class ControllerEmu:
self.http_requests.get()
def start_linebased(self):
"""generic linebased receiver (like telnet). for nodo plugin"""
import socket
import sys
self.linebased_lines=Queue()
def handle_connect(connection, client_address):
logging.getLogger("linebased").debug("Connect from "+str(client_address))
fh = connection.makefile()
for line in fh:
line=line.rstrip()
logging.getLogger("linebased").debug("Recv from "+str(client_address)+" :"+line)
self.linebased_lines.put( ( client_address, line ) )
logging.getLogger("linebased").debug("Disconnect from "+str(client_address))
def wait_accept():
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('', config.linebased_port)
sock.bind(server_address)
sock.listen()
while True:
# Wait for a connection
connection, client_address = sock.accept()
connect_thread=threading.Thread(target=handle_connect, kwargs=dict(connection=connection, client_address=client_address))
connect_thread.daemon=True
connect_thread.start()
accept_thread=threading.Thread(target=wait_accept)
accept_thread.daemon=True
accept_thread.start()
def clear_linebased(self):
"""clear queue"""
while not self.linebased_lines.empty():
self.linebased_lines.get()
def recv_domoticz_http(self, sensor_type, idx, timeout=60):
@@ -94,7 +140,10 @@ class ControllerEmu:
if request.path == "/json.htm":
if int(request.params.get('idx'))==idx:
if request.params.get('param')=='udevice':
svalues_str=request.params.get('svalue').split(";")
# svalues_str=request.params.get('svalue').split(";")
#nooozzz..the ; isnt properly escaped so python only returns the first value. woraround:
svalues_str=re.findall('svalue=([0-9.;]*)',request.query_string)[0].split(";")
svalues=[]
for svalue in svalues_str:
try:
@@ -108,13 +157,13 @@ class ControllerEmu:
elif sensor_type==SENSOR_TYPE_DUAL and len(svalues)==2:
return svalues
elif sensor_type==SENSOR_TYPE_TEMP_HUM and len(svalues)==3:
return svalues
elif sensor_type==SENSOR_TYPE_BARO and len(svalues)==5:
return [svalues[0], svalues[1]]
elif sensor_type==SENSOR_TYPE_TEMP_BARO and len(svalues)==5:
return [svalues[0], svalues[3]]
elif sensor_type==SENSOR_TYPE_TRIPLE and len(svalues)==3:
return svalues
elif sensor_type==SENSOR_TYPE_TEMHUM_BARO and len(svalues)==5:
return [svalues[0],svalues[2], svalues[3]]
elif sensor_type==SENSOR_TYPE_TEMP_HUM_BARO and len(svalues)==5:
return [svalues[0],svalues[1], svalues[3]]
elif sensor_type==SENSOR_TYPE_QUAD and len(svalues)==4:
return svalues
elif sensor_type==SENSOR_TYPE_WIND and len(svalues)==6:
@@ -127,7 +176,7 @@ class ControllerEmu:
elif request.params.get('switchcmd') == 'On':
return [1]
elif request.params.get('switchcmd') == 'Set Level':
return [int(request.params.get('level'))]
return [float(request.params.get('level'))]
raise(Exception("Timeout"))
+26 -5
View File
@@ -25,7 +25,7 @@ class EspEasy:
)
def controller_domoticz_mqtt(self, controllerip=config.mqtt_broker, **kwargs):
def controller_domoticz_mqtt(self, controllerip=config.mqtt_broker, controllerport=config.mqtt_port, **kwargs):
"""config controller to use domoticz via mqtt"""
self._node.log.info("Configuring controller domoticz mqtt "+str(kwargs))
@@ -41,17 +41,17 @@ class EspEasy:
protocol:2
usedns:0
controllerip:{controllerip}
controllerport:1883
controllerport:{controllerport}
controlleruser:
controllerpassword:
controllersubscribe:domoticz/out
controllerpublish:domoticz/in
controllerenabled:on
""".format(controllerip=controllerip,**kwargs)
""".format(controllerip=controllerip, controllerport=controllerport, **kwargs)
)
def controller_domoticz_http(self, **kwargs):
def controller_domoticz_http(self, controllerip=config.test_server, controllerport=config.http_port, **kwargs):
"""config controller to use domoticz via http"""
self._node.log.info("Configuring controller domoticz http "+str(kwargs))
@@ -71,10 +71,31 @@ class EspEasy:
controlleruser:
controllerpassword:
controllerenabled:on
""".format(**kwargs)
""".format(controllerip=controllerip, controllerport=controllerport, **kwargs)
)
def controller_nodo(self, controllerip=config.test_server, controllerport=config.linebased_port, **kwargs):
"""config controller to use nodo"""
self._node.log.info("Configuring controller nodo "+str(kwargs))
self._node.http_post(
twice=True, # needed for controllers and devices because of the way its implemented
page="controllers",
params="""
index:{index}
""".format(**kwargs),
data="""
protocol:3
usedns:0
controllerip:{controllerip}
controllerport:{controllerport}
controllerpassword:
controllerenabled:on
""".format(controllerip=controllerip, controllerport=controllerport,**kwargs)
)
+46 -32
View File
@@ -26,7 +26,7 @@ for n in config.nodes:
espeasy.append(EspEasy(node[-1]))
steps=[]
# steps=[]
log=logging.getLogger("esptest")
@@ -35,6 +35,7 @@ log=logging.getLogger("esptest")
controller=ControllerEmu()
### keep test state, so we can skip tests.
global state
state={
'module': None,
'name': None,
@@ -42,47 +43,60 @@ state={
}
with shelve.open("test.state") as shelve_db:
if 'state' in shelve_db:
global state
state=shelve_db['state']
def step(title=""):
def step_dec(step):
def step_dec(test):
"""add test step. test can resume from every test-step"""
if state['module'] and ( state['module'] != step.__module__ or state['name'] != step.__name__ or state['title'] != title):
log.debug("Skipping step "+title+": "+step.__module__ + "." + step.__name__ )
if state['module'] and ( state['module'] != test.__module__ or state['name'] != test.__name__ or state['title'] != title):
log.debug("Skipping test "+title+": "+test.__module__ + "." + test.__name__ )
else:
step.title=title
steps.append(step)
# add the rest of the steps as well
state['module']=None
print()
log.info("*** Starting "+title+": "+test.__module__ + "." + test.__name__ )
# store this test so we may resume later
with shelve.open("test.state") as shelve_db:
shelve_db['state']={
'module': test.__module__,
'name': test.__name__,
'title': title
}
#run the test. if there is an exception we resume this test the next time
test()
return(step_dec)
### run all the tests
def run():
"""run all tests"""
for step in steps:
print()
log.info("*** Starting "+step.title+": "+step.__module__ + "." + step.__name__ )
# store this step so we may resume later
state['module']=step.__module__
state['name']=step.__name__
state['title']=step.title
with shelve.open("test.state") as shelve_db:
shelve_db['state']=state
#run the step. if there is an exception we resume this step the next time
step()
# log.info("Completed step")
# all Completed
os.unlink("test.state")
log.info("*** All tests complete ***")
# ### run all the tests
# def run():
# """run all tests"""
#
# for step in steps:
# print()
# log.info("*** Starting "+step.title+": "+step.__module__ + "." + step.__name__ )
#
# # store this step so we may resume later
# state['module']=step.__module__
# state['name']=step.__name__
# state['title']=step.title
# with shelve.open("test.state") as shelve_db:
# shelve_db['state']=state
#
# #run the step. if there is an exception we resume this step the next time
# step()
#
#
# # log.info("Completed step")
#
# # all Completed
# os.unlink("test.state")
# log.info("*** All tests complete ***")
### auxillary test functions
+2 -2
View File
@@ -11,7 +11,7 @@ from esptest import *
# - correct values are send to domoticz via mqtt
# - test if powercycle value is valid (https://github.com/letscontrolit/ESPEasy/issues/719)
# espeasy[0].controller_thingspeak(index=1, controllerip=config.http_server, controllerport=config.http_port)
# espeasy[0].controller_thingspeak(index=1, controllerip=config.test_server, controllerport=config.http_port)
@step
@@ -24,7 +24,7 @@ def prepare_devices():
@step
def test_domoticz_http():
espeasy[0].controller_domoticz_http(index=1, controllerip=config.http_server, controllerport=config.http_port)
espeasy[0].controller_domoticz_http(index=1, controllerip=config.test_server, controllerport=config.http_port)
results=controller.recv_domoticz_http(SENSOR_TYPE_SINGLE,2001)
test_in_range(results[0], -5,40)
results=controller.recv_domoticz_http(SENSOR_TYPE_SINGLE,2002)
+1 -5
View File
@@ -14,6 +14,7 @@ from esptest import *
def prepare():
node[0].reboot()
node[0].pingserial()
node[0].serialcmd("resetFlashWriteCounter")
espeasy[0].controller_domoticz_mqtt(index=1, controllerip=config.mqtt_broker)
espeasy[0].device_p005(index=1, TDID1=4001)
@@ -23,8 +24,3 @@ def test():
results=controller.recv_domoticz_mqtt(SENSOR_TYPE_TEMP_HUM,4001)
test_in_range(results[0], -5,40)
test_in_range(results[1], 10,80)
run()
+2 -6
View File
@@ -8,7 +8,6 @@ from esptest import *
# tests:
# - sending all data types for all controllers, using dummy devices
@step()
def prepare():
node[0].reboot()
@@ -18,8 +17,9 @@ def prepare():
#traverse most controllers
for ( title, controller_config, controller_recv ) in [
("Domoticz MQTT", espeasy[0].controller_domoticz_mqtt, controller.recv_domoticz_mqtt ),
("Domoticz HTTP", espeasy[0].controller_domoticz_http, controller.recv_domoticz_http ),
("Domoticz MQTT", espeasy[0].controller_domoticz_mqtt, controller.recv_domoticz_mqtt )]:
]:
@step(title)
@@ -136,7 +136,3 @@ for ( title, controller_config, controller_recv ) in [
node[0].serialcmd("TaskValueSet 1,3,5024")
results=controller_recv(SENSOR_TYPE_WIND,5000)
test_is(results, [ 5022, 5023, 5024 ])
run()