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