Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 0ae81e9

Browse files
Add border router pairing test
1 parent a356695 commit 0ae81e9

File tree

3 files changed

+281
-5
lines changed

3 files changed

+281
-5
lines changed

src/test-apps/happy/test-templates/WeavePairing.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,23 @@ def __init__(self, opts=options):
8989

9090
def __pre_check(self):
9191
device_node_id = None
92-
# Set the produce resource that mock-device is paired to
93-
resourceDictionaries = self.getResourceIds()
94-
resourceIndexList = os.environ.get("RESOURCE_IDS", "thd1").split(" ")
95-
self.resources = [resourceDictionaries[resourceIndex]
96-
for resourceIndex in resourceIndexList]
92+
9793
# Check if Weave Pairing device node is given.
9894
if self.devices is None:
9995
emsg = "Missing name or address of the Weave Pairing device node."
10096
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
10197
sys.exit(1)
10298

99+
# Set the produce resource that mock-device is paired to
100+
resourceDictionaries = self.getResourceIds()
101+
if len(self.devices) == 1 and self.devices[0] == "border_gateway":
102+
resourceIndexList = ["nf1"]
103+
else:
104+
resourceIndexList = os.environ.get("RESOURCE_IDS", "thd1").split(" ")
105+
106+
self.resources = [resourceDictionaries[resourceIndex]
107+
for resourceIndex in resourceIndexList]
108+
103109
# Check if Weave Pairing mobile node is given.
104110
if self.mobile is None:
105111
emsg = "Missing name or address of the Weave Pairing mobile node."
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
#!/usr/bin/env python
2+
3+
4+
#
5+
# Copyright (c) 2020 Google LLC.
6+
# Copyright (c) 2016-2017 Nest Labs, Inc.
7+
# All rights reserved.
8+
#
9+
# Licensed under the Apache License, Version 2.0 (the "License");
10+
# you may not use this file except in compliance with the License.
11+
# You may obtain a copy of the License at
12+
#
13+
# http://www.apache.org/licenses/LICENSE-2.0
14+
#
15+
# Unless required by applicable law or agreed to in writing, software
16+
# distributed under the License is distributed on an "AS IS" BASIS,
17+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
# See the License for the specific language governing permissions and
19+
# limitations under the License.
20+
#
21+
22+
#
23+
# @file
24+
# Calls Weave Tunnel between a simulated BorderRouter and NestService.
25+
# After the tunnel is establish, weave-pairing interaction will be executed between the Mobile to Border Router,
26+
# and ThreadNode register to NestService.
27+
#
28+
29+
from __future__ import absolute_import
30+
from __future__ import print_function
31+
import os
32+
import re
33+
import sys
34+
import unittest
35+
import set_test_path
36+
37+
from happy.Utils import *
38+
39+
import WeavePairing
40+
import WeaveTunnelStart
41+
import WeaveTunnelStop
42+
import plugins.testrail.TestrailResultOutput
43+
44+
from topologies.dynamic.thread_wifi_ap_internet_configurable_topology import thread_wifi_ap_internet_configurable_topology
45+
from six.moves import range
46+
from six.moves import zip
47+
48+
TEST_OPTION_QUIET = True
49+
TESTRAIL_SECTION_NAME = "Weave pairing between Border router and Real-Service"
50+
TESTRAIL_SUFFIX = "_TESTRAIL.json"
51+
DEFAULT_FABRIC_SEED = "00001"
52+
53+
54+
class test_weave_pairing_br(unittest.TestCase):
55+
def setUp(self):
56+
self.tap = None
57+
self.tap_id = None
58+
self.quiet = TEST_OPTION_QUIET
59+
self.options = None
60+
61+
if "weave_service_address" in list(os.environ.keys()):
62+
if "unstable" not in os.environ["weave_service_address"]:
63+
found = re.search('.(\w+).nestlabs.com', os.environ["weave_service_address"])
64+
self.tier = found.group(1)
65+
else:
66+
found = re.search('(\w+.unstable).nestlabs.com', os.environ["weave_service_address"])
67+
self.tier = found.group(1)
68+
69+
self.topology_setup_required = int(os.environ.get("TOPOLOGY", "1")) == 1
70+
71+
fabric_seed = os.environ.get("FABRIC_SEED", DEFAULT_FABRIC_SEED)
72+
73+
if "FABRIC_OFFSET" in list(os.environ.keys()):
74+
self.fabric_id = format(int(fabric_seed, 16) + int(os.environ["FABRIC_OFFSET"]), 'x').zfill(5)
75+
else:
76+
self.fabric_id = fabric_seed
77+
78+
self.eui64_prefix = os.environ.get("EUI64_PREFIX", '18:B4:30:AA:00:')
79+
80+
self.customized_eui64_seed = self.eui64_prefix + self.fabric_id[0:2] + ':' + self.fabric_id[2:4] + ':' + self.fabric_id[4:]
81+
82+
self.device_numbers = 1
83+
84+
self.test_timeout = int(os.environ.get("TEST_TIMEOUT", 60 * 30))
85+
86+
self.username = os.environ.get("WEAVE_USERNAME", "test-it+weave_happy_fabric%[email protected]" % self.fabric_id)
87+
88+
self.password = os.environ.get("WEAVE_PASSWORD", "nest-egg123")
89+
90+
self.initial_device_index = int(os.environ.get("INITIAL_DEVICE_INDEX", "1"))
91+
92+
# TODO: Once LwIP bugs for tunnel are fix, enable this test on LwIP
93+
if "WEAVE_SYSTEM_CONFIG_USE_LWIP" in list(os.environ.keys()) and os.environ["WEAVE_SYSTEM_CONFIG_USE_LWIP"] == "1":
94+
self.tap = True
95+
self.tap_id = "wpan0"
96+
return
97+
else:
98+
self.tap = False
99+
100+
self.case = int(os.environ.get("CASE", "0")) == 1
101+
102+
self.use_service_dir = int(os.environ.get("USE_SERVICE_DIR", "0")) == 1
103+
104+
if self.topology_setup_required:
105+
self.topology = thread_wifi_ap_internet_configurable_topology(quiet=self.quiet,
106+
fabric_id=self.fabric_id,
107+
customized_eui64_seed=self.customized_eui64_seed,
108+
tap=self.tap,
109+
dns=None,
110+
device_numbers=self.device_numbers,
111+
mobile=True,
112+
initial_device_index=self.initial_device_index)
113+
self.topology.createTopology()
114+
else:
115+
print("topology set up not required")
116+
117+
self.show_strace = False
118+
119+
self.weave_wdm = None
120+
# Wait for a second to ensure that Weave ULA addresses passed dad
121+
# and are no longer tentative
122+
delayExecution(2)
123+
124+
# topology has nodes: ThreadNode, BorderRouter, onhub and NestService instance
125+
# we run tunnel between BorderRouter and NestService
126+
127+
# Start tunnel
128+
value, data = self.__start_tunnel_from("BorderRouter")
129+
delayExecution(1)
130+
131+
def tearDown(self):
132+
delayExecution(1)
133+
# Stop tunnel
134+
value, data = self.__stop_tunnel_from("BorderRouter")
135+
if self.topology_setup_required:
136+
self.topology.destroyTopology()
137+
self.topology = None
138+
139+
140+
def test_weave_pairing(self):
141+
# TODO: Once LwIP bugs are fix, enable this test on LwIP
142+
if "WEAVE_SYSTEM_CONFIG_USE_LWIP" in list(os.environ.keys()) and os.environ["WEAVE_SYSTEM_CONFIG_USE_LWIP"] == "1":
143+
print(hred("WARNING: Test skipped due to LwIP-based network cofiguration!"))
144+
return
145+
146+
# topology has nodes: ThreadNode, BorderRouter, onhub and NestService instance
147+
# we run pairing between BorderRouter and NestService depends on mobile
148+
value, data = self.__run_pairing_test_between("ThreadNode", "mobile")
149+
self.__process_result("BorderRouter", "service", value, data)
150+
151+
delayExecution(1)
152+
153+
154+
def __start_tunnel_from(self, gateway):
155+
options = WeaveTunnelStart.option()
156+
options["quiet"] = False
157+
options["border_gateway"] = gateway
158+
options["tap"] = self.tap_id
159+
160+
options["case"] = self.case
161+
options["service_dir"] = self.use_service_dir
162+
163+
weave_tunnel = WeaveTunnelStart.WeaveTunnelStart(options)
164+
ret = weave_tunnel.run()
165+
166+
value = ret.Value()
167+
data = ret.Data()
168+
169+
return value, data
170+
171+
172+
def __run_pairing_test_between(self, nodeA, nodeB):
173+
options = WeavePairing.option()
174+
options["quiet"] = False
175+
options["mobile"] = nodeB
176+
options["devices"] = ["BorderRouter"]
177+
options["server"] = "service"
178+
options["tap"] = self.tap_id
179+
options["username"] = self.username
180+
options["password"] = self.password
181+
options["tier"] = self.tier
182+
self.weave_pairing = WeavePairing.WeavePairing(options)
183+
ret = self.weave_pairing.run()
184+
185+
value = ret.Value()
186+
data = ret.Data()
187+
188+
return value, data
189+
190+
191+
def __process_result(self, nodeA, nodeB, value, data):
192+
success = True
193+
for result, device_output, device_strace, device_info in zip(value, data['devices_output'], data['devices_strace'], data['devices_info']):
194+
print("Service provision from " + device_info['resource']['id']+ " to real NestService using " + nodeB + " ", end=' ')
195+
196+
if result is True:
197+
print(hgreen("Passed"))
198+
else:
199+
success = False
200+
print(hred("Failed"))
201+
202+
try:
203+
self.assertTrue(value, "result %s == True %%" % (str(result)))
204+
except AssertionError as e:
205+
print(str(e))
206+
print("Captured experiment result:")
207+
208+
print("Device Output: ")
209+
for line in device_output.split("\n"):
210+
print("\t" + line)
211+
212+
if self.show_strace == True:
213+
print(" Device Strace: ")
214+
for line in device_strace.split("\n"):
215+
print("\t" + line)
216+
217+
test_results = []
218+
219+
test_results.append({
220+
'testName': 'Pairing-NestService-BR: Weave pairing between Border router and Real-Service',
221+
'testStatus': 'success' if result else 'failure',
222+
'testDescription': "Do weave pairing between Mock-Client %s and Real-Service" % device_info['device_weave_id'],
223+
'success_iterations_count': 1 if result else 0,
224+
'total_iterations_count': 1,
225+
'device_id': device_info['resource']['id']
226+
})
227+
228+
# output the test result to a json file
229+
output_data = {
230+
'sectionName': TESTRAIL_SECTION_NAME,
231+
'testResults': test_results
232+
}
233+
234+
output_file_name = self.weave_pairing.process_log_prefix + device_info['device'] + self.__class__.__name__ + device_info['resource']['id'] + TESTRAIL_SUFFIX
235+
236+
self.__output_test_result(output_file_name, output_data)
237+
238+
if not success:
239+
raise ValueError('test failure')
240+
241+
242+
def __output_test_result(self, file_path, output_data):
243+
options = plugins.testrail.TestrailResultOutput.option()
244+
options["quiet"] = TEST_OPTION_QUIET
245+
options["file_path"] = file_path
246+
options["output_data"] = output_data
247+
248+
output_test = plugins.testrail.TestrailResultOutput.TestrailResultOutput(options)
249+
output_test.run()
250+
251+
252+
def __stop_tunnel_from(self, gateway):
253+
options = WeaveTunnelStop.option()
254+
options["quiet"] = False
255+
options["border_gateway"] = gateway
256+
options["service_dir"] = self.use_service_dir
257+
weave_tunnel = WeaveTunnelStop.WeaveTunnelStop(options)
258+
ret = weave_tunnel.run()
259+
260+
value = ret.Value()
261+
data = ret.Data()
262+
263+
return value, data
264+
265+
266+
if __name__ == "__main__":
267+
unittest.main()
268+
269+

src/test-apps/happy/tests/service/run_single_weave_service_test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ set -e
3939

4040
if [[ $# -eq 0 ]]
4141
then
42+
pairing/test_weave_pairing_br.py
4243
pairing/test_weave_pairing_01.py
4344
# wdmNext/test_weave_wdm_next_service_mutual_subscribe_05.py
4445
# wdmNext/test_weave_wdm_next_service_mutual_subscribe_09.py

0 commit comments

Comments
 (0)