1 /*
  2  * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 import java.net.InetAddress;
 25 import java.util.Arrays;
 26 import java.util.List;
 27 import java.util.Map;
 28 import java.util.stream.Collectors;
 29 
 30 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4;
 31 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST;
 32 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6;
 33 import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST;
 34 
 35 import jdk.test.lib.net.IPSupport;
 36 import jdk.test.lib.NetworkConfiguration;
 37 import org.testng.annotations.Test;
 38 import org.testng.Assert;
 39 import org.testng.SkipException;
 40 
 41 /*
 42  * @test
 43  * @summary Test that platform lookup characteristic value is correctly initialized from
 44  *  system properties affecting order and type of queried addresses.
 45  * @library lib providers/simple /test/lib
 46  * @build test.library/testlib.ResolutionRegistry simple.provider/impl.SimpleResolverProviderImpl
 47  *        jdk.test.lib.net.IPSupport LookupPolicyMappingTest
 48  * @run testng/othervm LookupPolicyMappingTest
 49  * @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
 50  * @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
 51  * @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
 52  * @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
 53  * @run testng/othervm -Djava.net.preferIPv4Stack=true LookupPolicyMappingTest
 54  * @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
 55  * @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
 56  * @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
 57  * @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
 58  * @run testng/othervm -Djava.net.preferIPv4Stack=false LookupPolicyMappingTest
 59  * @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
 60  * @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
 61  * @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
 62  * @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
 63  * @run testng/othervm -Djava.net.preferIPv4Stack LookupPolicyMappingTest
 64  * @run testng/othervm -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
 65  * @run testng/othervm -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
 66  * @run testng/othervm -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
 67  * @run testng/othervm -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
 68  */
 69 
 70 public class LookupPolicyMappingTest {
 71 
 72     @Test
 73     public void testSystemProperties() throws Exception {
 74 
 75         // Check if platform network configuration matches the test requirements,
 76         // if not throw a SkipException
 77         checkPlatformNetworkConfiguration();
 78 
 79         System.err.println("javaTest.org resolved to:" + Arrays.deepToString(
 80                 InetAddress.getAllByName("javaTest.org")));
 81 
 82         // Acquire runtime characteristics from the test NSP
 83         int runtimeCharacteristics = impl.SimpleResolverProviderImpl.lastLookupPolicy().characteristics();
 84 
 85         // Calculate expected lookup policy characteristic
 86         String preferIPv4Stack = System.getProperty("java.net.preferIPv4Stack");
 87         String preferIPv6Addresses = System.getProperty("java.net.preferIPv6Addresses");
 88         String expectedResultsKey = calculateMapKey(preferIPv4Stack, preferIPv6Addresses);
 89         int expectedCharacteristics = EXPECTED_RESULTS_MAP.get(expectedResultsKey);
 90 
 91         Assert.assertTrue(characteristicsMatch(
 92                 runtimeCharacteristics, expectedCharacteristics), "Unexpected LookupPolicy observed");
 93     }
 94 
 95     // Throws SkipException if platform doesn't support required IP address types
 96     static void checkPlatformNetworkConfiguration() {
 97         IPSupport.throwSkippedExceptionIfNonOperational();
 98         IPSupport.printPlatformSupport(System.err);
 99         NetworkConfiguration.printSystemConfiguration(System.err);
100         // If preferIPv4=true and no IPv4 - skip
101         if (IPSupport.preferIPv4Stack()) {
102             if (!IPSupport.hasIPv4()) {
103                 throw new SkipException("Skip tests - IPv4 support required");
104             }
105             return;
106         }
107     }
108 
109     record ExpectedResult(String ipv4stack, String ipv6addresses, int characteristics) {
110         ExpectedResult {
111             if (!IPSupport.hasIPv4()) {
112                 characteristics = IPV6;
113             } else if (!IPSupport.hasIPv6()) {
114                 characteristics = IPV4;
115             }
116         }
117 
118         public String key() {
119             return calculateMapKey(ipv4stack, ipv6addresses);
120         }
121     }
122 
123     /*
124      *  Each row describes a combination of 'preferIPv4Stack', 'preferIPv6Addresses'
125      *  values and the expected characteristic value
126      */
127     private static List<ExpectedResult> EXPECTED_RESULTS_TABLE = List.of(
128             new ExpectedResult("true", "true", IPV4),
129             new ExpectedResult("true", "false", IPV4),
130             new ExpectedResult("true", "system", IPV4),
131             new ExpectedResult("true", "", IPV4),
132             new ExpectedResult("true", null, IPV4),
133 
134             new ExpectedResult("false", "true", IPV4 | IPV6 | IPV6_FIRST),
135             new ExpectedResult("false", "false", IPV4 | IPV6 | IPV4_FIRST),
136             new ExpectedResult("false", "system", IPV4 | IPV6),
137             new ExpectedResult("false", "", IPV4 | IPV6 | IPV4_FIRST),
138             new ExpectedResult("false", null, IPV4 | IPV6 | IPV4_FIRST),
139 
140             new ExpectedResult("", "true", IPV4 | IPV6 | IPV6_FIRST),
141             new ExpectedResult("", "false", IPV4 | IPV6 | IPV4_FIRST),
142             new ExpectedResult("", "system", IPV4 | IPV6),
143             new ExpectedResult("", "", IPV4 | IPV6 | IPV4_FIRST),
144             new ExpectedResult("", null, IPV4 | IPV6 | IPV4_FIRST),
145 
146             new ExpectedResult(null, "true", IPV4 | IPV6 | IPV6_FIRST),
147             new ExpectedResult(null, "false", IPV4 | IPV6 | IPV4_FIRST),
148             new ExpectedResult(null, "system", IPV4 | IPV6),
149             new ExpectedResult(null, "", IPV4 | IPV6 | IPV4_FIRST),
150             new ExpectedResult(null, null, IPV4 | IPV6 | IPV4_FIRST));
151 
152     private static final Map<String, Integer> EXPECTED_RESULTS_MAP = calculateExpectedCharacteristics();
153 
154     private static Map<String, Integer> calculateExpectedCharacteristics() {
155         return EXPECTED_RESULTS_TABLE.stream()
156                 .collect(Collectors.toUnmodifiableMap(
157                         ExpectedResult::key,
158                         ExpectedResult::characteristics)
159                 );
160     }
161 
162     private static String calculateMapKey(String ipv4stack, String ipv6addresses) {
163         return ipv4stack + "_" + ipv6addresses;
164     }
165 
166     private static boolean characteristicsMatch(int actual, int expected) {
167         System.err.printf("Comparing characteristics:%n\tActual: %s%n\tExpected: %s%n",
168                 Integer.toBinaryString(actual),
169                 Integer.toBinaryString(expected));
170         return (actual & (IPV4 | IPV6 | IPV4_FIRST | IPV6_FIRST)) == expected;
171     }
172 }