File: Base.java

package info (click to toggle)
openjdk-11 11.0.4%2B11-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 757,028 kB
  • sloc: java: 5,016,041; xml: 1,191,974; cpp: 934,731; ansic: 555,697; sh: 24,299; objc: 12,703; python: 3,602; asm: 3,415; makefile: 2,772; awk: 351; sed: 172; perl: 114; jsp: 24; csh: 3
file content (274 lines) | stat: -rw-r--r-- 12,235 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import jdk.testlibrary.JDKToolFinder;
import jdk.test.lib.compiler.CompilerUtils;

import static jdk.testlibrary.ProcessTools.executeCommand;

/*
 * Base class for tests.
 * The tests focuse on that LoggerFinder works well in jigsaw environment,
 * i.e. make sure correct Logger can be retrieved,
 * also verify that basic functionality of retrieved Logger's works well.
 *
 * Note: As the test will take long time, to avoid timeout,
 * split it as several tests, this class is the base class for tests.
 */
public class Base {
    protected static final String JAVA_HOME = System.getProperty("java.home");
    protected static final Path JDK_IMAGE = Paths.get(JAVA_HOME);
    protected static final Path JMODS = Paths.get(JAVA_HOME, "jmods");

    protected static final String TEST_SRC = System.getProperty("test.src");

    // logger client to get logger from java.base module, it should get a lazy logger
    // which wraps the underlying real logger implementation
    protected static final Path SRC_PATCHED_USAGE =
            Paths.get(TEST_SRC, "patched_usage", "java.base");
    protected static final Path DEST_PATCHED_USAGE = Paths.get("patched_usage", "java.base");
    protected static final Path SRC_PATCHED_CLIENT = Paths.get(TEST_SRC, "patched_client");
    protected static final Path DEST_PATCHED_CLIENT = Paths.get("patched_client");

    // logger client to get logger from bootclasspath/a, it should get a lazy logger
    // which wraps the underlying real logger implementation
    protected static final Path SRC_BOOT_USAGE = Paths.get(TEST_SRC, "boot_usage");
    protected static final Path DEST_BOOT_USAGE = Paths.get("boot_usage");
    protected static final Path SRC_BOOT_CLIENT = Paths.get(TEST_SRC, "boot_client");
    protected static final Path DEST_BOOT_CLIENT = Paths.get("boot_client");

    // logger provider in named module m.l.a
    protected static final Path SRC_NAMED_LOGGER = Paths.get(TEST_SRC, "named_logger");
    protected static final Path DEST_NAMED_LOGGER = Paths.get("mods_named_logger");

    // logger provider in unnamed module
    protected static final Path SRC_UNNAMED_LOGGER = Paths.get(TEST_SRC, "unnamed_logger");
    protected static final Path DEST_UNNAMED_LOGGER = Paths.get("cp_unnamed_logger");
    protected static final Path SRC_UNNAMED_LOGGER_SERVICE_FILE =
            SRC_UNNAMED_LOGGER.resolve("META-INF/services/java.lang.System$LoggerFinder");
    protected static final Path DEST_UNNAMED_LOGGER_SERVICE_DIR =
            DEST_UNNAMED_LOGGER.resolve("META-INF/services");
    protected static final Path DEST_UNNAMED_LOGGER_SERVICE_FILE =
            DEST_UNNAMED_LOGGER.resolve("META-INF/services/java.lang.System$LoggerFinder");

    // logger client in named module m.t.a
    protected static final Path SRC_NAMED_CLIENT = Paths.get(TEST_SRC, "named_client");
    protected static final Path DEST_NAMED_CLIENT = Paths.get("mods_named_client");

    // logger client in unnamed module
    protected static final Path SRC_UNNAMED_CLIENT = Paths.get(TEST_SRC, "unnamed_client");
    protected static final Path DEST_UNNAMED_CLIENT = Paths.get("cp_unnamed_client");

    // customized image with only module java.base
    protected static final Path IMAGE = Paths.get("image");
    // customized image with java.base and logger provider module m.l.a
    protected static final Path IMAGE_LOGGER = Paths.get("image_logger");
    // customized image with module java.base and logger client module m.t.a
    protected static final Path IMAGE_CLIENT = Paths.get("image_client");
    // customized image with module java.base, logger provider module m.l.a
    // and logger client module m.t.a
    protected static final Path IMAGE_CLIENT_LOGGER = Paths.get("image_all");

    // lazy logger class which wraps the underlying real logger implementation
    protected static final String LAZY_LOGGER =
            "jdk.internal.logger.LazyLoggers$JdkLazyLogger";
    // JUL logger class which wraps java.util.logging.Logger
    protected static final String JUL_LOGGER =
            "sun.util.logging.internal.LoggingProviderImpl$JULWrapper";
    // default simple logger class when no logger provider can be found
    protected static final String SIMPLE_LOGGER =
            "jdk.internal.logger.SimpleConsoleLogger";
    // logger class in named module m.l.a
    protected static final String LOGGER_A = "pkg.a.l.LoggerA";
    // logger class in unnamed module m.l.b
    protected static final String LOGGER_B = "pkg.b.l.LoggerB";

    // logger client in named module
    protected static final String CLIENT_A = "m.t.a/pkg.a.t.TestA";
    // logger client in unnamed module
    protected static final String CLIENT_B = "pkg.b.t.TestB";
    // logger client which gets logger through boot class BootUsage
    protected static final String BOOT_CLIENT = "BootClient";
    // logger client which gets logger through patched class
    // java.base/java.lang.PatchedUsage
    protected static final String PATCHED_CLIENT = "PatchedClient";

    protected void setupAllClient() throws Throwable {
        // compiles logger client which will get logger through patched
        // class java.base/java.lang.PatchedUsage
        compile(SRC_BOOT_USAGE, DEST_BOOT_USAGE);
        compile(SRC_BOOT_CLIENT, DEST_BOOT_CLIENT,
                "--class-path", DEST_BOOT_USAGE.toString());

        // compiles logger client which will get logger through boot
        // class BootUsage
        compile(SRC_PATCHED_USAGE, DEST_PATCHED_USAGE,
                "--patch-module", "java.base=" + SRC_PATCHED_USAGE.toString());
        compile(SRC_PATCHED_CLIENT, DEST_PATCHED_CLIENT,
                "--patch-module", "java.base=" + DEST_PATCHED_USAGE.toString());

        // compiles logger client in unnamed module
        compile(SRC_UNNAMED_CLIENT, DEST_UNNAMED_CLIENT,
                "--source-path", SRC_UNNAMED_CLIENT.toString());

        // compiles logger client in named module m.t.a
        compile(SRC_NAMED_CLIENT, DEST_NAMED_CLIENT,
                "--module-source-path", SRC_NAMED_CLIENT.toString());
    }

    protected void setupNamedLogger() throws Throwable {
        // compiles logger provider in named module m.l.a
        compile(SRC_NAMED_LOGGER, DEST_NAMED_LOGGER,
                "--module-source-path", SRC_NAMED_LOGGER.toString());
    }

    protected void setupUnnamedLogger() throws Throwable {
        // compiles logger provider in unnamed module
        compile(SRC_UNNAMED_LOGGER, DEST_UNNAMED_LOGGER,
                "--source-path", SRC_UNNAMED_LOGGER.toString());
        Files.createDirectories(DEST_UNNAMED_LOGGER_SERVICE_DIR);
        Files.copy(SRC_UNNAMED_LOGGER_SERVICE_FILE, DEST_UNNAMED_LOGGER_SERVICE_FILE,
                   StandardCopyOption.REPLACE_EXISTING);
    }

    protected boolean checkJMODS() throws Throwable {
        // if $JAVA_HOME/jmods does not exist, skip below steps
        // as there is no way to build customized images by jlink
        if (Files.notExists(JMODS)) {
            System.err.println("Skip tests which require image");
            return false;
        }
        return true;
    }

    protected void setupJavaBaseImage() throws Throwable {
        if (!checkJMODS()) {
            return;
        }

        // build image with just java.base module
        String mpath = JMODS.toString();
        execTool("jlink",
                "--module-path", mpath,
                "--add-modules", "java.base",
                "--output", IMAGE.toString());
    }

    protected void setupLoggerImage() throws Throwable {
        if (!checkJMODS()) {
            return;
        }

        // build image with java.base + m.l.a modules
        String mpath = DEST_NAMED_LOGGER.toString() + File.pathSeparator + JMODS.toString();
        execTool("jlink",
                "--module-path", mpath,
                "--add-modules", "m.l.a",
                "--output", IMAGE_LOGGER.toString());
    }

    protected void setupClientImage() throws Throwable {
        if (!checkJMODS()) {
            return;
        }

        // build image with java.base + m.t.a modules
        String mpath = DEST_NAMED_CLIENT.toString() + File.pathSeparator + JMODS.toString();
        execTool("jlink",
                "--module-path", mpath,
                "--add-modules", "m.t.a",
                "--output", IMAGE_CLIENT.toString());
    }

    protected void setupFullImage() throws Throwable {
        if (!checkJMODS()) {
            return;
        }

        // build image with java.base + m.l.a + m.t.a modules
        String mpath = DEST_NAMED_LOGGER.toString() + File.pathSeparator
                + DEST_NAMED_CLIENT.toString() + File.pathSeparator + JMODS.toString();
        execTool("jlink",
                "--module-path", mpath,
                "--add-modules", "m.l.a,m.t.a",
                "--output", IMAGE_CLIENT_LOGGER.toString());

    }

    protected static void assertTrue(boolean b) {
        if (!b) {
            throw new RuntimeException("expected true, but get false.");
        }
    }

    /*
     * run test with supplied java image which could be jdk image or customized image
     */
    protected void runTest(Path image, String... opts) throws Throwable {
        String[] options = Stream.concat(Stream.of(getJava(image)), Stream.of(opts))
                                 .toArray(String[]::new);

        ProcessBuilder pb = new ProcessBuilder(options);
        int exitValue = executeCommand(pb).outputTo(System.out)
                                          .errorTo(System.err)
                                          .getExitValue();
        assertTrue(exitValue == 0);
    }

    private void compile(Path src, Path dest, String... params) throws Throwable {
        assertTrue(CompilerUtils.compile(src, dest, params));
    }

    private String getJava(Path image) {
        boolean isWindows = System.getProperty("os.name").startsWith("Windows");
        Path java = image.resolve("bin").resolve(isWindows ? "java.exe" : "java");
        if (Files.notExists(java))
            throw new RuntimeException(java + " not found");
        return java.toAbsolutePath().toString();
    }

    private void execTool(String tool, String... args) throws Throwable {
        String path = JDKToolFinder.getJDKTool(tool);
        List<String> commands = new ArrayList<>();
        commands.add(path);
        Stream.of(args).forEach(commands::add);
        ProcessBuilder pb = new ProcessBuilder(commands);

        int exitValue = executeCommand(pb).outputTo(System.out)
                                          .errorTo(System.out)
                                          .shouldNotContain("no module is recorded in hash")
                                          .getExitValue();
        assertTrue(exitValue == 0);
    }
}