Skip to content

Commit 4fe8452

Browse files
authored
Add docker-composed based test fixture for GCS (#48903)
Similarly to what has be done for Azure in #48636, this commit adds a new :test:fixtures:gcs-fixture project which provides two docker-compose based fixtures that emulate a Google Cloud Storage service. Some code has been extracted from existing tests and placed into this new project so that it can be easily reused in other projects.
1 parent 1c95f09 commit 4fe8452

File tree

13 files changed

+551
-938
lines changed

13 files changed

+551
-938
lines changed

plugins/repository-gcs/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ dependencies {
5454
compile 'io.opencensus:opencensus-api:0.18.0'
5555
compile 'io.opencensus:opencensus-contrib-http-util:0.18.0'
5656
compile 'com.google.apis:google-api-services-storage:v1-rev20190426-1.28.0'
57+
58+
testCompile project(':test:fixtures:gcs-fixture')
5759
}
5860

5961
dependencyLicenses {

plugins/repository-gcs/qa/google-cloud-storage/build.gradle

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020

2121
import org.elasticsearch.gradle.MavenFilteringHack
22-
import org.elasticsearch.gradle.test.AntFixture
2322

2423
import java.security.KeyPair
2524
import java.security.KeyPairGenerator
@@ -28,7 +27,14 @@ import static org.elasticsearch.gradle.PropertyNormalization.IGNORE_VALUE
2827

2928
apply plugin: 'elasticsearch.standalone-rest-test'
3029
apply plugin: 'elasticsearch.rest-test'
30+
apply plugin: 'elasticsearch.test.fixtures'
3131

32+
// TODO think about flattening qa:google-cloud-storage project into parent
33+
dependencies {
34+
testCompile project(path: ':plugins:repository-gcs')
35+
}
36+
37+
testFixtures.useFixture(':test:fixtures:gcs-fixture')
3238
boolean useFixture = false
3339

3440
String gcsServiceAccount = System.getenv("google_storage_service_account")
@@ -38,7 +44,7 @@ String gcsBasePath = System.getenv("google_storage_base_path")
3844
File serviceAccountFile = null
3945
if (!gcsServiceAccount && !gcsBucket && !gcsBasePath) {
4046
serviceAccountFile = new File(project.buildDir, 'generated-resources/service_account_test.json')
41-
gcsBucket = 'bucket_test'
47+
gcsBucket = 'bucket'
4248
gcsBasePath = 'integration_test'
4349
useFixture = true
4450
} else {
@@ -48,12 +54,11 @@ if (!gcsServiceAccount && !gcsBucket && !gcsBasePath) {
4854
}
4955
}
5056

51-
/** A task to start the GoogleCloudStorageFixture which emulates a Google Cloud Storage service **/
52-
task googleCloudStorageFixture(type: AntFixture) {
53-
dependsOn testClasses
54-
env 'CLASSPATH', "${ -> project.sourceSets.test.runtimeClasspath.asPath }"
55-
executable = new File(project.runtimeJavaHome, 'bin/java')
56-
args 'org.elasticsearch.repositories.gcs.GoogleCloudStorageFixture', baseDir, 'bucket_test'
57+
def fixtureAddress = { fixture ->
58+
assert useFixture : 'closure should not be used without a fixture'
59+
int ephemeralPort = project(':test:fixtures:gcs-fixture').postProcessFixture.ext."test.fixtures.${fixture}.tcp.80"
60+
assert ephemeralPort > 0
61+
'http://127.0.0.1:' + ephemeralPort
5762
}
5863

5964
/** A service account file that points to the Google Cloud Storage service emulated by the fixture **/
@@ -96,10 +101,10 @@ testClusters.integTest {
96101
keystore 'gcs.client.integration_test.credentials_file', serviceAccountFile, IGNORE_VALUE
97102

98103
if (useFixture) {
99-
tasks.integTest.dependsOn createServiceAccountFile, googleCloudStorageFixture
104+
tasks.integTest.dependsOn createServiceAccountFile
100105
/* Use a closure on the string to delay evaluation until tests are executed */
101-
setting 'gcs.client.integration_test.endpoint', { "http://${googleCloudStorageFixture.addressAndPort}" }, IGNORE_VALUE
102-
setting 'gcs.client.integration_test.token_uri', { "http://${googleCloudStorageFixture.addressAndPort}/o/oauth2/token" }, IGNORE_VALUE
106+
setting 'gcs.client.integration_test.endpoint', { "${ -> fixtureAddress('gcs-fixture') }" }, IGNORE_VALUE
107+
setting 'gcs.client.integration_test.token_uri', { "${ -> fixtureAddress('gcs-fixture') }/o/oauth2/token" }, IGNORE_VALUE
103108
} else {
104109
println "Using an external service to test the repository-gcs plugin"
105110
}

plugins/repository-gcs/qa/google-cloud-storage/src/test/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageFixture.java

Lines changed: 0 additions & 611 deletions
This file was deleted.

plugins/repository-gcs/src/test/java/org/elasticsearch/repositories/gcs/GoogleCloudStorageBlobContainerRetriesTests.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.cloud.storage.StorageOptions;
2525
import com.sun.net.httpserver.HttpContext;
2626
import com.sun.net.httpserver.HttpServer;
27+
import fixture.gcs.FakeOAuth2HttpHandler;
2728
import org.apache.http.HttpStatus;
2829
import org.elasticsearch.common.Nullable;
2930
import org.elasticsearch.common.Strings;
@@ -68,6 +69,10 @@
6869
import java.util.concurrent.atomic.AtomicInteger;
6970
import java.util.concurrent.atomic.AtomicReference;
7071

72+
import static fixture.gcs.GoogleCloudStorageHttpHandler.getContentRangeEnd;
73+
import static fixture.gcs.GoogleCloudStorageHttpHandler.getContentRangeLimit;
74+
import static fixture.gcs.GoogleCloudStorageHttpHandler.getContentRangeStart;
75+
import static fixture.gcs.GoogleCloudStorageHttpHandler.parseMultipartRequestBody;
7176
import static java.nio.charset.StandardCharsets.UTF_8;
7277
import static org.elasticsearch.repositories.ESBlobStoreTestCase.randomBytes;
7378
import static org.elasticsearch.repositories.gcs.GoogleCloudStorageClientSettings.CREDENTIALS_FILE_SETTING;
@@ -144,13 +149,7 @@ StorageOptions createStorageOptions(final GoogleCloudStorageClientSettings clien
144149

145150
final List<HttpContext> httpContexts = Arrays.asList(
146151
// Auth
147-
httpServer.createContext("/token", exchange -> {
148-
byte[] response = ("{\"access_token\":\"foo\",\"token_type\":\"Bearer\",\"expires_in\":3600}").getBytes(UTF_8);
149-
exchange.getResponseHeaders().add("Content-Type", "application/json");
150-
exchange.sendResponseHeaders(HttpStatus.SC_OK, response.length);
151-
exchange.getResponseBody().write(response);
152-
exchange.close();
153-
}),
152+
httpServer.createContext("/token", new FakeOAuth2HttpHandler()),
154153
// Does bucket exists?
155154
httpServer.createContext("/storage/v1/b/bucket", exchange -> {
156155
byte[] response = ("{\"kind\":\"storage#bucket\",\"name\":\"bucket\",\"id\":\"0\"}").getBytes(UTF_8);
@@ -244,7 +243,7 @@ public void testWriteBlobWithRetries() throws Exception {
244243
httpServer.createContext("/upload/storage/v1/b/bucket/o", exchange -> {
245244
assertThat(exchange.getRequestURI().getQuery(), containsString("uploadType=multipart"));
246245
if (countDown.countDown()) {
247-
Optional<Tuple<String, BytesArray>> content = TestUtils.parseMultipartRequestBody(exchange.getRequestBody());
246+
Optional<Tuple<String, BytesArray>> content = parseMultipartRequestBody(exchange.getRequestBody());
248247
assertThat(content.isPresent(), is(true));
249248
assertThat(content.get().v1(), equalTo("write_blob_max_retries"));
250249
if (Objects.deepEquals(bytes, content.get().v2().array())) {
@@ -387,12 +386,12 @@ public void testWriteLargeBlob() throws IOException {
387386
final long bytesRead = Streams.copy(exchange.getRequestBody(), requestBody);
388387
assertThat(Math.toIntExact(bytesRead), anyOf(equalTo(defaultChunkSize), equalTo(lastChunkSize)));
389388

390-
final int rangeStart = TestUtils.getContentRangeStart(range);
391-
final int rangeEnd = TestUtils.getContentRangeEnd(range);
389+
final int rangeStart = getContentRangeStart(range);
390+
final int rangeEnd = getContentRangeEnd(range);
392391
assertThat(rangeEnd + 1 - rangeStart, equalTo(Math.toIntExact(bytesRead)));
393392
assertArrayEquals(Arrays.copyOfRange(data, rangeStart, rangeEnd + 1), requestBody.toByteArray());
394393

395-
final Integer limit = TestUtils.getContentRangeLimit(range);
394+
final Integer limit = getContentRangeLimit(range);
396395
if (limit != null) {
397396
exchange.sendResponseHeaders(RestStatus.OK.getStatus(), -1);
398397
exchange.close();

0 commit comments

Comments
 (0)