Skip to content

Commit 0193904

Browse files
committed
Make docker tests more reliable (#68512)
Closes #66656. Current, `Docker#verifyOssInstallation(...)` checks the permissions of `elasticsearch.keystore`, however this often causes problems when a test forgets to wait for ES and the keystore doesn't exist yet. Instead, add a test specifically to check `elasticsearch.keystore` and remove the check from `verifyOssInstallation()`.
1 parent 094bede commit 0193904

File tree

4 files changed

+44
-10
lines changed

4 files changed

+44
-10
lines changed

buildSrc/src/main/java/org/elasticsearch/gradle/docker/DockerSupportService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ public static class DockerAvailability {
311311
* <ul>
312312
* <li>Installed</li>
313313
* <li>Executable</li>
314-
* <li>Is at least version compatibile with minimum version</li>
314+
* <li>Is at least version compatible with minimum version</li>
315315
* <li>Can execute a command that requires privileges</li>
316316
* </ul>
317317
*/

qa/os/src/test/java/org/elasticsearch/packaging/test/DockerTests.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
import static java.nio.file.attribute.PosixFilePermissions.fromString;
4040
import static java.util.Collections.singletonMap;
41+
import static org.elasticsearch.packaging.util.Docker.assertPermissionsAndOwnership;
4142
import static org.elasticsearch.packaging.util.Docker.chownWithPrivilegeEscalation;
4243
import static org.elasticsearch.packaging.util.Docker.copyFromContainer;
4344
import static org.elasticsearch.packaging.util.Docker.existsInContainer;
@@ -151,6 +152,15 @@ public void test041AmazonCaCertsAreInTheKeystore() {
151152
assertTrue("Expected Amazon trusted cert in cacerts", matches);
152153
}
153154

155+
/**
156+
* Check that when the keystore is created on startup, it is created with the correct permissions.
157+
*/
158+
public void test042KeystorePermissionsAreCorrect() throws Exception {
159+
waitForElasticsearch(installation);
160+
161+
assertPermissionsAndOwnership(installation.config("elasticsearch.keystore"), p660);
162+
}
163+
154164
/**
155165
* Send some basic index, count and delete requests, in order to check that the installation
156166
* is minimally functional.
@@ -189,7 +199,7 @@ public void test070BindMountCustomPathConfAndJvmOptions() throws Exception {
189199

190200
waitForElasticsearch(installation);
191201

192-
final JsonNode nodes = getJson("_nodes").get("nodes");
202+
final JsonNode nodes = getJson("/_nodes").get("nodes");
193203
final String nodeId = nodes.fieldNames().next();
194204

195205
final int heapSize = nodes.at("/" + nodeId + "/jvm/mem/heap_init_in_bytes").intValue();
@@ -217,7 +227,7 @@ public void test071BindMountCustomPathWithDifferentUID() throws Exception {
217227

218228
waitForElasticsearch(installation);
219229

220-
final JsonNode nodes = getJson("_nodes");
230+
final JsonNode nodes = getJson("/_nodes");
221231

222232
assertThat(nodes.at("/_nodes/total").intValue(), equalTo(1));
223233
assertThat(nodes.at("/_nodes/successful").intValue(), equalTo(1));
@@ -729,7 +739,7 @@ public void test131InitProcessHasCorrectPID() {
729739
public void test140CgroupOsStatsAreAvailable() throws Exception {
730740
waitForElasticsearch(installation);
731741

732-
final JsonNode nodes = getJson("_nodes/stats/os").get("nodes");
742+
final JsonNode nodes = getJson("/_nodes/stats/os").get("nodes");
733743

734744
final String nodeId = nodes.fieldNames().next();
735745

qa/os/src/test/java/org/elasticsearch/packaging/test/PackagingTestCase.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
import static org.elasticsearch.packaging.util.Cleanup.cleanEverything;
5959
import static org.elasticsearch.packaging.util.Docker.ensureImageIsLoaded;
6060
import static org.elasticsearch.packaging.util.Docker.removeContainer;
61-
import static org.elasticsearch.packaging.util.Docker.waitForElasticsearch;
6261
import static org.elasticsearch.packaging.util.FileExistenceMatchers.fileExists;
6362
import static org.elasticsearch.packaging.util.FileUtils.append;
6463
import static org.hamcrest.CoreMatchers.anyOf;
@@ -218,7 +217,6 @@ protected static void install() throws Exception {
218217
case DOCKER:
219218
case DOCKER_UBI:
220219
installation = Docker.runContainer(distribution);
221-
waitForElasticsearch(installation);
222220
Docker.verifyContainerInstallation(installation, distribution);
223221
break;
224222
default:

qa/os/src/test/java/org/elasticsearch/packaging/util/Docker.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
import java.util.HashMap;
2525
import java.util.List;
2626
import java.util.Map;
27+
import java.util.Objects;
2728
import java.util.Set;
2829
import java.util.stream.Stream;
2930

3031
import static java.nio.file.attribute.PosixFilePermissions.fromString;
3132
import static org.elasticsearch.packaging.util.FileMatcher.p644;
32-
import static org.elasticsearch.packaging.util.FileMatcher.p660;
3333
import static org.elasticsearch.packaging.util.FileMatcher.p664;
3434
import static org.elasticsearch.packaging.util.FileMatcher.p755;
3535
import static org.elasticsearch.packaging.util.FileMatcher.p770;
@@ -84,6 +84,7 @@ public static void ensureImageIsLoaded(Distribution distribution) {
8484
* successfully.
8585
*
8686
* @param distribution details about the docker image being tested
87+
* @return an installation that models the running container
8788
*/
8889
public static Installation runContainer(Distribution distribution) {
8990
return runContainer(distribution, DockerRun.builder());
@@ -95,6 +96,7 @@ public static Installation runContainer(Distribution distribution) {
9596
*
9697
* @param distribution details about the docker image being tested
9798
* @param builder the command to run
99+
* @return an installation that models the running container
98100
*/
99101
public static Installation runContainer(Distribution distribution, DockerRun builder) {
100102
executeDockerRun(distribution, builder);
@@ -261,13 +263,17 @@ protected String[] getScriptCommand(String script) {
261263

262264
/**
263265
* Checks whether a path exists in the Docker container.
266+
* @param path the path that ought to exist
267+
* @return whether the path exists
264268
*/
265269
public static boolean existsInContainer(Path path) {
266270
return existsInContainer(path.toString());
267271
}
268272

269273
/**
270274
* Checks whether a path exists in the Docker container.
275+
* @param path the path that ought to exist
276+
* @return whether the path exists
271277
*/
272278
public static boolean existsInContainer(String path) {
273279
logger.debug("Checking whether file " + path + " exists in container");
@@ -366,6 +372,8 @@ public static void chownWithPrivilegeEscalation(Path localPath, String ownership
366372

367373
/**
368374
* Checks that the specified path's permissions and ownership match those specified.
375+
* @param path the path to check
376+
* @param expectedPermissions the unix permissions that the path ought to have
369377
*/
370378
public static void assertPermissionsAndOwnership(Path path, Set<PosixFilePermission> expectedPermissions) {
371379
logger.debug("Checking permissions and ownership of [" + path + "]");
@@ -387,6 +395,7 @@ public static void assertPermissionsAndOwnership(Path path, Set<PosixFilePermiss
387395

388396
/**
389397
* Waits for up to 20 seconds for a path to exist in the container.
398+
* @param path the path to await
390399
*/
391400
public static void waitForPathToExist(Path path) throws InterruptedException {
392401
int attempt = 0;
@@ -404,6 +413,8 @@ public static void waitForPathToExist(Path path) throws InterruptedException {
404413

405414
/**
406415
* Perform a variety of checks on an installation. If the current distribution is not OSS, additional checks are carried out.
416+
* @param installation the installation to verify
417+
* @param distribution the distribution to verify
407418
*/
408419
public static void verifyContainerInstallation(Installation installation, Distribution distribution) {
409420
verifyOssInstallation(installation);
@@ -424,8 +435,6 @@ private static void verifyOssInstallation(Installation es) {
424435

425436
Stream.of(es.modules).forEach(dir -> assertPermissionsAndOwnership(dir, p755));
426437

427-
assertPermissionsAndOwnership(es.config("elasticsearch.keystore"), p660);
428-
429438
Stream.of("elasticsearch.yml", "jvm.options", "log4j2.properties")
430439
.forEach(configFile -> assertPermissionsAndOwnership(es.config(configFile), p664));
431440

@@ -508,14 +517,31 @@ public static String getContainerId() {
508517
return containerId;
509518
}
510519

520+
/**
521+
* Performs an HTTP GET to <code>http://localhost:9200/</code> with the supplied path.
522+
* @param path the path to fetch, which must start with <code>/</code>
523+
* @return the parsed response
524+
*/
511525
public static JsonNode getJson(String path) throws Exception {
512-
final String pluginsResponse = makeRequest(Request.Get("http://localhost:9200/" + path));
526+
path = Objects.requireNonNull(path).trim();
527+
if (path.isEmpty()) {
528+
throw new IllegalArgumentException("path must be supplied");
529+
}
530+
if (path.startsWith("/") == false) {
531+
throw new IllegalArgumentException("path must start with /");
532+
}
533+
final String pluginsResponse = makeRequest(Request.Get("http://localhost:9200" + path));
513534

514535
ObjectMapper mapper = new ObjectMapper();
515536

516537
return mapper.readTree(pluginsResponse);
517538
}
518539

540+
/**
541+
* Fetches all the labels for a Docker image
542+
* @param distribution required to derive the image name
543+
* @return a mapping from label name to value
544+
*/
519545
public static Map<String, String> getImageLabels(Distribution distribution) throws Exception {
520546
// The format below extracts the .Config.Labels value, and prints it as json. Without the json
521547
// modifier, a stringified Go map is printed instead, which isn't helpful.

0 commit comments

Comments
 (0)