diff --git a/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/BaseServiceTest.java b/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/BaseServiceTest.java index 9a7038061..79ae45ea1 100644 --- a/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/BaseServiceTest.java +++ b/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/BaseServiceTest.java @@ -268,7 +268,11 @@ protected String uploadRun(Object runJson, String test, String schemaUri) { protected String uploadRun(Object runJson, String test, String schemaUri, Integer statusCode) { long timestamp = System.currentTimeMillis(); - String runId = uploadRun(Long.toString(timestamp), Long.toString(timestamp), test, UPLOADER_ROLES[0], Access.PUBLIC, + return uploadRun(timestamp, timestamp, runJson, test, schemaUri, statusCode); + } + + protected String uploadRun(long start, long stop, Object runJson, String test, String schemaUri, Integer statusCode) { + String runId = uploadRun(Long.toString(start), Long.toString(stop), test, UPLOADER_ROLES[0], Access.PUBLIC, null, schemaUri, null, statusCode, runJson); assertNotEquals("-1", runId); return runId; diff --git a/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/TestServiceTest.java b/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/TestServiceTest.java index ce3864722..43a663440 100644 --- a/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/TestServiceTest.java +++ b/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/TestServiceTest.java @@ -506,7 +506,7 @@ private String labelValuesSetup(Test t, boolean load) { } @org.junit.jupiter.api.Test - public void labelValuesIncludeExcluded() throws JsonProcessingException { + public void labelValuesIncludeExcluded() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, true); @@ -527,7 +527,83 @@ public void labelValuesIncludeExcluded() throws JsonProcessingException { } @org.junit.jupiter.api.Test - public void labelValuesFilterWithJsonpath() throws JsonProcessingException { + public void labelValuesWithTimestampAfterFilter() { + Test t = createTest(createExampleTest("my-test")); + labelValuesSetup(t, false); + long stop = System.currentTimeMillis(); + long start = System.currentTimeMillis(); + long delta = 5000; // 5 seconds + uploadRun(start, stop, "{ \"foo\": 1, \"bar\": \"uno\"}", t.name, "urn:foo", + jakarta.ws.rs.core.Response.Status.OK.getStatusCode()); + uploadRun(start + delta, stop, "{ \"foo\": 2, \"bar\": \"dos\"}", t.name, "urn:foo", + jakarta.ws.rs.core.Response.Status.OK.getStatusCode()); + uploadRun(start + delta, stop, "{ \"foo\": 3, \"bar\": \"tres\"}", t.name, "urn:foo", + jakarta.ws.rs.core.Response.Status.OK.getStatusCode()); + JsonNode response = jsonRequest() + .urlEncodingEnabled(true) + // keep only those runs that started after (start+delta-1) + .queryParam("after", Long.toString(start + delta - 1)) + .get("/api/test/" + t.id + "/labelValues") + .then() + .statusCode(200) + .extract() + .body() + .as(JsonNode.class); + assertInstanceOf(ArrayNode.class, response); + ArrayNode arrayResponse = (ArrayNode) response; + assertEquals(2, arrayResponse.size(), "unexpected number of responses " + response); + JsonNode first = arrayResponse.get(0); + assertTrue(first.has("values"), first.toString()); + JsonNode values = first.get("values"); + assertTrue(values.has("labelBar"), values.toString()); + assertEquals(JsonNodeType.STRING, values.get("labelBar").getNodeType()); + JsonNode second = arrayResponse.get(1); + assertTrue(first.has("values"), second.toString()); + JsonNode secondValues = second.get("values"); + assertTrue(secondValues.has("labelBar"), secondValues.toString()); + assertEquals(JsonNodeType.STRING, secondValues.get("labelBar").getNodeType()); + + List labelBarValues = List.of(values.get("labelBar").asText(), secondValues.get("labelBar").asText()); + assertTrue(labelBarValues.contains("dos"), labelBarValues.toString()); + assertTrue(labelBarValues.contains("tres"), labelBarValues.toString()); + } + + @org.junit.jupiter.api.Test + public void labelValuesWithISOAfterFilter() { + Test t = createTest(createExampleTest("my-test")); + labelValuesSetup(t, false); + long stop = System.currentTimeMillis(); + uploadRun(Util.toInstant("2024-10-06T20:20:32.183Z").toEpochMilli(), stop, "{ \"foo\": 1, \"bar\": \"uno\"}", t.name, + "urn:foo", jakarta.ws.rs.core.Response.Status.OK.getStatusCode()); + uploadRun(Util.toInstant("2024-10-06T20:20:32.183Z").toEpochMilli(), stop, "{ \"foo\": 2, \"bar\": \"dos\"}", t.name, + "urn:foo", jakarta.ws.rs.core.Response.Status.OK.getStatusCode()); + uploadRun(Util.toInstant("2024-10-09T20:20:32.183Z").toEpochMilli(), stop, "{ \"foo\": 3, \"bar\": \"tres\"}", t.name, + "urn:foo", jakarta.ws.rs.core.Response.Status.OK.getStatusCode()); + JsonNode response = jsonRequest() + .urlEncodingEnabled(true) + // keep only those runs that started after (start+delta-1) + .queryParam("after", "2024-10-07T20:20:32.183Z") + .queryParam("filter", Maps.of("labelBar", Arrays.asList("none", "tres"))) + .queryParam("multiFilter", true) + .get("/api/test/" + t.id + "/labelValues") + .then() + .statusCode(200) + .extract() + .body() + .as(JsonNode.class); + assertInstanceOf(ArrayNode.class, response); + ArrayNode arrayResponse = (ArrayNode) response; + assertEquals(1, arrayResponse.size(), "unexpected number of responses " + response); + JsonNode first = arrayResponse.get(0); + assertTrue(first.has("values"), first.toString()); + JsonNode values = first.get("values"); + assertTrue(values.has("labelBar"), values.toString()); + assertEquals(JsonNodeType.STRING, values.get("labelBar").getNodeType()); + assertEquals("tres", values.get("labelBar").asText()); + } + + @org.junit.jupiter.api.Test + public void labelValuesFilterWithJsonpath() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": \"uno\"}", t.name, "urn:foo"); @@ -554,7 +630,7 @@ public void labelValuesFilterWithJsonpath() throws JsonProcessingException { } @org.junit.jupiter.api.Test - public void labelValuesFilterWithInvalidJsonpath() throws JsonProcessingException { + public void labelValuesFilterWithInvalidJsonpath() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": \"uno\"}", t.name, "urn:foo"); @@ -569,7 +645,7 @@ public void labelValuesFilterWithInvalidJsonpath() throws JsonProcessingExceptio } @org.junit.jupiter.api.Test - public void labelValuesFilterWithObject() throws JsonProcessingException { + public void labelValuesFilterWithObject() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": \"uno\"}", t.name, "urn:foo"); @@ -597,7 +673,7 @@ public void labelValuesFilterWithObject() throws JsonProcessingException { } @org.junit.jupiter.api.Test - public void labelValuesFilterWithObjectNoMatch() throws JsonProcessingException { + public void labelValuesFilterWithObjectNoMatch() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": \"uno\"}", t.name, "urn:foo"); @@ -620,7 +696,7 @@ public void labelValuesFilterWithObjectNoMatch() throws JsonProcessingException } @org.junit.jupiter.api.Test - public void labelValuesFilterMultiSelectMultipleValues() throws JsonProcessingException { + public void labelValuesFilterMultiSelectMultipleValues() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": \"uno\"}", t.name, "urn:foo"); @@ -644,15 +720,15 @@ public void labelValuesFilterMultiSelectMultipleValues() throws JsonProcessingEx JsonNode values = first.get("values"); assertTrue(values.has("labelBar"), values.toString()); assertEquals(JsonNodeType.STRING, values.get("labelBar").getNodeType()); - JsonNode second = arrayResponse.get(0); + JsonNode second = arrayResponse.get(1); assertTrue(first.has("values"), second.toString()); JsonNode secondValues = second.get("values"); - assertTrue(values.has("labelBar"), secondValues.toString()); + assertTrue(secondValues.has("labelBar"), secondValues.toString()); assertEquals(JsonNodeType.STRING, secondValues.get("labelBar").getNodeType()); } @org.junit.jupiter.api.Test - public void labelValuesFilterMultiSelectStrings() throws JsonProcessingException { + public void labelValuesFilterMultiSelectStrings() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": \"uno\"}", t.name, "urn:foo"); @@ -679,7 +755,7 @@ public void labelValuesFilterMultiSelectStrings() throws JsonProcessingException } @org.junit.jupiter.api.Test - public void labelValuesFilterMultiSelectNumber() throws JsonProcessingException { + public void labelValuesFilterMultiSelectNumber() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": 10}", t.name, "urn:foo"); @@ -706,7 +782,7 @@ public void labelValuesFilterMultiSelectNumber() throws JsonProcessingException } @org.junit.jupiter.api.Test - public void labelValuesFilterMultiSelectBoolean() throws JsonProcessingException { + public void labelValuesFilterMultiSelectBoolean() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, false); uploadRun("{ \"foo\": 1, \"bar\": true}", t.name, "urn:foo"); @@ -733,7 +809,7 @@ public void labelValuesFilterMultiSelectBoolean() throws JsonProcessingException } @org.junit.jupiter.api.Test - public void labelValuesIncludeTwoParams() throws JsonProcessingException { + public void labelValuesIncludeTwoParams() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, true); @@ -754,7 +830,7 @@ public void labelValuesIncludeTwoParams() throws JsonProcessingException { } @org.junit.jupiter.api.Test - public void labelValuesIncludeTwoSeparated() throws JsonProcessingException { + public void labelValuesIncludeTwoSeparated() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, true); @@ -775,7 +851,7 @@ public void labelValuesIncludeTwoSeparated() throws JsonProcessingException { } @org.junit.jupiter.api.Test - public void labelValuesInclude() throws JsonProcessingException { + public void labelValuesInclude() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, true); @@ -796,7 +872,7 @@ public void labelValuesInclude() throws JsonProcessingException { } @org.junit.jupiter.api.Test - public void labelValuesExclude() throws JsonProcessingException { + public void labelValuesExclude() { Test t = createTest(createExampleTest("my-test")); labelValuesSetup(t, true); diff --git a/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/UtilTest.java b/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/UtilTest.java index b412f5b96..fb1cd409b 100644 --- a/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/UtilTest.java +++ b/horreum-backend/src/test/java/io/hyperfoil/tools/horreum/svc/UtilTest.java @@ -155,7 +155,7 @@ public void toInstant_nulls() throws UnsupportedEncodingException { } @Test - public void toInstant_valid() throws IOException { + public void toInstant_valid() { //already an instant assertNotNull(Util.toInstant(Instant.now()), "failed to handle instant input"); //number @@ -167,6 +167,7 @@ public void toInstant_valid() throws IOException { assertNotNull(Util.toInstant("2020-01-01T01:01:01Z"), "failed to parse YYYY-MM-DDThh:mm:ssZ"); assertNotNull(Util.toInstant("2020-01-01T01:01:01+00:00"), "failed to parse YYYY-MM-DDThh:mm:ss[+-]zz:zz"); assertNotNull(Util.toInstant("2024-03-11T22:16:24.302655-04:00"), "failed to parse ISO with microseconds and zzzz"); + assertNotNull(Util.toInstant("2024-10-07T20:20:32.183Z"), "failed to parse YYYY-MM-DDTHH:mm:ss.zzz"); //json assertNotNull(Util.toInstant(new TextNode("2020-01-01")), "failed to parse json text YYYY-MM-DD"); assertNotNull(Util.toInstant(new LongNode(System.currentTimeMillis())), "failed to parse current millis as json node");