def test_config_wifi(): """ Test paradrop.lib.config.wifi """ from paradrop.core.config import wifi update = MockUpdate() update.old = None update.new = MockChute() # Chute has no net information, we should pass silently. assert wifi.getOSWirelessConfig(update) is None interfaces = fake_interface_list() update.new.setCache('networkInterfaces', interfaces) wifi.getOSWirelessConfig(update) # Verify the new cache entry result = update.new.getCache('osWirelessConfig') assert len(result) == 1 # Need to make a writable location for our config files. settings.UCI_CONFIG_DIR = tempfile.mkdtemp() settings.UCI_BACKUP_DIR = tempfile.mkdtemp() wifi.setOSWirelessConfig(update) # Clean up our config dir pdos.remove(settings.UCI_CONFIG_DIR) pdos.remove(settings.UCI_BACKUP_DIR)
def test_revert_config(): """ Test the revertConfig function """ from paradrop.core.config import osconfig # Need to make a writable location for our config files. settings.UCI_CONFIG_DIR = tempfile.mkdtemp() settings.UCI_BACKUP_DIR = tempfile.mkdtemp() update = MockUpdate() update.old = None update.new = MockChute() osconfig.revertConfig(update, "network") # Clean up our config dir pdos.remove(settings.UCI_CONFIG_DIR) pdos.remove(settings.UCI_BACKUP_DIR)
def test_config_dhcp(): """ Test paradrop.lib.config.dhcp """ from paradrop.core.config import dhcp update = MockUpdate() update.old = None update.new = MockChute() # Should do nothing before we set "networkInterfaces". dhcp.getVirtDHCPSettings(update) interfaces = fake_interface_list() update.new.setCache("externalSystemDir", "/tmp") update.new.setCache("networkInterfaces", interfaces) settings.UCI_CONFIG_DIR = tempfile.mkdtemp() settings.UCI_BACKUP_DIR = tempfile.mkdtemp() # Test code path with caching enabled dhcp.DNSMASQ_CACHE_ENABLED = True dhcp.getVirtDHCPSettings(update) dhcp.setVirtDHCPSettings(update) # Test code path with caching disabled dhcp.DNSMASQ_CACHE_ENABLED = False dhcp.getVirtDHCPSettings(update) dhcp.setVirtDHCPSettings(update) pdos.remove(settings.UCI_CONFIG_DIR) pdos.remove(settings.UCI_BACKUP_DIR) # Test with missing "lease" field. interfaces.append({'name': 'broken', 'dhcp': {'start': 100, 'limit': 100}}) assert_raises(Exception, dhcp.getVirtDHCPSettings, update)
def test_addresses(): """ Test IP address utility functions """ from paradrop.lib.utils import addresses ipaddr = "192.168.1.1" assert addresses.isIpValid(ipaddr) ipaddr = "192.168.1.256" assert not addresses.isIpValid(ipaddr) chute = MockChute(name="first") chute.IPs.append("192.168.1.1") chute.SSIDs.append("Paradrop") chute.staticIPs.append("192.168.33.1") storage = MockChuteStorage() storage.chuteList.append(chute) assert not addresses.isIpAvailable("192.168.1.1", storage, "second") assert addresses.isIpAvailable("192.168.2.1", storage, "second") assert addresses.isIpAvailable("192.168.1.1", storage, "first") assert not addresses.isWifiSSIDAvailable("Paradrop", storage, "second") assert addresses.isWifiSSIDAvailable("available", storage, "second") assert addresses.isWifiSSIDAvailable("Paradrop", storage, "first") assert not addresses.isStaticIpAvailable("192.168.33.1", storage, "second") assert addresses.isStaticIpAvailable("192.168.35.1", storage, "second") assert addresses.isStaticIpAvailable("192.168.33.1", storage, "first") assert not addresses.checkPhyExists(-100) ipaddr = "192.168.1.1" netmask = "255.255.255.0" assert addresses.incIpaddr("192.168.1.1") == "192.168.1.2" assert addresses.incIpaddr("fail") is None assert addresses.maxIpaddr(ipaddr, netmask) == "192.168.1.254" assert addresses.maxIpaddr(ipaddr, "fail") is None assert addresses.getSubnet(ipaddr, netmask) == "192.168.1.0" assert addresses.getSubnet(ipaddr, "fail") is None # Test with nothing in the cache assert addresses.getInternalIntfList(chute) is None assert addresses.getGatewayIntf(chute) == (None, None) assert addresses.getWANIntf(chute) is None # Now put an interface in the cache ifaces = [{ 'internalIntf': "eth0", 'type': "wan", 'externalIpaddr': "192.168.1.1" }] chute.setCache("networkInterfaces", ifaces) assert addresses.getInternalIntfList(chute) == ["eth0"] assert addresses.getGatewayIntf(chute) == ("192.168.1.1", "eth0") assert addresses.getWANIntf(chute) == ifaces[0]
def test_state(): """ Test plan generation for state module """ from paradrop.core.plan import state from paradrop.core.chute.chute import Chute from paradrop.base import settings # Set this to exercise debug mode code settings.DEBUG_MODE = True update = MockUpdate() # generatePlans returns: # True on failure # None on success # Stop with no old chute should fail update.old = None update.new = MockChute() update.updateType = "stop" assert state.generatePlans(update) is True # Install with no old chute should succeed update.updateType = "install" update.new.state = Chute.STATE_RUNNING assert state.generatePlans(update) is None # Entering invalid state should fail update.new.state = Chute.STATE_INVALID assert state.generatePlans(update) is True # Start with old chute already running should fail update.old = MockChute() update.updateType = "start" update.old.state = Chute.STATE_RUNNING assert state.generatePlans(update) is True # But if the old chute was stopped, then start should succeed update.old.state = Chute.STATE_STOPPED assert state.generatePlans(update) is None # Should be fine update.updateType = "restart" assert state.generatePlans(update) is None # Create should fail when old chute exists update.updateType = "create" assert state.generatePlans(update) is True # Delete and set to stopped is fine update.new.state = Chute.STATE_STOPPED update.updateType = "delete" assert state.generatePlans(update) is None # Stopping an already stopped chute should fail update.updateType = "stop" update.old.state = Chute.STATE_STOPPED assert state.generatePlans(update) is True # Stopping a running chute is fine update.old.state = Chute.STATE_RUNNING assert state.generatePlans(update) is None
def test_get_network_config(): """ Test generating network configuration for a chute update. """ from paradrop.core.config import network from paradrop.core.config.reservations import DeviceReservations # Test normal case where key is defined and encryption is implied. iface = dict() cfg = {'key': 'password'} network.getWifiKeySettings(cfg, iface) assert iface['key'] == "password" # Test normal case where encryption is set to "none". iface = dict() cfg = {'encryption': 'none'} network.getWifiKeySettings(cfg, iface) assert iface['encryption'] == "none" # Test error case where encryption is defined but no key is present. iface = dict() cfg = {'encryption': 'psk2'} assert_raises(Exception, network.getWifiKeySettings, cfg, iface) update = MockUpdate() update.old = None update.new = MockChute() # Should do nothing on a chute with no "networkInterfaces" cache key. network.reclaimNetworkResources(update.new) # Chute has no net information, we should pass silently. assert network.getNetworkConfig(update) is None update.new.net = { 'mywifi': { 'type': 'wifi', 'intfName': 'wlan0', 'encryption': 'psk2', 'key': 'password' } } devices = { 'wifi': [{ 'name': 'wlan0', 'mac': '00:11:22:33:44:55', 'phy': 'phy0' }] } update.new.setCache("networkDevices", devices) update.new.setCache("deviceReservations", {"wlan0": DeviceReservations()}) update.new.setCache("subnetReservations", set()) update.new.setCache("interfaceReservations", set()) # Missing 'ssid' field should raise exception. assert_raises(Exception, network.getNetworkConfig, update) update.new.net['mywifi']['ssid'] = "Paradrop" # Need to make a writable location for our config files. settings.UCI_CONFIG_DIR = tempfile.mkdtemp() settings.UCI_BACKUP_DIR = tempfile.mkdtemp() # Try the normal sequence of steps for installing a new chute. network.getNetworkConfig(update) network.getOSNetworkConfig(update) network.setOSNetworkConfig(update) network.abortNetworkConfig(update) # Set up state so that old chute matches new chute. update.old = MockChute() update.old.net = update.new.net.copy() ifaces = list(update.new.getCache("networkInterfaces")) update.old.setCache("networkInterfaces", ifaces) # Now try sequence of steps that would occur for a restart. network.reclaimNetworkResources(update.old) network.getNetworkConfig(update) network.getOSNetworkConfig(update) network.setOSNetworkConfig(update) # Try asking for a new chute without any interfaces. update.new.net = dict() # This would be a restart where we remove an interface that was in old but # not in new. network.getNetworkConfig(update) network.getOSNetworkConfig(update) network.setOSNetworkConfig(update) network.abortNetworkConfig(update) # Try a network interface with missing 'type' field. update.new.net = { 'mywifi': { 'intfName': 'wlan0', } } assert_raises(Exception, network.getNetworkConfig, update) # Try asking for something funny. update.new.net = { 'mywifi': { 'type': 'fail', 'intfName': 'wlan0', } } assert_raises(Exception, network.getNetworkConfig, update) # Clean up our config dir pdos.remove(settings.UCI_CONFIG_DIR) pdos.remove(settings.UCI_BACKUP_DIR)
def test_config_firewall(): """ Test paradrop.lib.config.firewall """ from paradrop.core.config import firewall # Test findMatchingInterface function interfaces = fake_interface_list() assert firewall.findMatchingInterface("*wifi", interfaces) is not None assert firewall.findMatchingInterface("??lan", interfaces) is not None assert firewall.findMatchingInterface("missing", interfaces) is None update = MockUpdate() update.old = None update.new = MockChute() # No interfaces in the cache---should return without a problem firewall.getOSFirewallRules(update) firewall.getDeveloperFirewallRules(update) update.new.setCache("networkInterfaces", interfaces) firewall.getOSFirewallRules(update) result = update.new.getCache("osFirewallRules") assert len(result) >= 4 update.new.firewall = fake_rules_list() firewall.getDeveloperFirewallRules(update) result = update.new.getCache('developerFirewallRules') assert len(result) == 1 # Need to make a writable location for our config files. settings.UCI_CONFIG_DIR = tempfile.mkdtemp() settings.UCI_BACKUP_DIR = tempfile.mkdtemp() firewall.setOSFirewallRules(update) pdos.remove(settings.UCI_CONFIG_DIR) pdos.remove(settings.UCI_BACKUP_DIR) # Try a bad rule that has both from/to outside the chute. update.new.firewall = fake_rules_list() update.new.firewall.append({ 'name': 'bad', 'type': 'redirect', 'from': '@host.lan', 'to': '@host.lan' }) assert_raises(Exception, firewall.getDeveloperFirewallRules, update) # Try a bad rule that does not match an interface. update.new.firewall = fake_rules_list() update.new.firewall.append({ 'name': 'bad', 'type': 'redirect', 'from': '@host.lan', 'to': 'missing' }) assert_raises(Exception, firewall.getDeveloperFirewallRules, update) # Try an SNAT rule, which is not currently supported. update.new.firewall = fake_rules_list() update.new.firewall.append({ 'name': 'bad', 'type': 'redirect', 'from': 'missing', 'to': '@host.lan' }) assert_raises(Exception, firewall.getDeveloperFirewallRules, update) # Try something else that we do not recognize. update.new.firewall = fake_rules_list() update.new.firewall.append({ 'name': 'bad', 'type': 'redirect', 'from': 'missing', 'to': 'missing' }) assert_raises(Exception, firewall.getDeveloperFirewallRules, update)
def test_config_devices(): """ Test paradrop.core.config.devices """ from paradrop.core.config import devices # Test the isVirtual function assert devices.isVirtual("eth0") is False assert devices.isVirtual("v0000.eth0") assert devices.isVirtual("vethabcdef") assert devices.isWAN("eth0") assert devices.isWAN("wlan0") is False update = MockUpdate() update.old = None update.new = MockChute() hostConfig = { 'wan': { 'interface': 'eth0' }, 'lan': { 'interfaces': ['eth1'], 'ipaddr': '192.168.1.1', 'netmask': '255.255.255.0', 'dhcp': { 'start': 100, 'limit': 100, 'leasetime': '12h' } }, 'wifi': [{ 'macaddr': '00:11:22:33:44:55', 'channel': 1 }] } update.new.setCache('hostConfig', hostConfig) settings.UCI_CONFIG_DIR = tempfile.mkdtemp() settings.UCI_BACKUP_DIR = tempfile.mkdtemp() # Calling before getSystemDevices should do nothing. devices.setSystemDevices(update) # Test normal flow---our mock functions will simulate the existence of # various network interfaces. devices.getSystemDevices(update) devices.setSystemDevices(update) cachedDevices = update.new.getCache("networkDevices") assert len(cachedDevices) == 3 # Make sure it continues to work with missing devices. cachedDevices['lan'] = [] devices.setSystemDevices(update) cachedDevices['wifi'] = [] devices.setSystemDevices(update) cachedDevices['wan'] = [] devices.setSystemDevices(update) pdos.remove(settings.UCI_CONFIG_DIR) pdos.remove(settings.UCI_BACKUP_DIR)