1 /*
2  * Copyright (c) 2016, 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  * @summary Tests to verify jimage 'list' action
27  * @library /test/lib
28  * @modules jdk.jlink/jdk.tools.jimage
29  * @build jdk.test.lib.Asserts
30  * @run main JImageListTest
31  */
32 
33 import java.io.IOException;
34 import java.nio.file.Files;
35 import java.nio.file.Path;
36 import java.nio.file.Paths;
37 import java.util.*;
38 import java.util.stream.Collectors;
39 import java.util.stream.Stream;
40 
41 import static jdk.test.lib.Asserts.assertEquals;
42 import static jdk.test.lib.Asserts.assertFalse;
43 import static jdk.test.lib.Asserts.assertTrue;
44 
45 public class JImageListTest extends JImageCliTest {
testList()46     public void testList() {
47         jimage("list", getImagePath())
48                 .assertSuccess()
49                 .resultChecker(r -> {
50                     String[] lines = r.output.split(System.lineSeparator());
51                     assertTrue(lines.length > 0, "Option --list has output.");
52                     assertTrue(lines[0].startsWith("jimage: " + getImagePath()),
53                             "Output should start with jimage path.");
54 
55                     List<String> modules = Stream.of(lines)
56                             .filter(s -> s.startsWith("Module: "))
57                             .map(s -> s.substring(s.indexOf(':') + 1).trim())
58                             .collect(Collectors.toList());
59                     assertTrue(modules.size() > 0, "Image contains at least one module.");
60                     assertTrue(modules.contains("java.base"), "Module java.base found.");
61                 });
62     }
63 
testListHelp()64     public void testListHelp() {
65         for (String opt : Arrays.asList("-h", "--help")) {
66             jimage("list", opt)
67                     .assertSuccess()
68                     .resultChecker(r -> {
69                         // list  -  descriptive text
70                         assertMatches("\\s+list\\s+-\\s+.*", r.output);
71                     });
72         }
73     }
74 
testListVerbose()75     public void testListVerbose() {
76         jimage("list", "--verbose", getImagePath())
77                 .assertSuccess()
78                 .resultChecker(r -> {
79                     assertMatches("Offset\\s+Size\\s+Compressed\\s+Entry", r.output);
80 
81                     String[] lines = r.output.split("[" + System.lineSeparator() + "]+");
82                     assertTrue(lines.length > 0, "Option --list has output.");
83                     assertTrue(lines[0].startsWith("jimage: " + getImagePath()),
84                             "Output should start with jimage path.");
85 
86                     List<String> modules = Stream.of(lines)
87                             .filter(s -> s.startsWith("Module: "))
88                             .map(s -> s.substring(s.indexOf(':') + 1).trim())
89                             .collect(Collectors.toList());
90                     assertTrue(modules.size() > 0, "Image contains at least one module.");
91                     assertTrue(modules.contains("java.base"), "Module java.base found.");
92 
93                     Set<String> entries = Stream.of(lines)
94                             .filter(s -> { return !s.startsWith("Module: ") && !s.startsWith("Offset"); })
95                             // Offset \d+  Size \d+  Compressed \d+ Entry \.*
96                             .filter(s -> !s.matches("\\s+\\d+\\s+\\d+\\s+\\d+\\s+.*"))
97                             .collect(Collectors.toSet());
98                     assertEquals(entries, new HashSet<>() {{ add("jimage: " + getImagePath()); }},
99                             "All entries should be in format: Offset Size Compressed Entry");
100                 });
101     }
102 
testListIncludeAllWithGlob()103     public void testListIncludeAllWithGlob() {
104         JImageResult listAll = jimage("list", getImagePath()).assertSuccess();
105         JImageResult listAllGlob = jimage("list", "--include", "**", getImagePath()).assertSuccess();
106         assertEquals(listAllGlob.output, listAll.output, "--include ** should produce the same output");
107     }
108 
testListIncludeWithGlob()109     public void testListIncludeWithGlob() {
110         JImageResult listAll = jimage("list", getImagePath()).assertSuccess();
111         Set<String> expected = Stream.of(listAll.output.split("[" + System.lineSeparator() + "]+"))
112                 .map(String::trim)
113                 .filter(s -> s.startsWith("java/util/zip"))
114                 .collect(Collectors.toSet());
115 
116         JImageResult listJavaUtil = jimage("list", "--include", "/java.base/java/util/zip/**", getImagePath()).assertSuccess();
117         Set<String> actual = Stream.of(listJavaUtil.output.split("[" + System.lineSeparator() + "]+"))
118                 .map(String::trim)
119                 .filter(s -> !s.startsWith("jimage:") && !s.startsWith("Module:"))
120                 .collect(Collectors.toSet());
121         assertEquals(actual, expected, "All java.util.zip classes are listed");
122     }
123 
testListIncludeNoMatchWithGlob()124     public void testListIncludeNoMatchWithGlob() {
125         JImageResult listNotMatching = jimage("list", "--include", "not_matching", getImagePath()).assertSuccess();
126         Set<String> entries = Stream.of(listNotMatching.output.split("["+ System.lineSeparator() + "]+"))
127                 .map(String::trim)
128                 .filter(s -> !s.startsWith("jimage:") && !s.startsWith("Module:"))
129                 .collect(Collectors.toSet());
130         assertEquals(entries, Collections.emptySet(), "No java.util classes are listed");
131     }
132 
testListIncludeAllWithExplicitGlob()133     public void testListIncludeAllWithExplicitGlob() {
134         JImageResult listAll = jimage("list", getImagePath()).assertSuccess();
135         JImageResult listAllGlob = jimage("list", "--include", "glob:**", getImagePath()).assertSuccess();
136         assertEquals(listAllGlob.output, listAll.output, "--include glob:** should produce the same output");
137     }
138 
testListIncludeAllWithRegex()139     public void testListIncludeAllWithRegex() {
140         JImageResult listAll = jimage("list", getImagePath()).assertSuccess();
141         JImageResult listAllRegex = jimage("list", "--include", "regex:.*", getImagePath()).assertSuccess();
142         assertEquals(listAllRegex.output, listAll.output, "--include regex:.* should produce the same output");
143     }
144 
testListIncludeWithRegex()145     public void testListIncludeWithRegex() {
146         JImageResult listAll = jimage("list", getImagePath()).assertSuccess();
147         Set<String> expected = Stream.of(listAll.output.split("[" + System.lineSeparator() + "]+"))
148                 .map(String::trim)
149                 .filter(s -> s.startsWith("java/text/"))
150                 .collect(Collectors.toSet());
151         assertFalse(expected.isEmpty(), "There should be classes from java.text package");
152 
153         JImageResult listJavaText = jimage("list", "--include", "regex:/java.base/java/text/.*", getImagePath()).assertSuccess();
154         Set<String> actual = Stream.of(listJavaText.output.split("[" + System.lineSeparator() + "]+"))
155                 .map(String::trim)
156                 .filter(s -> !s.startsWith("jimage:") && !s.startsWith("Module:"))
157                 .collect(Collectors.toSet());
158 
159         assertEquals(actual, expected, "All java.text classes are listed");
160     }
161 
testListIncludeNoMatchWithRegex()162     public void testListIncludeNoMatchWithRegex() {
163         JImageResult listNotMatching = jimage("list", "--include", "regex:not_matching",
164                 getImagePath()).assertSuccess();
165         Set<String> entries = Stream.of(listNotMatching.output.split("[" + System.lineSeparator() + "]+"))
166                 .map(String::trim)
167                 .filter(s -> !s.startsWith("jimage:") && !s.startsWith("Module:"))
168                 .collect(Collectors.toSet());
169         assertEquals(entries, Collections.emptySet(), "No classes are listed");
170     }
171 
testListIncludeMultiplePatterns()172     public void testListIncludeMultiplePatterns() throws IOException {
173         JImageResult listAll = jimage("list", getImagePath()).assertSuccess();
174         Set<String> expected = Stream.of(listAll.output.split("[" + System.lineSeparator() + "]+"))
175                 .map(String::trim)
176                 .filter(s -> s.startsWith("java/time/") || s.startsWith("java/util/zip"))
177                 .collect(Collectors.toSet());
178         assertFalse(expected.isEmpty(), "There should be classes from java.time and java.io packages");
179 
180         JImageResult listMatched = jimage("list", "--include", "glob:/java.base/java/time/**,regex:/java.base/java/util/zip/.*",
181                 getImagePath()).assertSuccess();
182         Set<String> actual = Stream.of(listMatched.output.split("[" + System.lineSeparator() + "]+"))
183                 .map(String::trim)
184                 .filter(s -> !s.startsWith("jimage:") && !s.startsWith("Module:"))
185                 .collect(Collectors.toSet());
186 
187         assertEquals(actual, expected, "All java.time and java.util.zip classes are listed");
188     }
189 
testListNoImageSpecified()190     public void testListNoImageSpecified() {
191         jimage("list", "")
192                 .assertFailure()
193                 .assertShowsError();
194     }
195 
testListEmptyFile()196     public void testListEmptyFile() throws IOException {
197         Path tmp = Files.createTempFile(Paths.get("."), getClass().getName(), "empty_file");
198         jimage("list", tmp.toString())
199                 .assertFailure()
200                 .assertShowsError();
201     }
202 
testListNotAnImage()203     public void testListNotAnImage() throws IOException {
204         Path tmp = Files.createTempFile(Paths.get("."), getClass().getName(), "not_an_image");
205         Files.write(tmp, "This is not an image".getBytes());
206         jimage("list", tmp.toString())
207                 .assertFailure()
208                 .assertShowsError();
209     }
210 
testListNotExistingImage()211     public void testListNotExistingImage() throws IOException {
212         Path tmp = Paths.get(".", "not_existing_image");
213         Files.deleteIfExists(tmp);
214         jimage("list", tmp.toString())
215                 .assertFailure()
216                 .assertShowsError();
217     }
218 
testListWithUnknownOption()219     public void testListWithUnknownOption() {
220         jimage("list", "--unknown")
221                 .assertFailure()
222                 .assertShowsError();
223     }
224 
main(String[] args)225     public static void main(String[] args) throws Throwable {
226         new JImageListTest().runTests();
227         // Just to ensure that jimage files will be unmapped
228         System.gc();
229     }
230 }
231 
232