| #!/usr/bin/env python |
| |
| # |
| # Copyright (c) 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 WeaveWdmNext Next class that tests Weave WDM Next among Weave Nodes. |
| # |
| |
| import os |
| 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 |
| import plugin.WeaveUtilities as WeaveUtilities |
| import plugins.plaid.Plaid as Plaid |
| |
| options = { "clients": None, |
| "server": None, |
| "quiet": False, |
| "tap": None, |
| "wdm_option": None, |
| "strace": True, |
| "plaid": "auto", |
| "timeout": None, |
| "enable_client_stop": True, |
| "save_client_perf": False, |
| "client_faults": None, |
| "server_faults": None, |
| "client_event_generator": False, |
| "client_inter_event_period": None, |
| "enable_server_stop": False, |
| "save_server_perf": False, |
| "server_event_generator": None, |
| "server_inter_event_period": None, |
| "test_server_iterations": 1, |
| "wdm_client_liveness_check_period": None, |
| "wdm_server_liveness_check_period": None, |
| "case": False, |
| "enable_retry": False, |
| "case_cert_path": None, |
| "enable_mock_event_timestamp_initial_counter": False, |
| "case_key_path": None, |
| "group_enc": False, |
| "group_enc_key_id": None, |
| "use_persistent_storage": True |
| } |
| |
| |
| def option(): |
| return options.copy() |
| |
| |
| class WeaveWdmNext(HappyNode, HappyNetwork, WeaveTest): |
| """ |
| Runs a WDM test between a client and a server. The following options are supported. |
| |
| test_client_case, test_server_case: |
| |
| Maps to --test-case |
| Controls which traits are published and subscribed to. |
| The same value needs to be specified for both, for the subscriptions to work |
| |
| |
| total_client_count, total_server_count: |
| |
| Maps to --total-count |
| The number of times the node will mutate the trait instance per iteration; |
| The frequency of the mutations is controlled by timer_server_period and timer_client_period |
| Note that the server sends a custom command at the same time it mutates the trait instance. |
| The command type alternates between 1 and 2. Command 1 is served immediately by the client; |
| Command 2 is executed with a delay (the client sends a kMsgType_InProgress). |
| |
| |
| timer_server_period, timer_client_period: |
| |
| Maps to --timer-period |
| The period of the trait instance mutations. |
| |
| |
| final_client_status, final_server_status: |
| |
| Maps to --final-status, with the following values: |
| 0(client cancel), 1(publisher cancel), 2(client abort), 3(Publisher abort), 4(Idle) |
| This parameter controls what ends the test iteration. Both the client and the server have |
| a subscription client and a subscription handler (publisher). The node will terminate the |
| iteration with a Cancel or Abort, after either its publisher or its client have performed |
| all mutations and have become Idle. |
| A value of 4(Idle) means that the node will just wait for the other node to act. |
| |
| |
| test_client_iterations: |
| |
| Maps to --test-iterations on the client node |
| The number of times the test sequence (establish subscriptions, mutate N times, |
| cancel or abort) should be repeated. |
| |
| |
| test_server_iterations: |
| |
| Maps to --test-iterations on the server node |
| This is 1 by default and our tests never change it, since the tests are driven from |
| the client side and the server node is passive. |
| |
| |
| test_client_delay, test_server_delay: |
| |
| Maps to --test-delay. |
| The nodes will sleep for the given number of milliseconds between iterations |
| Currently, this needs to be more than 2 seconds if the server is sending commands, since the |
| client executes command type 2 with a delay of 2 seconds. |
| |
| |
| client_clear_state_between_iterations, server_clear_state_between_iterations: |
| |
| Maps to --clear-state-between-iterations |
| Resets the state of the data sink after each iteration |
| |
| |
| enable_client_stop, enable_server_stop: |
| |
| Maps to --enable-stop |
| Controls whether the process will exit the iteration or not at the end of the iteration |
| This is always enabled on the client, and disabled on the server; the caller should |
| not need to change these values. |
| |
| |
| client_event_generator, server_event_generator: |
| |
| Maps to --event-generator |
| Controls the event generator (None | Debug | Livenesss | Security | Telemetry | TestTrait) |
| running in the node's background. |
| See the option help string in TestWdmNext.cpp. The frequency at which events are generated |
| is controlled by client_inter_event_period and server_inter_event_period |
| |
| |
| client_inter_event_period, server_inter_event_period: |
| |
| Maps to --inter-event-period |
| The period used by the event generator in milliseconds |
| """ |
| |
| def __init__(self, opts=options): |
| HappyNode.__init__(self) |
| HappyNetwork.__init__(self) |
| WeaveTest.__init__(self) |
| |
| remove_keys = ["test_server_case", "total_server_count", "final_server_status", "timer_server_period", |
| "enable_server_stop", "test_server_iterations", "test_server_delay", "enable_server_flip", |
| "save_server_perf", "server_event_generator", "server_inter_event_period", |
| "wdm_server_liveness_check_period"] |
| |
| if opts['server'] == 'service': |
| for i in remove_keys: |
| if i in opts: |
| del opts[i] |
| |
| self.__dict__.update(opts) |
| |
| self.no_service = False |
| |
| self.server_process_tag = "WEAVE_WDM_SERVER" + (opts["test_tag"] if "test_tag" in opts else "") |
| self.client_process_tag = "WEAVE_WDM_CLIENT" + (opts["test_tag"] if "test_tag" in opts else "") |
| self.plaid_server_process_tag = "PLAID_SERVER" + (opts["test_tag"] if "test_tag" in opts else "") |
| |
| self.client_node_id = None |
| self.server_node_id = None |
| |
| self.clients_info = [] |
| |
| self.wdm_client_option = None |
| self.wdm_server_option = None |
| |
| plaid_opts = Plaid.default_options() |
| plaid_opts["quiet"] = self.quiet |
| self.plaid_server_node_id = "node03" |
| plaid_opts["server_node_id"] = self.plaid_server_node_id |
| plaid_opts["num_clients"] = 2 |
| plaid_opts["server_ip_address"] = self.getNodeWeaveIPAddress(self.plaid_server_node_id) |
| plaid_opts["strace"] = self.strace |
| self.plaid = Plaid.Plaid(plaid_opts) |
| |
| self.use_plaid = opts["plaid"] |
| if opts["plaid"] == "auto": |
| if self.server == "service": |
| # can't use plaid when talking to an external service |
| self.use_plaid = False |
| else: |
| self.use_plaid = self.plaid.isPlaidConfigured() |
| |
| |
| def __pre_check(self): |
| # Make sure that fabric was created |
| if self.getFabricId() == None: |
| emsg = "Weave Fabric has not been created yet." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % (emsg)) |
| sys.exit(1) |
| |
| # Check if Weave WDM server node is given. |
| if self.server == None: |
| emsg = "Missing name or address of the WeaveWdmNext server node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % (emsg)) |
| sys.exit(1) |
| |
| # Check if WeaveWdmNext server node exists. |
| if self._nodeExists(self.server): |
| self.server_node_id = self.server |
| self.server_process_tag = self.server_node_id + "_" + self.server_process_tag |
| |
| # Check if server is provided in a form of IP address |
| if self.isIpAddress(self.server): |
| self.no_service = True |
| self.server_ip = self.server |
| self.server_weave_id = self.IPv6toWeaveId(self.server) |
| elif self.isDomainName(self.server) or self.server == "service": |
| self.no_service = True |
| self.server_ip = self.getServiceWeaveIPAddress("DataManagement") |
| self.server_weave_id = self.IPv6toWeaveId(self.server_ip) |
| else: |
| # Check if server is a true cloud service instance |
| if self.getNodeType(self.server) == self.node_type_service: |
| self.no_service = True |
| |
| if not self.no_service and self.server_node_id is None: |
| emsg = "Unknown identity of the server node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.getNodeType(self.server_node_id) == "service": |
| self.server_ip = self.getServiceWeaveIPAddress("WeaveWdmNext", self.server_node_id) |
| self.server_weave_id = self.getServiceWeaveID("WeaveWdmNext", self.server_node_id) |
| else: |
| if not self.no_service: |
| self.server_ip = self.getNodeWeaveIPAddress(self.server_node_id) |
| self.server_weave_id = self.getWeaveNodeID(self.server_node_id) |
| |
| if self.server_ip is None: |
| emsg = "Could not find IP address of the server node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not self.no_service and self.server_weave_id is None: |
| emsg = "Could not find Weave node ID of the server node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| for client in self.clients: |
| client_node_id = None |
| client_ip = None |
| client_weave_id = None |
| # Check if Weave Wdm Next client node is given. |
| if client == None: |
| emsg = "Missing name or address of the WeaveWdmNext client node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % (emsg)) |
| sys.exit(1) |
| |
| # Check if WeaveWdmNext client node exists. |
| if self._nodeExists(client): |
| client_node_id = client |
| |
| # Check if client is provided in a form of IP address |
| if self.isIpAddress(client): |
| client_node_id = self.getNodeIdFromAddress(client) |
| |
| if client_node_id is None: |
| emsg = "Unknown identity of the client node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.getNodeType(client_node_id) == "service": |
| client_ip = self.getServiceWeaveIPAddress("WeaveWdmNext", client_node_id) |
| client_weave_id = self.getServiceWeaveID("WeaveWdmNext", client_node_id) |
| else: |
| client_ip = self.getNodeWeaveIPAddress(client_node_id) |
| client_weave_id = self.getWeaveNodeID(client_node_id) |
| |
| if client_ip is None: |
| emsg = "Could not find IP address of the client node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if client_weave_id is None: |
| emsg = "Could not find Weave node ID of the client node." |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| self.clients_info.append({"client": client, "client_node_id": client_node_id, "client_ip": client_ip, |
| "client_weave_id": client_weave_id, "client_process_tag": client + "_" + self.client_process_tag}) |
| |
| if self.wdm_option == "view": |
| self.wdm_client_option = " --wdm-simple-view-client" |
| self.wdm_server_option = " --wdm-simple-view-server" |
| print "view disabled" |
| sys.exit(1) |
| elif self.wdm_option == "one_way_subscribe": |
| self.wdm_client_option = " --wdm-one-way-sub-client" |
| self.wdm_server_option = " --wdm-one-way-sub-publisher" |
| elif self.wdm_option == "mutual_subscribe": |
| self.wdm_client_option = " --wdm-init-mutual-sub" |
| self.wdm_server_option = " --wdm-resp-mutual-sub" |
| else: |
| emsg = "NOT SUPPORTED WDM OPTION" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.test_client_case not in [1, 2, 3, 4, 5]: |
| emsg = "TestWdmNext only support test case 1, 2, 3, 4 and 5 in in client side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.total_client_count, int) and self.total_client_count >= -1): |
| emsg = "The number of notifications should not less than -1 in client side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.final_client_status not in [0, 1, 2, 3, 4]: |
| emsg = "TestWdmNext only support final status, 0(client cancel), 1(publisher cancel), 2(client abort)," \ |
| " 3(Publisher abort), 4(Idle) in client side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.timer_client_period, int) and self.timer_client_period >= 0): |
| emsg = "The period of notification timer should not less than 0 in client side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not isinstance(self.enable_client_stop, bool): |
| emsg = "TestWdmNext needs to specify if stopping test finally in client side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.test_client_iterations, int) and self.test_client_iterations >= 1): |
| emsg = "TestWdmNext needs at least one iteration in client side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.test_client_delay, int) and self.test_client_delay >= 0): |
| emsg = "The test delay between iterations should not less than 0 in client side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not isinstance(self.save_client_perf, bool): |
| emsg = "TestWdmNext needs to save per date in file finally in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.enable_client_flip not in [0, 1]: |
| emsg = "TestWdmNext only support flip 0 and 1 in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| if self.server != "service": |
| if self.test_server_case not in [1, 2, 3, 4, 5]: |
| emsg = "TestWdmNext only support test case 1, 2, 3, 4 and 5 in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.total_server_count, int) and self.total_server_count >= -1): |
| emsg = "The number of notifications should not less than -1 in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.final_server_status not in [0, 1, 2, 3, 4]: |
| emsg = "TestWdmNext only support final status, 0(client cancel), 1(publisher cancel), 2(client abort)," \ |
| " 3(Publisher abort), 4(Idle) in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.timer_server_period, int) and self.timer_server_period >= 0): |
| emsg = "The period of notification timer should not less than 0 in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not isinstance(self.enable_server_stop, bool): |
| emsg = "TestWdmNext needs to specify if stopping test finally in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.test_server_iterations, int) and self.test_server_iterations >= 1): |
| emsg = "TestWdmNext needs at least one iteration in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not (isinstance(self.test_server_delay, int) and self.test_server_delay >= 0): |
| emsg = "The test delay between iterations should not less than 0 in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if not isinstance(self.save_server_perf, bool): |
| emsg = "TestWdmNext needs to save per date in file finally in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.enable_server_flip not in [0, 1]: |
| emsg = "TestWdmNext only support flip 0 and 1 in server side" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.server_event_generator is not None and self.server_event_generator not in ["Debug", "Livenesss", "Security"]: |
| emsg = "TestWdmNext only support Debug, Liveness, and Security event" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| if self.server_inter_event_period is not None and int(self.server_inter_event_period) < 0: |
| emsg = "TestWdmNext event generation's period shoud be larger than 0" |
| self.logger.error("[localhost] WeaveWdmNext: %s" % emsg) |
| sys.exit(1) |
| |
| def __process_results(self, client_output, server_output, client_info): |
| kevents = re.findall(r"WEAVE:.+kEvent_\w+", client_output) |
| smoke_check = False |
| client_parser_error = None |
| client_leak_detected = None |
| server_parser_error = None |
| server_leak_detected = None |
| result = {} |
| 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 |
| if server_output is not "": |
| server_parser_error, server_leak_detected = WeaveUtilities.scan_for_leaks_and_parser_errors(server_output) |
| result["no_server_parser_error"] = not client_parser_error |
| result["no_server_leak_detected"] = not server_leak_detected |
| if self.wdm_option == "view": |
| if any("kEvent_ViewResponseReceived" in s for s in kevents) and \ |
| kevents[-1] == "kEvent_ViewResponseConsumed": |
| smoke_check = True |
| else: |
| smoke_check = False |
| elif self.wdm_option == "one_way_subscribe": |
| if any("Client->kEvent_OnSubscriptionEstablished" in s for s in kevents) \ |
| and "Closing endpoints" in client_output: |
| smoke_check = True |
| else: |
| smoke_check = False |
| elif self.wdm_option == "mutual_subscribe": |
| if any("Publisher->kEvent_OnSubscriptionEstablished" in s for s in kevents) \ |
| and "Closing endpoints" in client_output: |
| smoke_check = True |
| else: |
| smoke_check = False |
| result["smoke_check"] = smoke_check |
| |
| if self.quiet is False: |
| print "weave-wdm-next %s from node %s (%s) to node %s (%s) : "\ |
| % (self.wdm_option, client_info["client_node_id"], client_info["client_ip"], self.server_node_id, self.server_ip) |
| if smoke_check is True: |
| for kevent in kevents: |
| print hgreen(kevent) |
| print hgreen("weave-wdm-next %s success" % self.wdm_option) |
| else: |
| for kevent in kevents: |
| print hred(kevent) |
| print hred("weave-wdm-next %s failure" % self.wdm_option) |
| |
| if client_parser_error is True: |
| print hred("client parser error") |
| if client_leak_detected is True: |
| print hred("client_resource leak detected") |
| if server_parser_error is True: |
| print hred("server parser error") |
| if server_leak_detected is True: |
| print hred("server resource leak detected") |
| |
| return result |
| |
| |
| def wdm_next_checksum_check_process(self, log): |
| """Pull out checksum value list for each trait object sent or received.""" |
| checksum_list= re.findall("Checksum is (\w+)", log) |
| return checksum_list |
| |
| |
| def wdm_next_client_event_sequence_process(self, log): |
| """Pull out the number of events sent in a notification. Only notifications with non-zero events are reported""" |
| success = True |
| client_event_list= re.findall("Fetched (\d+) events", log) |
| client_event_process_list = [int(event) for event in client_event_list if int(event) > 0] |
| return {"client_event_list":client_event_process_list, "length": len(client_event_process_list), "success": success} |
| |
| |
| def wdm_next_publisher_event_sequence_process(self, log): |
| """Pull out the number of events received in a notification. All notifications with EventList element are reported. It would be considered an error to receive an empty EventList""" |
| publisher_event_list = re.finditer("WEAVE:DMG: \tEventList =", log) |
| success = True |
| event_list_len = [] |
| for eventListMarker in publisher_event_list: |
| startEventList = eventListMarker.end() |
| endEventListMarker = re.search(".*WEAVE:DMG: \t],.*", log[startEventList:]) |
| if endEventListMarker: |
| endEventList = endEventListMarker.end() |
| event_list_len.append(len(re.findall("WEAVE:DMG: \t\t{", log[startEventList:(startEventList+endEventList)]))) |
| else: |
| success = False |
| return {"publisher_event_list":event_list_len, "length": len(event_list_len), "success": success} |
| |
| def __start_plaid_server(self): |
| |
| self.plaid.startPlaidServerProcess() |
| |
| emsg = "plaid-server should be running." |
| self.logger.debug("[%s] WeaveWdmNext: %s" % (self.plaid_server_node_id, emsg)) |
| |
| def __start_server_side(self): |
| if self.no_service: |
| return |
| cmd = self.getWeaveWdmNextPath() |
| if not cmd: |
| return |
| self.server_id = self.server_weave_id |
| cmd += self.wdm_server_option |
| |
| if self.enable_server_stop is True: |
| cmd += " --enable-stop " |
| |
| if self.save_server_perf is True: |
| cmd += " --save-perf" |
| |
| if self.wdm_server_liveness_check_period is not None: |
| cmd += " --wdm-liveness-check-period " + str(self.wdm_server_liveness_check_period) |
| |
| cmd += " --test-case " + str(self.test_server_case) |
| cmd += " --total-count " + str(self.total_server_count) |
| cmd += " --final-status " + str(self.final_server_status) |
| cmd += " --timer-period " + str(self.timer_server_period) |
| cmd += " --test-iterations " + str(self.test_server_iterations) |
| cmd += " --test-delay " + str(self.test_server_delay) |
| cmd += " --enable-flip " + str(self.enable_server_flip) |
| if self.server_faults != None: |
| cmd += " --faults " + self.server_faults |
| |
| if self.__dict__.get("server_clear_state_between_iterations", False): |
| cmd += " --clear-state-between-iterations" |
| |
| if self.server_event_generator is not None: |
| cmd += " --event-generator " + str(self.server_event_generator) |
| |
| if self.server_inter_event_period is not None: |
| cmd += " --inter-event-period " + str(self.server_inter_event_period) |
| |
| if self.tap: |
| cmd += " --interface " + self.tap |
| |
| custom_env = {} |
| if self.use_plaid: |
| custom_env = self.plaid.getPlaidClientLibEnv(self.server_node_id) |
| |
| self.start_simple_weave_server(cmd, self.server_ip, self.server_node_id, self.server_process_tag, listen=False, strace=self.strace, env=custom_env, use_persistent_storage=self.use_persistent_storage) |
| |
| |
| def __start_client_side(self, client_info): |
| cmd = self.getWeaveWdmNextPath() |
| if not cmd: |
| return |
| cmd += self.wdm_client_option |
| cmd += " --wdm-publisher " + self.server_weave_id |
| |
| if self.enable_client_stop is True: |
| cmd += " --enable-stop " |
| |
| if self.save_client_perf is True: |
| cmd += " --save-perf" |
| |
| if self.wdm_client_liveness_check_period is not None: |
| cmd += " --wdm-liveness-check-period " + str(self.wdm_client_liveness_check_period) |
| |
| cmd += " --enable-dictionary-test " if self.enable_client_dictionary_test else "" |
| |
| cmd += " --test-case " + str(self.test_client_case) |
| cmd += " --total-count " + str(self.total_client_count) |
| cmd += " --final-status " + str(self.final_client_status) |
| cmd += " --timer-period " + str(self.timer_client_period) |
| cmd += " --test-iterations " + str(self.test_client_iterations) |
| cmd += " --test-delay " + str(self.test_client_delay) |
| cmd += " --enable-flip " + str(self.enable_client_flip) |
| |
| if self.__dict__.get("client_clear_state_between_iterations", False): |
| cmd += " --clear-state-between-iterations" |
| |
| if self.client_faults != None: |
| cmd += " --faults " + self.client_faults |
| |
| if self.tap: |
| cmd += " --interface " + self.tap |
| |
| if self.server == "service": |
| node_id = client_info["client_weave_id"] |
| fabric_id = self.getFabricId() |
| client_info["client_ip"] = None |
| cmd += " --wdm-subnet 5 --node-id=%s --fabric-id %s " % (node_id, fabric_id) |
| |
| if self.client_event_generator is not None: |
| cmd += " --event-generator " + str(self.client_event_generator) |
| |
| if self.client_inter_event_period is not None: |
| cmd += " --inter-event-period " + str(self.client_inter_event_period) |
| |
| if self.case: |
| self.cert_file = self.case_cert_path if self.case_cert_path else os.path.join(self.main_conf["log_directory"], node_id.upper() + "-cert.weave-b64") |
| self.key_file = self.case_key_path if self.case_key_path else os.path.join(self.main_conf["log_directory"], node_id.upper() + "-key.weave-b64") |
| cmd += " --case " + " --node-cert " + self.cert_file + " --node-key " + self.key_file |
| |
| if self.group_enc: |
| cmd += ' --group-enc ' + ' --group-enc-key-id ' + self.group_enc_key_id |
| |
| if self.enable_retry: |
| cmd += " --enable-retry" |
| |
| if self.enable_mock_event_timestamp_initial_counter: |
| cmd += " --enable-mock-event-timestamp-initial-counter" |
| |
| custom_env = {} |
| if self.use_plaid: |
| custom_env = self.plaid.getPlaidClientLibEnv(client_info["client_node_id"]) |
| |
| self.start_simple_weave_client(cmd, client_info["client_ip"], None, None, client_info["client_node_id"], |
| client_info["client_process_tag"], strace=self.strace, env=custom_env, use_persistent_storage=self.use_persistent_storage) |
| |
| |
| def __wait_for_client(self, client_info): |
| self.wait_for_test_to_end(client_info["client_node_id"], client_info["client_process_tag"], quiet=False, timeout=self.timeout) |
| |
| |
| def __stop_server_side(self): |
| if self.no_service: |
| return |
| |
| self.stop_weave_process(self.server_node_id, self.server_process_tag) |
| |
| |
| def __stop_client_side(self): |
| if self.no_service: |
| return |
| |
| self.stop_weave_process(self.client_node_id, self.client_process_tag) |
| |
| |
| def __stop_plaid_server(self): |
| self.plaid.stopPlaidServerProcess() |
| |
| |
| def run_client_test(self): |
| all_data = [] |
| success = True |
| self.__pre_check() |
| |
| if self.use_plaid: |
| self.__start_plaid_server() |
| |
| self.__start_server_side() |
| |
| emsg = "WeaveWdmNext %s should be running." % self.server_process_tag |
| self.logger.debug("[%s] WeaveWdmNext: %s" % (self.server_node_id, emsg)) |
| |
| for client_info in self.clients_info: |
| self.__start_client_side(client_info) |
| for client_info in self.clients_info: |
| self.__wait_for_client(client_info) |
| for client_info in self.clients_info: |
| client_output_value, client_output_data = \ |
| self.get_test_output(client_info["client_node_id"], client_info["client_process_tag"], True) |
| if self.strace: |
| client_strace_value, client_strace_data = \ |
| self.get_test_strace(client_info["client_node_id"], client_info["client_process_tag"], True) |
| |
| if self.no_service: |
| server_output_data = "" |
| server_strace_data = "" |
| else: |
| self.__stop_server_side() |
| if self.use_plaid: |
| self.__stop_plaid_server() |
| server_output_value, server_output_data = \ |
| self.get_test_output(self.server_node_id, self.server_process_tag, True) |
| if self.strace: |
| server_strace_value, server_strace_data = \ |
| self.get_test_strace(self.server_node_id, self.server_process_tag, True) |
| |
| success_dic = self.__process_results(client_output_data, server_output_data, client_info) |
| |
| smoke_check_ghost = success_dic["smoke_check"] |
| if self.client_faults or self.server_faults: |
| success_dic["smoke_check"] = True |
| success = reduce(lambda x, y: x and y, success_dic.values()) |
| success_dic["smoke_check"] = smoke_check_ghost |
| |
| data = {} |
| data.update(client_info) |
| data["client_output"] = client_output_data |
| data["server_output"] = server_output_data |
| if self.strace: |
| data["client_strace"] = client_strace_data |
| data["server_strace"] = server_strace_data |
| data["success_dic"] = success_dic |
| all_data.append(data) |
| |
| return ReturnMsg(success, all_data) |
| |
| def run(self): |
| return self.run_client_test() |