diff options
author | Vegard Sjonfjell <vegardsjo@gmail.com> | 2016-10-05 16:15:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-05 16:15:49 +0200 |
commit | e2ca1dab831acea34f47e9f9da1eb2d21d840f6b (patch) | |
tree | 824ce6d80728ad07acf21e36e17c1a50be3766fc /config-model | |
parent | 988a165429ef19b388e684faa712ffd9096cc559 (diff) |
Revert "Voffeloff/constant tensor validation"
Diffstat (limited to 'config-model')
3 files changed, 0 insertions, 399 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java b/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java index 5b3ce7136d5..2a4e231dee4 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java @@ -26,7 +26,6 @@ public class RankingConstant { public String getName() { return name; } public String getFileName() { return fileName; } public String getFileReference() { return fileRef; } - public TensorType getTensorType() { return tensorType; } public String getType() { return tensorType.toString(); } public void validate() { diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidator.java deleted file mode 100644 index 0485750bc16..00000000000 --- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidator.java +++ /dev/null @@ -1,191 +0,0 @@ -package com.yahoo.vespa.model.application.validation; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.google.common.base.Joiner; -import com.yahoo.tensor.TensorType; - -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @author Vegard Sjonfjell - */ -public class ConstantTensorJsonValidator { - static private final JsonFactory jsonFactory = new JsonFactory(); - private TensorType tensorType; - private JsonParser parser; - - public static class InvalidConstantTensor extends RuntimeException { - public InvalidConstantTensor(JsonParser parser, String message) { - super(message + " " + parser.getCurrentLocation().toString()); - } - - public InvalidConstantTensor(JsonParser parser, Exception base) { - super("Failed to parse JSON stream " + parser.getCurrentLocation().toString(), base); - } - } - - @FunctionalInterface - private static interface SubroutineThrowingIOException { - void invoke() throws IOException; - } - - private void wrapIOException(SubroutineThrowingIOException lambda) { - try { - lambda.invoke(); - } catch (IOException e) { - throw new InvalidConstantTensor(parser, e); - } - } - - public ConstantTensorJsonValidator(Reader tensorFile, TensorType tensorType) { - wrapIOException(() -> { - this.parser = jsonFactory.createParser(tensorFile); - this.tensorType = tensorType; - }); - } - - public void validate() { - wrapIOException(() -> { - assertNextTokenIs(JsonToken.START_OBJECT); - assertNextTokenIs(JsonToken.FIELD_NAME); - assertFieldNameIs("cells"); - - assertNextTokenIs(JsonToken.START_ARRAY); - - while (parser.nextToken() != JsonToken.END_ARRAY) { - validateTensorCell(tensorType.dimensions()); - } - - assertNextTokenIs(JsonToken.END_OBJECT); - }); - } - - private void validateTensorCell(Collection<TensorType.Dimension> tensorDimensions) { - wrapIOException(() -> { - assertCurrentTokenIs(JsonToken.START_OBJECT); - - final List<String> fieldNameCandidates = new ArrayList<>(Arrays.asList("address", "value")); - for (int i = 0; i < 2; i++) { - assertNextTokenIs(JsonToken.FIELD_NAME); - final String fieldName = parser.getCurrentName(); - - if (fieldNameCandidates.contains(fieldName)) { - fieldNameCandidates.remove(fieldName); - - if (fieldName.equals("address")) { - validateTensorAddress(tensorDimensions); - } else if (fieldName.equals("value")) { - validateTensorValue(); - } - } else { - throw new InvalidConstantTensor(parser, "Only \"address\" or \"value\" fields are permitted within a cell object"); - } - } - - assertNextTokenIs(JsonToken.END_OBJECT); - }); - } - - private void validateTensorAddress(Collection<TensorType.Dimension> tensorDimensions) throws IOException { - assertNextTokenIs(JsonToken.START_OBJECT); - - final Map<String, TensorType.Dimension> tensorDimensionsMapping = tensorDimensions.stream() - .collect(Collectors.toMap(TensorType.Dimension::name, Function.identity())); - - // Iterate within the address key, value pairs - while ((parser.nextToken() != JsonToken.END_OBJECT)) { - assertCurrentTokenIs(JsonToken.FIELD_NAME); - - final String dimensionName = parser.getCurrentName(); - TensorType.Dimension dimension = tensorDimensionsMapping.get(dimensionName); - if (dimension == null) { - throw new InvalidConstantTensor(parser, String.format("Tensor dimension with name \"%s\" does not exist", parser.getCurrentName())); - } - - tensorDimensionsMapping.remove(dimensionName); - validateTensorCoordinate(dimension); - } - - if (!tensorDimensionsMapping.isEmpty()) { - throw new InvalidConstantTensor(parser, String.format("Tensor address missing dimension(s): %s", Joiner.on(", ").join(tensorDimensionsMapping.keySet()))); - } - } - - /* - * Tensor coordinates are always strings. Coordinates for a mapped dimension can be any string, - * but those for indexed dimensions needs to be able to be interpreted as integers, and, - * additionally, those for indexed bounded dimensions needs to fall within the dimension size. - */ - private void validateTensorCoordinate(TensorType.Dimension dimension) throws IOException { - assertNextTokenIs(JsonToken.VALUE_STRING); - - if (dimension instanceof TensorType.IndexedBoundDimension) { - validateBoundedCoordinate((TensorType.IndexedBoundDimension) dimension); - } else if (dimension instanceof TensorType.IndexedUnboundDimension) { - validateUnboundedCoordinate(dimension); - } - } - - private void validateBoundedCoordinate(TensorType.IndexedBoundDimension dimension) { - wrapIOException(() -> { - try { - final int value = Integer.parseInt(parser.getValueAsString()); - if (value >= dimension.size().get()) { - throwCoordinateOutsideBoundedDimension(parser.getValueAsString(), dimension.name()); - } - } catch (NumberFormatException e) { - throwCoordinateOutsideBoundedDimension(parser.getValueAsString(), dimension.name()); - } - }); - } - - private void throwCoordinateOutsideBoundedDimension(String value, String dimensionName) { - throw new InvalidConstantTensor(parser, String.format("Coordinate \"%s\" not within limits of bounded dimension %s", value, dimensionName)); - } - - private void validateUnboundedCoordinate(TensorType.Dimension dimension) { - wrapIOException(() -> { - try { - Integer.parseInt(parser.getValueAsString()); - } catch (NumberFormatException e) { - throw new InvalidConstantTensor(parser, String.format("Coordinate \"%s\" for dimension %s is not an integer", parser.getValueAsString(), dimension.name())); - } - }); - } - - private void validateTensorValue() throws IOException { - assertNextTokenIs(JsonToken.VALUE_NUMBER_FLOAT); - } - - private void assertCurrentTokenIs(JsonToken wantedToken) { - assertTokenIs(parser.getCurrentToken(), wantedToken); - } - - private void assertNextTokenIs(JsonToken wantedToken) throws IOException { - assertTokenIs(parser.nextToken(), wantedToken); - } - - private void assertTokenIs(JsonToken token, JsonToken wantedToken) { - if (token != wantedToken) { - throw new InvalidConstantTensor(parser, String.format("Expected JSON token %s, but got %s", wantedToken.toString(), token.toString())); - } - } - - private void assertFieldNameIs(String wantedFieldName) throws IOException { - final String actualFieldName = parser.getCurrentName(); - - if (!actualFieldName.equals(wantedFieldName)) { - throw new InvalidConstantTensor(parser, String.format("Expected field name \"%s\", got \"%s\"", wantedFieldName, actualFieldName)); - } - } -} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidatorTest.java deleted file mode 100644 index e43b1597f59..00000000000 --- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidatorTest.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.yahoo.vespa.model.application.validation; - -import com.yahoo.tensor.TensorType; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.io.Reader; -import java.io.StringReader; - -import static com.yahoo.test.json.JsonTestHelper.inputJson; -import static com.yahoo.vespa.model.application.validation.ConstantTensorJsonValidator.InvalidConstantTensor; - -public class ConstantTensorJsonValidatorTest { - private static Reader inputJsonToReader(String... lines) { - return new StringReader(inputJson(lines)); - } - - private static void validateTensorJson(TensorType tensorType, Reader jsonTensorReader) { - ConstantTensorJsonValidator validator = new ConstantTensorJsonValidator(jsonTensorReader, tensorType); - validator.validate(); - } - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void ensure_that_unbounded_tensor_works() { - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '99999', 'y': '47' },", - " 'value': 9932.0", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_bounded_tensor_within_limits_works() { - validateTensorJson( - TensorType.fromSpec("tensor(x[5], y[10])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3', 'y': '2' },", - " 'value': 2.0", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_multiple_cells_work() { - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3', 'y': '2' },", - " 'value': 2.0", - " },", - " {", - " 'address': { 'x': '2', 'y': '0' },", - " 'value': 4.5", - " }", - " ]", - "}")); - } - - - @Test - public void ensure_that_no_cells_work() { - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': []", - "}")); - } - - @Test - public void ensure_that_bounded_tensor_outside_limits_is_disallowed() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Coordinate \"9\" not within limits of bounded dimension x"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[5], y[10])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '9', 'y': '2' },", - " 'value': 1e47", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_mapped_tensor_works() { - validateTensorJson( - TensorType.fromSpec("tensor(x{}, y{})"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': 'andrei', 'y': 'bjarne' },", - " 'value': 2.0", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_non_integer_strings_in_address_points_are_disallowed() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Coordinate \"a\" for dimension x is not an integer"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': 'a' },", - " 'value': 47.0", - " }", - " ]", - "}")); - - } - - @Test - public void ensure_that_missing_coordinates_fail() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Tensor address missing dimension(s): y, z"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[], z[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3' },", - " 'value': 99.3", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_extra_dimensions_are_disallowed() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Tensor dimension with name \"z\" does not exist"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'cells': [", - " {", - " 'address': { 'x': '3', 'y': '2', 'z': '4' },", - " 'value': 99.3", - " }", - " ]", - "}")); - } - - @Test - public void ensure_that_invalid_json_fails() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Failed to parse JSON stream"); - - validateTensorJson( - TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " cells': [", - " {", - " 'address': { 'x': '3' 'y': '2' }", - " 'value': 2.0", - " }", - " ", - "}")); - } - - @Test - public void ensure_that_invalid_json_not_in_tensor_format_fails() { - expectedException.expect(InvalidConstantTensor.class); - expectedException.expectMessage("Expected field name \"cells\", got \"stats\""); - - validateTensorJson(TensorType.fromSpec("tensor(x[], y[])"), - inputJsonToReader( - "{", - " 'stats': {", - " 'grandma-surprise': true,", - " 'points': 47", - " }", - "}")); - } -}
\ No newline at end of file |