Test7029048.java revision 5116:d45bc4307996
1/*
2 * Copyright (c) 2011, 2012, 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/*
25 * @test
26 * @bug 7029048
27 * @summary Checks for LD_LIBRARY_PATH on *nixes
28 * @compile -XDignore.symbol.file ExecutionEnvironment.java Test7029048.java
29 * @run main Test7029048
30 */
31
32/*
33 * 7029048: test for LD_LIBRARY_PATH set to different paths pointing which may
34 * contain a libjvm.so and may not, but we test to ensure that the launcher
35 * behaves correctly in all cases.
36 */
37import java.io.File;
38import java.io.IOException;
39import java.nio.file.Files;
40import java.util.ArrayList;
41import java.util.HashMap;
42import java.util.List;
43import java.util.Map;
44
45public class Test7029048 extends TestHelper {
46
47    static int passes = 0;
48    static int errors = 0;
49
50    private static final String LIBJVM = ExecutionEnvironment.LIBJVM;
51    private static final String LD_LIBRARY_PATH =
52            ExecutionEnvironment.LD_LIBRARY_PATH;
53    private static final String LD_LIBRARY_PATH_32 =
54            ExecutionEnvironment.LD_LIBRARY_PATH_32;
55    private static final String LD_LIBRARY_PATH_64 =
56            ExecutionEnvironment.LD_LIBRARY_PATH_64;
57
58    private static final File libDir =
59            new File(System.getProperty("sun.boot.library.path"));
60    private static final File srcServerDir = new File(libDir, "server");
61    private static final File srcLibjvmSo = new File(srcServerDir, LIBJVM);
62
63    private static final File dstLibDir = new File("lib");
64    private static final File dstLibArchDir =
65            new File(dstLibDir, getJreArch());
66
67    private static final File dstServerDir = new File(dstLibArchDir, "server");
68    private static final File dstServerLibjvm = new File(dstServerDir, LIBJVM);
69
70    private static final File dstClientDir = new File(dstLibArchDir, "client");
71    private static final File dstClientLibjvm = new File(dstClientDir, LIBJVM);
72
73    // used primarily to test the solaris variants in dual mode
74    private static final File dstOtherArchDir;
75    private static final File dstOtherServerDir;
76    private static final File dstOtherServerLibjvm;
77
78    private static final Map<String, String> env = new HashMap<>();
79
80    static {
81        if (isDualMode) {
82            dstOtherArchDir = new File(dstLibDir, getComplementaryJreArch());
83            dstOtherServerDir = new File(dstOtherArchDir, "server");
84            dstOtherServerLibjvm = new File(dstOtherServerDir, LIBJVM);
85        } else {
86            dstOtherArchDir = null;
87            dstOtherServerDir = null;
88            dstOtherServerLibjvm = null;
89        }
90    }
91
92    static String getValue(String name, List<String> in) {
93        for (String x : in) {
94            String[] s = x.split("=");
95            if (name.equals(s[0].trim())) {
96                return s[1].trim();
97            }
98        }
99        return null;
100    }
101
102    static void run(boolean want32, String dflag, Map<String, String> env,
103            int nLLPComponents, String caseID) {
104        final boolean want64 = want32 == false;
105        env.put(ExecutionEnvironment.JLDEBUG_KEY, "true");
106        List<String> cmdsList = new ArrayList<>();
107
108        // only for a dual-mode system
109        if (want64 && isDualMode) {
110            cmdsList.add(java64Cmd);
111        } else {
112            cmdsList.add(javaCmd); // a 32-bit java command for all
113        }
114
115        /*
116         * empty or null strings can confuse the ProcessBuilder. A null flag
117         * indicates that the appropriate data model is enforced on the chosen
118         * launcher variant.
119         */
120
121        if (dflag != null) {
122            cmdsList.add(dflag);
123        } else {
124            cmdsList.add(want32 ? "-d32" : "-d64");
125        }
126        cmdsList.add("-server");
127        cmdsList.add("-jar");
128        cmdsList.add(ExecutionEnvironment.testJarFile.getAbsolutePath());
129        String[] cmds = new String[cmdsList.size()];
130        TestResult tr = doExec(env, cmdsList.toArray(cmds));
131        analyze(tr, nLLPComponents, caseID);
132    }
133
134    // no cross launch, ie. no change to the data model.
135    static void run(Map<String, String> env, int nLLPComponents, String caseID)
136            throws IOException {
137        boolean want32 = is32Bit;
138        run(want32, null, env, nLLPComponents, caseID);
139    }
140
141    static void analyze(TestResult tr, int nLLPComponents, String caseID) {
142        String envValue = getValue(LD_LIBRARY_PATH, tr.testOutput);
143       /*
144        * the envValue can never be null, since the test code should always
145        * print a "null" string.
146        */
147        if (envValue == null) {
148            System.out.println(tr);
149            throw new RuntimeException("NPE, likely a program crash ??");
150        }
151        String values[] = envValue.split(File.pathSeparator);
152        if (values.length == nLLPComponents) {
153            System.out.println(caseID + " :OK");
154            passes++;
155        } else {
156            System.out.println("FAIL: test7029048, " + caseID);
157            System.out.println(" expected " + nLLPComponents
158                    + " but got " + values.length);
159            System.out.println(envValue);
160            System.out.println(tr);
161            errors++;
162        }
163    }
164
165    /*
166     * A crucial piece, specifies what we should expect, given the conditions.
167     * That is for a given enum type, the value indicates how many absolute
168     * environment variables that can be expected. This value is used to base
169     * the actual expected values by adding the set environment variable usually
170     * it is 1, but it could be more if the test wishes to set more paths in
171     * the future.
172     */
173    private static enum LLP_VAR {
174        LLP_SET_NON_EXISTENT_PATH(0),   // env set, but the path does not exist
175        LLP_SET_EMPTY_PATH(0),          // env set, with a path but no libjvm.so
176        LLP_SET_WITH_JVM(3);            // env set, with a libjvm.so
177        private final int value;
178        LLP_VAR(int i) {
179            this.value = i;
180        }
181    }
182
183    /*
184     * test for 7029048
185     */
186    static void test7029048() throws IOException {
187        String desc = null;
188        for (LLP_VAR v : LLP_VAR.values()) {
189            switch (v) {
190                case LLP_SET_WITH_JVM:
191                    // copy the files into the directory structures
192                    copyFile(srcLibjvmSo, dstServerLibjvm);
193                    // does not matter if it is client or a server
194                    copyFile(srcLibjvmSo, dstClientLibjvm);
195                    // does not matter if the arch do not match either
196                    if (isDualMode) {
197                        copyFile(srcLibjvmSo, dstOtherServerLibjvm);
198                    }
199                    desc = "LD_LIBRARY_PATH should be set";
200                    break;
201                case LLP_SET_EMPTY_PATH:
202                    if (!dstClientDir.exists()) {
203                        Files.createDirectories(dstClientDir.toPath());
204                    } else {
205                        Files.deleteIfExists(dstClientLibjvm.toPath());
206                    }
207
208                    if (!dstServerDir.exists()) {
209                        Files.createDirectories(dstServerDir.toPath());
210                    } else {
211                        Files.deleteIfExists(dstServerLibjvm.toPath());
212                    }
213
214                    if (isDualMode) {
215                        if (!dstOtherServerDir.exists()) {
216                            Files.createDirectories(dstOtherServerDir.toPath());
217                        } else {
218                            Files.deleteIfExists(dstOtherServerLibjvm.toPath());
219                        }
220                    }
221
222                    desc = "LD_LIBRARY_PATH should not be set";
223                    break;
224                case LLP_SET_NON_EXISTENT_PATH:
225                    if (dstLibDir.exists()) {
226                        recursiveDelete(dstLibDir);
227                    }
228                    desc = "LD_LIBRARY_PATH should not be set";
229                    break;
230                default:
231                    throw new RuntimeException("unknown case");
232            }
233
234            /*
235             * Case 1: set the server path
236             */
237            env.clear();
238            env.put(LD_LIBRARY_PATH, dstServerDir.getAbsolutePath());
239            run(env, v.value + 1, "Case 1: " + desc);
240
241            /*
242             * Case 2: repeat with client path
243             */
244            env.clear();
245            env.put(LD_LIBRARY_PATH, dstClientDir.getAbsolutePath());
246            run(env, v.value + 1, "Case 2: " + desc);
247
248            if (!isDualMode) {
249                continue; // nothing more to do for Linux
250            }
251
252            // Tests applicable only to solaris.
253
254            // initialize test variables for dual mode operations
255            final File dst32ServerDir = is32Bit
256                    ? dstServerDir
257                    : dstOtherServerDir;
258
259            final File dst64ServerDir = is64Bit
260                    ? dstServerDir
261                    : dstOtherServerDir;
262
263            /*
264             * Case 3: set the appropriate LLP_XX flag,
265             * java32 -d32, LLP_32 is relevant, LLP_64 is ignored
266             * java64 -d64, LLP_64 is relevant, LLP_32 is ignored
267             */
268            env.clear();
269            env.put(LD_LIBRARY_PATH_32, dst32ServerDir.getAbsolutePath());
270            env.put(LD_LIBRARY_PATH_64, dst64ServerDir.getAbsolutePath());
271            run(is32Bit, null, env, v.value + 1, "Case 3: " + desc);
272
273            /*
274             * Case 4: we are in dual mode environment, running 64-bit then
275             * we have the following scenarios:
276             * java32 -d64, LLP_64 is relevant, LLP_32 is ignored
277             * java64 -d32, LLP_32 is relevant, LLP_64 is ignored
278             */
279            if (dualModePresent()) {
280                run(true, "-d64", env, v.value + 1, "Case 4A: " + desc);
281                run(false,"-d32", env, v.value + 1, "Case 4B: " + desc);
282            }
283        }
284        return;
285    }
286
287    public static void main(String... args) throws Exception {
288        if (TestHelper.isWindows || TestHelper.isMacOSX) {
289            System.out.println("Note: applicable on neither Windows nor MacOSX");
290            return;
291        }
292        // create our test jar first
293        ExecutionEnvironment.createTestJar();
294
295        // run the tests
296        test7029048();
297        if (errors > 0) {
298            throw new Exception("Test7029048: FAIL: with "
299                    + errors + " errors and passes " + passes);
300        } else if (dualModePresent() && passes < 15) {
301            throw new Exception("Test7029048: FAIL: " +
302                    "all tests did not run, expected " + 15 + " got " + passes);
303        } else if (isSolaris && passes < 9) {
304            throw new Exception("Test7029048: FAIL: " +
305                    "all tests did not run, expected " + 9 + " got " + passes);
306        } else if (isLinux && passes < 6) {
307             throw new Exception("Test7029048: FAIL: " +
308                    "all tests did not run, expected " + 6 + " got " + passes);
309        } else {
310            System.out.println("Test7029048: PASS " + passes);
311        }
312    }
313}
314