|
1 | 1 | package org.testcontainers.utility; |
2 | 2 |
|
| 3 | +import org.apache.commons.lang.StringUtils; |
3 | 4 | import org.hamcrest.Description; |
4 | 5 | import org.hamcrest.Matcher; |
5 | 6 | import org.hamcrest.core.IsCollectionContaining; |
|
9 | 10 | import org.testcontainers.images.builder.ImageFromDockerfile; |
10 | 11 |
|
11 | 12 | import java.io.File; |
| 13 | +import java.io.IOException; |
| 14 | +import java.util.ArrayList; |
12 | 15 | import java.util.Arrays; |
| 16 | +import java.util.List; |
13 | 17 |
|
| 18 | +import static org.apache.commons.lang.StringUtils.isEmpty; |
14 | 19 | import static org.hamcrest.CoreMatchers.allOf; |
15 | 20 | import static org.hamcrest.CoreMatchers.containsString; |
| 21 | +import static org.hamcrest.CoreMatchers.endsWith; |
| 22 | +import static org.hamcrest.Matchers.equalTo; |
16 | 23 | import static org.rnorth.visibleassertions.VisibleAssertions.assertThat; |
17 | 24 | import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue; |
18 | 25 |
|
19 | 26 | public class DirectoryTarResourceTest { |
20 | | - |
21 | 27 | @Test |
22 | 28 | public void simpleRecursiveFileTest() { |
23 | 29 | // 'src' is expected to be the project base directory, so all source code/resources should be copied in |
24 | 30 | File directory = new File("src"); |
25 | 31 |
|
26 | | - GenericContainer container = new GenericContainer( |
27 | | - new ImageFromDockerfile() |
28 | | - .withDockerfileFromBuilder(builder -> |
29 | | - builder.from("alpine:3.14") |
30 | | - .copy("/tmp/foo", "/foo") |
31 | | - .cmd("cat /foo/test/resources/test-recursive-file.txt") |
32 | | - .build() |
33 | | - ).withFileFromFile("/tmp/foo", directory)) |
34 | | - .withStartupCheckStrategy(new OneShotStartupCheckStrategy()); |
| 32 | + try (GenericContainer container = new GenericContainer( |
| 33 | + new ImageFromDockerfile() |
| 34 | + .withDockerfileFromBuilder(builder -> |
| 35 | + builder.from("alpine:3.14") |
| 36 | + .copy("/tmp/foo", "/foo") |
| 37 | + .cmd("cat /foo/test/resources/test-recursive-file.txt") |
| 38 | + .build() |
| 39 | + ).withFileFromFile("/tmp/foo", directory)) |
| 40 | + .withStartupCheckStrategy(new OneShotStartupCheckStrategy())) { |
35 | 41 |
|
36 | | - container.start(); |
| 42 | + container.start(); |
37 | 43 |
|
38 | | - final String results = container.getLogs(); |
| 44 | + final String results = container.getLogs(); |
39 | 45 |
|
40 | | - assertTrue("The container has a file that was copied in via a recursive copy", results.contains("Used for DirectoryTarResourceTest")); |
| 46 | + assertTrue("The container has a file that was copied in via a recursive copy", results.contains("Used for DirectoryTarResourceTest")); |
| 47 | + } |
41 | 48 | } |
42 | 49 |
|
43 | 50 | @Test |
44 | 51 | public void simpleRecursiveFileWithPermissionTest() { |
45 | | - GenericContainer container = new GenericContainer( |
46 | | - new ImageFromDockerfile() |
47 | | - .withDockerfileFromBuilder(builder -> |
48 | | - builder.from("alpine:3.14") |
49 | | - .copy("/tmp/foo", "/foo") |
50 | | - .cmd("ls", "-al", "/") |
51 | | - .build() |
52 | | - ).withFileFromFile("/tmp/foo", new File("/mappable-resource/test-resource.txt"), |
53 | | - 0754)) |
54 | | - .withStartupCheckStrategy(new OneShotStartupCheckStrategy()); |
55 | | - |
56 | | - container.start(); |
57 | | - String listing = container.getLogs(); |
58 | | - |
59 | | - assertThat("Listing shows that file is copied with mode requested.", |
| 52 | + try (GenericContainer container = new GenericContainer( |
| 53 | + new ImageFromDockerfile() |
| 54 | + .withDockerfileFromBuilder(builder -> |
| 55 | + builder.from("alpine:3.14") |
| 56 | + .copy("/tmp/foo", "/foo") |
| 57 | + .cmd("ls", "-al", "/") |
| 58 | + .build() |
| 59 | + ).withFileFromFile("/tmp/foo", new File("/mappable-resource/test-resource.txt"), |
| 60 | + 0754)) |
| 61 | + .withStartupCheckStrategy(new OneShotStartupCheckStrategy())) { |
| 62 | + |
| 63 | + container.start(); |
| 64 | + String listing = container.getLogs(); |
| 65 | + |
| 66 | + assertThat("Listing shows that file is copied with mode requested.", |
60 | 67 | Arrays.asList(listing.split("\\n")), |
61 | | - exactlyNItems(1, allOf(containsString("-rwxr-xr--"), containsString("foo")))); |
| 68 | + exactlyOnce(allOf(containsString("-rwxr-xr--"), containsString("foo")))); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + @Test |
| 73 | + public void transferFileDockerDaemon() { |
| 74 | + final File theFile = new File("src/test/resources/mappable-resource/test-resource.txt"); |
| 75 | + try (GenericContainer container = new GenericContainer( |
| 76 | + new ImageFromDockerfile() |
| 77 | + .withDockerfileFromBuilder(builder -> |
| 78 | + builder.from("alpine:3.3") |
| 79 | + .copy(".", "/foo/") |
| 80 | + .cmd("ls", "-lapR", "/foo") |
| 81 | + .build() |
| 82 | + ) |
| 83 | + .withFileFromFile("bar1", theFile) |
| 84 | + .withFileFromFile("./bar2", theFile) |
| 85 | + .withFileFromFile("../bar3", theFile) |
| 86 | + .withFileFromFile(".bar4", theFile) |
| 87 | + .withFileFromFile("..bar5", theFile) |
| 88 | + .withFileFromFile("xxx/../bar6", theFile) |
| 89 | + .withFileFromFile("x7/./bar7", theFile) |
| 90 | + .withFileFromFile("x8/././bar8", theFile) |
| 91 | + .withFileFromFile("x9/../../bar9", theFile)) |
| 92 | + .withStartupCheckStrategy(new OneShotStartupCheckStrategy())) { |
| 93 | + |
| 94 | + container.start(); |
| 95 | + |
| 96 | + final List<String> logLines = Arrays.asList(container.getLogs().split("\\n")); |
| 97 | + assertThat("Three groups of dirs", logLines.stream() |
| 98 | + .filter(StringUtils::isEmpty) |
| 99 | + .count(), equalTo(2L)); |
| 100 | + |
| 101 | + // parent dir + 2 sub dirs |
| 102 | + List<String> parentDir = null; |
| 103 | + List<String> subDir1 = null; |
| 104 | + int start = 0; |
| 105 | + for (int i = 0; i < logLines.size(); i++) { |
| 106 | + if (isEmpty(logLines.get(i))) { |
| 107 | + if (parentDir == null) { |
| 108 | + parentDir = new ArrayList<>(logLines.subList(start, i)); |
| 109 | + start = i; |
| 110 | + } else if (subDir1 == null) { |
| 111 | + subDir1 = new ArrayList<>(logLines.subList(start, i)); |
| 112 | + start = i; |
| 113 | + } |
| 114 | + } |
| 115 | + } |
| 116 | + List<String> subDir2 = new ArrayList<>(logLines.subList(start, logLines.size())); |
| 117 | + |
| 118 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" bar1"))); |
| 119 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" bar2"))); |
| 120 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" bar3"))); |
| 121 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" .bar4"))); |
| 122 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" ..bar5"))); |
| 123 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" bar6"))); |
| 124 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" x7/"))); |
| 125 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" x8/"))); |
| 126 | + assertThat("Listing shows that file is copied.", parentDir, exactlyOnce(endsWith(" bar9"))); |
| 127 | + assertThat("Listing shows that file is copied.", subDir1, exactlyOnce(endsWith(" bar7"))); |
| 128 | + assertThat("Listing shows that file is copied.", subDir2, exactlyOnce(endsWith(" bar8"))); |
| 129 | + } |
62 | 130 | } |
63 | 131 |
|
64 | 132 | @Test |
65 | 133 | public void simpleRecursiveClasspathResourceTest() { |
66 | 134 | // This test combines the copying of classpath resources from JAR files with the recursive TAR approach, to allow JARed classpath resources to be copied in to an image |
67 | 135 |
|
68 | | - GenericContainer container = new GenericContainer( |
69 | | - new ImageFromDockerfile() |
70 | | - .withDockerfileFromBuilder(builder -> |
71 | | - builder.from("alpine:3.14") |
72 | | - .copy("/tmp/foo", "/foo") |
73 | | - .cmd("ls -lRt /foo") |
74 | | - .build() |
75 | | - ).withFileFromClasspath("/tmp/foo", "/recursive/dir")) // here we use /org/junit as a directory that really should exist on the classpath |
76 | | - .withStartupCheckStrategy(new OneShotStartupCheckStrategy()); |
| 136 | + try (GenericContainer container = new GenericContainer( |
| 137 | + new ImageFromDockerfile() |
| 138 | + .withDockerfileFromBuilder(builder -> |
| 139 | + builder.from("alpine:3.14") |
| 140 | + .copy("/tmp/foo", "/foo") |
| 141 | + .cmd("ls -lRt /foo") |
| 142 | + .build() |
| 143 | + ).withFileFromClasspath("/tmp/foo", "/recursive/dir")) // here we use /org/junit as a directory that really should exist on the classpath |
| 144 | + .withStartupCheckStrategy(new OneShotStartupCheckStrategy())) { |
77 | 145 |
|
78 | | - container.start(); |
| 146 | + container.start(); |
79 | 147 |
|
80 | | - final String results = container.getLogs(); |
| 148 | + final String results = container.getLogs(); |
| 149 | + |
| 150 | + // ExternalResource.class is known to exist in a subdirectory of /org/junit so should be successfully copied in |
| 151 | + assertTrue("The container has a file that was copied in via a recursive copy from a JAR resource", results.contains("content.txt")); |
| 152 | + } |
| 153 | + } |
81 | 154 |
|
82 | | - // ExternalResource.class is known to exist in a subdirectory of /org/junit so should be successfully copied in |
83 | | - assertTrue("The container has a file that was copied in via a recursive copy from a JAR resource", results.contains("content.txt")); |
| 155 | + public static <T> Matcher<Iterable<? super T>> exactlyOnce(Matcher<? super T> elementMatcher) { |
| 156 | + return exactlyNItems(1, elementMatcher); |
84 | 157 | } |
85 | 158 |
|
86 | 159 | public static <T> Matcher<Iterable<? super T>> exactlyNItems(final int n, Matcher<? super T> elementMatcher) { |
|
0 commit comments