1#!/usr/bin/env python3 2# 3# Copyright 2020 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import os 18import time 19import unittest 20from unittest.mock import patch 21 22from acts.controllers.ap_lib import radvd_constants 23from acts.controllers.ap_lib.radvd import Error 24from acts.controllers.ap_lib.radvd import Radvd 25 26from acts.controllers.ap_lib.radvd_config import RadvdConfig 27 28RADVD_PREFIX = 'fd00::/64' 29SEARCH_FILE = ('acts.controllers.utils_lib.commands.shell.' 30 'ShellCommand.search_file') 31DELETE_FILE = ('acts.controllers.utils_lib.commands.shell.ShellCommand.' 32 'delete_file') 33 34CORRECT_COMPLEX_RADVD_CONFIG = ("""interface wlan0 { 35 IgnoreIfMissing on; 36 AdvSendAdvert off; 37 UnicastOnly on; 38 MaxRtrAdvInterval 60; 39 MinRtrAdvInterval 5; 40 MinDelayBetweenRAs 5; 41 AdvManagedFlag off; 42 AdvOtherConfigFlag on; 43 AdvLinkMTU 1400; 44 AdvReachableTime 3600000; 45 AdvRetransTimer 10; 46 AdvCurHopLimit 50; 47 AdvDefaultLifetime 8000; 48 AdvDefaultPreference off; 49 AdvSourceLLAddress on; 50 AdvHomeAgentFlag off; 51 AdvHomeAgentInfo on; 52 HomeAgentLifetime 100; 53 HomeAgentPreference 100; 54 AdvMobRtrSupportFlag off; 55 AdvIntervalOpt on; 56 prefix fd00::/64 57 { 58 AdvOnLink off; 59 AdvAutonomous on; 60 AdvRouterAddr off; 61 AdvValidLifetime 86400; 62 AdvPreferredLifetime 14400; 63 Base6to4Interface NA; 64 }; 65 clients 66 { 67 fe80::c66d:3c75:2cec:1d72; 68 fe80::c66d:3c75:2cec:1d73; 69 }; 70 route fd00::/64 { 71 AdvRouteLifetime 1024; 72 AdvRoutePreference high; 73 }; 74 RDNSS 2401:fa00:480:7a00:4d56:5373:4549:1e29 2401:fa00:480:7a00:4d56:5373:4549:1e30 { 75 AdvRDNSSPreference 8; 76 AdvRDNSSOpen on; 77 AdvRDNSSLifetime 1025; 78 }; 79};""".replace(" ", "\t")) 80 81CORRECT_SIMPLE_RADVD_CONFIG = ("""interface wlan0 { 82 AdvSendAdvert on; 83 prefix fd00::/64 84 { 85 AdvOnLink on; 86 AdvAutonomous on; 87 }; 88};""".replace(" ", "\t")) 89 90 91def delete_file_mock(file_to_delete): 92 if os.path.exists(file_to_delete): 93 os.remove(file_to_delete) 94 95 96def write_configs_mock(config_file_with_path, output_config): 97 with open(config_file_with_path, 'w+') as config_fileId: 98 config_fileId.write(output_config) 99 100 101class RadvdTest(unittest.TestCase): 102 @patch('acts.controllers.utils_lib.commands.shell.ShellCommand.kill') 103 def test_radvd_ikill(self, kill): 104 kill.return_value = True 105 radvd_mock = Radvd('mock_runner', 'wlan0') 106 self.assertIsNone(radvd_mock.stop()) 107 108 @patch('acts.controllers.utils_lib.commands.shell.ShellCommand.is_alive') 109 def test_radvd_is_alive_True(self, is_alive_mock): 110 is_alive_mock.return_value = True 111 radvd_mock = Radvd('mock_runner', 'wlan0') 112 self.assertTrue(radvd_mock.is_alive()) 113 114 @patch('acts.controllers.utils_lib.commands.shell.ShellCommand.is_alive') 115 def test_radvd_is_alive_False(self, is_alive_mock): 116 is_alive_mock.return_value = False 117 radvd_mock = Radvd('mock_runner', 'wlan0') 118 self.assertFalse(radvd_mock.is_alive()) 119 120 @patch('acts.controllers.ap_lib.radvd.Radvd._scan_for_errors') 121 @patch('acts.controllers.ap_lib.radvd.Radvd.is_alive') 122 def test_wait_for_process_process_alive(self, is_alive_mock, 123 _scan_for_errors_mock): 124 is_alive_mock.return_value = True 125 _scan_for_errors_mock.return_value = True 126 radvd_mock = Radvd('mock_runner', 'wlan0') 127 self.assertIsNone(radvd_mock._wait_for_process(timeout=2)) 128 129 @patch('acts.controllers.ap_lib.radvd.Radvd.is_alive') 130 @patch(SEARCH_FILE) 131 def test_scan_for_errors_is_dead(self, search_file_mock, is_alive_mock): 132 is_alive_mock.return_value = False 133 search_file_mock.return_value = False 134 radvd_mock = Radvd('mock_runner', 'wlan0') 135 with self.assertRaises(Error) as context: 136 radvd_mock._scan_for_errors(True) 137 self.assertTrue('Radvd failed to start' in str(context.exception)) 138 139 @patch('acts.controllers.ap_lib.radvd.Radvd.is_alive') 140 @patch(SEARCH_FILE) 141 def test_scan_for_errors_exited_prematurely(self, search_file_mock, 142 is_alive_mock): 143 is_alive_mock.return_value = True 144 search_file_mock.return_value = True 145 radvd_mock = Radvd('mock_runner', 'wlan0') 146 with self.assertRaises(Error) as context: 147 radvd_mock._scan_for_errors(True) 148 self.assertTrue('Radvd exited prematurely.' in str(context.exception)) 149 150 @patch('acts.controllers.ap_lib.radvd.Radvd.is_alive') 151 @patch(SEARCH_FILE) 152 def test_scan_for_errors_success(self, search_file_mock, is_alive_mock): 153 is_alive_mock.return_value = True 154 search_file_mock.return_value = False 155 radvd_mock = Radvd('mock_runner', 'wlan0') 156 self.assertIsNone(radvd_mock._scan_for_errors(True)) 157 158 @patch(DELETE_FILE) 159 @patch('acts.controllers.utils_lib.commands.shell.ShellCommand.write_file') 160 def test_write_configs_simple(self, write_file, delete_file): 161 delete_file.side_effect = delete_file_mock 162 write_file.side_effect = write_configs_mock 163 basic_radvd_config = RadvdConfig( 164 prefix=RADVD_PREFIX, 165 adv_send_advert=radvd_constants.ADV_SEND_ADVERT_ON, 166 adv_on_link=radvd_constants.ADV_ON_LINK_ON, 167 adv_autonomous=radvd_constants.ADV_AUTONOMOUS_ON) 168 radvd_mock = Radvd('mock_runner', 'wlan0') 169 radvd_mock._write_configs(basic_radvd_config) 170 radvd_config = radvd_mock._config_file 171 with open(radvd_config, 'r') as radvd_config_fileId: 172 config_data = radvd_config_fileId.read() 173 self.assertTrue(CORRECT_SIMPLE_RADVD_CONFIG == config_data) 174 175 @patch(DELETE_FILE) 176 @patch('acts.controllers.utils_lib.commands.shell.ShellCommand.write_file') 177 def test_write_configs_complex(self, write_file, delete_file): 178 delete_file.side_effect = delete_file_mock 179 write_file.side_effect = write_configs_mock 180 complex_radvd_config = RadvdConfig( 181 prefix=RADVD_PREFIX, 182 clients=['fe80::c66d:3c75:2cec:1d72', 'fe80::c66d:3c75:2cec:1d73'], 183 route=RADVD_PREFIX, 184 rdnss=[ 185 '2401:fa00:480:7a00:4d56:5373:4549:1e29', 186 '2401:fa00:480:7a00:4d56:5373:4549:1e30', 187 ], 188 ignore_if_missing=radvd_constants.IGNORE_IF_MISSING_ON, 189 adv_send_advert=radvd_constants.ADV_SEND_ADVERT_OFF, 190 unicast_only=radvd_constants.UNICAST_ONLY_ON, 191 max_rtr_adv_interval=60, 192 min_rtr_adv_interval=5, 193 min_delay_between_ras=5, 194 adv_managed_flag=radvd_constants.ADV_MANAGED_FLAG_OFF, 195 adv_other_config_flag=radvd_constants.ADV_OTHER_CONFIG_FLAG_ON, 196 adv_link_mtu=1400, 197 adv_reachable_time=3600000, 198 adv_retrans_timer=10, 199 adv_cur_hop_limit=50, 200 adv_default_lifetime=8000, 201 adv_default_preference=radvd_constants.ADV_DEFAULT_PREFERENCE_OFF, 202 adv_source_ll_address=radvd_constants.ADV_SOURCE_LL_ADDRESS_ON, 203 adv_home_agent_flag=radvd_constants.ADV_HOME_AGENT_FLAG_OFF, 204 adv_home_agent_info=radvd_constants.ADV_HOME_AGENT_INFO_ON, 205 home_agent_lifetime=100, 206 home_agent_preference=100, 207 adv_mob_rtr_support_flag=radvd_constants. 208 ADV_MOB_RTR_SUPPORT_FLAG_OFF, 209 adv_interval_opt=radvd_constants.ADV_INTERVAL_OPT_ON, 210 adv_on_link=radvd_constants.ADV_ON_LINK_OFF, 211 adv_autonomous=radvd_constants.ADV_AUTONOMOUS_ON, 212 adv_router_addr=radvd_constants.ADV_ROUTER_ADDR_OFF, 213 adv_valid_lifetime=86400, 214 adv_preferred_lifetime=14400, 215 base_6to4_interface='NA', 216 adv_route_lifetime=1024, 217 adv_route_preference=radvd_constants.ADV_ROUTE_PREFERENCE_HIGH, 218 adv_rdnss_preference=8, 219 adv_rdnss_open=radvd_constants.ADV_RDNSS_OPEN_ON, 220 adv_rdnss_lifetime=1025) 221 radvd_mock = Radvd('mock_runner', 'wlan0') 222 radvd_mock._write_configs(complex_radvd_config) 223 radvd_config = radvd_mock._config_file 224 with open(radvd_config, 'r') as radvd_config_fileId: 225 config_data = radvd_config_fileId.read() 226 self.assertTrue(CORRECT_COMPLEX_RADVD_CONFIG == config_data) 227