| #!/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 |
| # Implementes WeaveServiceDir class that test Weave Service Directory profile |
| # between a node and a service. |
| # |
| |
| import os |
| import sys |
| import time |
| import pprint |
| |
| from happy.ReturnMsg import ReturnMsg |
| from happy.Utils import * |
| from happy.HappyNetwork import HappyNetwork |
| from happy.HappyNode import HappyNode |
| |
| import happy.HappyNodeRoute |
| import happy.HappyNetworkAddress |
| |
| from plugin.WeaveTest import WeaveTest |
| import plugin.WeaveUtilities as WeaveUtilities |
| import plugins.plaid.Plaid as Plaid |
| |
| |
| options = {} |
| options["quiet"] = False |
| options["client"] = None |
| options["service"] = None |
| options["tap"] = None |
| options["test_tag"] = "" |
| options["iterations"] = 1 |
| options["client_faults"] = None |
| options["service_faults"] = None |
| options["plaid"] = False |
| options["strace"] = False |
| |
| |
| def option(): |
| return options.copy() |
| |
| |
| class WeaveServiceDir(HappyNode, HappyNetwork, WeaveTest): |
| """ |
| weave-service-dir test Weave Service Directory Profile between a client and a service |
| |
| weave-service-dir [-h --help] [-q --quiet] [-c --client <NODE_ID>] |
| [-s --service <NODE_ID>] [-p --tap <TAP_INTERFACE>] |
| |
| Example: |
| $ weave-service-dir BorderRouter cloud |
| Run Weave Service Directory Profile test between client BorderRouter and service cloud. |
| |
| |
| return: |
| 0 success |
| 1 fail |
| """ |
| |
| def __init__(self, opts = options): |
| HappyNode.__init__(self) |
| HappyNetwork.__init__(self) |
| WeaveTest.__init__(self) |
| |
| self.__dict__.update(opts) |
| |
| self.client_process_tag = "WEAVE-SD-CLIENT" + self.test_tag |
| self.service_process_tag = "WEAVE-SD-SERVICE" + self.test_tag |
| |
| plaid_opts = Plaid.default_options() |
| plaid_opts['num_clients'] = 2 |
| plaid_opts['strace'] = self.strace |
| self.plaid = Plaid.Plaid(plaid_opts) |
| |
| self.use_plaid = opts["plaid"] |
| if opts["plaid"] == "auto": |
| self.use_plaid = self.plaid.isPlaidConfigured() |
| |
| |
| def __pre_check(self): |
| # Check if client was given |
| if not self.client: |
| emsg = "client id not specified." |
| self.logger.error("[localhost] WeaveServiceDir: %s" % (emsg)) |
| self.exit() |
| |
| if not self._nodeExists(self.client): |
| emsg = "client %s does not exist." % (self.client) |
| self.logger.error("[localhost] WeaveServiceDir: %s" % (emsg)) |
| self.exit() |
| |
| # Check if service was given |
| if not self.service: |
| emsg = "Service node not specified." |
| self.logger.error("[localhost] WeaveServiceDir: %s" % (emsg)) |
| self.exit() |
| |
| if not self._nodeExists(self.service): |
| emsg = "Service %s does not exist." % (self.service) |
| self.logger.error("[localhost] WeaveServiceDir: %s" % (emsg)) |
| self.exit() |
| |
| self.fabric_id = self.getFabricId() |
| |
| # Check if there is no fabric |
| if self.fabric_id == None: |
| emsg = "There is not Weave fabric." |
| self.logger.error("[localhost] WeaveServiceDir: %s" % (emsg)) |
| self.exit() |
| |
| # Service Directory Endpoint ID: 0x18b4300200000001 |
| self.service_weave_id = self.getServiceWeaveID("Directory") |
| self.service_ip = self.getNodePublicIPv4Address(self.service) |
| self.client_ip = self.getNodeWeaveIPAddress(self.client) |
| |
| # Check if all unknowns were found |
| |
| if self.service_ip == None: |
| emsg = "Could not find IP address of the service." |
| self.logger.error("[localhost] WeaveServiceDir: %s" % (emsg)) |
| self.exit() |
| |
| if self.client_ip == None: |
| emsg = "Could not find IP address of the client." |
| self.logger.error("[localhost] WeaveServiceDir: %s" % (emsg)) |
| self.exit() |
| |
| |
| def __process_results(self, client_output, service_output): |
| result = {} |
| result["connection_completed"] = False |
| |
| client_parser_error, client_leak_detected = WeaveUtilities.scan_for_leaks_and_parser_errors(client_output) |
| result["no_client_parser_error"] = not client_parser_error |
| result["no_client_leak_detected"] = not client_leak_detected |
| |
| service_parser_error, service_leak_detected = WeaveUtilities.scan_for_leaks_and_parser_errors(service_output) |
| result["no_service_parser_error"] = not service_parser_error |
| result["no_service_leak_detected"] = not service_leak_detected |
| |
| for line in client_output.split("\n"): |
| if "AppConnectionComplete" in line: |
| result["connection_completed"] = True |
| break |
| |
| final_result = reduce((lambda x, y: x and y), result.values()) |
| |
| print "weave-service-dir test from client %s to service %s: " % (self.client, self.service) |
| |
| if self.quiet == False: |
| if final_result: |
| print hgreen("succeeded") |
| else: |
| print hred("failed") |
| |
| if not final_result: |
| pprint.pprint(result) |
| |
| return result |
| |
| |
| def __assing_directory_endpoint_ula_at_service(self): |
| addr = self.getServiceWeaveIPAddress("Directory", self.service) |
| |
| options = happy.HappyNodeAddress.option() |
| options["quiet"] = self.quiet |
| options["node_id"] = self.service |
| options["interface"] = "eth0" |
| options["address"] = addr |
| options["add"] = True |
| |
| addAddr = happy.HappyNodeAddress.HappyNodeAddress(options) |
| addAddr.run() |
| |
| |
| def __start_client_side(self): |
| cmd = self.getWeaveServiceDirPath() |
| if not cmd: |
| return |
| |
| cmd += " --node-addr " + self.client_ip |
| cmd += " --service-dir-url " + self.service_ip |
| cmd += " --debug-resource-usage" |
| cmd += " --print-fault-counters" |
| |
| if self.client_faults: |
| cmd += " --faults " + self.client_faults |
| |
| cmd += " --iterations " + str(self.iterations) |
| |
| if self.tap: |
| cmd += " --interface " + self.tap |
| |
| custom_env = {} |
| if self.use_plaid: |
| custom_env = self.plaid.getPlaidClientLibEnv(self.client) |
| |
| self.start_weave_process(self.client, cmd, self.client_process_tag, strace=self.strace, env=custom_env) |
| |
| |
| def __wait_for_client(self): |
| self.wait_for_test_to_end(self.client, self.client_process_tag) |
| |
| |
| def __stop_client_side(self): |
| self.stop_weave_process(self.client, self.client_process_tag) |
| |
| def __start_plaid_server(self): |
| |
| self.plaid.startPlaidServerProcess() |
| |
| emsg = "plaid-server should be running." |
| self.logger.debug("WeaveServiceDir: %s" % (emsg)) |
| |
| def __stop_plaid_server(self): |
| self.plaid.stopPlaidServerProcess() |
| |
| |
| def __start_service_side(self): |
| cmd = self.getWeaveServiceDirPath() |
| if not cmd: |
| return |
| |
| cmd += " --node-id " + str(self.service_weave_id) |
| cmd += " --fabric-id " + str(self.fabric_id) |
| |
| if self.tap: |
| cmd += " --interface " + self.tap |
| |
| if self.service_faults: |
| cmd += " --faults " + self.service_faults |
| |
| cmd += " --debug-resource-usage" |
| cmd += " --print-fault-counters" |
| |
| custom_env = {} |
| if self.use_plaid: |
| custom_env = self.plaid.getPlaidClientLibEnv(self.service) |
| |
| self.start_weave_process(self.service, cmd, self.service_process_tag, strace=self.strace, env=custom_env, sync_on_output = self.ready_to_service_events_str) |
| |
| |
| def __stop_service_side(self): |
| self.stop_weave_process(self.service, self.service_process_tag) |
| |
| |
| def run(self): |
| self.logger.debug("[localhost] WeaveServiceDir: Run.") |
| |
| self.__pre_check() |
| |
| if self.use_plaid: |
| self.__start_plaid_server() |
| |
| self.__start_service_side() |
| self.__assing_directory_endpoint_ula_at_service() |
| |
| self.__start_client_side() |
| self.__wait_for_client() |
| |
| self.__stop_service_side() |
| |
| if self.use_plaid: |
| self.__stop_plaid_server() |
| |
| data = {} |
| |
| client_output_value, client_output_data = \ |
| self.get_test_output(self.client, self.client_process_tag, True) |
| if self.strace: |
| client_strace_value, client_strace_data = \ |
| self.get_test_strace(self.client, self.client_process_tag, True) |
| data["client_strace"] = client_strace_data |
| |
| service_output_value, service_output_data = \ |
| self.get_test_output(self.service, self.service_process_tag, True) |
| if self.strace: |
| service_strace_value, service_strace_data = \ |
| self.get_test_strace(self.service, self.service_process_tag, True) |
| data["service_strace"] = service_strace_data |
| |
| result = self.__process_results(client_output_data, service_output_data) |
| data["client_output"] = client_output_data |
| data["service_output"] = service_output_data |
| data["result_details"] = result |
| |
| final_result = reduce((lambda x, y: x and y), result.values()) |
| |
| self.logger.debug("[localhost] WeaveServiceDir: Done.") |
| return ReturnMsg(final_result, data) |
| |