Skip to content

Commit

Permalink
test: added tests for new ETag caching code
Browse files Browse the repository at this point in the history
  • Loading branch information
quintesse committed Feb 8, 2023
1 parent 9848c8c commit a27766c
Showing 1 changed file with 177 additions and 17 deletions.
194 changes: 177 additions & 17 deletions src/test/java/dev/jbang/util/TestUtilDownloads.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.github.tomakehurst.wiremock.http.Request;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
import com.github.tomakehurst.wiremock.matching.EqualToPattern;
import com.github.tomakehurst.wiremock.matching.MatchResult;
import com.github.tomakehurst.wiremock.matching.ValueMatcher;

import dev.jbang.BaseTest;
import dev.jbang.Configuration;
Expand All @@ -31,6 +38,8 @@ void resetConfig() {
@Test
void test1ReqSimple(WireMockRuntimeInfo wmri) throws IOException {
stubFor(get(urlEqualTo("/test.txt"))
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("test")));
Expand All @@ -42,38 +51,86 @@ void test1ReqSimple(WireMockRuntimeInfo wmri) throws IOException {
}

@Test
void test2ReqSimple(WireMockRuntimeInfo wmri) throws IOException {
void test2ReqSimple(WireMockRuntimeInfo wmri) throws IOException, InterruptedException {
UUID id = UUID.randomUUID();
stubFor(any(urlEqualTo("/test.txt"))
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("test")));

String url = wmri.getHttpBaseUrl() + "/test.txt";
Path file = Util.downloadAndCacheFile(url);
FileTime lmt = Files.getLastModifiedTime(file);
ZonedDateTime zlmt = ZonedDateTime.ofInstant(lmt.toInstant(), ZoneId.of("GMT"));
String cachedLastModified = DateTimeFormatter.RFC_1123_DATE_TIME.format(zlmt);
assertThat(file.toFile(), anExistingFile());
assertThat(Util.readString(file), is("test"));

editStub(any(urlEqualTo("/test.txt"))
Thread.sleep(1100);

editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.withHeader("If-Modified-Since", new EqualToPattern(
cachedLastModified))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("test2")));

Path file2 = Util.downloadAndCacheFile(url);
assertThat(file2.toFile(), anExistingFile());
assertThat(file2, equalTo(file));
assertThat(Files.getLastModifiedTime(file2), equalTo(lmt));
assertThat(Util.readString(file2), is("test"));
assertThat(Files.getLastModifiedTime(file2), not(equalTo(lmt)));
assertThat(Util.readString(file2), is("test2"));
}

@Test
void test2ReqSimpleFresh(WireMockRuntimeInfo wmri) throws IOException, InterruptedException {
UUID id = UUID.randomUUID();
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("test")));

String url = wmri.getHttpBaseUrl() + "/test.txt";
Path file = Util.downloadAndCacheFile(url);
FileTime lmt = Files.getLastModifiedTime(file);
assertThat(file.toFile(), anExistingFile());
assertThat(Util.readString(file), is("test"));

Thread.sleep(1100);

editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("test2")));

Util.freshly(() -> {
Path file2 = Util.downloadAndCacheFile(url);
assertThat(file2.toFile(), anExistingFile());
assertThat(file2, equalTo(file));
assertThat(Files.getLastModifiedTime(file2), not(equalTo(lmt)));
assertThat(Util.readString(file2), is("test2"));
return null;
});
}

@Test
void test2ReqWithLastModifiedSame(WireMockRuntimeInfo wmri) throws IOException {
UUID id = UUID.randomUUID();
stubFor(any(urlEqualTo("/test.txt"))
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("Last-Modified",
Expand All @@ -83,12 +140,18 @@ void test2ReqWithLastModifiedSame(WireMockRuntimeInfo wmri) throws IOException {
String url = wmri.getHttpBaseUrl() + "/test.txt";
Path file = Util.downloadAndCacheFile(url);
FileTime lmt = Files.getLastModifiedTime(file);
ZonedDateTime zlmt = ZonedDateTime.ofInstant(lmt.toInstant(), ZoneId.of("GMT"));
String cachedLastModified = DateTimeFormatter.RFC_1123_DATE_TIME.format(zlmt);
assertThat(file.toFile(), anExistingFile());
assertThat(Util.readString(file), is("test"));

editStub(any(urlEqualTo("/test.txt"))
editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.withHeader("If-Modified-Since", new EqualToPattern(
cachedLastModified))
.willReturn(aResponse()
.withStatus(304)
.withHeader("Content-Type", "text/plain")
.withHeader("Last-Modified",
"Thu, 02 Feb 2023 22:22:49 GMT")
Expand All @@ -97,15 +160,17 @@ void test2ReqWithLastModifiedSame(WireMockRuntimeInfo wmri) throws IOException {
Path file2 = Util.downloadAndCacheFile(url);
assertThat(file2.toFile(), anExistingFile());
assertThat(file2, equalTo(file));
assertThat(Files.getLastModifiedTime(file2), equalTo(lmt));
assertThat(Files.getLastModifiedTime(file2), greaterThanOrEqualTo(lmt));
assertThat(Util.readString(file2), is("test"));
}

@Test
void test2ReqWithLastModifiedUpdated(WireMockRuntimeInfo wmri) throws IOException {
void test2ReqWithLastModifiedUpdated(WireMockRuntimeInfo wmri) throws IOException, InterruptedException {
UUID id = UUID.randomUUID();
stubFor(any(urlEqualTo("/test.txt"))
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("Last-Modified",
Expand All @@ -118,7 +183,9 @@ void test2ReqWithLastModifiedUpdated(WireMockRuntimeInfo wmri) throws IOExceptio
assertThat(file.toFile(), anExistingFile());
assertThat(Util.readString(file), is("test"));

editStub(any(urlEqualTo("/test.txt"))
Thread.sleep(1100);

editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
Expand All @@ -138,8 +205,10 @@ void test2ReqWithLastModifiedUpdatedNeverEvict(WireMockRuntimeInfo wmri) throws
Configuration.instance().put("cache-evict", "never");

UUID id = UUID.randomUUID();
stubFor(any(urlEqualTo("/test.txt"))
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("Last-Modified",
Expand All @@ -152,7 +221,7 @@ void test2ReqWithLastModifiedUpdatedNeverEvict(WireMockRuntimeInfo wmri) throws
assertThat(file.toFile(), anExistingFile());
assertThat(Util.readString(file), is("test"));

editStub(any(urlEqualTo("/test.txt"))
editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
Expand All @@ -172,8 +241,10 @@ void test2ReqWithLastModifiedUpdatedEvict1(WireMockRuntimeInfo wmri) throws IOEx
Configuration.instance().put("cache-evict", "1");

UUID id = UUID.randomUUID();
stubFor(any(urlEqualTo("/test.txt"))
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("Last-Modified",
Expand All @@ -188,7 +259,7 @@ void test2ReqWithLastModifiedUpdatedEvict1(WireMockRuntimeInfo wmri) throws IOEx

Thread.sleep(1100);

editStub(any(urlEqualTo("/test.txt"))
editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
Expand All @@ -208,8 +279,10 @@ void test2ReqWithLastModifiedUpdatedEvictPT1S(WireMockRuntimeInfo wmri) throws I
Configuration.instance().put("cache-evict", "pt1s");

UUID id = UUID.randomUUID();
stubFor(any(urlEqualTo("/test.txt"))
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("Last-Modified",
Expand All @@ -224,7 +297,7 @@ void test2ReqWithLastModifiedUpdatedEvictPT1S(WireMockRuntimeInfo wmri) throws I

Thread.sleep(1100);

editStub(any(urlEqualTo("/test.txt"))
editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
Expand All @@ -239,4 +312,91 @@ void test2ReqWithLastModifiedUpdatedEvictPT1S(WireMockRuntimeInfo wmri) throws I
assertThat(Util.readString(file2), is("test2"));
}

@Test
void test2ReqWithETagSame(WireMockRuntimeInfo wmri) throws IOException {
UUID id = UUID.randomUUID();
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("ETag", "tag1")
.withBody("test")));

String url = wmri.getHttpBaseUrl() + "/test.txt";
Path file = Util.downloadAndCacheFile(url);
FileTime lmt = Files.getLastModifiedTime(file);
ZonedDateTime zlmt = ZonedDateTime.ofInstant(lmt.toInstant(), ZoneId.of("GMT"));
String cachedLastModified = DateTimeFormatter.RFC_1123_DATE_TIME.format(zlmt);
assertThat(file.toFile(), anExistingFile());
assertThat(Util.readString(file), is("test"));
Path etag = Util.etagFile(file);
assertThat(etag.toFile(), anExistingFile());
assertThat(Util.readString(etag), is("tag1"));

editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.withHeader("If-None-Match", new EqualToPattern("tag1"))
.withHeader("If-Modified-Since", new EqualToPattern(cachedLastModified))
.willReturn(aResponse()
.withStatus(304)
.withHeader("Content-Type", "text/plain")
.withHeader("ETag", "tag1")
.withBody("test2")));

Path file2 = Util.downloadAndCacheFile(url);
assertThat(file2.toFile(), anExistingFile());
assertThat(file2, equalTo(file));
assertThat(Files.getLastModifiedTime(file2), greaterThanOrEqualTo(lmt));
assertThat(Util.readString(file2), is("test"));
Path etag2 = Util.etagFile(file2);
assertThat(etag2.toFile(), anExistingFile());
assertThat(Util.readString(etag2), is("tag1"));
}

@Test
void test2ReqWithETagUpdated(WireMockRuntimeInfo wmri) throws IOException, InterruptedException {
UUID id = UUID.randomUUID();
stubFor(get(urlEqualTo("/test.txt"))
.withId(id)
.andMatching(withoutHeader("If-None-Match"))
.andMatching(withoutHeader("If-Modified-Since"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("ETag", "tag1")
.withBody("test")));

String url = wmri.getHttpBaseUrl() + "/test.txt";
Path file = Util.downloadAndCacheFile(url);
FileTime lmt = Files.getLastModifiedTime(file);
assertThat(file.toFile(), anExistingFile());
assertThat(Util.readString(file), is("test"));
Path etag = Util.etagFile(file);
assertThat(etag.toFile(), anExistingFile());
assertThat(Util.readString(etag), is("tag1"));

Thread.sleep(1100);

editStub(get(urlEqualTo("/test.txt"))
.withId(id)
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withHeader("ETag", "tag2")
.withBody("test2")));

Path file2 = Util.downloadAndCacheFile(url);
assertThat(file2.toFile(), anExistingFile());
assertThat(file2, equalTo(file));
assertThat(Files.getLastModifiedTime(file2), not(equalTo(lmt)));
assertThat(Util.readString(file2), is("test2"));
Path etag2 = Util.etagFile(file2);
assertThat(etag2.toFile(), anExistingFile());
assertThat(Util.readString(etag2), is("tag2"));
}

private static ValueMatcher<Request> withoutHeader(String hdr) {
return req -> MatchResult.of(!req.containsHeader(hdr));
}

}

0 comments on commit a27766c

Please sign in to comment.