def basic_call(sipcenter, caller, callee, board, sipserver_ip, dial_number, tcid): """ To make a basic call. Parameters: sipcenter(object): sipcenter device caller(object): caller device callee(object): callee device sipserver_ip(string): sipserver_ip dial_number(string): number to be dialed Return: media_out(string): media output through which tones are validated """ # phone start retry_on_exception(caller.phone_start, ()) retry_on_exception(callee.phone_start, ()) # phone dial caller.dial(dial_number, sipserver_ip) # phone answer callee.answer() # board verify media_out = board.check_media_started(tcid) # call hangup board.expect(pexpect.TIMEOUT, timeout=20) board.send_sip_offhook_onhook(flag="onhook", tcid=tcid) # phone kill caller.phone_kill() callee.phone_kill() return media_out
def kill_process(device, process="tcpdump", pid=None, sync=True, port=None): """Kill any active process :param device: lan or wan :type device: Object :param process: process to kill, defaults to tcpdump :type process: String, Optional :param pid: process id to kill, defaults to None :type pid: String, Optional :param sync: Marked False if sync should not be executed;defaults to True :type sync: Boolean,optional :param port: port number to kill :type port: int :return: Console output of sync sendline command after kill process :rtype: string """ if pid: device.sudo_sendline("kill %s" % pid) elif port: device.sudo_sendline(r"kill $(lsof -t -i:%s)" % str(port)) else: device.sudo_sendline("killall %s" % process) device.expect(device.prompt) if sync: device.sudo_sendline("sync") retry_on_exception(device.expect, (device.prompt, ), retries=5, tout=60) return device.before
def nmap_cli(device, ip_address, port, protocol=None, retry=0, timing="", optional=""): """To run port scanning on the specified target.Port scan is a method for determining which ports on a interface are open. This method is used to perform port scanning on the specified port range of the target ip specified from the device specified. :param device: device on which nmap command to run :type device: object :param ip_address: target ip address :type ip_address: string :param port: port range to be scanned :type port: string :param protocol: protocol (tcp/ucp/both), default to None :type protocol: String, Optional :param retry: maximum number of retries, defaults to 0 :type retry: integer, Optional :param timing: Timing templates(-T[1-4]), defaults to '' Each template will have different timings for different actions :type timing: String, Optional :param optional: Other options like minimum rate limit(packets/sec), max rate limit(packets/sec) :type optional: String :return: Output of namp command. :rtype: string """ if not protocol: protocol = "both" ipv6 = ("-6" if "IPv6Address" == type( ipaddress.ip_address(six.text_type(ip_address))).__name__ else "") protocol_commandmap = {"tcp": "-sT", "udp": "-sU", "both": "-sT -sU"} device.sudo_sendline( "nmap %s %s %s %s -p%s -Pn -r -max-retries %s %s > nmap_logs.txt" % ( ipv6, timing, protocol_commandmap[protocol], ip_address, port, retry, optional, )) retry_on_exception(device.expect, (device.prompt, ), retries=16, tout=30) device.sendline("cat nmap_logs.txt") device.expect(device.prompt) nmap_output = device.before device.sendline("rm nmap_logs.txt") device.expect(device.prompt) return nmap_output
def kill_process(device, process="tcpdump"): """Kill any active process :param device: lan or wan :type device: Object :param process: process to kill, defaults to tcpdump :type process: String, Optional :return: Console ouput of sync sendline command after kill process :rtype: string """ device.sudo_sendline("killall %s" % process) device.expect(device.prompt) device.sudo_sendline("sync") retry_on_exception(device.expect, (device.prompt, ), retries=5, tout=60) return device.before
def _restart_dhcp(self): do_ipv6 = True try: chk_ip = self.get_interface_ip6addr(self.iface_dut) if ipaddress.IPv6Address( six.text_type(chk_ip)) not in self.prov_nw_ipv6: do_ipv6 = False if self.tftp_device.tftp_server_ipv6_int() is None: do_ipv6 = False except: do_ipv6 = False match_num = retry_on_exception(self._try_to_restart_dhcp, (do_ipv6, )) if match_num != 0: self.sendline('tail /var/log/syslog -n 100') self.expect(self.prompt) self.sendline('cat /etc/dhcp/dhcpd.conf') self.expect(self.prompt) self.sendline('cat /etc/dhcp/dhcpd6.conf') self.expect(self.prompt) assert match_num == 0, "Incorrect number of DHCP servers started, something went wrong!" self.sendline('ps aux | grep dhcpd; echo DONE') self.expect_exact('ps aux | grep dhcpd; echo DONE') self.expect('DONE') assert len(re.findall( 'dhcpd[^\n]*-4', self.before)) == 1, "Wrong number of DHCP4 servers running" assert len(re.findall( 'dhcpd[^\n]*-6', self.before)) == 1, "Wrong number of DHCP6 servers running" self.expect(self.prompt)
def check_cm_firmware_version(board, wan, env_helper): """Compare CM firmware version with provided enviornment FM version checking all images ending with suffix <fm_version>.* eg CH7465LG-NCIP-6.12.18.26-3-GA-SH.p7 :param board : board DUT device class :type board : device_type.DUT :param wan : wan is wan device type :type wan : device_type.wan :param env_helper : device class to fetch different devices :type env_helper : boardfarm_docsis.devices.Docsis :rtype: Bool :raise Assertion: Asserts when CM FM Mismatch or exception :return: returns bool True if FM Matches """ if env_helper.has_image(): fm_ver = env_helper.get_image(mirror=False).rpartition(".")[0] cm_ip = board.get_interface_ipaddr(board.wan_iface) result = retry_on_exception( SnmpHelper.snmp_v2, [wan, cm_ip, "docsDevSwCurrentVers"], retries=2 ) # temporary fix, needs rework to being vendor independent assert ( result in fm_ver ), "CM FM Version Mismatch current {} not in requested {}".format( result, fm_ver ) return True
def start_lan_client(self, wan_gw=None, ipv4_only=False): ipv4, ipv6 = None, None self.sendline('ip link set down %s && ip link set up %s' % (self.iface_dut, self.iface_dut)) self.expect(self.prompt) self.sendline("dhclient -4 -r %s" % self.iface_dut) self.expect(self.prompt) self.sendline('dhclient -6 -r -i %s' % self.iface_dut) self.expect(self.prompt, timeout=60) self.sendline('kill $(</run/dhclient6.pid)') self.expect(self.prompt) self.sendline('kill $(</run/dhclient.pid)') self.expect(self.prompt) self.sendline('ps aux') if self.expect(['dhclient'] + self.prompt) == 0: print( "WARN: dhclient still running, something started rogue client!" ) self.sendline('pkill --signal 9 -f dhclient.*%s' % self.iface_dut) self.expect(self.prompt) if not ipv4_only: self.disable_ipv6(self.iface_dut) self.enable_ipv6(self.iface_dut) self.sendline('sysctl -w net.ipv6.conf.%s.accept_dad=0' % self.iface_dut) # check if board is providing an RA, if yes use that detail to perform DHCPv6 # default method used will be statefull DHCPv6 output = self.check_output("rdisc6 -1 %s" % self.iface_dut, timeout=60) M_bit, O_bit = True, True if "Prefix" in output: M_bit, O_bit = map(lambda x: "Yes" in x, re.findall(r"Stateful.*\W", output)) # Condition for Stateless DHCPv6, this should update DNS details via DHCP and IP via SLAAC if not M_bit and O_bit: self.sendline("dhclient -S -v %s" % self.iface_dut) if 0 == self.expect([pexpect.TIMEOUT] + self.prompt, timeout=15): self.sendcontrol('c') self.expect(self.prompt) # Condition for Statefull DHCPv6, DNS and IP details provided using DHCPv6 elif M_bit and O_bit: self.sendline('dhclient -6 -i -v %s' % self.iface_dut) if 0 == self.expect([pexpect.TIMEOUT] + self.prompt, timeout=15): self.sendcontrol('c') self.expect(self.prompt) # if env is dual, code should always return an IPv6 address # need to actually throw an error, for IPv6 not receiving an IP try: ipv6 = self.get_interface_ip6addr(self.iface_dut) except: pass self.disable_ipv6('eth0') self.sendline('\nifconfig %s 0.0.0.0' % self.iface_dut) self.expect(self.prompt) self.sendline('rm /var/lib/dhcp/dhclient.leases') self.expect(self.prompt) self.sendline( "sed -e 's/mv -f $new_resolv_conf $resolv_conf/cat $new_resolv_conf > $resolv_conf/g' -i /sbin/dhclient-script" ) self.expect(self.prompt) if self.mgmt_dns is not None: self.sendline( "sed '/append domain-name-servers %s/d' -i /etc/dhcp/dhclient.conf" % str(self.mgmt_dns)) self.expect(self.prompt) self.sendline( 'echo "append domain-name-servers %s;" >> /etc/dhcp/dhclient.conf' % str(self.mgmt_dns)) self.expect(self.prompt) # TODO: don't hard code eth0 self.sendline('ip route del default dev eth0') self.expect(self.prompt) for attempt in range(3): try: self.sendline('dhclient -4 -v %s' % self.iface_dut) if 0 == self.expect(['DHCPOFFER'] + self.prompt, timeout=30): self.expect(self.prompt) break else: retry_on_exception( valid_ipv4, (self.get_interface_ipaddr(self.iface_dut), ), retries=5) break except: self.sendline('killall dhclient') self.sendcontrol('c') else: raise Exception( "Error: Device on LAN couldn't obtain address via DHCP.") self.sendline('cat /etc/resolv.conf') self.expect(self.prompt) self.sendline('ip addr show dev %s' % self.iface_dut) self.expect(self.prompt) self.sendline('ip route') # TODO: we should verify this so other way, because the they could be the same subnets # in theory i = self.expect([ 'default via %s dev %s' % (self.lan_gateway, self.iface_dut), pexpect.TIMEOUT ], timeout=5) if i == 1: # bridged mode self.is_bridged = True # update gw self.sendline("ip route list 0/0 | awk '{print $3}'") self.expect_exact("ip route list 0/0 | awk '{print $3}'") self.expect(self.prompt) self.lan_gateway = ipaddress.IPv4Address( six.text_type(self.before.strip())) ip_addr = self.get_interface_ipaddr(self.iface_dut) self.sendline("ip route | grep %s | awk '{print $1}'" % ip_addr) self.expect_exact("ip route | grep %s | awk '{print $1}'" % ip_addr) self.expect(self.prompt) self.lan_network = ipaddress.IPv4Network( six.text_type(self.before.strip())) self.sendline('ip -6 route') self.expect(self.prompt) # Setup HTTP proxy, so board webserver is accessible via this device self.sendline('curl --version') self.expect_exact('curl --version') self.expect(self.prompt) self.sendline('ab -V') self.expect(self.prompt) self.sendline('nmap --version') self.expect(self.prompt) self.start_tinyproxy() # Write a useful ssh config for routers self.sendline('mkdir -p ~/.ssh') self.sendline('cat > ~/.ssh/config << EOF') self.sendline('Host %s' % self.lan_gateway) self.sendline('StrictHostKeyChecking no') self.sendline('UserKnownHostsFile=/dev/null') self.sendline('') self.sendline('Host krouter') self.sendline('Hostname %s' % self.lan_gateway) self.sendline('StrictHostKeyChecking no') self.sendline('UserKnownHostsFile=/dev/null') self.sendline('EOF') self.expect(self.prompt) # Copy an id to the router so people don't have to type a password to ssh or scp self.sendline('nc %s 22 -w 1 | cut -c1-3' % self.lan_gateway) self.expect_exact('nc %s 22 -w 1 | cut -c1-3' % self.lan_gateway) if 0 == self.expect(['SSH'] + self.prompt, timeout=5) and not self.is_bridged: self.sendcontrol('c') self.expect(self.prompt) self.sendline( '[ -e /root/.ssh/id_rsa ] || ssh-keygen -N "" -f /root/.ssh/id_rsa' ) if 0 != self.expect(['Protocol mismatch.'] + self.prompt): self.sendline( '\nscp ~/.ssh/id_rsa.pub %s:/etc/dropbear/authorized_keys' % self.lan_gateway) self.expect('_keys') if 0 == self.expect(['assword:'] + self.prompt): self.sendline('password') self.expect(self.prompt) else: self.sendcontrol('c') self.expect(self.prompt) if self.install_pkgs_after_dhcp: self.install_pkgs() if wan_gw is not None and 'options' in self.kwargs and \ 'lan-fixed-route-to-wan' in self.kwargs['options']: self.sendline('ip route add %s via %s' % (wan_gw, self.lan_gateway)) self.expect(self.prompt) ipv4 = self.get_interface_ipaddr(self.iface_dut) return ipv4, ipv6
def test_retry_on_exception_neg_retry(self): """The exception is raised when no retries are specified.""" with pytest.raises(NameError): common.retry_on_exception(throw_error, (), -1, tout=0)
def test_retry_with_exceptions(self, test_input): """The exception is raised after a given number of retries.""" with pytest.raises(NameError): common.retry_on_exception(throw_error, (), test_input, tout=0)
def test_retry_on_exception_no_output(self): """A proper function call does not trigger any exception.""" print_var = ["you should read this line only once"] out = common.retry_on_exception(prt_smt, print_var, 1, tout=0) assert out is None
def test_retry_on_exception_no_raise_1_retry(self): """A proper function call does not trigger any exception.""" out = common.retry_on_exception(sum, [(3, 2)], 1, tout=0) assert out == 5
def _start_lan_client(dev): ipv4, ipv6 = retry_on_exception(dev.start_lan_client, [], retries=1) return {"ipv4": ipv4, "ipv6": ipv6}