Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Teagan42 authored and seldondev committed Apr 2, 2020
1 parent ebed914 commit 7dc9120
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import static io.seldon.engine.util.StreamUtils.toByteArray;

@RestController
public class RestClientController {

Expand Down Expand Up @@ -160,7 +162,7 @@ public ResponseEntity<String> predictions_text(RequestEntity<String> requestEnti
@RequestMapping(
value = {"/api/v1.0/predictions", "/api/v0.1/predictions"},
method = RequestMethod.POST,
consumes = "application/octet-stream; charset=utf-8",
consumes = "application/octet-stream",
produces = "application/json; charset=utf-8")
public ResponseEntity<String> predictions_binary(RequestEntity<InputStream> requestEntity) {
logger.debug("Received binary predict request");
Expand All @@ -173,7 +175,7 @@ public ResponseEntity<String> predictions_binary(RequestEntity<InputStream> requ
try {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> protoBody = new HashMap<String, Object>() {{
put("binData", ByteString.readFrom(requestEntity.getBody()));
put("binData", toByteArray(requestEntity.getBody()));
}};
return _predictions(mapper.writeValueAsString(protoBody));
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.seldon.engine.config;

import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import static io.seldon.engine.util.StreamUtils.copyStream;

/**
* Configure Spring Boot to allow upload of octet-stream.
*/
@Configuration
public class MessageConvertersConfig extends WebMvcConfigurationSupport {

@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new AbstractHttpMessageConverter<InputStream>(MediaType.APPLICATION_OCTET_STREAM) {
protected boolean supports(@NotNull Class<?> clazz) {
return InputStream.class.isAssignableFrom(clazz);
}

@NotNull
protected InputStream readInternal(
@NotNull Class<? extends InputStream> clazz,
@NotNull HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return inputMessage.getBody();
}

protected void writeInternal(
@NotNull InputStream inputStream,
@NotNull HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
copyStream(inputStream, outputMessage.getBody());
}
});

super.configureMessageConverters(converters);
}
}
29 changes: 29 additions & 0 deletions engine/src/main/java/io/seldon/engine/util/StreamUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.seldon.engine.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public final class StreamUtils {
private static final int EOF = -1;
private static final int BUFFER_SIZE = 1024 * 4;

public static byte[] toByteArray(InputStream inputStream) throws IOException {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

copyStream(inputStream, outputStream);

return outputStream.toByteArray();
}

public static void copyStream(final InputStream input, final OutputStream output)
throws IOException {
final byte[] buffer = new byte[BUFFER_SIZE];
int n;

while (EOF != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@
package io.seldon.engine.api.rest;

import static org.mockito.Mockito.when;
import static io.seldon.engine.util.TestUtils.readFileBase64;
import static io.seldon.engine.util.TestUtils.readFileBytes;

import io.opentracing.mock.MockSpan;
import io.opentracing.mock.MockTracer;
import io.seldon.engine.filters.XSSFilter;
import io.seldon.engine.pb.ProtoBufUtils;
import io.seldon.engine.tracing.TracingProvider;
import io.seldon.protos.PredictionProtos.SeldonMessage;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletResponse;
import org.junit.Assert;
import org.junit.Before;
Expand Down Expand Up @@ -334,4 +340,56 @@ public void testPredict_multiform_strData_as_text() throws Exception {
Assert.assertEquals(strdata, seldonMessage.getStrData());
Assert.assertEquals("1234", seldonMessage.getMeta().getPuid());
}

@Test
public void testPredict_b64img_as_text() throws Exception {
String base64Image = readFileBase64("src/test/resources/pug-690566_640.jpg");
MvcResult res =
mvc.perform(
MockMvcRequestBuilders.post("/api/v1.0/predictions")
.accept(MediaType.APPLICATION_JSON)
.content(base64Image)
.contentType(MediaType.TEXT_PLAIN))
.andReturn();
String response = res.getResponse().getContentAsString();
System.out.println(response);
Assert.assertEquals(200, res.getResponse().getStatus());
SeldonMessage.Builder builder = SeldonMessage.newBuilder();
ProtoBufUtils.updateMessageBuilderFromJson(builder, response);
SeldonMessage seldonMessage = builder.build();
Assert.assertEquals(3, seldonMessage.getMeta().getMetricsCount());
Assert.assertEquals("COUNTER", seldonMessage.getMeta().getMetrics(0).getType().toString());
Assert.assertEquals("GAUGE", seldonMessage.getMeta().getMetrics(1).getType().toString());
Assert.assertEquals("TIMER", seldonMessage.getMeta().getMetrics(2).getType().toString());
Assert.assertEquals(base64Image, seldonMessage.getStrData());
// No Puid specified in request, verify response generated random of correct length
Assert.assertNotNull(seldonMessage.getMeta().getPuid());
Assert.assertTrue(Pattern.matches("[a-z0-7]{26}", seldonMessage.getMeta().getPuid()));
}

@Test
public void testPredict_img_as_binary() throws Exception {
byte[] imageBytes = readFileBytes("src/test/resources/pug-690566_640.jpg");
MvcResult res =
mvc.perform(
MockMvcRequestBuilders.post("/api/v1.0/predictions")
.accept(MediaType.APPLICATION_JSON)
.content(imageBytes)
.contentType(MediaType.APPLICATION_OCTET_STREAM))
.andReturn();
String response = res.getResponse().getContentAsString();
System.out.println(response);
Assert.assertEquals(200, res.getResponse().getStatus());
SeldonMessage.Builder builder = SeldonMessage.newBuilder();
ProtoBufUtils.updateMessageBuilderFromJson(builder, response);
SeldonMessage seldonMessage = builder.build();
Assert.assertEquals(3, seldonMessage.getMeta().getMetricsCount());
Assert.assertEquals("COUNTER", seldonMessage.getMeta().getMetrics(0).getType().toString());
Assert.assertEquals("GAUGE", seldonMessage.getMeta().getMetrics(1).getType().toString());
Assert.assertEquals("TIMER", seldonMessage.getMeta().getMetrics(2).getType().toString());
Assert.assertEquals(imageBytes, seldonMessage.getBinData().toByteArray());
// No Puid specified in request, verify response generated random of correct length
Assert.assertNotNull(seldonMessage.getMeta().getPuid());
Assert.assertTrue(Pattern.matches("[a-z0-7]{26}", seldonMessage.getMeta().getPuid()));
}
}
12 changes: 10 additions & 2 deletions engine/src/test/java/io/seldon/engine/util/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class TestUtils {

public static byte[] readFileBytes(String path) throws IOException {
return Files.readAllBytes(Paths.get(path));
}

public static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
return new String(readFileBytes(path), encoding);
}

public static String readFileBase64(String path) throws IOException {
return Base64.getEncoder().encodeToString(readFileBytes(path));
}
}
Binary file added engine/src/test/resources/pug-690566_640.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7dc9120

Please sign in to comment.