summaryrefslogtreecommitdiffstats
path: root/ci
diff options
context:
space:
mode:
authorMichael Abel <75477722+abelikt@users.noreply.github.com>2021-04-09 12:20:06 +0200
committerGitHub <noreply@github.com>2021-04-09 12:20:06 +0200
commit9bce25c637b26eff390935999f96265a71b23913 (patch)
tree381e916d6dc54e6cd203c6a20cf589c12d9a8c7b /ci
parentd17d0ad57bcd857fdbfa4c95a3ae7ab096306919 (diff)
[CIT-279] Improve roundtrip test script (#164)
- Add optional command line parameters for size, timeslot size and delay - Increase c8y page size - Adopt user model and use sudo - Add more checks for the c8y response - Remove timezone management and use UTC instead Signed-off-by: Michael Abel <info@abel-ikt.de>
Diffstat (limited to 'ci')
-rwxr-xr-xci/roundtrip_local_to_c8y.py104
1 files changed, 77 insertions, 27 deletions
diff --git a/ci/roundtrip_local_to_c8y.py b/ci/roundtrip_local_to_c8y.py
index e01f2eee..ba68c8b5 100755
--- a/ci/roundtrip_local_to_c8y.py
+++ b/ci/roundtrip_local_to_c8y.py
@@ -3,7 +3,10 @@
"""
This is a hack to do a full roundtrip of data from thin-edge to c8y and back.
-It publishes numbers from 0..19 and expects to read them back from the cloud.
+It publishes a sequence of numbers and expects to read them back from the cloud.
+For thin-edge JSON the sawtooth publisher is used to publish.
+For SmartREST the tedge is used to publish.
+
Call example:
./roundtrip_local_to_c8y.py -m REST -pub ~/thin-edge.io/target/debug/examples/ -u <username> -t <tennant> -pass <pass> -id <id>
@@ -20,49 +23,50 @@ import time
import requests
# Warning: the list begins with the earliest one
-PAGE_SIZE = "200"
+PAGE_SIZE = "500"
-# Seconds to retrieve from the past (smaller than 10 does not work all the time)
-TIMESLOT = 10
+# sudo is currently needed to avoid "User's Home Directory not found."
+CMD_PUBLISH_REST = "sudo tedge mqtt pub c8y/s/us 211,%i"
-CMD_PUBLISH_REST = "tedge mqtt pub c8y/s/us 211,%i"
-CMD_PUBLISH_JSON = "sawtooth_publisher 100 20 1 flux"
+CMD_PUBLISH_JSON = "sawtooth_publisher %s %s 1 flux"
-def act(path_publisher, mode):
+def act(path_publisher, mode, publish_amount, delay):
"""Act: Publishing values with temperature_publisher"""
if mode == "JSON":
print("Act: Publishing values with temperature_publisher")
- ret = os.system(os.path.join(path_publisher, CMD_PUBLISH_JSON))
+ ret = os.system(
+ os.path.join(path_publisher, CMD_PUBLISH_JSON % (delay, publish_amount))
+ )
if ret != 0:
print("Error cannot run publisher")
sys.exit(1)
elif mode == "REST":
print("Act: Publishing values with tedge pub")
- for i in range(0, 20):
+ for i in range(0, int(publish_amount)):
ret = os.system(CMD_PUBLISH_REST % i)
if ret != 0:
print("Error cannot run publisher")
sys.exit(1)
- time.sleep(0.1)
+ time.sleep(delay / 1000)
else:
sys.exit(1)
- print("Waiting 2s for values to arrive in C8y")
+ print("Waiting 3s for values to arrive in C8y")
- time.sleep(2)
+ time.sleep(3)
-def retrieve_data(user, device_id, password, tenant, verbose):
+def retrieve_data(user, device_id, password, tenant, verbose, timeslot):
"""Download via REST"""
time_to = datetime.utcnow().replace(microsecond=0)
- time_from = time_to - timedelta(seconds=TIMESLOT)
+ time_from = time_to - timedelta(seconds=timeslot)
- date_from = time_from.isoformat(sep="T") + 'Z'
- date_to = time_to.isoformat(sep="T") + 'Z'
+ date_from = time_from.isoformat(sep="T") + "Z"
+ date_to = time_to.isoformat(sep="T") + "Z"
print(f"Gathering values from {time_from} to {time_to}")
@@ -117,12 +121,20 @@ def check_timestamps(timestamps, laststamp):
tstampiso = datetime.fromisoformat(tstamp)
+ warning = 0
+
if tstampiso > laststamp:
laststamp = tstampiso
+ if tstampiso == laststamp:
+ laststamp = tstampiso
+ warning += 1
else:
print("Oops", tstampiso, "is smaller than", laststamp)
failed = True
+ if warning:
+ print(f"WARNING: found {warning} equal timestamps!")
+
if not failed:
print("Timestamp verification PASSED")
else:
@@ -130,29 +142,50 @@ def check_timestamps(timestamps, laststamp):
sys.exit(1)
-def assert_values(mode, user, device_id, password, tenant, verbose):
+def assert_values(
+ mode, user, device_id, password, tenant, verbose, publish_amount, timeslot
+):
"""Assert: Retrieving data via REST interface"""
print("Assert: Retrieving data via REST interface")
- req, time_from = retrieve_data(user, device_id, password, tenant, verbose)
+ req, time_from = retrieve_data(user, device_id, password, tenant, verbose, timeslot)
+
+ response = req.json()
+
+ assert "statistics" in response
+ page_size = response["statistics"]["pageSize"]
amount = len(req.json()["measurements"])
print(f"Found {amount} recorded values: ")
+ if page_size == amount:
+ print(f"Got {amount} values: your page size {page_size} is probably to small!")
+ sys.exit(1)
+
values = []
timestamps = []
- for i in req.json()["measurements"]:
+ assert "measurements" in response
+
+ for i in response["measurements"]:
+ source = i["source"]["id"]
+ assert source == device_id
if mode == "JSON":
+
+ assert i["type"] == "ThinEdgeMeasurement"
+
try:
value = i["Flux [F]"]["Flux [F]"]["value"]
except KeyError:
print(f"Error: Cannot parse response: {i}")
sys.exit(1)
elif mode == "REST":
+
+ assert i["type"] == "c8y_TemperatureMeasurement"
+
try:
value = i["c8y_TemperatureMeasurement"]["T"]["value"]
except KeyError:
@@ -168,7 +201,7 @@ def assert_values(mode, user, device_id, password, tenant, verbose):
values.append(value)
timestamps.append(tstamp)
- expected = list(range(0, 20))
+ expected = list(range(0, int(publish_amount)))
print("Retrieved:", values)
print("Expected:", expected)
@@ -182,7 +215,8 @@ def assert_values(mode, user, device_id, password, tenant, verbose):
check_timestamps(timestamps, time_from)
-if __name__ == "__main__":
+def main():
+ """The 'main' function"""
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", help="Mode JSON or REST")
@@ -191,7 +225,14 @@ if __name__ == "__main__":
parser.add_argument("-t", "--tenant", help="C8y tenant")
parser.add_argument("-pass", "--password", help="C8y Password")
parser.add_argument("-id", "--id", help="Device ID for C8y")
- parser.add_argument('--verbose', '-v', action='count', default=0)
+ parser.add_argument("--verbose", "-v", action="count", default=0)
+ parser.add_argument(
+ "--size", "-s", type=int, help="Amount of values to publish", default=20
+ )
+ parser.add_argument("--slot", "-o", type=int, help="Timeslot size", default=10)
+ parser.add_argument(
+ "--delay", "-d", type=int, help="Delay between publishs", default=100
+ )
args = parser.parse_args()
mode = args.mode
@@ -202,14 +243,23 @@ if __name__ == "__main__":
tenant = args.tenant
password = args.password
device_id = args.id
+ publish_amount = args.size
+ timeslot = args.slot
+ delay = args.delay
if verbose:
print(f"Mode: {mode}")
print(f"Using path for publisher: {path_publisher}")
- print(f"Using user name: HIDDEN")
- print(f"Using tenant-id: HIDDEN")
- print(f"Using device-id: HIDDEN")
+ print("Using user name: HIDDEN")
+ print("Using tenant-id: HIDDEN")
+ print("Using device-id: HIDDEN")
+
+ act(path_publisher, mode, publish_amount, delay)
- act(path_publisher, mode)
+ assert_values(
+ mode, user, device_id, password, tenant, verbose, publish_amount, timeslot
+ )
- assert_values(mode, user, device_id, password, tenant, verbose)
+
+if __name__ == "__main__":
+ main()