def condition_test(): """Test basic Condition functionality.""" x = y = 0 callback_sink = [] cx = ratchet.Condition('cx', lambda: x != 0, 0) cy = ratchet.Condition('cx', lambda: y != 0, 0.1, callback=lambda: callback_sink.append([0])) wvtest.WVEXCEPT(ratchet.TimeoutException, cx.check) wvtest.WVFAIL(cy.check()) time.sleep(0.1) wvtest.WVEXCEPT(ratchet.TimeoutException, cy.check) x = 1 wvtest.WVEXCEPT(ratchet.TimeoutException, cx.check) cx.reset() wvtest.WVPASS(cx.check()) y = 1 cy.reset() wvtest.WVPASS(cy.check()) wvtest.WVPASSEQ(len(callback_sink), 1) # Callback shouldn't fire again. wvtest.WVPASS(cy.check()) wvtest.WVPASSEQ(len(callback_sink), 1) cy.reset() wvtest.WVPASS(cy.check()) wvtest.WVPASSEQ(len(callback_sink), 2)
def file_condition_test(): """Test File*Condition functionality.""" _, filename = tempfile.mkstemp() c_exists = ratchet.FileExistsCondition('c exists', filename, 0.1) c_touched = ratchet.FileTouchedCondition('c touched', filename, 0.1) wvtest.WVPASS(c_exists.check()) wvtest.WVFAIL(c_touched.check()) # File mtime resolution isn't fine enough to see the difference between this # write and the previous one, so sleep for a short time before writing to # ensure a different mtime. time.sleep(0.01) open(filename, 'w') wvtest.WVPASS(c_touched.check()) # Test that pre-existing files don't count. c_touched.reset() wvtest.WVFAIL(c_touched.check()) time.sleep(0.1) wvtest.WVEXCEPT(ratchet.TimeoutException, c_touched.check) # Test that deleting files doesn't count. c_touched.reset() wvtest.WVFAIL(c_touched.check()) os.unlink(filename) wvtest.WVFAIL(c_touched.check())
def TaxonomyTest(): taxonomy.dhcp.DHCP_LEASES_FILE = 'fake/dhcp.leases' clientinfo.FINGERPRINTS_DIR = 'fake/taxonomy' wvtest.WVPASS('Nexus 6' in clientinfo.taxonomize('00:00:01:00:00:01')) wvtest.WVPASS('Nexus 6' in clientinfo.taxonomize('00:00:01:00:00:01\n')) v = 'Moto G or Moto X' wvtest.WVPASS(v in clientinfo.taxonomize('9c:d9:17:00:00:02')) wvtest.WVPASSEQ(clientinfo.taxonomize('00:00:22:00:00:22'), None)
def ReadParameterTest(): d = tempfile.mkdtemp() try: wc = waveguide.WifiblasterController([], d) testfile = os.path.join(d, 'wifiblaster.name') # Result should be equal in value and type (unless None). testcases = [('1\n', int, 1), ('1.5\n', float, 1.5), ('True\n', str, 'True\n'), ('x\n', int, None)] for (read_data, typecast, expected) in testcases: open(testfile, 'w').write(read_data) result = wc._ReadParameter('name', typecast) wvtest.WVPASSEQ(result, expected) if result: wvtest.WVPASS(isinstance(result, typecast)) # Make sure it works if the file isn't readable os.chmod(testfile, 0) result = wc._ReadParameter('name', int) wvtest.WVPASSEQ(result, None) # and if it generally doesn't exist os.unlink(testfile) result = wc._ReadParameter('name', str) wvtest.WVPASSEQ(result, None) finally: os.rmdir(d)
def ratchet_test(): """Test Ratchet functionality.""" class P(object): X = 'X' Y = 'Y' Z = 'Z' status.P = P status.IMPLICATIONS = {} status_export_path = tempfile.mkdtemp() try: x = y = z = 0 r = ratchet.Ratchet('test ratchet', [ ratchet.Condition('x', lambda: x, 0.1), ratchet.Condition('y', lambda: y, 0.1), ratchet.Condition('z', lambda: z, 0.1), ], status.Status('test ratchet', status_export_path)) x = y = 1 # Test that timeouts are not just summed, but start whenever the previous # step completed. wvtest.WVPASSEQ(r._current_step, 0) # pylint: disable=protected-access wvtest.WVFAIL(os.path.isfile(os.path.join(status_export_path, 'X'))) wvtest.WVFAIL(os.path.isfile(os.path.join(status_export_path, 'Y'))) wvtest.WVFAIL(os.path.isfile(os.path.join(status_export_path, 'Z'))) r.start() wvtest.WVPASS(os.path.isfile(os.path.join(status_export_path, 'X'))) wvtest.WVFAIL(os.path.isfile(os.path.join(status_export_path, 'Y'))) wvtest.WVFAIL(os.path.isfile(os.path.join(status_export_path, 'Z'))) time.sleep(0.05) wvtest.WVFAIL(r.check()) wvtest.WVPASSEQ(r._current_step, 2) # pylint: disable=protected-access wvtest.WVPASS(os.path.isfile(os.path.join(status_export_path, 'X'))) wvtest.WVPASS(os.path.isfile(os.path.join(status_export_path, 'Y'))) wvtest.WVPASS(os.path.isfile(os.path.join(status_export_path, 'Z'))) wvtest.WVFAIL(r.check()) wvtest.WVPASSEQ(r._current_step, 2) # pylint: disable=protected-access time.sleep(0.1) wvtest.WVEXCEPT(ratchet.TimeoutException, r.check) x = y = z = 1 r.start() wvtest.WVPASS(r.check()) finally: shutil.rmtree(status_export_path)
def cycler_test(): c = cycler.AgingPriorityCycler() wvtest.WVPASS(c.next() is None) cycle_length_s = .01 c = cycler.AgingPriorityCycler(cycle_length_s=cycle_length_s, items=(('A', 10), ('B', 5), ('C', 1))) # We should get all three in order, since they all have the same insertion # time. They will all get slightly different insertion times, but next() # should be fast enough that the differences don't make much difference. wvtest.WVPASSEQ(c.peek(), 'A') wvtest.WVPASSEQ(c.next(), 'A') wvtest.WVPASSEQ(c.next(), 'B') wvtest.WVPASSEQ(c.next(), 'C') wvtest.WVPASS(c.peek() is None) wvtest.WVPASS(c.next() is None) wvtest.WVPASS(c.next() is None) # Now, wait for items to be ready again and just cycle one of them. time.sleep(cycle_length_s) wvtest.WVPASSEQ(c.next(), 'A') # Now, if we wait 1.9 cycles, the aged priorities will be as follows: # A: 0.9 * 10 = 9 # B: 1.9 * 5 = 9.5 # C: 1.9 * 1 = 1.9 time.sleep(cycle_length_s * 1.9) wvtest.WVPASSEQ(c.next(), 'B') wvtest.WVPASSEQ(c.next(), 'A') wvtest.WVPASSEQ(c.next(), 'C') # Update c, keeping A as-is, removing B, updating C's priority, and adding D. # Sleep for two cycles. After the first cycle, D has priority 20 and A and C # have priority 0 (since we just cycled them). After the second cycle, the # priorities are as follows: # A: 1 * 10 = 10 # C: 1 * 20 = 20 # D: 2 * 20 = 40 c.update((('A', 10), ('C', 20), ('D', 20))) time.sleep(cycle_length_s * 2) wvtest.WVPASSEQ(c.next(), 'D') wvtest.WVPASSEQ(c.next(), 'C') wvtest.WVPASSEQ(c.next(), 'A') wvtest.WVPASS(c.next() is None)
def test_proposition(): export_path = tempfile.mkdtemp() try: rain = status.Proposition('rain', export_path) wet = status.Proposition('wet', export_path) dry = status.Proposition('dry', export_path) rain.implies(wet) wet.implies_not(dry) # Test basics. rain.set(True) wvtest.WVPASS(file_in(export_path, 'rain')) wvtest.WVPASS(file_in(export_path, 'wet')) wvtest.WVFAIL(file_in(export_path, 'dry')) # It may be wet even if it is not raining, but even in that case it is still # not dry. rain.set(False) wvtest.WVFAIL(file_in(export_path, 'rain')) wvtest.WVPASS(file_in(export_path, 'wet')) wvtest.WVFAIL(file_in(export_path, 'dry')) # Test contrapositives. dry.set(True) wvtest.WVFAIL(file_in(export_path, 'rain')) wvtest.WVFAIL(file_in(export_path, 'wet')) wvtest.WVPASS(file_in(export_path, 'dry')) # Make sure cycles are okay. tautology = status.Proposition('tautology', export_path) tautology.implies(tautology) tautology.set(True) wvtest.WVPASS(file_in(export_path, 'tautology')) zig = status.Proposition('zig', export_path) zag = status.Proposition('zag', export_path) zig.implies(zag) zag.implies(zig) zig.set(True) wvtest.WVPASS(file_in(export_path, 'zig')) wvtest.WVPASS(file_in(export_path, 'zag')) zag.set(False) wvtest.WVFAIL(file_in(export_path, 'zig')) wvtest.WVFAIL(file_in(export_path, 'zag')) finally: shutil.rmtree(export_path)
def validate_set_options_test(): """Tests utils.validate_set_options.""" os.environ['WIFI_PSK'] = 'NOT_USED' for case in _VALIDATION_PASS: try: utils.validate_set_wifi_options(make_optdict(**case)) wvtest.WVPASS(True) # Make WvTest count this as a test. except utils.BinWifiException: wvtest.WVFAIL('Test failed.') for case in _VALIDATION_FAIL: wvtest.WVEXCEPT(utils.BinWifiException, utils.validate_set_wifi_options, make_optdict(**case)) # Test failure when WIFI_PSK is missing del os.environ['WIFI_PSK'] wvtest.WVEXCEPT(utils.BinWifiException, utils.validate_set_wifi_options, make_optdict(**_VALIDATION_PASS[0])) wvtest.WVEXCEPT(utils.BinWifiException, utils.validate_set_wifi_options, make_optdict(encryption='WEP'))
def hostapd_options_preexisting_dir_test(): """Test normal bandsteering when there is a preexisting directory.""" unused_raii = experiment_testutils.MakeExperimentDirs() experiment_testutils.enable('WifiBandsteering') bandsteering_dir = bandsteering._BANDSTEERING_DIR # Create a preexisting 2.4 GHz bandsteering directory with a file in it. os.makedirs(os.path.join(bandsteering_dir, '2.4_xxxxxxxxxx')) filename = 'foo' open(os.path.join(bandsteering_dir, '2.4_xxxxxxxxxx', filename), 'a').close() # Get the options for 2.4 GHz; this should move the old directory. bandsteering.hostapd_options('2.4', 'my_ssid') # If the old directory was moved correctly, we should see our file in the new # one, and the old directory should be gone. wvtest.WVPASS( os.path.isfile( os.path.join(bandsteering_dir, '2.4_30abcc9ec8', filename))) wvtest.WVFAIL( os.path.exists(os.path.join(bandsteering_dir, '2.4_xxxxxxxxxx')))
def generic_wifi_test(w, wpa_path): # Not currently connected. subprocess.wifi.WPA_PATH = wpa_path wvtest.WVFAIL(w.wpa_supplicant) # wpa_supplicant connects. ssid = 'my=ssid' psk = 'passphrase' subprocess.mock('wifi', 'remote_ap', ssid=ssid, psk=psk, band='5', bssid='00:00:00:00:00:00', connection_check_result='succeed') subprocess.check_call(['wifi', 'setclient', '--ssid', ssid, '--band', '5'], env={'WIFI_CLIENT_PSK': psk}) wvtest.WVPASS(w.wpa_supplicant) w.set_gateway_ip('192.168.1.1') # wpa_supplicant disconnects. subprocess.mock('wifi', 'disconnected_event', '5') wvtest.WVFAIL(w.wpa_supplicant) # The wpa_supplicant process disconnects and terminates. subprocess.check_call(['wifi', 'stopclient', '--band', '5']) wvtest.WVFAIL(w.wpa_supplicant)
def OverlapsTest(): wvtest.WVPASSGE(autochannel.Overlaps20(2412, 2411), 2) # partial overlap wvtest.WVPASSEQ(autochannel.Overlaps20(2412, 2412), 1) # clean overlap wvtest.WVPASS(autochannel.Overlaps20(2412, 2393)) wvtest.WVFAIL(autochannel.Overlaps20(2412, 2392)) wvtest.WVPASS(autochannel.Overlaps20(2412, 2412)) wvtest.WVPASS(autochannel.Overlaps20(2412, 2417)) wvtest.WVPASS(autochannel.Overlaps20(2412, 2422)) wvtest.WVPASS(autochannel.Overlaps20(2412, 2427)) wvtest.WVPASS(autochannel.Overlaps20(2412, 2431)) wvtest.WVFAIL(autochannel.Overlaps20(2412, 2432)) wvtest.WVPASS(autochannel.Overlaps40(2412, 2432)) wvtest.WVPASS(autochannel.Overlaps40(2412, 2451)) # This one is non-obvious! Because on 2.4 GHz, 40 MHz wide channels are so # flexible, any 40 MHz channel overlaps with any other 40 MHz channel, even # if the primary channels are >= 40 MHz apart. For example, imagine an # AP on (2412,2432) and another on (2432,2452). They will definitely # interfere with each other. # # To narrow this down, we cheat. Overlaps40 treats the first parameter # as a verbatim 20 MHz channel, and searches for the second parameter # as part of a channel group. wvtest.WVFAIL(autochannel.Overlaps40(2412, 2452)) # On the other hand, on 5 GHz, 40 MHz channel pairs are better defined, # so there are far fewer risky combinations. wvtest.WVFAIL(autochannel.Overlaps40(5745, 5725)) wvtest.WVPASS(autochannel.Overlaps40(5745, 5765)) wvtest.WVPASS(autochannel.Overlaps40(5745, 5784)) wvtest.WVFAIL(autochannel.Overlaps40(5745, 5785)) # There are no 80 MHz channels on 2.4 GHz, so it's always the same answer # as for 40 MHz. wvtest.WVPASS(autochannel.Overlaps80(2412, 2432)) wvtest.WVFAIL(autochannel.Overlaps80(2412, 2452)) wvtest.WVFAIL(autochannel.Overlaps80(2412, 2462)) # On 5 GHz, 80 MHz pairs exist and are well-defined. wvtest.WVFAIL(autochannel.Overlaps80(5745, 5725)) wvtest.WVPASS(autochannel.Overlaps80(5745, 5765)) wvtest.WVPASS(autochannel.Overlaps80(5745, 5784)) wvtest.WVPASS(autochannel.Overlaps80(5745, 5785))
def AutoChannelTest(): combos = list( autochannel.LegalCombos(range(2412, 2500, 5), autochannel.C_24ANY)) combos_20 = [i for i in combos if len(i) == 1] # With no other APs and all idle channels, every channel is equally likely. results = set() for i in range(10000): results.add( autochannel.SoloChooseChannel(GenState([], []), combos, use_primary_spreading=True, use_active_time=True, hysteresis_freq=None).primary_freq) if len(results) == 11: break wvtest.WVPASSGE(len(results), 11) # Every channel is equally likely, but with hysteresis, we pick the # same channel every time. result1 = autochannel.SoloChooseChannel(GenState([], []), combos, use_primary_spreading=True, use_active_time=True, hysteresis_freq=None).primary_freq results = set() for i in range(100): results.add( autochannel.SoloChooseChannel( GenState([], []), combos, use_primary_spreading=True, use_active_time=True, hysteresis_freq=result1).primary_freq) print results wvtest.WVPASSEQ(len(results), 1) result1 = autochannel.SoloChooseChannel(GenState([], []), combos, use_primary_spreading=False, use_active_time=True, hysteresis_freq=None).primary_freq results = set() for i in range(100): results.add( autochannel.SoloChooseChannel( GenState([], []), combos, use_primary_spreading=False, use_active_time=True, hysteresis_freq=result1).primary_freq) print results wvtest.WVPASSEQ(len(results), 1) # With a single AP at 2432, the system should try for a 40 MHz channel # that either doesn't include 2432 (impossible) or aligns so it # at least doesn't partially overlap with 2432. That means one of the # two channels should be 2432. And we want it to *not* be the primary # channel, so that 20 MHz traffic is non-interfering. r = autochannel.SoloChooseChannel(GenState([2432], []), combos, use_primary_spreading=True, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASSNE(r.primary_freq, 2432) wvtest.WVPASSEQ(len(r.group), 2) wvtest.WVPASS(r.primary_freq in [2412, 2452]) wvtest.WVPASSEQ(r.count_80, 1) # With use_primary_spreading=False, the logic above should all work the # same, but now it should choose 2432 as the primary every time. r = autochannel.SoloChooseChannel(GenState([2432], []), combos, use_primary_spreading=False, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASSEQ(r.primary_freq, 2432) wvtest.WVPASSEQ(len(r.group), 2) wvtest.WVPASSEQ(r.count_80, 1) # A bad scenario: two existing APs too close together in the middle of the # spectrum. There's no way to get a 40 MHz channel without some kind of # partial overlap. With use_primary_spreading=True, at least the primary # channel will be clear. r = autochannel.SoloChooseChannel(GenState([2432, 2437], []), combos, use_primary_spreading=True, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASS(r.primary_freq in [2412, 2457, 2462]) # TODO(apenwarr): really we should switch to 20 MHz wide in this case. # Anything to avoid a partial overlap. But we don't yet. # wvtest.WVPASSEQ(len(r.group), 1) wvtest.WVPASSGT(r.count_80, 1) wvtest.WVPASSGT(r.count_40, 1) wvtest.WVPASSEQ(r.count_20, 0) r = autochannel.SoloChooseChannel(GenState([2432, 2437], []), combos, use_primary_spreading=False, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASS(r.primary_freq in [2432, 2437]) wvtest.WVPASSGT(r.count_80, 1) wvtest.WVPASSGT(r.count_40, 1) wvtest.WVPASSGT(r.count_20, 1) # When we force to a 20 MHz channel, it should not have any overlap, # regardless of use_primary_spreading. r = autochannel.SoloChooseChannel(GenState([2432, 2437], []), combos_20, use_primary_spreading=False, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASS(r.primary_freq in [2412, 2457, 2462]) wvtest.WVPASSEQ(r.count_20, 0) # If there are two APs on 2432, it's better to partially overlap with # those than with the one AP on 2437. r = autochannel.SoloChooseChannel(GenState([2432, 2432, 2437], []), combos, use_primary_spreading=False, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASSEQ(r.primary_freq, 2432) r = autochannel.SoloChooseChannel(GenState([2432, 2432, 2437], []), combos, use_primary_spreading=True, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASSEQ(r.primary_freq, 2412) # Even when we force 20 MHz channels, only 2412 is the right match. # The system considers 2412+2432, 2417+2437, 2432+2452, and 2437+2457 are # all in use, some of them twice. 2412 has the fewest *partial* overlaps. # (This can be improved if we teach waveguide about HT40+ vs HT40-.) r = autochannel.SoloChooseChannel(GenState([2432, 2432, 2437], []), combos_20, use_primary_spreading=True, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASS(r.primary_freq in [2412, 2452, 2457, 2462]) # Check that a busy channel overrides other logic. # With 2412 ruled out, 2452 is the next best match. r = autochannel.SoloChooseChannel(GenState([2432, 2432, 2437], [(2412, 1000, 100)]), combos_20, use_primary_spreading=True, use_active_time=True, hysteresis_freq=None) print r wvtest.WVPASSEQ(r.primary_freq, 2452) # Make sure use_active_time=False causes us to ignore busy channels. r = autochannel.SoloChooseChannel(GenState([2432, 2432, 2437], [(2412, 1000, 100)]), combos_20, use_primary_spreading=True, use_active_time=False, hysteresis_freq=None) print r wvtest.WVPASSEQ(r.primary_freq, 2412)
def lock_test(): """Test utils.lock and utils._lockfile_create_retries.""" wvtest.WVPASSEQ(utils._lockfile_create_retries(0), 1) wvtest.WVPASSEQ(utils._lockfile_create_retries(4), 1) wvtest.WVPASSEQ(utils._lockfile_create_retries(5), 2) wvtest.WVPASSEQ(utils._lockfile_create_retries(14), 2) wvtest.WVPASSEQ(utils._lockfile_create_retries(15), 3) wvtest.WVPASSEQ(utils._lockfile_create_retries(60), 5) try: temp_dir = tempfile.mkdtemp() lockfile = os.path.join(temp_dir, 'lock_and_unlock_test') def lock_until_qi_nonempty(qi, qo, timeout_sec): try: utils.lock(lockfile, timeout_sec) except utils.BinWifiException: qo.put('timed out') return qo.put('acquired') wvtest.WVPASSEQ(qi.get(), 'release') qo.put('released') sys.exit(0) # Use multiprocessing because we're using lockfile-create with --use-pid, so # we need separate PIDs. q1i = multiprocessing.Queue() q1o = multiprocessing.Queue() # The timeout here is 5 because occasionally it takes more than one second # to acquire the lock, causing the test to hang. Five seconds is enough to # prevent this. p1 = multiprocessing.Process(target=lock_until_qi_nonempty, args=(q1i, q1o, 1)) q2i = multiprocessing.Queue() q2o = multiprocessing.Queue() p2 = multiprocessing.Process(target=lock_until_qi_nonempty, args=(q2i, q2o, 10)) p1.start() wvtest.WVPASSEQ(q1o.get(), 'acquired') p2.start() wvtest.WVPASS(q2o.empty()) q1i.put('release') wvtest.WVPASSEQ(q1o.get(), 'released') p1.join() wvtest.WVPASSEQ(q2o.get(), 'acquired') q2i.put('release') wvtest.WVPASSEQ(q2o.get(), 'released') p2.join() # Now test that the timeout works. q3i = multiprocessing.Queue() q3o = multiprocessing.Queue() p3 = multiprocessing.Process(target=lock_until_qi_nonempty, args=(q3i, q3o, 1)) q4i = multiprocessing.Queue() q4o = multiprocessing.Queue() p4 = multiprocessing.Process(target=lock_until_qi_nonempty, args=(q4i, q4o, 1)) p3.start() wvtest.WVPASSEQ(q3o.get(), 'acquired') p4.start() wvtest.WVPASSEQ(q4o.get(), 'timed out') p4.join() q3i.put('release') p3.join() finally: shutil.rmtree(temp_dir)
def test_status(): export_path_s = tempfile.mkdtemp() export_path_t = tempfile.mkdtemp() export_path_st = tempfile.mkdtemp() try: s = status.Status('s', export_path_s) t = status.Status('t', export_path_t) st = status.CompositeStatus('s_or t', export_path_st, [s, t]) # Sanity check that there are no contradictions. for p, (want_true, want_false) in status.IMPLICATIONS.iteritems(): setattr(s, p.lower(), True) wvtest.WVPASS(has_file(s, p)) for wt in want_true: wvtest.WVPASS(has_file(s, wt)) for wf in want_false: wvtest.WVFAIL(has_file(s, wf)) def check_exported(check_s, check_t, filename): wvtest.WVPASSEQ(check_s, has_file(s, filename)) wvtest.WVPASSEQ(check_t, has_file(t, filename)) wvtest.WVPASSEQ(check_s or check_t, has_file(st, filename)) s.trying_wlan = True t.trying_wlan = False check_exported(True, False, status.P.TRYING_WLAN) check_exported(False, False, status.P.CONNECTED_TO_WLAN) s.connected_to_open = True check_exported(True, False, status.P.CONNECTED_TO_OPEN) check_exported(False, False, status.P.CONNECTED_TO_WLAN) s.connected_to_wlan = True t.trying_wlan = True check_exported(True, False, status.P.CONNECTED_TO_WLAN) check_exported(True, False, status.P.HAVE_WORKING_CONFIG) check_exported(False, False, status.P.CONNECTED_TO_OPEN) check_exported(False, True, status.P.TRYING_WLAN) check_exported(False, False, status.P.TRYING_OPEN) s.can_reach_acs = True s.can_reach_internet = True check_exported(True, False, status.P.CAN_REACH_ACS) check_exported(True, False, status.P.COULD_REACH_ACS) check_exported(True, False, status.P.CAN_REACH_INTERNET) check_exported(False, False, status.P.PROVISIONING_FAILED) # These should not have changed check_exported(True, False, status.P.CONNECTED_TO_WLAN) check_exported(True, False, status.P.HAVE_WORKING_CONFIG) check_exported(False, False, status.P.CONNECTED_TO_OPEN) check_exported(False, True, status.P.TRYING_WLAN) check_exported(False, False, status.P.TRYING_OPEN) # Test provisioning statuses. s.waiting_for_dhcp = True check_exported(False, True, status.P.TRYING_WLAN) check_exported(False, False, status.P.TRYING_OPEN) check_exported(False, False, status.P.CONNECTED_TO_WLAN) check_exported(True, False, status.P.CONNECTED_TO_OPEN) check_exported(True, False, status.P.WAITING_FOR_PROVISIONING) check_exported(True, False, status.P.WAITING_FOR_DHCP) s.acs_connection_check = True check_exported(False, False, status.P.WAITING_FOR_DHCP) check_exported(True, False, status.P.ACS_CONNECTION_CHECK) s.waiting_for_cwmp_wakeup = True check_exported(False, False, status.P.ACS_CONNECTION_CHECK) check_exported(True, False, status.P.WAITING_FOR_CWMP_WAKEUP) s.waiting_for_acs_session = True check_exported(False, False, status.P.WAITING_FOR_DHCP) check_exported(False, False, status.P.WAITING_FOR_CWMP_WAKEUP) check_exported(True, False, status.P.WAITING_FOR_ACS_SESSION) s.provisioning_completed = True check_exported(False, False, status.P.WAITING_FOR_PROVISIONING) check_exported(False, False, status.P.WAITING_FOR_DHCP) check_exported(False, False, status.P.ACS_CONNECTION_CHECK) check_exported(False, False, status.P.WAITING_FOR_CWMP_WAKEUP) check_exported(False, False, status.P.WAITING_FOR_CWMP_WAKEUP) finally: shutil.rmtree(export_path_s) shutil.rmtree(export_path_t) shutil.rmtree(export_path_st)
def bridge_test(): """Test Interface and Bridge.""" tmp_dir = tempfile.mkdtemp() try: autoprov_filepath = os.path.join(tmp_dir, 'autoprov') b = Bridge('br0', '10', acs_autoprovisioning_filepath=autoprov_filepath) b.set_connection_check_result('succeed') wvtest.WVFAIL(b.acs()) wvtest.WVFAIL(b.internet()) wvtest.WVFAIL(b.current_routes()) wvtest.WVFAIL(b.current_routes_normal_testonly()) wvtest.WVFAIL(os.path.exists(autoprov_filepath)) b.add_moca_station(0) wvtest.WVFAIL(os.path.exists(autoprov_filepath)) b.set_subnet('192.168.1.0/24') b.set_gateway_ip('192.168.1.1') wvtest.WVFAIL(os.path.exists(autoprov_filepath)) # Everything should fail because the interface is not initialized. wvtest.WVFAIL(b.acs()) wvtest.WVFAIL(b.internet()) wvtest.WVFAIL(b.current_routes_normal_testonly()) wvtest.WVFAIL(os.path.exists(autoprov_filepath)) b.initialize() wvtest.WVPASS(b.acs()) wvtest.WVPASS(b.internet()) current_routes = b.current_routes() wvtest.WVPASSEQ(len(current_routes), 3) wvtest.WVPASS('default' in current_routes) wvtest.WVPASS('subnet' in current_routes) wvtest.WVPASS('multicast' in current_routes) wvtest.WVPASS(os.path.exists(autoprov_filepath)) b.add_moca_station(1) wvtest.WVPASS(b.acs()) wvtest.WVPASS(b.internet()) wvtest.WVPASSEQ(len(b.current_routes()), 3) wvtest.WVPASS(os.path.exists(autoprov_filepath)) b.remove_moca_station(0) b.remove_moca_station(1) wvtest.WVFAIL(b.acs()) wvtest.WVFAIL(b.internet()) # We have no links, so should have no routes. wvtest.WVFAIL(b.current_routes()) wvtest.WVFAIL(os.path.exists(autoprov_filepath)) b.add_moca_station(2) wvtest.WVPASS(b.acs()) wvtest.WVPASS(b.internet()) wvtest.WVPASSEQ(len(b.current_routes()), 3) wvtest.WVPASS(os.path.exists(autoprov_filepath)) b.set_connection_check_result('fail') b.update_routes() wvtest.WVFAIL(b.acs()) wvtest.WVFAIL(b.internet()) # We have links but the connection check failed, so we should only have a # low priority route, i.e. metric at least 50. wvtest.WVPASSEQ(len(b.current_routes()), 3) wvtest.WVFAIL(b.current_routes_normal_testonly()) wvtest.WVFAIL(os.path.exists(autoprov_filepath)) b.set_connection_check_result('restricted') b.update_routes() wvtest.WVPASS(b.acs()) wvtest.WVFAIL(b.internet()) wvtest.WVPASSEQ(len(b.current_routes()), 3) wvtest.WVPASS(os.path.exists(autoprov_filepath)) wvtest.WVFAIL(b.get_ip_address()) subprocess.call(['ip', 'addr', 'add', '192.168.1.100', 'dev', b.name]) wvtest.WVPASSEQ(b.get_ip_address(), '192.168.1.100') # Get a new gateway/subnet (e.g. due to joining a new network). # Not on the subnet; adding IP should fail. b.set_gateway_ip('192.168.2.1') wvtest.WVFAIL('default' in b.current_routes()) wvtest.WVPASS('subnet' in b.current_routes()) # Without a default route, the connection check should fail. wvtest.WVFAIL(b.acs()) # Now we get the subnet and should add updated subnet and gateway routes. b.set_subnet('192.168.2.0/24') wvtest.WVPASSEQ(b.current_routes()['default']['via'], '192.168.2.1') wvtest.WVPASSLE(int(b.current_routes()['default']['metric']), 50) wvtest.WVPASSEQ(b.current_routes()['subnet']['route'], '192.168.2.0/24') wvtest.WVPASSLE(int(b.current_routes()['subnet']['metric']), 50) wvtest.WVPASS(b.acs()) # If we have no subnet, make sure that both subnet and default routes are # removed. b.set_subnet(None) wvtest.WVFAIL('subnet' in b.current_routes()) wvtest.WVFAIL('default' in b.current_routes()) # Now repeat the new-network test, but with a faulty connection. Make sure # the metrics are set appropriately. b.set_connection_check_result('fail') b.set_subnet('192.168.3.0/24') b.set_gateway_ip('192.168.3.1') wvtest.WVPASSGE(int(b.current_routes()['default']['metric']), 50) wvtest.WVPASSGE(int(b.current_routes()['subnet']['metric']), 50) # Now test deleting only the gateway IP. b.set_gateway_ip(None) wvtest.WVPASS('subnet' in b.current_routes()) wvtest.WVFAIL('default' in b.current_routes()) finally: shutil.rmtree(tmp_dir)
def simulate_wireless_test(): """Test the WifiSimulateWireless experiment.""" unused_raii = experiment_testutils.MakeExperimentDirs() tmp_dir = tempfile.mkdtemp() interface.CWMP_PATH = tempfile.mkdtemp() interface.MAX_ACS_FAILURE_S = 1 contact = os.path.join(interface.CWMP_PATH, 'acscontact') connected = os.path.join(interface.CWMP_PATH, 'acsconnected') try: autoprov_filepath = os.path.join(tmp_dir, 'autoprov') b = Bridge('br0', '10', acs_autoprovisioning_filepath=autoprov_filepath) b.add_moca_station(0) b.set_gateway_ip('192.168.1.1') b.set_subnet('192.168.1.0/24') b.set_connection_check_result('succeed') b.initialize() # Initially, the connection check passes. wvtest.WVPASS(b.internet()) # Enable the experiment. experiment_testutils.enable('WifiSimulateWireless') # Calling update_routes overwrites the connection status cache, which we # need in order to see the effects we are looking for immediately # (ConnectionManager calls this every few seconds). b.update_routes() wvtest.WVFAIL(b.internet()) # Create an ACS connection attempt. open(contact, 'w') b.update_routes() wvtest.WVFAIL(b.internet()) # Record success. open(connected, 'w') b.update_routes() wvtest.WVFAIL(b.internet()) # Disable the experiment and the connection check should pass again. experiment_testutils.disable('WifiSimulateWireless') b.update_routes() wvtest.WVPASS(b.internet()) # Reenable the experiment and the connection check should fail again. experiment_testutils.enable('WifiSimulateWireless') b.update_routes() wvtest.WVFAIL(b.internet()) # Wait until we've failed for long enough for the experiment to "expire", # then log another attempt without success. Make sure the connection check # passes. time.sleep(interface.MAX_ACS_FAILURE_S) open(contact, 'w') b.update_routes() wvtest.WVPASS(b.internet()) finally: shutil.rmtree(tmp_dir) shutil.rmtree(interface.CWMP_PATH)