summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlbin Suresh <albin.suresh@softwareag.com>2021-09-15 12:50:14 +0530
committerGitHub <noreply@github.com>2021-09-15 12:50:14 +0530
commita9acd6e8b7f197d5c3b3380ce7c3049598aaacf8 (patch)
treecfb1c5658e8e7082672894205377515f0d2e77d6
parent71ba065980c97f71d92366e4fd620b642ab85743 (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.rs15
-rw-r--r--tests/PySys/environments/environment_c8y.py81
-rw-r--r--tests/PySys/pysysproject.xml18
-rw-r--r--tests/PySys/tedge_connect_test_positive/run.py11
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")