107 getPackageName(cmd))); |
112 getPackageName(cmd))); |
108 return null; |
113 return null; |
109 }).get(); |
114 }).get(); |
110 } |
115 } |
111 |
116 |
|
117 static long getInstalledPackageSizeKB(JPackageCommand cmd) { |
|
118 cmd.verifyIsOfType(PackageType.LINUX); |
|
119 |
|
120 final Path packageFile = cmd.outputBundle(); |
|
121 switch (cmd.packageType()) { |
|
122 case LINUX_DEB: |
|
123 return Long.parseLong(getDebBundleProperty(packageFile, |
|
124 "Installed-Size")); |
|
125 |
|
126 case LINUX_RPM: |
|
127 return Long.parseLong(getRpmBundleProperty(packageFile, "Size")) >> 10; |
|
128 } |
|
129 |
|
130 return 0; |
|
131 } |
|
132 |
112 static String getDebBundleProperty(Path bundle, String fieldName) { |
133 static String getDebBundleProperty(Path bundle, String fieldName) { |
113 return new Executor() |
134 return new Executor() |
114 .saveFirstLineOfOutput() |
|
115 .setExecutable("dpkg-deb") |
135 .setExecutable("dpkg-deb") |
116 .addArguments("-f", bundle.toString(), fieldName) |
136 .addArguments("-f", bundle.toString(), fieldName) |
117 .execute() |
137 .executeAndGetFirstLineOfOutput(); |
118 .assertExitCodeIsZero().getFirstLineOfOutput(); |
138 } |
119 } |
139 |
120 |
140 static String getRpmBundleProperty(Path bundle, String fieldName) { |
121 static String geRpmBundleProperty(Path bundle, String fieldName) { |
|
122 return new Executor() |
141 return new Executor() |
123 .saveFirstLineOfOutput() |
|
124 .setExecutable("rpm") |
142 .setExecutable("rpm") |
125 .addArguments( |
143 .addArguments( |
126 "-qp", |
144 "-qp", |
127 "--queryformat", |
145 "--queryformat", |
128 String.format("%%{%s}", fieldName), |
146 String.format("%%{%s}", fieldName), |
129 bundle.toString()) |
147 bundle.toString()) |
130 .execute() |
148 .executeAndGetFirstLineOfOutput(); |
131 .assertExitCodeIsZero().getFirstLineOfOutput(); |
149 } |
|
150 |
|
151 static void addDebBundleDesktopIntegrationVerifier(PackageTest test, |
|
152 boolean integrated) { |
|
153 Function<List<String>, String> verifier = (lines) -> { |
|
154 // Lookup for xdg commands |
|
155 return lines.stream().filter(line -> { |
|
156 Set<String> words = Set.of(line.split("\\s+")); |
|
157 return words.contains("xdg-desktop-menu") || words.contains( |
|
158 "xdg-mime") || words.contains("xdg-icon-resource"); |
|
159 }).findFirst().orElse(null); |
|
160 }; |
|
161 |
|
162 test.addBundleVerifier(cmd -> { |
|
163 Test.withTempDirectory(tempDir -> { |
|
164 try { |
|
165 // Extract control Debian package files into temporary directory |
|
166 new Executor() |
|
167 .setExecutable("dpkg") |
|
168 .addArguments( |
|
169 "-e", |
|
170 cmd.outputBundle().toString(), |
|
171 tempDir.toString() |
|
172 ).execute().assertExitCodeIsZero(); |
|
173 |
|
174 Path controlFile = Path.of("postinst"); |
|
175 |
|
176 // Lookup for xdg commands in postinstall script |
|
177 String lineWithXsdCommand = verifier.apply( |
|
178 Files.readAllLines(tempDir.resolve(controlFile))); |
|
179 String assertMsg = String.format( |
|
180 "Check if %s@%s control file uses xdg commands", |
|
181 cmd.outputBundle(), controlFile); |
|
182 if (integrated) { |
|
183 Test.assertNotNull(lineWithXsdCommand, assertMsg); |
|
184 } else { |
|
185 Test.assertNull(lineWithXsdCommand, assertMsg); |
|
186 } |
|
187 } catch (IOException ex) { |
|
188 throw new RuntimeException(ex); |
|
189 } |
|
190 }); |
|
191 }); |
|
192 } |
|
193 |
|
194 static void initFileAssociationsTestFile(Path testFile) { |
|
195 try { |
|
196 // Write something in test file. |
|
197 // On Ubuntu and Oracle Linux empty files are considered |
|
198 // plain text. Seems like a system bug. |
|
199 // |
|
200 // $ >foo.jptest1 |
|
201 // $ xdg-mime query filetype foo.jptest1 |
|
202 // text/plain |
|
203 // $ echo > foo.jptest1 |
|
204 // $ xdg-mime query filetype foo.jptest1 |
|
205 // application/x-jpackage-jptest1 |
|
206 // |
|
207 Files.write(testFile, Arrays.asList("")); |
|
208 } catch (IOException ex) { |
|
209 throw new RuntimeException(ex); |
|
210 } |
|
211 } |
|
212 |
|
213 private static Path getSystemDesktopFilesFolder() { |
|
214 return Stream.of("/usr/share/applications", |
|
215 "/usr/local/share/applications").map(Path::of).filter(dir -> { |
|
216 return Files.exists(dir.resolve("defaults.list")); |
|
217 }).findFirst().orElseThrow(() -> new RuntimeException( |
|
218 "Failed to locate system .desktop files folder")); |
|
219 } |
|
220 |
|
221 static void addFileAssociationsVerifier(PackageTest test, FileAssociations fa) { |
|
222 test.addInstallVerifier(cmd -> { |
|
223 Test.withTempFile(fa.getSuffix(), testFile -> { |
|
224 initFileAssociationsTestFile(testFile); |
|
225 |
|
226 String mimeType = queryFileMimeType(testFile); |
|
227 |
|
228 Test.assertEquals(fa.getMime(), mimeType, String.format( |
|
229 "Check mime type of [%s] file", testFile)); |
|
230 |
|
231 String desktopFileName = queryMimeTypeDefaultHandler(mimeType); |
|
232 |
|
233 Path desktopFile = getSystemDesktopFilesFolder().resolve( |
|
234 desktopFileName); |
|
235 |
|
236 Test.assertFileExists(desktopFile, true); |
|
237 |
|
238 Test.trace(String.format("Reading [%s] file...", desktopFile)); |
|
239 String mimeHandler = null; |
|
240 try { |
|
241 mimeHandler = Files.readAllLines(desktopFile).stream().peek( |
|
242 v -> Test.trace(v)).filter( |
|
243 v -> v.startsWith("Exec=")).map( |
|
244 v -> v.split("=", 2)[1]).findFirst().orElseThrow(); |
|
245 } catch (IOException ex) { |
|
246 throw new RuntimeException(ex); |
|
247 } |
|
248 Test.trace(String.format("Done")); |
|
249 |
|
250 Test.assertEquals(cmd.launcherInstallationPath().toString(), |
|
251 mimeHandler, String.format( |
|
252 "Check mime type handler is the main application launcher")); |
|
253 |
|
254 }); |
|
255 }); |
|
256 |
|
257 test.addUninstallVerifier(cmd -> { |
|
258 Test.withTempFile(fa.getSuffix(), testFile -> { |
|
259 initFileAssociationsTestFile(testFile); |
|
260 |
|
261 String mimeType = queryFileMimeType(testFile); |
|
262 |
|
263 Test.assertNotEquals(fa.getMime(), mimeType, String.format( |
|
264 "Check mime type of [%s] file", testFile)); |
|
265 |
|
266 String desktopFileName = queryMimeTypeDefaultHandler(fa.getMime()); |
|
267 |
|
268 Test.assertNull(desktopFileName, String.format( |
|
269 "Check there is no default handler for [%s] mime type", |
|
270 fa.getMime())); |
|
271 }); |
|
272 }); |
|
273 } |
|
274 |
|
275 private static String queryFileMimeType(Path file) { |
|
276 return new Executor() |
|
277 .setExecutable("xdg-mime") |
|
278 .addArguments("query", "filetype", file.toString()) |
|
279 .executeAndGetFirstLineOfOutput(); |
|
280 } |
|
281 |
|
282 private static String queryMimeTypeDefaultHandler(String mimeType) { |
|
283 return new Executor() |
|
284 .setExecutable("xdg-mime") |
|
285 .addArguments("query", "default", mimeType) |
|
286 .executeAndGetFirstLineOfOutput(); |
132 } |
287 } |
133 |
288 |
134 private static String getPackageArch(PackageType type) { |
289 private static String getPackageArch(PackageType type) { |
135 if (archs == null) { |
290 if (archs == null) { |
136 archs = new HashMap<>(); |
291 archs = new HashMap<>(); |
137 } |
292 } |
138 |
293 |
139 String arch = archs.get(type); |
294 String arch = archs.get(type); |
140 if (arch == null) { |
295 if (arch == null) { |
141 Executor exec = new Executor(); |
296 Executor exec = new Executor(); |
142 exec.saveFirstLineOfOutput(); |
|
143 switch (type) { |
297 switch (type) { |
144 case LINUX_DEB: |
298 case LINUX_DEB: |
145 exec.setExecutable("dpkg").addArgument( |
299 exec.setExecutable("dpkg").addArgument( |
146 "--print-architecture"); |
300 "--print-architecture"); |
147 break; |
301 break; |