diff options
author | Albin Suresh <albin.suresh@softwareag.com> | 2021-09-15 12:50:14 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-15 12:50:14 +0530 |
commit | a9acd6e8b7f197d5c3b3380ce7c3049598aaacf8 (patch) | |
tree | cfb1c5658e8e7082672894205377515f0d2e77d6 | |
parent | 71ba065980c97f71d92366e4fd620b642ab85743 (diff) |
[CIT-547] Device type for thin-edge devices on Cumulocity (#416)
* [CIT-547] Device type for thin-edge devices on Cumulocity
-rw-r--r-- | tedge/src/cli/connect/command.rs | 15 | ||||
-rw-r--r-- | tests/PySys/environments/environment_c8y.py | 81 | ||||
-rw-r--r-- | tests/PySys/pysysproject.xml | 18 | ||||
-rw-r--r-- | tests/PySys/tedge_connect_test_positive/run.py | 11 |
4 files changed, 105 insertions, 20 deletions
diff --git a/tedge/src/cli/connect/command.rs b/tedge/src/cli/connect/command.rs index 162d8368..56d7a566 100644 --- a/tedge/src/cli/connect/command.rs +++ b/tedge/src/cli/connect/command.rs @@ -166,13 +166,14 @@ impl ConnectCommand { fn check_connection(&self, config: &TEdgeConfig) -> Result<DeviceStatus, ConnectError> { let port = config.query(MqttPortSetting)?.into(); + let device_id: String = config.query(DeviceIdSetting)?.into(); println!( "Sending packets to check connection. This may take up to {} seconds.\n", WAIT_FOR_CHECK_SECONDS ); match self.cloud { Cloud::Azure => check_device_status_azure(port), - Cloud::C8y => check_device_status_c8y(port), + Cloud::C8y => check_device_status_c8y(port, device_id.as_str()), } } @@ -206,11 +207,11 @@ where // If the device is already registered, it can finish in the first try. // If the device is new, the device is going to be registered here and // the check can finish in the second try as there is no error response in the first try. -fn check_device_status_c8y(port: u16) -> Result<DeviceStatus, ConnectError> { +fn check_device_status_c8y(port: u16, device_id: &str) -> Result<DeviceStatus, ConnectError> { for i in 0..2 { println!("Try {} / 2: Sending a message to Cumulocity. ", i + 1,); - match create_device(port) { + match create_device(port, device_id) { Ok(DeviceStatus::MightBeNew) => return Ok(DeviceStatus::MightBeNew), Ok(DeviceStatus::AlreadyExists) => { println!("Received expected response message, connection check is successful.\n",); @@ -242,12 +243,14 @@ fn check_device_status_c8y(port: u16) -> Result<DeviceStatus, ConnectError> { return Ok(DeviceStatus::MightBeNew); } -fn create_device(port: u16) -> Result<DeviceStatus, ConnectError> { +fn create_device(port: u16, device_id: &str) -> Result<DeviceStatus, ConnectError> { const C8Y_TOPIC_BUILTIN_MESSAGE_UPSTREAM: &str = "c8y/s/us"; const C8Y_TOPIC_ERROR_MESSAGE_DOWNSTREAM: &str = "c8y/s/e"; const CLIENT_ID: &str = "check_connection_c8y"; - const REGISTRATION_PAYLOAD: &[u8] = b"100"; const REGISTRATION_ERROR: &[u8] = b"41,100,Device already existing"; + const DEVICE_TYPE: &str = "thin-edge.io"; + + let registration_payload = format!("100,{},{}", device_id, DEVICE_TYPE); let mut options = MqttOptions::new(CLIENT_ID, DEFAULT_HOST, port); options.set_keep_alive(RESPONSE_TIMEOUT.as_secs() as u16); @@ -265,7 +268,7 @@ fn create_device(port: u16) -> Result<DeviceStatus, ConnectError> { C8Y_TOPIC_BUILTIN_MESSAGE_UPSTREAM, AtLeastOnce, false, - REGISTRATION_PAYLOAD, + registration_payload.as_bytes(), )?; } Ok(Event::Incoming(Packet::PubAck(_))) => { diff --git a/tests/PySys/environments/environment_c8y.py b/tests/PySys/environments/environment_c8y.py index d8b287d0..f78493fd 100644 --- a/tests/PySys/environments/environment_c8y.py +++ b/tests/PySys/environments/environment_c8y.py @@ -1,4 +1,6 @@ -import pysys +import json +from pysys.constants import FAILED +import requests from pysys.basetest import BaseTest """ @@ -10,10 +12,82 @@ service mosquitto and service tedge-mapper. """ +class Cumulocity(object): + + c8y_url = "" + tenant_id = "" + username = "" + password = "" + auth = "" + + def __init__(self, c8y_url, tenant_id, username, password): + self.c8y_url = c8y_url + self.tenant_id = tenant_id + self.username = username + self.password = password + + self.auth = ('%s/%s' % (self.tenant_id, self.username), self.password) + + def request(self, method, url_path, **kwargs) -> requests.Response: + return requests.request(method, self.c8y_url + url_path, auth=self.auth, **kwargs) + + def get_all_devices(self) -> requests.Response: + params = { + "fragmentType": "c8y_IsDevice" + } + res = requests.get( + url=self.c8y_url + "/inventory/managedObjects", params=params, auth=self.auth) + + return self.to_json_response(res) + + def to_json_response(self, res: requests.Response): + if res.status_code != 200: + raise Exception( + "Received invalid response with exit code: {}, reason: {}".format(res.status_code, res.reason)) + return json.loads(res.text) + + def get_all_devices_by_type(self, type: str) -> requests.Response: + params = { + "fragmentType": "c8y_IsDevice", + "type": type, + } + res = requests.get( + url=self.c8y_url + "/inventory/managedObjects", params=params, auth=self.auth) + return self.to_json_response(res) + + def get_all_thin_edge_devices(self) -> requests.Response: + return self.get_all_devices_by_type("thin-edge.io") + + def get_thin_edge_device_by_name(self, device_id: str): + json_response = self.get_all_devices_by_type("thin-edge.io") + for device in json_response['managedObjects']: + if device_id in device['name']: + return device + return None + + class EnvironmentC8y(BaseTest): + cumulocity: Cumulocity + def setup(self): self.log.debug("EnvironmentC8y Setup") + if self.project.c8yurl == "": + self.abort( + FAILED, "Cumulocity tenant URL is not set. Set with the env variable C8YURL") + if self.project.tenant == "": + self.abort( + FAILED, "Cumulocity tenant ID is not set. Set with the env variable C8YTENANT") + if self.project.username == "": + self.abort( + FAILED, "Cumulocity tenant username is not set. Set with the env variable C8YUSERNAME") + if self.project.c8ypass == "": + self.abort( + FAILED, "Cumulocity tenant password is not set. Set with the env variable C8YPASS") + if self.project.deviceid == "": + self.abort( + FAILED, "Device ID is not set. Set with the env variable C8YDEVICEID") + self.tedge = "/usr/bin/tedge" self.tedge_mapper_c8y = "tedge-mapper-c8y" self.sudo = "/usr/bin/sudo" @@ -26,7 +100,7 @@ class EnvironmentC8y(BaseTest): command=self.systemctl, arguments=["status", self.tedge_mapper_c8y], stdouterr="serv_mapper1", - expectedExitStatus="==3", # 3: disabled + expectedExitStatus="==3", # 3: disabled ) # Connect the bridge @@ -57,6 +131,9 @@ class EnvironmentC8y(BaseTest): stdouterr="serv_mapper3", ) + self.cumulocity = Cumulocity( + self.project.c8yurl, self.project.tenant, self.project.username, self.project.c8ypass) + def execute(self): self.log.debug("EnvironmentC8y Execute") diff --git a/tests/PySys/pysysproject.xml b/tests/PySys/pysysproject.xml index e0bf006e..23b821df 100644 --- a/tests/PySys/pysysproject.xml +++ b/tests/PySys/pysysproject.xml @@ -4,14 +4,18 @@ <requires-python>3.7.3</requires-python> <property name="appHome" value="${env.PYSYS_APP_HOME}" default="${testRootDir}/.." pathMustExist="true"/> <property name="c8yswrepo" value="${env.C8YSWREPO}" default="" /> - <property name="tebasedir" value="${env.TEBASEDIR}" /> - <property name="exampledir" value="${env.EXAMPLEDIR}" /> - <property name="username" value="${env.C8YUSERNAME}" /> - <property name="c8ypass" value="${env.C8YPASS}" /> - <property name="tenant" value="${env.C8YTENANT}" /> - <property name="deviceid" value="${env.C8YDEVICEID}" /> - <property name="device" value="${env.C8YDEVICE}" /> + <property name="tebasedir" value="${env.TEBASEDIR}" default="${testRootDir}/../.."/> + <property name="exampledir" value="${env.EXAMPLEDIR}" default="${testRootDir}/../../ci"/> + <property name="c8yurl" value="${env.C8YURL}" default=""/> + <property name="username" value="${env.C8YUSERNAME}" default=""/> + <property name="c8ypass" value="${env.C8YPASS}" default=""/> + <property name="tenant" value="${env.C8YTENANT}" default=""/> + <property name="deviceid" value="${env.C8YDEVICEID}" default=""/> + <property name="device" value="${env.C8YDEVICE}" default=""/> <property name="platform" default='None' /> + + <pythonpath value="${testRootDir}/environments" /> + <writers> <writer classname="pysys.writer.testoutput.TestOutputArchiveWriter"> <property name="destDir" value="__pysys_output_archives/"/> diff --git a/tests/PySys/tedge_connect_test_positive/run.py b/tests/PySys/tedge_connect_test_positive/run.py index 5e8361f1..2e2cd407 100644 --- a/tests/PySys/tedge_connect_test_positive/run.py +++ b/tests/PySys/tedge_connect_test_positive/run.py @@ -1,6 +1,3 @@ -import sys - -sys.path.append("environments") from environment_c8y import EnvironmentC8y """ @@ -20,17 +17,21 @@ Then the test has passed class TedgeConnectTestPositive(EnvironmentC8y): def execute(self): super().execute() - self.systemctl="/usr/bin/systemctl" + self.systemctl = "/usr/bin/systemctl" self.log.info("Execute `tedge connect c8y --test`") self.startProcess( command=self.sudo, arguments=[self.tedge, "connect", "c8y", "--test"], stdouterr="tedge_connect_c8y_test_positive", ) + self.device_fragment = self.cumulocity.get_thin_edge_device_by_name( + self.project.deviceid) def validate(self): super().validate() self.log.info("Validate") self.assertGrep( "tedge_connect_c8y_test_positive.out", "connection check is successful.", contains=True - )
\ No newline at end of file + ) + self.assertTrue( + self.device_fragment['id'] != None, "thin-edge.io device with the given name exists") |