blob: 3270602feef6211b5c96e1a9f7026ee55a7cee8c [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (c) 2015-2017 Nest Labs, Inc.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# @file
# Implements WeavePairing class that tests Weave Pairing among Weave node and device manager.
#
import os
import random
import re
import sys
from happy.ReturnMsg import ReturnMsg
from happy.Utils import *
from happy.HappyNode import HappyNode
from happy.HappyNetwork import HappyNetwork
from plugin.WeaveTest import WeaveTest
options = {"quiet": False,
"mobile": None,
"device": None,
"server": None,
"tap": None,
"tier": None,
"username": None,
"password": None,
"devices_info": [],
'mobile_process_tag': "WEAVE-PAIRING-MOBILE",
'device_process_tag': "WEAVE-PAIRING-DEVICE",
'server_process_tag': "WEAVE-PAIRING-SERVER",
'mobile_node_id': None,
'server_node_id': None,
'register_cmd': None}
def option():
return options.copy()
class WeavePairing(HappyNode, HappyNetwork, WeaveTest):
"""
weave-pairing [-h --help] [-q --quiet] [-m --mobile <NAME>] [-d --device <NAME>] [-s --server <NAME>]
command to test pairing using a local mock server:
$ weave-pairing --mobile node01 --device node02 --server node03
command to test pairing using the default Weave ServiceProvisioning node-id over the internet:
$ weave-pairing --mobile node01 --device node02 --server service
command to test pairing using a custom Weave ServiceProvisioning server over the internet:
$ weave-pairing --mobile node01 --device node02 --server <ip address>
return:
0 success
1 failure
"""
def __init__(self, opts = options):
HappyNode.__init__(self)
HappyNetwork.__init__(self)
WeaveTest.__init__(self)
self.__dict__.update(opts)
def __pre_check(self):
# Set the produce resource that mock-device is paired to
resourceids = self.getResourceIds()
self.resource = resourceids[os.environ.get("RESOURCE_ID", "thd1")]
device_node_id = None
# Check if Weave Pairing device node is given.
if self.devices == None:
emsg = "Missing name or address of the Weave Pairing device node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
# Check if Weave Pairing mobile node is given.
if self.mobile == None:
emsg = "Missing name or address of the Weave Pairing mobile node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
# Check if Weave Pairing server info is given.
if self.server == None:
emsg = "Missing name or address of the Weave Pairing server node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
# Make sure that fabric was created
if self.getFabricId() == None:
emsg = "Weave Fabric has not been created yet."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
# Check if Weave Pairing mobile node exists.
if self._nodeExists(self.mobile):
self.mobile_node_id = self.mobile
# Check if mobile is provided in a form of IP address
if self.isIpAddress(self.mobile):
self.mobile_node_id = self.getNodeIdFromAddress(self.mobile)
if self.mobile_node_id == None:
emsg = "Unknown identity of the mobile node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
# Find out whether to use a local mock server or a server
# reachable over the internet
if self._nodeExists(self.server):
self.server_node_id = self.server
self.server_ip = self.getNodeWeaveIPAddress(self.server_node_id)
self.server_weave_id = self.getWeaveNodeID(self.server_node_id)
elif self.isIpAddress(self.server):
self.server_ip = self.server
self.server_weave_id = self.IPv6toWeaveId(self.server)
elif self.isDomainName(self.server) or self.server == "service":
self.server_ip = self.getServiceWeaveIPAddress("ServiceProvisioning")
self.server_weave_id = self.IPv6toWeaveId(self.server_ip)
self.mobile_ip = self.getNodeWeaveIPAddress(self.mobile_node_id)
self.mobile_weave_id = self.getWeaveNodeID(self.mobile_node_id)
for device in self.devices:
# Check if Weave Pairing device node exists.
if self._nodeExists(device):
device_node_id = device
# Check if device is provided in a form of IP address
if self.isIpAddress(device):
device_node_id = self.getNodeIdFromAddress(device)
if device_node_id == None:
emsg = "Unknown identity of the device node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
device_ip = self.getNodeWeaveIPAddress(device_node_id)
device_weave_id = self.getWeaveNodeID(device_node_id)
if device_ip == None:
emsg = "Could not find IP address of the device node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
if device_weave_id == None:
emsg = "Could not find Weave node ID of the device node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
self.devices_info.append({'device': device, 'device_node_id': device_node_id, 'device_ip': device_ip,
'device_weave_id': device_weave_id, 'device_process_tag': device + "_" + self.device_process_tag})
if self.mobile_ip == None:
emsg = "Could not find IP address of the mobile node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
if self.mobile_weave_id == None:
emsg = "Could not find Weave node ID of the mobile node."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
if self.server_ip == None:
emsg = "Could not find IP address of the server."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
if self.server_weave_id == None:
emsg = "Could not find Weave node ID of the server."
self.logger.error("[localhost] WeavePairing: %s" % (emsg))
sys.exit(1)
def getResourceIds(self):
resource_ids = {}
resource_ids['t2'] = {}
resource_ids['t2']['vendor_id'] = '9050'
resource_ids['t2']['software_id'] = '1.0'
resource_ids['t2']['product_id'] = '0'
resource_ids['f1'] = {}
resource_ids['f1']['vendor_id'] = '9050'
resource_ids['f1']['software_id'] = '1.0'
resource_ids['f1']['product_id'] = '0'
resource_ids['p1'] = {}
resource_ids['p1']['vendor_id'] = '9050'
resource_ids['p1']['software_id'] = '1.0'
resource_ids['p1']['product_id'] = '12'
resource_ids['k1'] = {}
resource_ids['k1']['vendor_id'] = '9050'
resource_ids['k1']['software_id'] = '1.0'
resource_ids['k1']['product_id'] = '8'
resource_ids['n1'] = {}
resource_ids['n1']['vendor_id'] = '9050'
resource_ids['n1']['software_id'] = '1.0'
resource_ids['n1']['product_id'] = '19'
resource_ids['q1'] = {}
resource_ids['q1']['vendor_id'] = '9050'
resource_ids['q1']['software_id'] = '1.0'
resource_ids['q1']['product_id'] = '13'
resource_ids['an1'] = {}
resource_ids['an1']['vendor_id'] = '9050'
resource_ids['an1']['software_id'] = '1.0'
resource_ids['an1']['product_id'] = '22'
resource_ids['th1'] = {}
resource_ids['th1']['vendor_id'] = '59175'
resource_ids['th1']['software_id'] = '1.0'
resource_ids['th1']['product_id'] = '1'
# Test Resources
resource_ids['thd1'] = {}
resource_ids['thd1']['vendor_id'] = '9050'
resource_ids['thd1']['software_id'] = '1.0'
resource_ids['thd1']['product_id'] = '65534'
resource_ids['tst1'] = {}
resource_ids['tst1']['vendor_id'] = '9050'
resource_ids['tst1']['software_id'] = '1.0'
resource_ids['tst1']['product_id'] = '65024'
return resource_ids
def __start_server(self):
cmd = self.getWeaveMockDevicePath()
if not cmd:
return
cmd += " --node-addr " + self.server_ip
if self.tap:
cmd += " --interface " + self.tap
self.start_weave_process(self.server_node_id, cmd, self.server_process_tag, sync_on_output = self.ready_to_service_events_str)
def __start_mobile_side(self, device_info, mobile_process_tag):
cmd = "/usr/bin/env python " + os.path.dirname(os.path.realpath(__file__)) + "/WeaveDeviceManager.py"
if not cmd:
return
cmd += " " + device_info['device_ip'] + " " + device_info['device_weave_id']
cmd += " --pairing-code TEST"
if self.server is not None and not self.server_node_id:
if not self.register_cmd:
import plugin.WeaveRegisterService as WeaveRegisterService
options = WeaveRegisterService.option()
options["tier"] = self.tier
options["username"] = self.username
options["password"] = self.password
registration = WeaveRegisterService.WeaveRegisterService(options)
self.register_cmd = registration.run()
if self.register_cmd:
cmd += self.register_cmd
else:
raise ValueError('register_cmd is empty')
if self.tap:
cmd += " --interface " + self.tap
self.start_weave_process(self.mobile_node_id, cmd, mobile_process_tag, env=os.environ)
def __start_device_side(self, device_info):
cmd = self.getWeaveMockDevicePath()
if not cmd:
return
cmd += " --node-addr " + device_info['device_ip'] + " --pairing-code TEST"
if self.server is not None:
cmd += " --pairing-server " + self.server_ip \
+ " --wrm-pairing" \
+ " --vendor-id " + self.resource['vendor_id'] \
+ " --software-version " + '"'+ self.resource['software_id'] + '"' \
+ " --product-id " + self.resource['product_id'] \
+ " --suppress-ac" # Suppress access controls to work around WEAV-2024
if self.server_node_id is not None:
# if the server is a local mock, we need to override the default endpoint id
cmd += " --pairing-endpoint-id " + self.server_weave_id
if self.tap:
cmd += " --interface " + self.tap
self.start_weave_process(device_info['device_node_id'], cmd, device_info['device_process_tag'], sync_on_output = self.ready_to_service_events_str)
def __process_results(self, mobiles_output, devices_info):
result_list = []
for mobile_output in mobiles_output:
if "Shutdown complete" in mobile_output:
result_list.append(True)
else:
result_list.append(False)
for device_info, result in zip(devices_info, result_list):
print " %s weave-pairing from mobile %s (%s) to device %s (%s) : " % \
("Success for" if result else "Fail for", self.mobile_node_id, self.mobile_ip, device_info['device_node_id'], device_info['device_ip'])
return result_list
def __wait_for_mobile(self, mobile_process_tag):
self.wait_for_test_to_end(self.mobile_node_id, mobile_process_tag)
def __stop_device_side(self, device_info):
self.stop_weave_process(device_info['device_node_id'], device_info['device_process_tag'])
def __stop_server_side(self):
self.stop_weave_process(self.server_node_id, self.server_process_tag)
def run(self):
self.logger.debug("[localhost] WeavePairing: Run.")
self.__pre_check()
devices_output_data = []
devices_strace_data = []
mobiles_output_data = []
mobiles_strace_data = []
for device_info in self.devices_info:
self.__start_device_side(device_info)
delayExecution(0.5)
emsg = "WeavePairing %s should be running." % (device_info['device_process_tag'])
self.logger.debug("[%s] WeavePairing: %s" % (device_info['device_node_id'], emsg))
if self.server_node_id:
self.__start_server()
mobile_process_tag = self.mobile_process_tag + device_info['device']
self.__start_mobile_side(device_info, mobile_process_tag)
self.__wait_for_mobile(mobile_process_tag)
mobile_output_value, mobile_output_data = \
self.get_test_output(self.mobile_node_id, mobile_process_tag, True)
mobile_strace_value, mobile_strace_data = \
self.get_test_strace(self.mobile_node_id, mobile_process_tag, True)
self.__stop_device_side(device_info)
device_output_value, device_output_data = \
self.get_test_output(device_info['device_node_id'], device_info['device_process_tag'], True)
device_strace_value, device_strace_data = \
self.get_test_strace(device_info['device_node_id'], device_info['device_process_tag'], True)
devices_output_data.append(device_output_data)
devices_strace_data.append(device_strace_data)
mobiles_output_data.append(mobile_output_data)
mobiles_strace_data.append(mobile_strace_data)
delayExecution(3)
server_output_value = None
server_output_data = None
server_strace_value = None
server_strace_data = None
if self.server_node_id:
self.__stop_server_side()
server_output_value, server_output_data = \
self.get_test_output(self.server_node_id, self.server_process_tag, True)
server_strace_value, server_strace_data = \
self.get_test_strace(self.server_node_id, self.server_process_tag, True)
result_list = self.__process_results(mobiles_output_data, self.devices_info)
data = {}
data["devices_output"] = devices_output_data
data["devices_strace"] = devices_strace_data
data["mobiles_output"] = mobiles_output_data
data["mobiles_strace"] = mobiles_strace_data
data["server_output"] = server_output_data
data["server_strace"] = server_strace_data
data["devices_info"] = self.devices_info
self.logger.debug("[localhost] WeavePairing: Done.")
return ReturnMsg(result_list, data)