1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.hazendaz.maven.makeself;
19
20 import java.io.File;
21 import java.lang.reflect.Field;
22 import java.lang.reflect.Method;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.util.Arrays;
26 import java.util.List;
27
28 import org.apache.maven.plugin.MojoExecutionException;
29 import org.apache.maven.plugin.logging.Log;
30 import org.apache.maven.project.MavenProject;
31 import org.apache.maven.project.MavenProjectHelper;
32 import org.eclipse.aether.RepositorySystemSession;
33 import org.eclipse.aether.repository.LocalRepository;
34 import org.junit.jupiter.api.Assertions;
35 import org.junit.jupiter.api.Assumptions;
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.api.extension.ExtendWith;
38 import org.junit.jupiter.api.io.TempDir;
39 import org.mockito.Mock;
40 import org.mockito.Mockito;
41 import org.mockito.junit.jupiter.MockitoExtension;
42
43
44
45
46 @ExtendWith(MockitoExtension.class)
47 class MakeselfMojoTest {
48
49
50 @TempDir
51 Path tempDir;
52
53
54 @Mock
55 private Log log;
56
57
58 @Mock
59 private RepositorySystemSession repoSession;
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 private static void setField(final Object obj, final String fieldName, final Object value) throws Exception {
75 final Field field = findField(obj.getClass(), fieldName);
76 field.setAccessible(true);
77 field.set(obj, value);
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 private static Field findField(final Class<?> clazz, final String name) throws NoSuchFieldException {
94 try {
95 return clazz.getDeclaredField(name);
96 } catch (final NoSuchFieldException e) {
97 if (clazz.getSuperclass() != null) {
98 return findField(clazz.getSuperclass(), name);
99 }
100 throw e;
101 }
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115 @SuppressWarnings("unchecked")
116 private static List<String> callLoadArgs(final MakeselfMojo mojo) throws Exception {
117 final Method method = MakeselfMojo.class.getDeclaredMethod("loadArgs");
118 method.setAccessible(true);
119 return (List<String>) method.invoke(mojo);
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 private static boolean callIsTrue(final MakeselfMojo mojo, final Boolean value) throws Exception {
136 final Method method = MakeselfMojo.class.getDeclaredMethod("isTrue", Boolean.class);
137 method.setAccessible(true);
138 return (boolean) method.invoke(mojo, value);
139 }
140
141
142
143
144
145
146
147 @Test
148 void testSkipExecution() throws Exception {
149 final MakeselfMojo mojo = new MakeselfMojo();
150 mojo.setLog(log);
151 setField(mojo, "skip", true);
152
153 mojo.execute();
154
155 Mockito.verify(log).info("Makeself is skipped");
156 }
157
158
159
160
161
162
163
164 @Test
165 void testMissingArchiveDir() throws Exception {
166 final MakeselfMojo mojo = new MakeselfMojo();
167 mojo.setLog(log);
168 setField(mojo, "buildTarget", tempDir.toString() + "/");
169 setField(mojo, "archiveDir", "does-not-exist");
170
171 Assertions.assertThrows(MojoExecutionException.class, mojo::execute);
172 }
173
174
175
176
177
178
179
180 @Test
181 void testInlineScriptWithoutScriptArgs() throws Exception {
182 final MakeselfMojo mojo = new MakeselfMojo();
183 mojo.setLog(log);
184 Files.createDirectory(tempDir.resolve("archive"));
185 setField(mojo, "inlineScript", true);
186 setField(mojo, "buildTarget", tempDir.toString() + "/");
187 setField(mojo, "archiveDir", "archive");
188
189
190 Assertions.assertThrows(MojoExecutionException.class, mojo::execute);
191 }
192
193
194
195
196
197
198
199 @Test
200 void testStartupScriptWithoutDotSlash() throws Exception {
201 final MakeselfMojo mojo = new MakeselfMojo();
202 mojo.setLog(log);
203 Files.createDirectory(tempDir.resolve("archive"));
204 setField(mojo, "buildTarget", tempDir.toString() + "/");
205 setField(mojo, "archiveDir", "archive");
206 setField(mojo, "startupScript", "script.sh");
207
208 Assertions.assertThrows(MojoExecutionException.class, mojo::execute);
209 }
210
211
212
213
214
215
216
217 @Test
218 void testStartupScriptFileMissing() throws Exception {
219 final MakeselfMojo mojo = new MakeselfMojo();
220 mojo.setLog(log);
221 Files.createDirectory(tempDir.resolve("archive"));
222 setField(mojo, "buildTarget", tempDir.toString() + "/");
223 setField(mojo, "archiveDir", "archive");
224 setField(mojo, "startupScript", "./nonexistent.sh");
225
226 Assertions.assertThrows(MojoExecutionException.class, mojo::execute);
227 }
228
229
230
231
232
233
234
235 @Test
236 void testLoadArgsEmpty() throws Exception {
237 final MakeselfMojo mojo = new MakeselfMojo();
238 mojo.setLog(log);
239
240 final List<String> args = callLoadArgs(mojo);
241
242 Assertions.assertTrue(args.isEmpty());
243 }
244
245
246
247
248
249
250
251 @Test
252 void testLoadArgsBooleanFlags() throws Exception {
253 final MakeselfMojo mojo = new MakeselfMojo();
254 mojo.setLog(log);
255 setField(mojo, "tarQuietly", Boolean.TRUE);
256 setField(mojo, "quiet", Boolean.TRUE);
257 setField(mojo, "gzip", Boolean.TRUE);
258 setField(mojo, "bzip2", Boolean.TRUE);
259 setField(mojo, "bzip3", Boolean.TRUE);
260 setField(mojo, "pbzip2", Boolean.TRUE);
261 setField(mojo, "xz", Boolean.TRUE);
262 setField(mojo, "lzo", Boolean.TRUE);
263 setField(mojo, "lz4", Boolean.TRUE);
264 setField(mojo, "zstd", Boolean.TRUE);
265 setField(mojo, "pigz", Boolean.TRUE);
266 setField(mojo, "base64", Boolean.TRUE);
267 setField(mojo, "gpgEncrypt", Boolean.TRUE);
268 setField(mojo, "gpgAsymmetricEncryptSign", Boolean.TRUE);
269 setField(mojo, "sslEncrypt", Boolean.TRUE);
270 setField(mojo, "sslNoMd", Boolean.TRUE);
271 setField(mojo, "compress", Boolean.TRUE);
272 setField(mojo, "nochown", Boolean.TRUE);
273 setField(mojo, "chown", Boolean.TRUE);
274 setField(mojo, "nocomp", Boolean.TRUE);
275 setField(mojo, "notemp", Boolean.TRUE);
276 setField(mojo, "needroot", Boolean.TRUE);
277 setField(mojo, "current", Boolean.TRUE);
278 setField(mojo, "follow", Boolean.TRUE);
279 setField(mojo, "noprogress", Boolean.TRUE);
280 setField(mojo, "append", Boolean.TRUE);
281 setField(mojo, "copy", Boolean.TRUE);
282 setField(mojo, "nox11", Boolean.TRUE);
283 setField(mojo, "nowait", Boolean.TRUE);
284 setField(mojo, "nomd5", Boolean.TRUE);
285 setField(mojo, "nocrc", Boolean.TRUE);
286 setField(mojo, "sha256", Boolean.TRUE);
287 setField(mojo, "keepUmask", Boolean.TRUE);
288 setField(mojo, "exportConf", Boolean.TRUE);
289 setField(mojo, "nooverwrite", Boolean.TRUE);
290
291 final List<String> args = callLoadArgs(mojo);
292
293 Assertions.assertTrue(args.containsAll(Arrays.asList("--tar-quietly", "--quiet", "--gzip", "--bzip2", "--bzip3",
294 "--pbzip2", "--xz", "--lzo", "--lz4", "--zstd", "--pigz", "--base64", "--gpg-encrypt",
295 "--gpg-asymmetric-encrypt-sign", "--ssl-encrypt", "--ssl-no-md", "--compress", "--nochown", "--chown",
296 "--nocomp", "--notemp", "--needroot", "--current", "--follow", "--noprogress", "--append", "--copy",
297 "--nox11", "--nowait", "--nomd5", "--nocrc", "--sha256", "--keep-umask", "--export-conf",
298 "--nooverwrite")));
299 }
300
301
302
303
304
305
306
307 @Test
308 void testLoadArgsStringAndIntOptions() throws Exception {
309 final MakeselfMojo mojo = new MakeselfMojo();
310 mojo.setLog(log);
311 setField(mojo, "sslPasswd", "mypassword");
312 setField(mojo, "sslPassSrc", "env:MY_PASS");
313 setField(mojo, "complevel", 6);
314 setField(mojo, "compExtra", "--extra-opt");
315 setField(mojo, "threads", 4);
316 setField(mojo, "headerFile", "my-header.sh");
317 setField(mojo, "preextractScript", "preextract.sh");
318 setField(mojo, "cleanupScript", "cleanup.sh");
319 setField(mojo, "lsmFile", "my-package.lsm");
320 setField(mojo, "gpgExtraOpt", "--gpg-opt");
321 setField(mojo, "tarFormatOpt", "posix");
322 setField(mojo, "tarExtraOpt", "--exclude=.git");
323 setField(mojo, "untarExtraOpt", "--strip=1");
324 setField(mojo, "signPassphrase", "signingkey");
325 setField(mojo, "extractTargetDir", "/opt/myapp");
326 setField(mojo, "packagingDate", "2026-01-01");
327 setField(mojo, "licenseFile", "LICENSE");
328 setField(mojo, "helpHeaderFile", "help-header.txt");
329
330 final List<String> args = callLoadArgs(mojo);
331
332 Assertions.assertAll(() -> Assertions.assertTrue(args.contains("--ssl-passwd") && args.contains("mypassword")),
333 () -> Assertions.assertTrue(args.contains("--ssl-pass-src") && args.contains("env:MY_PASS")),
334 () -> Assertions.assertTrue(args.contains("--complevel") && args.contains("6")),
335 () -> Assertions.assertTrue(args.contains("--comp-extra") && args.contains("--extra-opt")),
336 () -> Assertions.assertTrue(args.contains("--threads") && args.contains("4")),
337 () -> Assertions.assertTrue(args.contains("--header") && args.contains("my-header.sh")),
338 () -> Assertions.assertTrue(args.contains("--preextract") && args.contains("preextract.sh")),
339 () -> Assertions.assertTrue(args.contains("--cleanup") && args.contains("cleanup.sh")),
340 () -> Assertions.assertTrue(args.contains("--lsm") && args.contains("my-package.lsm")),
341 () -> Assertions.assertTrue(args.contains("--gpg-extra") && args.contains("--gpg-opt")),
342 () -> Assertions.assertTrue(args.contains("--tar-format") && args.contains("posix")),
343 () -> Assertions.assertTrue(args.contains("--tar-extra") && args.contains("--exclude=.git")),
344 () -> Assertions.assertTrue(args.contains("--untar-extra") && args.contains("--strip=1")),
345 () -> Assertions.assertTrue(args.contains("--sign") && args.contains("signingkey")),
346 () -> Assertions.assertTrue(args.contains("--target") && args.contains("/opt/myapp")),
347 () -> Assertions.assertTrue(args.contains("--packaging-date") && args.contains("2026-01-01")),
348 () -> Assertions.assertTrue(args.contains("--license") && args.contains("LICENSE")),
349 () -> Assertions.assertTrue(args.contains("--help-header") && args.contains("help-header.txt")));
350 }
351
352
353
354
355
356
357
358 @Test
359 void testIsTrue() throws Exception {
360 final MakeselfMojo mojo = new MakeselfMojo();
361
362 Assertions.assertAll(() -> Assertions.assertFalse(callIsTrue(mojo, null)),
363 () -> Assertions.assertTrue(callIsTrue(mojo, Boolean.TRUE)),
364 () -> Assertions.assertFalse(callIsTrue(mojo, Boolean.FALSE)));
365 }
366
367
368
369
370
371
372
373 @Test
374 void testExtractMakeself() throws Exception {
375 final MakeselfMojo mojo = new MakeselfMojo();
376 mojo.setLog(log);
377 setField(mojo, "makeselfTempDirectory", tempDir.toFile());
378
379 final Method method = MakeselfMojo.class.getDeclaredMethod("extractMakeself");
380 method.setAccessible(true);
381 method.invoke(mojo);
382
383 Assertions.assertTrue(Files.exists(tempDir.resolve("makeself.sh")),
384 "makeself.sh should be extracted to temp directory");
385 Assertions.assertTrue(Files.exists(tempDir.resolve("makeself-header.sh")),
386 "makeself-header.sh should be extracted to temp directory");
387 }
388
389
390
391
392
393
394
395 @Test
396 void testExtractMakeselfIdempotent() throws Exception {
397 final MakeselfMojo mojo = new MakeselfMojo();
398 mojo.setLog(log);
399 setField(mojo, "makeselfTempDirectory", tempDir.toFile());
400
401 final Method method = MakeselfMojo.class.getDeclaredMethod("extractMakeself");
402 method.setAccessible(true);
403
404
405 method.invoke(mojo);
406 final long modifiedFirst = tempDir.resolve("makeself.sh").toFile().lastModified();
407
408
409 method.invoke(mojo);
410 final long modifiedSecond = tempDir.resolve("makeself.sh").toFile().lastModified();
411
412 Assertions.assertEquals(modifiedFirst, modifiedSecond, "makeself.sh should not be overwritten on second call");
413 }
414
415
416
417
418
419
420
421 @Test
422 void testSetFilePermissions() throws Exception {
423 final MakeselfMojo mojo = new MakeselfMojo();
424 mojo.setLog(log);
425
426 final File tempFile = Files.createTempFile(tempDir, "test", ".sh").toFile();
427
428 final Method method = MakeselfMojo.class.getDeclaredMethod("setFilePermissions", File.class);
429 method.setAccessible(true);
430 method.invoke(mojo, tempFile);
431
432 Assertions.assertTrue(tempFile.canExecute(), "File should be executable after setFilePermissions");
433 }
434
435
436
437
438
439
440
441
442 @Test
443 void testSetPosixFilePermissions() throws Exception {
444 final MakeselfMojo mojo = new MakeselfMojo();
445 mojo.setLog(log);
446
447 final Path tempFile = Files.createTempFile(tempDir, "test", ".sh");
448
449 final Method method = MakeselfMojo.class.getDeclaredMethod("setPosixFilePermissions", Path.class);
450 method.setAccessible(true);
451
452 method.invoke(mojo, tempFile);
453 }
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469 private MakeselfMojo buildFullFlowMojo(final String archiveDirName, final String startupScriptName)
470 throws Exception {
471 final Path archivePath = Files.createDirectories(tempDir.resolve(archiveDirName));
472 Files.createFile(archivePath.resolve(startupScriptName));
473
474 final File makeselfTempDir = Files.createDirectories(tempDir.resolve("makeself-tmp")).toFile();
475 final MavenProjectHelper projectHelper = Mockito.mock(MavenProjectHelper.class);
476 final MavenProject project = new MavenProject();
477
478 final MakeselfMojo mojo = new MakeselfMojo();
479 mojo.setLog(log);
480 setField(mojo, "buildTarget", tempDir.toString() + "/");
481 setField(mojo, "archiveDir", archiveDirName);
482 setField(mojo, "startupScript", "./" + startupScriptName);
483 setField(mojo, "fileName", "output.sh");
484 setField(mojo, "label", "Test Archive");
485 setField(mojo, "makeselfTempDirectory", makeselfTempDir);
486 setField(mojo, "projectHelper", projectHelper);
487 setField(mojo, "project", project);
488 return mojo;
489 }
490
491
492
493
494
495
496
497
498 @Test
499 void testExecuteFullFlowOnLinux() throws Exception {
500 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Test only applicable on non-Windows");
501
502 final MakeselfMojo mojo = buildFullFlowMojo("makeself", "makeself.sh");
503
504 mojo.execute();
505
506 Mockito.verify(log).info("Running makeself build");
507 }
508
509
510
511
512
513
514
515 @Test
516 void testExecuteWithVersionFlag() throws Exception {
517 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Test only applicable on non-Windows");
518
519 final MakeselfMojo mojo = buildFullFlowMojo("makeself", "makeself.sh");
520 setField(mojo, "version", Boolean.TRUE);
521
522 mojo.execute();
523
524 Mockito.verify(log, Mockito.never()).info("Running makeself build");
525 }
526
527
528
529
530
531
532
533 @Test
534 void testExecuteWithHelpFlag() throws Exception {
535 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Test only applicable on non-Windows");
536
537 final MakeselfMojo mojo = buildFullFlowMojo("makeself", "makeself.sh");
538 setField(mojo, "help", Boolean.TRUE);
539
540 mojo.execute();
541
542 Mockito.verify(log, Mockito.never()).info("Running makeself build");
543 }
544
545
546
547
548
549
550
551 @Test
552 void testExecuteWithAutoRun() throws Exception {
553 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Test only applicable on non-Windows");
554
555 final MakeselfMojo mojo = buildFullFlowMojo("makeself", "makeself.sh");
556 setField(mojo, "autoRun", true);
557
558 mojo.execute();
559
560 Mockito.verify(log).info("Auto-run created shell (this may take a few minutes)");
561 }
562
563
564
565
566
567
568
569 @Test
570 void testExecuteWithInlineScriptAndScriptArgs() throws Exception {
571 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Test only applicable on non-Windows");
572
573 final Path archivePath = Files.createDirectories(tempDir.resolve("myarchive"));
574 Files.createFile(archivePath.resolve("dummy.txt"));
575
576 final File makeselfTempDir = Files.createDirectories(tempDir.resolve("makeself-tmp")).toFile();
577 final MavenProjectHelper projectHelper = Mockito.mock(MavenProjectHelper.class);
578 final MavenProject project = new MavenProject();
579
580 final MakeselfMojo mojo = new MakeselfMojo();
581 mojo.setLog(log);
582 setField(mojo, "buildTarget", tempDir.toString() + "/");
583 setField(mojo, "archiveDir", "myarchive");
584 setField(mojo, "startupScript", "echo");
585 setField(mojo, "inlineScript", true);
586 setField(mojo, "scriptArgs", Arrays.asList("hello"));
587 setField(mojo, "fileName", "output.sh");
588 setField(mojo, "label", "Test Archive");
589 setField(mojo, "makeselfTempDirectory", makeselfTempDir);
590 setField(mojo, "projectHelper", projectHelper);
591 setField(mojo, "project", project);
592
593 mojo.execute();
594
595 Mockito.verify(log).info("Running makeself build");
596 }
597
598
599
600
601
602
603
604 @Test
605 void testLoadArgsWithFalseFlags() throws Exception {
606 final MakeselfMojo mojo = new MakeselfMojo();
607 mojo.setLog(log);
608 setField(mojo, "gzip", Boolean.FALSE);
609 setField(mojo, "bzip2", Boolean.FALSE);
610 setField(mojo, "xz", Boolean.FALSE);
611 setField(mojo, "nocomp", Boolean.FALSE);
612 setField(mojo, "nomd5", Boolean.FALSE);
613
614 final List<String> args = callLoadArgs(mojo);
615
616 Assertions.assertFalse(args.contains("--gzip"), "--gzip should not be present when gzip=false");
617 Assertions.assertFalse(args.contains("--bzip2"), "--bzip2 should not be present when bzip2=false");
618 Assertions.assertFalse(args.contains("--xz"), "--xz should not be present when xz=false");
619 Assertions.assertFalse(args.contains("--nocomp"), "--nocomp should not be present when nocomp=false");
620 Assertions.assertFalse(args.contains("--nomd5"), "--nomd5 should not be present when nomd5=false");
621 }
622
623
624
625
626
627
628
629
630
631 @Test
632 void testExecuteWindowsSimulatedExistingGitPath() throws Exception {
633 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Windows-simulation test is only run on non-Windows");
634
635 final MakeselfMojo mojo = new MakeselfMojo() {
636 @Override
637 protected boolean isWindows() {
638 return true;
639 }
640 };
641 mojo.setLog(log);
642
643
644 final Path archivePath = Files.createDirectories(tempDir.resolve("archive-w"));
645 Files.createFile(archivePath.resolve("startup.sh"));
646 final File makeselfTempDir = Files.createDirectories(tempDir.resolve("makeself-tmp-w")).toFile();
647 final MavenProjectHelper projectHelper = Mockito.mock(MavenProjectHelper.class);
648 final MavenProject project = new MavenProject();
649
650 setField(mojo, "buildTarget", tempDir.toString() + "/");
651 setField(mojo, "archiveDir", "archive-w");
652 setField(mojo, "startupScript", "./startup.sh");
653 setField(mojo, "fileName", "output-w.sh");
654 setField(mojo, "label", "Test");
655 setField(mojo, "makeselfTempDirectory", makeselfTempDir);
656 setField(mojo, "projectHelper", projectHelper);
657 setField(mojo, "project", project);
658
659
660 setField(mojo, "gitPath", tempDir.toString());
661
662
663 mojo.execute();
664
665
666 Mockito.verify(log).error(Mockito.eq(""), Mockito.any(Exception.class));
667 }
668
669
670
671
672
673
674
675
676
677 @Test
678 void testExecuteWindowsSimulatedCheckGitSetup() throws Exception {
679 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Windows-simulation test is only run on non-Windows");
680
681 final MakeselfMojo mojo = new MakeselfMojo() {
682 @Override
683 protected boolean isWindows() {
684 return true;
685 }
686
687 @Override
688 public void checkGitSetup() {
689
690 }
691 };
692 mojo.setLog(log);
693
694 final MakeselfMojo configured = mojo;
695 final MavenProjectHelper projectHelper = Mockito.mock(MavenProjectHelper.class);
696 final MavenProject project = new MavenProject();
697
698 final Path archivePath = Files.createDirectories(tempDir.resolve("archive-wcs"));
699 Files.createFile(archivePath.resolve("startup.sh"));
700 final File makeselfTempDir = Files.createDirectories(tempDir.resolve("makeself-tmp-wcs")).toFile();
701
702 setField(configured, "buildTarget", tempDir.toString() + "/");
703 setField(configured, "archiveDir", "archive-wcs");
704 setField(configured, "startupScript", "./startup.sh");
705 setField(configured, "fileName", "output-wcs.sh");
706 setField(configured, "label", "Test");
707 setField(configured, "makeselfTempDirectory", makeselfTempDir);
708 setField(configured, "projectHelper", projectHelper);
709 setField(configured, "project", project);
710
711
712 mojo.execute();
713
714 Mockito.verify(log).info("Running makeself build");
715 }
716
717
718
719
720
721
722
723
724 @Test
725 void testExecutePrivateWindowsPortableGitNotNull() throws Exception {
726 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Windows-simulation test is only run on non-Windows");
727
728 final MakeselfMojo mojo = new MakeselfMojo() {
729 @Override
730 protected boolean isWindows() {
731 return true;
732 }
733 };
734 mojo.setLog(log);
735
736 final PortableGit portableGit = new PortableGit(log);
737 setField(mojo, "portableGit", portableGit);
738
739 final LocalRepository localRepository = new LocalRepository(tempDir.toFile());
740 Mockito.when(repoSession.getLocalRepository()).thenReturn(localRepository);
741 setField(mojo, "repoSession", repoSession);
742
743
744 final Method executeMethod = MakeselfMojo.class.getDeclaredMethod("execute", List.class, boolean.class);
745 executeMethod.setAccessible(true);
746 executeMethod.invoke(mojo, Arrays.asList("bash", "--version"), false);
747
748
749 Mockito.verify(log, Mockito.atLeastOnce()).debug(Mockito.anyString());
750 }
751
752
753
754
755
756
757
758 @Test
759 void testSetFilePermissionsFailure() throws Exception {
760 final MakeselfMojo mojo = new MakeselfMojo();
761 mojo.setLog(log);
762
763 final File mockFile = Mockito.mock(File.class);
764 Mockito.when(mockFile.setExecutable(true, true)).thenReturn(false);
765 Mockito.when(mockFile.getName()).thenReturn("test-failure.sh");
766
767 final Method method = MakeselfMojo.class.getDeclaredMethod("setFilePermissions", File.class);
768 method.setAccessible(true);
769 method.invoke(mojo, mockFile);
770
771 Mockito.verify(log).error(Mockito.contains("Unable to set executable:"));
772 }
773
774
775
776
777
778
779
780
781 @Test
782 void testSetPosixFilePermissionsIOException() throws Exception {
783 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "POSIX permissions only apply on non-Windows");
784
785 final MakeselfMojo mojo = new MakeselfMojo();
786 mojo.setLog(log);
787
788
789 final Path nonExistent = tempDir.resolve("nonexistent-posix.sh");
790
791 final Method method = MakeselfMojo.class.getDeclaredMethod("setPosixFilePermissions", Path.class);
792 method.setAccessible(true);
793 method.invoke(mojo, nonExistent);
794
795 Mockito.verify(log).error(Mockito.eq("Failed attempted Posix permissions"), Mockito.any(Exception.class));
796 }
797
798
799
800
801
802
803
804
805 @Test
806 void testExtractMakeselfCreatesNewDirectory() throws Exception {
807 final MakeselfMojo mojo = new MakeselfMojo();
808 mojo.setLog(log);
809
810
811 final File newDir = tempDir.resolve("brand-new-makeself-dir").toFile();
812 Assertions.assertFalse(newDir.exists(), "Pre-condition: directory should not exist before the test");
813 setField(mojo, "makeselfTempDirectory", newDir);
814
815 final Method method = MakeselfMojo.class.getDeclaredMethod("extractMakeself");
816 method.setAccessible(true);
817 method.invoke(mojo);
818
819 Assertions.assertTrue(Files.exists(newDir.toPath().resolve("makeself.sh")),
820 "makeself.sh should be extracted into the newly created directory");
821 }
822
823
824
825
826
827
828
829 @Test
830 void testExtractMakeselfMkdirsFails() throws Exception {
831 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Test uses /dev/null which is only available on Unix");
832
833 final MakeselfMojo mojo = new MakeselfMojo();
834 mojo.setLog(log);
835
836
837 final Path impossibleDir = Path.of("/dev/null/impossible-makeself-dir");
838 setField(mojo, "makeselfTempDirectory", impossibleDir.toFile());
839
840 final Method method = MakeselfMojo.class.getDeclaredMethod("extractMakeself");
841 method.setAccessible(true);
842 method.invoke(mojo);
843
844 Mockito.verify(log).error(Mockito.contains("Unable to make directory"));
845 }
846
847
848
849
850
851
852
853 @Test
854 void testExecutePrivateFailStatus() throws Exception {
855 Assumptions.assumeFalse(AbstractGitMojo.WINDOWS, "Uses bash which is only available on Unix");
856
857 final MakeselfMojo mojo = new MakeselfMojo();
858 mojo.setLog(log);
859
860 final Method executeMethod = MakeselfMojo.class.getDeclaredMethod("execute", List.class, boolean.class);
861 executeMethod.setAccessible(true);
862 executeMethod.invoke(mojo, Arrays.asList("bash", "-c", "exit 1"), false);
863
864 Mockito.verify(log).error(Mockito.contains("makeself failed with error status:"));
865 }
866
867 }