| #!/usr/bin/env python |
| |
| |
| # |
| # Copyright (c) 2016-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 thread_wifi_ap_internet_configurable_topology. |
| ## Example of Thead, WiFi, and WAN networks, which have: |
| # - one thread-only device ThreadNode |
| # - one thread-wifi-cellular border_gateway device BorderRouter |
| # - one access-point router onhub |
| # - the onhub router is connected to the Internet |
| # |
| |
| import getopt |
| import os |
| from happy.Utils import * |
| import happy.HappyTopologyMgr |
| import sys |
| import uuid |
| |
| |
| default_quiet = False |
| default_tap = False |
| |
| |
| class thread_wifi_ap_internet_configurable_topology(object): |
| """ |
| thread_wifi_ap_internet_configurable_topology provides topology creation and destroy functionality. |
| |
| python weave_wdm_next_test_service_topology [-h --help] [-q --quiet] [-a --action] [-f --fabric_id] |
| [-e --customized_eui64_seed] [-t --tap] [-c --cellular] |
| [-m --mobile] [-n --device_numbers] |
| |
| note: please pair weave node id in service before testing |
| Example: |
| $ python thread_wifi_ap_internet_configurable_topology.py --action="create" --fabric_id="00000" --customized_eui64_seed="18:B4:30:00:00:00:00:0" --cellular --mobile --enable_random_fabric --device_numbers=3 --initial_device_index=1 |
| $ python thread_wifi_ap_internet_configurable_topology.py --action="destroy" --fabric_id="00000" --customized_eui64_seed="18:B4:30:00:00:00:00:0" --cellular --mobile --enable_random_fabric --device_numbers=3 --initial_device_index=1 |
| |
| fabric_id in test is a postfix which is set as only 5 hex, for example, 00000, then random 4 hex digit would append with fabric_id, which is used to test load balancer of service |
| customized_eui64_seed in test is set as only 15 hex, for example, 18:B4:30:00:00:00:00:0 |
| cellular is set when cellular topology is applied |
| there are three devices per fabric |
| initial_device_index is set as 1 |
| return: |
| 0 success |
| 1 fail |
| """ |
| def __init__(self, quiet=False, fabric_id=None, device_numbers=None, customized_eui64_seed=None, tap=False, dns=None, cellular=False, mobile=False, initial_device_index=1, enable_random_fabric=False): |
| if device_numbers is None: |
| self.device_numbers = 1 |
| else: |
| self.device_numbers = device_numbers |
| self.quiet = quiet |
| |
| if enable_random_fabric: |
| self.fabric_id = uuid.uuid4().hex[0:4] + fabric_id |
| else: |
| self.fabric_id = fabric_id |
| |
| self.customized_eui64_seed = customized_eui64_seed |
| self.customized_eui64_BorderRouter = self.customized_eui64_seed + "0" |
| self.tap = tap |
| self.dns = dns |
| self.cellular = cellular |
| self.topology = happy.HappyTopologyMgr.HappyTopologyMgr() |
| self.mobile = mobile |
| self.initial_device_index = initial_device_index |
| |
| |
| def createTopology(self): |
| self.topology.HappyNetworkAdd(network_id="HomeThread", type="thread", quiet=self.quiet) |
| self.topology.HappyNetworkAddress(network_id="HomeThread", address="2001:db8:111:1::", quiet=self.quiet) |
| self.topology.HappyNetworkAdd(network_id="HomeWiFi", type="wifi", quiet=self.quiet) |
| self.topology.HappyNetworkAddress(network_id="HomeWiFi", address="2001:db8:222:2::", quiet=self.quiet) |
| self.topology.HappyNetworkAddress(network_id="HomeWiFi", address="10.0.1.0", quiet=self.quiet) |
| |
| self.topology.WeaveFabricAdd(fabric_id=self.fabric_id, quiet=self.quiet) |
| |
| for device_index in range(self.device_numbers): |
| ThreadNodeId = "ThreadNode%s" % str(device_index + self.initial_device_index).zfill(2) |
| customized_eui64_ThreadNode = self.customized_eui64_seed + "%s" % format(device_index + self.initial_device_index, 'x') |
| self.topology.HappyNodeAdd(node_id=ThreadNodeId, quiet=self.quiet) |
| self.topology.HappyNodeJoin(node_id=ThreadNodeId, network_id="HomeThread", customized_eui64=customized_eui64_ThreadNode, |
| tap=self.tap, quiet=self.quiet) |
| # set up ThreadNode weave params |
| opts = {} |
| opts['quiet'] = self.quiet |
| opts['node_name'] = ThreadNodeId |
| opts['customized_eui64'] = customized_eui64_ThreadNode.replace(':', '-') |
| |
| self.topology.WeaveNodeConfigure(opts) |
| |
| |
| self.topology.HappyNodeAdd(node_id="BorderRouter", quiet=self.quiet) |
| self.topology.HappyNodeJoin(node_id="BorderRouter", network_id="HomeThread", customized_eui64=self.customized_eui64_BorderRouter, tap=self.tap, quiet=self.quiet) |
| self.topology.HappyNodeJoin(node_id="BorderRouter", network_id="HomeWiFi", customized_eui64=self.customized_eui64_BorderRouter, tap= self.tap, quiet=self.quiet) |
| |
| self.topology.HappyNodeAdd(node_id="onhub", type="ap", quiet=self.quiet) |
| self.topology.HappyNodeJoin(node_id="onhub", network_id="HomeWiFi", quiet=self.quiet) |
| |
| self.topology.HappyNetworkRoute(network_id="HomeThread", to="default", via="BorderRouter", quiet=self.quiet) |
| |
| if self.cellular: |
| self.topology.HappyNetworkRoute(network_id="HomeWiFi", to="default", via="onhub", prefix="10.0.1.0", quiet=self.quiet, isp="eth", seed=249) |
| else: |
| self.topology.HappyNetworkRoute(network_id="HomeWiFi", to="default", via="onhub", prefix="10.0.1.0", quiet=self.quiet) |
| |
| if self.mobile: |
| self.topology.HappyNetworkAdd(network_id="TMobile", type="cellular", quiet=self.quiet) |
| self.topology.HappyNetworkAddress(network_id="TMobile", address="2001:db8:333:3::", quiet=self.quiet) |
| self.topology.HappyNodeAdd(node_id="mobile", quiet=self.quiet) |
| self.topology.HappyNodeJoin(node_id="mobile", network_id="TMobile", quiet=self.quiet) |
| self.topology.HappyNodeJoin(node_id="BorderRouter", network_id="TMobile", quiet=self.quiet) |
| self.topology.HappyNetworkRoute(network_id="TMobile", to="default", via="BorderRouter", quiet=self.quiet) |
| # set up mobile weave params |
| opts = {} |
| opts['quiet'] = self.quiet |
| opts['node_name'] = "mobile" |
| self.topology.WeaveNodeConfigure(opts) |
| |
| self.topology.HappyNetworkRoute(network_id="HomeWiFi", to="default", via="onhub", prefix="2001:db8:222:2::", quiet=self.quiet) |
| |
| self.topology.HappyInternet(add=True, node_id="onhub", quiet=self.quiet, isp="eth", seed="249") |
| if self.cellular: |
| self.topology.HappyInternet(add=True, node_id="BorderRouter", quiet=self.quiet, isp="cell", seed="250") |
| self.topology.HappyDNS(add=True, quiet=self.quiet, dns=self.dns) |
| |
| # set up BorderRouter weave params |
| opts = {} |
| opts['quiet'] = self.quiet |
| opts['node_name'] = 'BorderRouter' |
| opts['customized_eui64'] = self.customized_eui64_BorderRouter.replace(':', '-') |
| self.topology.WeaveNodeConfigure(opts) |
| |
| self.topology.WeaveNetworkGateway(network_id="HomeThread", gateway="BorderRouter", quiet=self.quiet) |
| |
| |
| def destroyTopology(self): |
| self.topology.HappyDNS(dns=self.dns, delete=True, quiet=self.quiet) |
| if self.cellular: |
| self.topology.HappyInternet(delete=True, quiet=self.quiet, isp="cell", seed="250") |
| self.topology.HappyInternet(delete=True, quiet=self.quiet, isp="eth", seed="249") |
| self.topology.WeaveNetworkGateway(network_id="HomeThread", gateway="BorderRouter", delete=True, quiet=self.quiet) |
| self.topology.WeaveFabricDelete(fabric_id=self.fabric_id, quiet=self.quiet) |
| self.topology.HappyStateDelete(quiet=self.quiet) |
| |
| |
| if __name__ == "__main__": |
| options = {"quiet":False, "tap": False, "cellular": False, "mobile": False, "enable_random_fabric": False} |
| try: |
| opts, args = getopt.getopt(sys.argv[1:], "ha:qf:e:t:cmn:i:r", |
| ["help", "action=", "quiet", "fabric_id=", "customized_eui64_seed=", "tap=", "cellular", "mobile", "device_numbers=", "initial_device_index=", "enable_random_fabric"]) |
| |
| except getopt.GetoptError as err: |
| print thread_wifi_ap_internet_configurable_topology.__doc__ |
| print hred(str(err)) |
| sys.exit(hred("%s: Failed to parse arguments." % (__file__))) |
| |
| for o, a in opts: |
| if o in ("-h", "--help"): |
| sys.exit(0) |
| |
| elif o in ("-q", "--quiet"): |
| options["quiet"] = True |
| |
| elif o in ("-a", "--action"): |
| options["action"] = a |
| |
| elif o in ("-f", "--fabric_id"): |
| options["fabric_id"] = a |
| |
| elif o in ("-e", "--customized_eui64_seed"): |
| options["customized_eui64_seed"] = a |
| |
| elif o in ("-t", "--tap"): |
| options["tap"] = True |
| |
| elif o in ("-c", "--cellular"): |
| options["cellular"] = True |
| |
| elif o in ("-m", "--mobile"): |
| options["mobile"] = True |
| |
| elif o in ("-n", "--device_numbers"): |
| options["device_numbers"] = a |
| |
| elif o in ("-i", "--initial_device_index"): |
| options["initial_device_index"] = a |
| |
| elif o in ("-r", "--enable_random_fabric"): |
| options["enable_random_fabric"] = True |
| |
| else: |
| assert False, "unhandled option" |
| |
| if "action" not in options: |
| print thread_wifi_ap_internet_configurable_topology.__doc__ |
| sys.exit(0) |
| |
| if options["action"] not in ["create", "destroy"]: |
| print thread_wifi_ap_internet_configurable_topology.__doc__ |
| sys.exit(0) |
| |
| if ("fabric_id" in options) and ("customized_eui64_seed" in options): |
| fabric_id = options["fabric_id"] |
| customized_eui64_seed = options["customized_eui64_seed"] |
| |
| else: |
| print thread_wifi_ap_internet_configurable_topology.__doc__ |
| sys.exit(0) |
| |
| if "device_numbers" in options: |
| device_numbers = int(options["device_numbers"]) |
| else: |
| device_numbers = 1 |
| |
| if "initial_device_index" in options: |
| initial_device_index = int(options["initial_device_index"]) |
| else: |
| initial_device_index = 1 |
| |
| topology = thread_wifi_ap_internet_configurable_topology(quiet=options["quiet"], |
| fabric_id=fabric_id, |
| customized_eui64_seed=customized_eui64_seed, |
| tap=options["tap"], |
| dns=["8.8.8.8", "172.16.255.1", "172.16.255.153", "172.16.255.53"], |
| cellular=options["cellular"], |
| device_numbers=device_numbers, |
| mobile=options["mobile"], |
| initial_device_index=initial_device_index, |
| enable_random_fabric = options["enable_random_fabric"]) |
| if options["action"] == "create": |
| topology.createTopology() |
| else: |
| topology.destroyTopology() |
| |
| |
| |
| |
| |