summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorVegard Sjonfjell <vegardsjo@gmail.com>2016-10-05 16:15:49 +0200
committerGitHub <noreply@github.com>2016-10-05 16:15:49 +0200
commite2ca1dab831acea34f47e9f9da1eb2d21d840f6b (patch)
tree824ce6d80728ad07acf21e36e17c1a50be3766fc /config-model
parent988a165429ef19b388e684faa712ffd9096cc559 (diff)
Revert "Voffeloff/constant tensor validation"
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/RankingConstant.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidator.java191
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ConstantTensorJsonValidatorTest.java207
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