mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
test suite: fixed issues, started working on nodo
This commit is contained in:
+4
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user