1c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev/* 2c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * Copyright (C) 2018 The Android Open Source Project 3c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * 4c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * Licensed under the Apache License, Version 2.0 (the "License"); 5c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * you may not use this file except in compliance with the License. 6c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * You may obtain a copy of the License at 7c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * 8c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * http://www.apache.org/licenses/LICENSE-2.0 9c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * 10c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * Unless required by applicable law or agreed to in writing, software 11c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * distributed under the License is distributed on an "AS IS" BASIS, 12c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * See the License for the specific language governing permissions and 14c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * limitations under the License. 15c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev */ 16c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 17c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevpackage com.android.server.net; 18c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 19c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport static org.junit.Assert.assertEquals; 20c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport static org.junit.Assert.assertNotNull; 21c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport static org.junit.Assert.fail; 22c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 23c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.net.IpConfiguration; 24c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.net.IpConfiguration.IpAssignment; 25c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.net.IpConfiguration.ProxySettings; 26c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.net.LinkAddress; 27c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.net.NetworkUtils; 28c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.net.ProxyInfo; 29c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.net.StaticIpConfiguration; 30c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.support.test.runner.AndroidJUnit4; 31c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport android.util.ArrayMap; 32c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 33c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport org.junit.Test; 34c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport org.junit.runner.RunWith; 35c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 36c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport java.io.ByteArrayInputStream; 37c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport java.io.ByteArrayOutputStream; 38c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport java.io.DataOutputStream; 39c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport java.io.IOException; 40c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevimport java.io.InputStream; 41c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 42c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev/** 43c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev * Unit tests for {@link IpConfigStore} 44c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev */ 45c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev@RunWith(AndroidJUnit4.class) 46c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsevpublic class IpConfigStoreTest { 47c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 48c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev @Test 49c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev public void backwardCompatibility2to3() throws IOException { 50c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final int KEY_CONFIG = 17; 51c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 52c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev DataOutputStream outputStream = new DataOutputStream(byteStream); 53c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 54c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev IpConfiguration expectedConfig = new IpConfiguration(IpAssignment.DHCP, 55c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev ProxySettings.NONE, null, null); 56c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 57c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev // Emulate writing to old format. 58c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev writeDhcpConfigV2(outputStream, KEY_CONFIG, expectedConfig); 59c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 60c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev InputStream in = new ByteArrayInputStream(byteStream.toByteArray()); 61c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev ArrayMap<String, IpConfiguration> configurations = IpConfigStore.readIpConfigurations(in); 62c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 63c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertNotNull(configurations); 64c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertEquals(1, configurations.size()); 65c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev IpConfiguration actualConfig = configurations.get(String.valueOf(KEY_CONFIG)); 66c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertNotNull(actualConfig); 67c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertEquals(expectedConfig, actualConfig); 68c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } 69c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 70c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev @Test 71c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev public void staticIpMultiNetworks() throws Exception { 72c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final String IFACE_1 = "eth0"; 73c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final String IFACE_2 = "eth1"; 74c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final String IP_ADDR_1 = "192.168.1.10/24"; 75c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final String IP_ADDR_2 = "192.168.1.20/24"; 76c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final String DNS_IP_ADDR_1 = "1.2.3.4"; 77c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final String DNS_IP_ADDR_2 = "5.6.7.8"; 78c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 79c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration(); 80c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev staticIpConfiguration.ipAddress = new LinkAddress(IP_ADDR_1); 81c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev staticIpConfiguration.dnsServers.add(NetworkUtils.numericToInetAddress(DNS_IP_ADDR_1)); 82c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev staticIpConfiguration.dnsServers.add(NetworkUtils.numericToInetAddress(DNS_IP_ADDR_2)); 83c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 84c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev ProxyInfo proxyInfo = new ProxyInfo("10.10.10.10", 88, "host1,host2"); 85c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 86c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev IpConfiguration expectedConfig1 = new IpConfiguration(IpAssignment.STATIC, 87c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev ProxySettings.STATIC, staticIpConfiguration, proxyInfo); 88c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev IpConfiguration expectedConfig2 = new IpConfiguration(expectedConfig1); 89c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev expectedConfig2.getStaticIpConfiguration().ipAddress = new LinkAddress(IP_ADDR_2); 90c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 91c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev ArrayMap<String, IpConfiguration> expectedNetworks = new ArrayMap<>(); 92c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev expectedNetworks.put(IFACE_1, expectedConfig1); 93c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev expectedNetworks.put(IFACE_2, expectedConfig2); 94c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 95c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev MockedDelayedDiskWrite writer = new MockedDelayedDiskWrite(); 96c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev IpConfigStore store = new IpConfigStore(writer); 97c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev store.writeIpConfigurations("file/path/not/used/", expectedNetworks); 98c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 99c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev InputStream in = new ByteArrayInputStream(writer.byteStream.toByteArray()); 100c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev ArrayMap<String, IpConfiguration> actualNetworks = IpConfigStore.readIpConfigurations(in); 101c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertNotNull(actualNetworks); 102c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertEquals(2, actualNetworks.size()); 103c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertEquals(expectedNetworks.get(IFACE_1), actualNetworks.get(IFACE_1)); 104c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev assertEquals(expectedNetworks.get(IFACE_2), actualNetworks.get(IFACE_2)); 105c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } 106c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 107c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev // This is simplified snapshot of code that was used to store values in V2 format (key as int). 108c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev private static void writeDhcpConfigV2(DataOutputStream out, int configKey, 109c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev IpConfiguration config) throws IOException { 110c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev out.writeInt(2); // VERSION 2 111c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev switch (config.ipAssignment) { 112c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev case DHCP: 113c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev out.writeUTF("ipAssignment"); 114c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev out.writeUTF(config.ipAssignment.toString()); 115c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev break; 116c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev default: 117c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev fail("Not supported in test environment"); 118c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } 119c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 120c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev out.writeUTF("id"); 121c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev out.writeInt(configKey); 122c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev out.writeUTF("eos"); 123c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } 124c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 125c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev /** Synchronously writes into given byte steam */ 126c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev private static class MockedDelayedDiskWrite extends DelayedDiskWrite { 127c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 128c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 129c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev @Override 130c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev public void write(String filePath, Writer w) { 131c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev DataOutputStream outputStream = new DataOutputStream(byteStream); 132c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev 133c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev try { 134c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev w.onWriteCalled(outputStream); 135c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } catch (IOException e) { 136c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev fail(); 137c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } 138c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } 139c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev } 140c07a96d1e4a90c1c42040fd24ad9e4f209becce4Pavel Maltsev} 141