From 1540ec43d826213bf1d04219ca621830a59b4b40 Mon Sep 17 00:00:00 2001 From: Ondrej Sery <38768065+osery@users.noreply.github.com> Date: Thu, 13 Jun 2019 13:55:36 +0200 Subject: [PATCH] Allow extra fields in scoring requests. (#71) This has been requested in: https://github.com/h2oai/h2oai/issues/9395. I don't think that we want to allow subset of fields in the requests as it may silently ignore typos in the input data (we already saw an example of that with the local scorer). So keeping that side of the check intact. Also duplicated here: #70. --- .../common/transform/RequestChecker.java | 11 +++--- .../common/transform/RequestCheckerTest.java | 35 ++++++++++++++++++- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/common/transform/src/main/java/ai/h2o/mojos/deploy/common/transform/RequestChecker.java b/common/transform/src/main/java/ai/h2o/mojos/deploy/common/transform/RequestChecker.java index 4432c621..912f17ab 100644 --- a/common/transform/src/main/java/ai/h2o/mojos/deploy/common/transform/RequestChecker.java +++ b/common/transform/src/main/java/ai/h2o/mojos/deploy/common/transform/RequestChecker.java @@ -5,10 +5,7 @@ import ai.h2o.mojos.runtime.frame.MojoColumn; import ai.h2o.mojos.runtime.frame.MojoFrameMeta; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import static java.util.Arrays.asList; @@ -42,10 +39,10 @@ private String getProblemMessageOrNull(ScoreRequest scoreRequest, MojoFrameMeta if (rows == null || rows.isEmpty()) { return "List of input data rows cannot be empty"; } - Set expFields = new HashSet(asList(expectedMeta.getColumnNames())); - if (!expFields.equals(new HashSet(fields))) { - return String.format("Input fields don't match the Mojo, expected %s actual %s", - Arrays.toString(expectedMeta.getColumnNames()), fields.toString()); + List expectedFields = asList(expectedMeta.getColumnNames()); + if (!fields.containsAll(expectedFields)) { + return String.format("Input fields don't contain all the Mojo fields, expected %s actual %s", + expectedFields.toString(), fields.toString()); } int i = 0; for (Row row : scoreRequest.getRows()) { diff --git a/common/transform/src/test/java/ai/h2o/mojos/deploy/common/transform/RequestCheckerTest.java b/common/transform/src/test/java/ai/h2o/mojos/deploy/common/transform/RequestCheckerTest.java index 3f0cd87b..57ff6473 100644 --- a/common/transform/src/test/java/ai/h2o/mojos/deploy/common/transform/RequestCheckerTest.java +++ b/common/transform/src/test/java/ai/h2o/mojos/deploy/common/transform/RequestCheckerTest.java @@ -97,7 +97,40 @@ void verifyMismatchedFieldsRequest_throws() { // When & then ScoreRequestFormatException exception = assertThrows(ScoreRequestFormatException.class, () -> checker.verify(request, expectedMeta)); - assertThat(exception.getMessage()).contains("fields don't match"); + assertThat(exception.getMessage()).contains("fields don't contain all"); + } + + @Test + void verifyTooFewFieldsRequest_throws() { + // Given + ScoreRequest request = new ScoreRequest(); + request.addFieldsItem("field1"); + request.addRowsItem(toRow("text")); + MojoFrameMeta expectedMeta = new MojoFrameMeta( + new String[]{"field1", "field2"}, + new MojoColumn.Type[]{MojoColumn.Type.Str, MojoColumn.Type.Str}); + + // When & then + ScoreRequestFormatException exception = + assertThrows(ScoreRequestFormatException.class, () -> checker.verify(request, expectedMeta)); + assertThat(exception.getMessage()).contains("fields don't contain all"); + } + + @Test + void verifyExtraFieldsRequest_succeeds() throws ScoreRequestFormatException { + // Given + ScoreRequest request = new ScoreRequest(); + request.addFieldsItem("field1"); + request.addFieldsItem("field2"); + request.addRowsItem(toRow("text1", "text2")); + MojoFrameMeta expectedMeta = new MojoFrameMeta( + new String[]{"field1"}, + new MojoColumn.Type[]{MojoColumn.Type.Str}); + + // When + checker.verify(request, expectedMeta); + + // Then all ok } @Test