Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ void calculateLabelValues(int testId, int datasetId, Integer[] queryLabelIds) {
FingerprintDAO.deleteById(datasetId);
Util.evaluateWithCombinationFunction(toCompute,
(row) -> (String) row[2],
(row) -> (row[3] instanceof ArrayNode ? flatten((ArrayNode) row[3]) : (JsonNode) row[3]),
(row) -> (JsonNode) row[3],
(row, result) -> createLabelValue(datasetId, (int) row[0], Util.convertToJson(result)),
(row) -> createLabelValue(datasetId, (int) row[0], (JsonNode) row[3]),
(row, e, jsCode) -> logMessage(datasetId, PersistentLogDAO.ERROR,
Expand Down Expand Up @@ -583,18 +583,6 @@ public void deleteDataset(int datasetId) {
em.createNativeQuery("DELETE FROM dataset WHERE id = ?1").setParameter(1, datasetId).executeUpdate();
}

private ArrayNode flatten(ArrayNode bucket) {
JsonNode data = bucket.get(0);
if (data == null)
return bucket;

if (data instanceof ArrayNode) {
bucket.removeAll();
data.forEach(bucket::add);
}
return bucket;
}

@WithRoles(extras = Roles.HORREUM_SYSTEM)
@Transactional(Transactional.TxType.REQUIRES_NEW)
protected void findFailingExtractor(int datasetId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,14 @@ protected int[] updateLabels(Schema schema, Label... labels) {

protected int postLabel(Schema schema, String name, String function, Consumer<Label> mutate,
Extractor... extractors) {
Label l = createLabelDto(schema, name, function, mutate, extractors);
Response response = jsonRequest().body(List.of(l)).post("/api/schema/" + schema.id + "/labels");
response.then().statusCode(201);
return response.body().as(Integer[].class)[0];
}

protected Label createLabelDto(Schema schema, String name, String function, Consumer<Label> mutate,
Extractor... extractors) {
Label l = new Label();
l.name = name;
l.function = function;
Expand All @@ -584,9 +592,8 @@ protected int postLabel(Schema schema, String name, String function, Consumer<La
if (mutate != null) {
mutate.accept(l);
}
Response response = jsonRequest().body(List.of(l)).post("/api/schema/" + schema.id + "/labels");
response.then().statusCode(201);
return response.body().as(Integer[].class)[0];

return l;
}

protected int putLabel(Schema schema, Integer labelId, String name, String function, Consumer<Label> mutate,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.hyperfoil.tools.horreum.svc;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -111,7 +112,7 @@ public void testDatasetLabelsSingle() {
@org.junit.jupiter.api.Test
public void testDatasetLabelSingleWithReduceFunctionArray() {
withExampleSchemas((schemas) -> {
int labelReduce = addLabel(schemas[0], "sum", "value => { return value.reduce((a,b) => a+b); }",
int labelReduce = addLabel(schemas[0], "sum", "value => { return value[0].reduce((a,b) => a+b); }",
new Extractor("value", "$.samplesArray", true));
List<Label.Value> values = withLabelValues(createSampleArray());
assertEquals(30, values.stream().filter(v -> v.labelId == labelReduce).map(v -> v.value.numberValue()).findFirst()
Expand All @@ -122,7 +123,7 @@ public void testDatasetLabelSingleWithReduceFunctionArray() {
@org.junit.jupiter.api.Test
public void testDatasetLabelAsyncSingleWithReduceFunctionArray() {
withExampleSchemas((schemas) -> {
int labelReduce = addLabel(schemas[0], "sum", "async (value) => { return value.reduce((a,b) => a+b); }",
int labelReduce = addLabel(schemas[0], "sum", "async (value) => { return value[0].reduce((a,b) => a+b); }",
new Extractor("value", "$.samplesArray", true));
List<Label.Value> values = withLabelValues(createSampleArray());
assertEquals(30, values.stream().filter(v -> v.labelId == labelReduce).map(v -> v.value.numberValue()).findFirst()
Expand Down Expand Up @@ -546,4 +547,217 @@ public void testDatasetListByRun() {
assertEquals(initialRunID, datasetsList.datasets.get(1).runId);
assertEquals(latterRunID, datasetsList.datasets.get(0).runId);
}

@org.junit.jupiter.api.Test
public void labelValuesWithAllMatchMultipleExtractorsAndJs() {
Test t = createTest(createExampleTest("my-test"));

// create a schema with all match label extractor
Schema fooSchema = createSchema("foo", "urn:foo");
Extractor fooExtractor = new Extractor();
fooExtractor.name = "foo";
fooExtractor.jsonpath = "$.foo[*].inner";
fooExtractor.isArray = true;
Extractor barExtractor = new Extractor();
barExtractor.name = "bar";
barExtractor.jsonpath = "$.bar";

// pass the array of arrays to a js function
Label label = createLabelDto(fooSchema, "labelFoo", "val => val.foo", null, fooExtractor, barExtractor);
Response addLabelResponse = jsonRequest().body(List.of(label)).post("/api/schema/" + fooSchema.id + "/labels");
addLabelResponse.then().statusCode(201);

List<Integer> ids = uploadRun(
"""
{
"bar": "test1",
"foo": [{"inner":[{"id": 1}, {"id": 2}]}, {"inner":[{"id": 3}]}, {"inner":[{"id": 4}, {"id": 5}]}]
}
""",
t.name, fooSchema.uri);
assertEquals(1, ids.size());
// force to recalculate datasets and label values sync
recalculateDatasetForRun(ids.get(0));

int datasetId = DatasetDAO.<DatasetDAO> find("runId = ?1", ids.get(0)).firstResult().id;

// check the preview label
JsonNode preview = jsonRequest()
.body(label)
.post("/api/dataset/" + datasetId + "/previewLabel")
.then()
.statusCode(200)
.extract()
.as(JsonNode.class);

// expecting an array of arrays [[1, 2], [3], [4, 5]]
JsonNode previewValue = preview.get("value");
assertInstanceOf(ArrayNode.class, previewValue);
assertEquals(3, previewValue.size());
assertTrue(previewValue.get(0).isArray());

// check the actual label value
JsonNode response = jsonRequest()
.get("/api/dataset/" + datasetId + "/labelValues?include=labelFoo")
.then()
.statusCode(200)
.extract()
.body()
.as(JsonNode.class);

assertInstanceOf(ArrayNode.class, response);
ArrayNode arrayResponse = (ArrayNode) response;
assertEquals(1, arrayResponse.size());
assertInstanceOf(ObjectNode.class, arrayResponse.get(0));
ObjectNode objectNode = (ObjectNode) arrayResponse.get(0);

assertEquals("labelFoo", objectNode.get("name").asText());
assertTrue(objectNode.get("value").isArray());
// expecting an array of arrays [[1, 2], [3], [4, 5]]
assertEquals(3, objectNode.get("value").size());
assertTrue(objectNode.get("value").get(0).isArray());

// check both, preview and actual label value return the same result after js application
assertEquals(previewValue, objectNode.get("value"));
}

@org.junit.jupiter.api.Test
public void labelValuesWithAllMatchSingleExtractorAndJs() {
Test t = createTest(createExampleTest("my-test"));

// create a schema with all match label extractor
Schema fooSchema = createSchema("foo", "urn:foo");
Extractor fooExtractor = new Extractor();
fooExtractor.name = "foo";
fooExtractor.jsonpath = "$.foo[*].inner";
fooExtractor.isArray = true;

// pass the array of arrays to a js function
Label label = createLabelDto(fooSchema, "labelFoo", "val => val", null, fooExtractor);
Response addLabelResponse = jsonRequest().body(List.of(label)).post("/api/schema/" + fooSchema.id + "/labels");
addLabelResponse.then().statusCode(201);

List<Integer> ids = uploadRun(
"""
{
"bar": "test1",
"foo": [{"inner":[{"id": 1}, {"id": 2}]}, {"inner":[{"id": 3}]}, {"inner":[{"id": 4}, {"id": 5}]}]
}
""",
t.name, fooSchema.uri);
assertEquals(1, ids.size());
// force to recalculate datasets and label values sync
recalculateDatasetForRun(ids.get(0));

int datasetId = DatasetDAO.<DatasetDAO> find("runId = ?1", ids.get(0)).firstResult().id;

// check the preview label
JsonNode preview = jsonRequest()
.body(label)
.post("/api/dataset/" + datasetId + "/previewLabel")
.then()
.statusCode(200)
.extract()
.as(JsonNode.class);

// expecting an array of arrays [[1, 2], [3], [4, 5]]
JsonNode previewValue = preview.get("value");
assertInstanceOf(ArrayNode.class, previewValue);
assertEquals(3, previewValue.size());
assertTrue(previewValue.get(0).isArray());

// check the actual label value
JsonNode response = jsonRequest()
.get("/api/dataset/" + datasetId + "/labelValues?include=labelFoo")
.then()
.statusCode(200)
.extract()
.body()
.as(JsonNode.class);

assertInstanceOf(ArrayNode.class, response);
ArrayNode arrayResponse = (ArrayNode) response;
assertEquals(1, arrayResponse.size());
assertInstanceOf(ObjectNode.class, arrayResponse.get(0));
ObjectNode objectNode = (ObjectNode) arrayResponse.get(0);

assertEquals("labelFoo", objectNode.get("name").asText());
assertTrue(objectNode.get("value").isArray());
// expecting an array of arrays [[1, 2], [3], [4, 5]]
assertEquals(3, objectNode.get("value").size());
assertTrue(objectNode.get("value").get(0).isArray());

// check both, preview and actual label value return the same result after js application
assertEquals(previewValue, objectNode.get("value"));
}

@org.junit.jupiter.api.Test
public void labelValuesWithFirstMatchSingleExtractorAndJs() {
Test t = createTest(createExampleTest("my-test"));

// create a schema with all match label extractor
Schema fooSchema = createSchema("foo", "urn:foo");
Extractor fooExtractor = new Extractor();
fooExtractor.name = "foo";
fooExtractor.jsonpath = "$.foo[*].inner";
fooExtractor.isArray = false;

// pass the array of arrays to a js function
Label label = createLabelDto(fooSchema, "labelFoo", "val => val", null, fooExtractor);
Response addLabelResponse = jsonRequest().body(List.of(label)).post("/api/schema/" + fooSchema.id + "/labels");
addLabelResponse.then().statusCode(201);

List<Integer> ids = uploadRun(
"""
{
"bar": "test1",
"foo": [{"inner":[{"id": 1}, {"id": 2}]}, {"inner":[{"id": 3}]}, {"inner":[{"id": 4}, {"id": 5}]}]
}
""",
t.name, fooSchema.uri);
assertEquals(1, ids.size());
// force to recalculate datasets and label values sync
recalculateDatasetForRun(ids.get(0));

int datasetId = DatasetDAO.<DatasetDAO> find("runId = ?1", ids.get(0)).firstResult().id;

// check the preview label
JsonNode preview = jsonRequest()
.body(label)
.post("/api/dataset/" + datasetId + "/previewLabel")
.then()
.statusCode(200)
.extract()
.as(JsonNode.class);

// expecting an array of arrays [1, 2]
JsonNode previewValue = preview.get("value");
assertInstanceOf(ArrayNode.class, previewValue);
assertEquals(2, previewValue.size());
assertTrue(previewValue.get(0).isObject());

// check the actual label value
JsonNode response = jsonRequest()
.get("/api/dataset/" + datasetId + "/labelValues?include=labelFoo")
.then()
.statusCode(200)
.extract()
.body()
.as(JsonNode.class);

assertInstanceOf(ArrayNode.class, response);
ArrayNode arrayResponse = (ArrayNode) response;
assertEquals(1, arrayResponse.size());
assertInstanceOf(ObjectNode.class, arrayResponse.get(0));
ObjectNode objectNode = (ObjectNode) arrayResponse.get(0);

assertEquals("labelFoo", objectNode.get("name").asText());
assertTrue(objectNode.get("value").isArray());
// expecting an array of arrays [1, 2]
assertEquals(2, objectNode.get("value").size());
assertTrue(objectNode.get("value").get(0).isObject());

// check both, preview and actual label value return the same result after js application
assertEquals(previewValue, objectNode.get("value"));
}
}
Loading