Skip to content

Commit

Permalink
Add framework to allow test-specific assertions on HTTP response.
Browse files Browse the repository at this point in the history
Motivation:

Individual tests may expect IDS to respond in a specific fashion.
Currently there is no way for tests that execise IDS request that return
content to assert the HTTP response.  This is because, for these
interactions, the test client returns the content from IDS and not the
HTTP response.

Modification:

Add the ability for a test to make an HTTP request that includes an
assertion on the HTTP response.  This is done by providing the
assertions as a `Consumer` object.  Lambdas provides a light-weight
mechanism for writing such assertions.

An interceptor is used to create a custom client that asserts the
response.  The existing code is refactored to take advantage of this.

To keep code DRY, two new static methods are introduced that provide
lambdas that assert that the response is chunked or is not chunked.

Some existing tests are updated to take advantage of this framework.

Result:

It is now possible to write tests that make test-specific assertions on
the HTTP response from IDS, even for interactions where IDS returns
content.
  • Loading branch information
paulmillar committed Feb 3, 2024
1 parent 1e32fb4 commit 3105926
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 59 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/org/icatproject/ids/integration/BaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -20,6 +21,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.UUID;
import java.util.zip.CRC32;
Expand Down Expand Up @@ -369,6 +371,16 @@ protected void checkStream(InputStream stream, long id) throws IOException {
assertTrue(found);
}

protected long fileLength(long id) {
for (Entry<String, Long> e : ids.entrySet()) {
if (id == e.getValue()) {
var fileContents = contents.get(e.getKey());
return fileContents.getBytes(StandardCharsets.UTF_8).length;
}
}
throw new NoSuchElementException("No file with id " + id);
}

protected void writeToFile(Datafile df, String content, String key)
throws IOException, IcatException_Exception, NoSuchAlgorithmException {
Path path = setup.getStorageDir().resolve(df.getLocation());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.io.InputStream;
import java.util.Arrays;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;

import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
Expand All @@ -15,6 +17,7 @@
import org.icatproject.ids.integration.util.client.InsufficientPrivilegesException;
import org.icatproject.ids.integration.util.client.NotFoundException;
import org.icatproject.ids.integration.util.client.TestingClient.Flag;
import static org.icatproject.ids.integration.util.client.TestingClient.isNotChunkedEncoded;

public class GetDataExplicitTest extends BaseTest {

Expand Down Expand Up @@ -98,52 +101,75 @@ public void forbiddenTest() throws Exception {

@Test
public void correctBehaviourTestNone() throws Exception {
try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.NONE, 0, 200)) {
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.NONE, 0, 200)) {
checkZipStream(stream, datafileIds, 57L, 0);
}

try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafile(datafileIds.get(0)),
Flag.NONE, 0, 200)) {
var datafileId = datafileIds.get(0);
var fileLength = fileLength(datafileId);
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.assertingHttpResponse(r -> {
var contentLength = r.getFirstHeader("Content-Length");
var entitySize = Long.valueOf(contentLength.getValue());
assertThat(entitySize, equalTo(fileLength));
})
.getData(sessionId, new DataSelection().addDatafile(datafileId),
Flag.NONE, 0, 200)) {
checkStream(stream, datafileIds.get(0));
}
}

@Test
public void correctBehaviourTestCompress() throws Exception {
try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.COMPRESS, 0, 200)) {
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.COMPRESS, 0, 200)) {
checkZipStream(stream, datafileIds, 36L, 0);
}

try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafile(datafileIds.get(0)),
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.getData(sessionId, new DataSelection().addDatafile(datafileIds.get(0)),
Flag.COMPRESS, 0, 200)) {
checkStream(stream, datafileIds.get(0));
}
}

@Test
public void correctBehaviourTestZip() throws Exception {
try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.ZIP, 0, 200)) {
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.ZIP, 0, 200)) {
checkZipStream(stream, datafileIds, 57L, 0);
}

try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafile(datafileIds.get(0)),
Flag.ZIP, 0, 200)) {
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.getData(sessionId, new DataSelection().addDatafile(datafileIds.get(0)),
Flag.ZIP, 0, 200)) {
checkZipStream(stream, datafileIds.subList(0, 1), 57L, 0);
}
}

@Test
public void correctBehaviourTestZipAndCompress() throws Exception {
try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.ZIP_AND_COMPRESS, 0, 200)) {
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.getData(sessionId, new DataSelection().addDatafiles(datafileIds),
Flag.ZIP_AND_COMPRESS, 0, 200)) {
checkZipStream(stream, datafileIds, 36L, 0);
}

try (InputStream stream = testingClient.getData(sessionId, new DataSelection().addDatafile(datafileIds.get(0)),
Flag.ZIP_AND_COMPRESS, 0, 200)) {
try (InputStream stream = testingClient
.assertingHttpResponse(isNotChunkedEncoded()) // assumes caching
.getData(sessionId, new DataSelection().addDatafile(datafileIds.get(0)),
Flag.ZIP_AND_COMPRESS, 0, 200)) {
checkZipStream(stream, datafileIds.subList(0, 1), 36L, 0);
}
}
Expand Down
33 changes: 33 additions & 0 deletions src/test/java/org/icatproject/ids/integration/util/LongValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.icatproject.ids.integration.util;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

/**
* A Matcher that checks whether a String argument is a Long value. The code is
* heavily based on an answer from Ezequiel to
* <a href="https://stackoverflow.com/questions/58099695/is-there-a-way-in-hamcrest-to-test-for-a-value-to-be-a-number">
* a stack overview question</a>.
*/
public class LongValue extends TypeSafeMatcher<String> {

@Override
protected boolean matchesSafely(String s) {
try {
Long.valueOf(s);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}

@Override
public void describeTo(Description description) {
description.appendText("is long");
}

public static Matcher<String> longValue() {
return new LongValue();
}
}
Loading

0 comments on commit 3105926

Please sign in to comment.