blob: 5b27019c041961e21616d314432626c53fc19f89 [file] [log] [blame]
#!/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
# Implements WeaveTunnelTest class that executes a set of Weave
# Tunnel tests between border-gateway and a service.
#
import os
import sys
import time
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
import plugin.WeaveTunnelStop as WeaveTunnelStop
from plugin.WeaveTest import WeaveTest
options = {}
options["quiet"] = False
options["border_gateway"] = None
options["service"] = None
options["tap"] = None
def option():
return options.copy()
class WeaveTunnelTest(HappyNode, HappyNetwork, WeaveTest):
"""
weave-tunnel-test start a tunnel between border-gateway and the service and run all tests
weave-tunnel-test [-h --help] [-q --quiet] [-b --border_gateway <NODE_ID>]
[-s --service <NODE_ID> | <IP_ADDR>] [-p --tap <TAP_INTERFACE>]
Example:
$ weave-tunnel-test node01 node02
Start weave tunnel test between border-gateway node01 and service node02.
$ weave-tunnel-test node01 184.72.129.8
Start weave tunnel between border-gateway node01 and a node with an IP address 184.72.129.8.
return:
0 success
1 fail
"""
def __init__(self, opts = options):
HappyNode.__init__(self)
HappyNetwork.__init__(self)
WeaveTest.__init__(self)
self.quiet = opts["quiet"]
self.border_gateway = opts["border_gateway"]
self.service = opts["service"]
self.tap = opts["tap"]
self.service_process_tag = "WEAVE-TUNNEL-TEST-SERVER"
self.gateway_process_tag = "WEAVE-TUNNEL-TEST-BORDER-GW"
self.gateway_node_id = None
self.service_node_id = None
def __pre_check(self):
# Check if border-gateway node was given
if not self.border_gateway:
emsg = "Border-gateway node id not specified."
self.logger.error("[localhost] WeaveTunnelTest: %s" % (emsg))
sys.exit(1)
# Check if Weave Tunnel service node is given.
if not self.service:
emsg = "Service node id not specified."
self.logger.error("[localhost] WeaveTunnelTest: %s" % (emsg))
sys.exit(1)
# Check if Weave Tunnel border gateway node exists.
if not self._nodeExists(self.border_gateway):
emsg = "Border-gateway node %s does not exist." % (self.border_gateway)
self.logger.error("[localhost] WeaveTunnelTest: %s" % (emsg))
sys.exit(1)
# Check if Weave Tunnel service node exists.
if not self._nodeExists(self.service):
emsg = "Service node %s does not exist." % (self.service)
self.logger.error("[localhost] WeaveTunnelTest: %s" % (emsg))
sys.exit(1)
self.fabric_id = self.getFabricId()
# Check if there is no fabric
if self.fabric_id == None:
emsg = "There is no Weave fabric."
self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
sys.exit(1)
# Get the IPv4 address of the Service to connect to
self.service_public_ip = self.getNodePublicIPv4Address(self.service)
# Get the Weave ID for the Service node
self.service_weave_id = self.getServiceWeaveID("Tunnel")
# Get the Weave ID for the Border gateway node
self.gateway_weave_id = self.getWeaveNodeID(self.border_gateway)
# Get the Weave IPv6 ULA address of the Ser\vice node
self.server_ula = self.getServiceWeaveIPAddress("Tunnel", self.service_weave_id)
# Check if all unknowns were found
if self.service_public_ip == None:
emsg = "Could not find IP address of the service node."
self.logger.error("[localhost] WeaveTunnel: %s" % (emsg))
sys.exit(1)
if self.service_weave_id == None:
emsg = "Could not find Weave node ID of the service node."
self.logger.error("[localhost] WeaveTunnel: %s" % (emsg))
sys.exit(1)
if self.gateway_weave_id == None:
emsg = "Could not find Weave node ID of the border-gateway node."
self.logger.error("[localhost] WeaveTunnel: %s" % (emsg))
sys.exit(1)
if self.server_ula == None:
emsg = "Could not find Weave ULA Address of the Service node."
self.logger.error("[localhost] WeaveTunnel: %s" % (emsg))
sys.exit(1)
def __wait_for_gateway(self):
self.wait_for_test_to_end(self.border_gateway, self.gateway_process_tag)
def __stop_server_side(self):
self.stop_weave_process(self.service, self.service_process_tag)
def __process_results(self, client_output):
# search for 'Passed' word
pass_test = True
for line in client_output.split("\n"):
if "'FAILED'" in line or "'PASSED'" in line:
tokens = line.split("'")
for str in tokens:
if str.startswith('Test', 0, len(str)):
testName = str
if "'FAILED'" in line:
print hred(testName + ":" + " FAILED ")
pass_test = False
if "'PASSED'" in line:
print hgreen(testName + ":" + " PASSED ")
return (pass_test, client_output)
def __start_tunnel_test_server(self):
cmd = self.getWeaveTunnelTestServerPath()
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
cmd = self.runAsRoot(cmd)
self.start_weave_process(self.service, cmd, self.service_process_tag, sync_on_output=self.ready_to_service_events_str)
max_wait_time = 40
while not self._nodeInterfaceExists(self.service_tun, self.service):
time.sleep(0.1)
max_wait_time -= 1
if max_wait_time <= 0:
emsg = "Service-side tunnel interface %s was not created." % (self.service_tun)
self.logger.error("[%s] WeaveTunnel: %s" % (self.service, emsg))
sys.exit(1)
if (max_wait_time) % 10 == 0:
emsg = "Waiting for interface %s to be created." % (self.service_tun)
self.logger.debug("[%s] WeaveTunnel: %s" % (self.service, emsg))
with self.getStateLockManager():
self.readState()
new_node_interface = {}
new_node_interface["link"] = None
new_node_interface["type"] = self.network_type["tun"]
new_node_interface["ip"] = {}
self.setNodeInterface(self.service, self.service_tun, new_node_interface)
self.writeState()
def __assign_tunnel_endpoint_ula_at_test_server(self):
addr = self.getServiceWeaveIPAddress("Tunnel", self.service)
options = happy.HappyNodeAddress.option()
options["quiet"] = self.quiet
options["node_id"] = self.service
options["interface"] = self.service_tun
options["address"] = addr
options["add"] = True
addAddr = happy.HappyNodeAddress.HappyNodeAddress(options)
addAddr.run()
def __start_test_tunnel_border_gateway_client(self):
cmd = self.getWeaveTunnelTestBRPath()
if not cmd:
return
cmd += " --node-id " + self.gateway_weave_id
cmd += " --fabric-id " + str(self.fabric_id)
if self.tap:
cmd += " --interface " + self.tap
cmd += " -S " + str(self.server_ula) + " --connect-to " + self.service_public_ip + " " + str(self.service_weave_id)
cmd = self.runAsRoot(cmd)
self.start_weave_process(self.border_gateway, cmd, self.gateway_process_tag, sync_on_output=self.ready_to_service_events_str)
def run(self):
self.logger.debug("[localhost] WeaveTunnelStart: Run.")
with self.getStateLockManager():
self.__pre_check()
self.__start_tunnel_test_server()
self.__assign_tunnel_endpoint_ula_at_test_server()
self.__start_test_tunnel_border_gateway_client()
self.__wait_for_gateway()
gateway_output_value, gateway_output_data = \
self.get_test_output(self.border_gateway, self.gateway_process_tag, True)
gateway_strace_value, gateway_strace_data = \
self.get_test_strace(self.border_gateway, self.gateway_process_tag, True)
self.__stop_server_side()
service_output_value, service_output_data = \
self.get_test_output(self.service, self.service_process_tag, True)
service_strace_value, service_strace_data = \
self.get_test_strace(self.service, self.service_process_tag, True)
status, results = self.__process_results(gateway_output_data)
data = {}
data["gateway_output"] = gateway_output_data
data["gateway_strace"] = gateway_strace_data
data["service_output"] = service_output_data
data["service_strace"] = service_strace_data
self.logger.debug("[localhost] WeaveTunnelTest: Done.")
return ReturnMsg(status, data)