Skip to content

Commit d3dfb83

Browse files
Using matching docker container server version in unit tests (#904) (#907)
* unit test container version latest * fetching version info from artifacts api * using io utils also for writing * checkstyle Co-authored-by: Laura Trotta <153528055+l-trotta@users.noreply.github.com>
1 parent 084e48c commit d3dfb83

File tree

1 file changed

+66
-4
lines changed

1 file changed

+66
-4
lines changed

java-client/src/test/java/co/elastic/clients/elasticsearch/ElasticsearchTestServer.java

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import co.elastic.clients.transport.Version;
3030
import co.elastic.clients.transport.endpoints.DelegatingJsonEndpoint;
3131
import co.elastic.clients.transport.rest_client.RestClientTransport;
32+
import org.apache.commons.io.FileUtils;
3233
import org.apache.http.HttpHost;
3334
import org.apache.http.auth.AuthScope;
3435
import org.apache.http.auth.UsernamePasswordCredentials;
@@ -40,12 +41,15 @@
4041
import org.testcontainers.utility.DockerImageName;
4142

4243
import javax.net.ssl.SSLContext;
44+
import java.io.File;
4345
import java.io.IOException;
4446
import java.io.InputStream;
4547
import java.net.HttpURLConnection;
4648
import java.net.URL;
4749
import java.nio.charset.StandardCharsets;
4850
import java.time.Duration;
51+
import java.time.Instant;
52+
import java.time.temporal.ChronoUnit;
4953
import java.util.Base64;
5054

5155
public class ElasticsearchTestServer implements AutoCloseable {
@@ -58,6 +62,7 @@ public class ElasticsearchTestServer implements AutoCloseable {
5862
private ElasticsearchClient client;
5963

6064
private static ElasticsearchTestServer global;
65+
private static final String artifactsApiUrl = "https://artifacts-api.elastic.co/v1/versions/";
6166

6267
public static synchronized ElasticsearchTestServer global() {
6368
if (global == null) {
@@ -112,14 +117,70 @@ AuthScope.ANY, new UsernamePasswordCredentials("elastic", "changeme")
112117
client = new ElasticsearchClient(transport);
113118
}
114119

120+
private Version selectLatestVersion(Version version, String info) {
121+
if (info.contains(version.toString())) {
122+
return version;
123+
}
124+
// if no version X.Y.0 was found, we give up
125+
if (version.maintenance() == 0) {
126+
throw new RuntimeException("Elasticsearch server container version: " + version + " not yet " +
127+
"available");
128+
}
129+
return selectLatestVersion(new Version(version.major(), version.minor(), version.maintenance() - 1,
130+
false), info);
131+
}
132+
133+
private String fetchAndWriteVersionInfo(File file) throws IOException {
134+
String versionInfo = IOUtils.toString(new URL(artifactsApiUrl), StandardCharsets.UTF_8);
135+
FileUtils.writeStringToFile(file, versionInfo, StandardCharsets.UTF_8);
136+
return versionInfo;
137+
}
138+
139+
private Version getLatestAvailableServerVersion(Version version) {
140+
try {
141+
// check if there's cached information
142+
ClassLoader classLoader = getClass().getClassLoader();
143+
URL location = classLoader.getResource("./co/elastic/clients/version.json");
144+
145+
// writing the info on file before returning
146+
if (location == null) {
147+
File file = new File(classLoader.getResource("./co/elastic/clients").getFile() + "/version" +
148+
".json");
149+
String versionInfo = fetchAndWriteVersionInfo(file);
150+
return selectLatestVersion(version, versionInfo);
151+
}
152+
153+
File file = new File(location.getFile());
154+
155+
// info file was found, but it's expired
156+
if (Instant.ofEpochMilli(file.lastModified()).isBefore(Instant.now().minus(24,
157+
ChronoUnit.HOURS))) {
158+
String versionInfo = fetchAndWriteVersionInfo(file);
159+
return selectLatestVersion(version, versionInfo);
160+
}
161+
162+
// info file exists and it has new info
163+
String versionInfo = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
164+
return selectLatestVersion(version, versionInfo);
165+
166+
} catch (IOException e) {
167+
throw new RuntimeException(e);
168+
}
169+
}
170+
115171
public synchronized ElasticsearchTestServer start() {
116172
if (this.client != null) {
117173
return this;
118174
}
119175

120-
Version version = Version.VERSION.major() < 8 ? new Version(7,17,5,false) : new Version(8,12,0,false);
176+
Version version = getLatestAvailableServerVersion(Version.VERSION);
177+
178+
// using specific stable version for tests with plugins
179+
if (plugins.length > 0) {
180+
version = Version.VERSION.major() < 8 ? new Version(7, 17, 25, false) : new Version(8, 16, 0,
181+
false);
182+
}
121183

122-
// Note we could use version.major() + "." + version.minor() + "-SNAPSHOT" but plugins won't install on a snapshot version
123184
String esImage = "docker.elastic.co/elasticsearch/elasticsearch:" + version;
124185

125186
DockerImageName image;
@@ -166,10 +227,11 @@ public static <Req> JsonData getJsonResponse(ElasticsearchClient client, Req req
166227

167228
try {
168229
@SuppressWarnings("unchecked")
169-
JsonEndpoint<Req, JsonData, ErrorResponse> endpoint0 = (JsonEndpoint<Req, JsonData, ErrorResponse>) request.getClass()
230+
JsonEndpoint<Req, JsonData, ErrorResponse> endpoint0 = (JsonEndpoint<Req, JsonData,
231+
ErrorResponse>) request.getClass()
170232
.getDeclaredField("_ENDPOINT").get(null);
171233
endpoint = endpoint0;
172-
} catch (IllegalAccessException|NoSuchFieldException e) {
234+
} catch (IllegalAccessException | NoSuchFieldException e) {
173235
throw new RuntimeException(e);
174236
}
175237

0 commit comments

Comments
 (0)