Skip to content

Commit c4a0f75

Browse files
committed
Finish test
1 parent 55e66b2 commit c4a0f75

File tree

2 files changed

+65
-4
lines changed
  • x-pack/plugin/esql
    • qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node
    • tools/src/main/java/org/elasticsearch/xpack/esql/tools

2 files changed

+65
-4
lines changed

x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/RestEsqlIT.java

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.elasticsearch.client.ResponseException;
1818
import org.elasticsearch.common.io.Streams;
1919
import org.elasticsearch.common.settings.Settings;
20+
import org.elasticsearch.common.xcontent.XContentHelper;
2021
import org.elasticsearch.test.ListMatcher;
2122
import org.elasticsearch.test.MapMatcher;
2223
import org.elasticsearch.test.TestClustersThreadFilter;
@@ -30,10 +31,10 @@
3031
import org.junit.Assert;
3132
import org.junit.ClassRule;
3233

34+
import java.io.ByteArrayInputStream;
3335
import java.io.ByteArrayOutputStream;
3436
import java.io.IOException;
3537
import java.io.InputStream;
36-
import java.nio.charset.Charset;
3738
import java.nio.charset.StandardCharsets;
3839
import java.util.ArrayList;
3940
import java.util.Arrays;
@@ -49,11 +50,14 @@
4950
import static org.hamcrest.Matchers.containsInAnyOrder;
5051
import static org.hamcrest.Matchers.containsString;
5152
import static org.hamcrest.Matchers.either;
53+
import static org.hamcrest.Matchers.empty;
5254
import static org.hamcrest.Matchers.equalTo;
5355
import static org.hamcrest.Matchers.greaterThan;
56+
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
5457
import static org.hamcrest.Matchers.hasItem;
5558
import static org.hamcrest.Matchers.instanceOf;
5659
import static org.hamcrest.Matchers.not;
60+
import static org.hamcrest.Matchers.oneOf;
5761
import static org.hamcrest.Matchers.startsWith;
5862
import static org.hamcrest.core.Is.is;
5963

@@ -335,6 +339,7 @@ public void testProfile() throws IOException {
335339
}
336340
}
337341

342+
@SuppressWarnings("unchecked")
338343
public void testProfileParsing() throws IOException {
339344
indexTimestampData(1);
340345

@@ -346,9 +351,65 @@ public void testProfileParsing() throws IOException {
346351
try (XContentBuilder jsonOutputBuilder = new XContentBuilder(JsonXContent.jsonXContent, os)) {
347352
parseProfile(result, jsonOutputBuilder);
348353
}
349-
String parsedProfile = os.toString(Charset.defaultCharset());
350354

351-
assertFalse(true);
355+
// Read the written JSON again into a map, so we can make assertions on it
356+
ByteArrayInputStream profileJson = new ByteArrayInputStream(os.toByteArray());
357+
Map<String, Object> parsedProfile = XContentHelper.convertToMap(JsonXContent.jsonXContent, profileJson, true);
358+
359+
assertEquals(parsedProfile.get("displayTimeUnit"), "ns");
360+
List<Map<String, Object>> events = (List<Map<String, Object>>) parsedProfile.get("traceEvents");
361+
// At least 1 metadata event to declare the node, and 2 events each for the data, node_reduce and final drivers, resp.
362+
assertThat(events.size(), greaterThanOrEqualTo(7));
363+
364+
// Declaration of each node as a "process" via a metadata event (phase `ph` is `M`)
365+
Map<String, Object> nodeMetadata = events.get(0);
366+
assertEquals(nodeMetadata.get("ph"), "M");
367+
assertEquals(nodeMetadata.get("name"), "process_name");
368+
int nodeIndex = 0;
369+
assertEquals(nodeMetadata.get("pid"), nodeIndex);
370+
Map<String, Object> nodeMetadataArgs = (Map<String, Object>) nodeMetadata.get("args");
371+
// cluster:node should be the label for the "process" name
372+
assertEquals(nodeMetadataArgs.get("name"), "test-cluster:test-cluster-0");
373+
374+
// The rest should be pairs of 2 events: first, a metadata event, declaring 1 "thread" per driver in the profile, then
375+
// a "complete" event (phase `ph` is `X`) with a timestamp, duration `dur`, thread duration `tdur` (cpu time) and additional
376+
// arguments obtained from the driver.
377+
for (int i = 1; i < events.size() - 1; i = i + 2) {
378+
Map<String, Object> driverMetadata = events.get(i);
379+
380+
assertEquals(driverMetadata.get("ph"), "M");
381+
assertEquals(driverMetadata.get("name"), "thread_name");
382+
assertEquals(driverMetadata.get("pid"), nodeIndex);
383+
int driverIndex = i / 2;
384+
assertEquals(driverMetadata.get("tid"), driverIndex);
385+
Map<String, Object> driverMetadataArgs = (Map<String, Object>) driverMetadata.get("args");
386+
String driverType = (String) driverMetadataArgs.get("name");
387+
assertThat(driverType, oneOf("data", "node_reduce", "final"));
388+
389+
Map<String, Object> driverSlice = events.get(i + 1);
390+
assertEquals(driverSlice.get("ph"), "X");
391+
assertThat((String) driverSlice.get("name"), startsWith(driverType));
392+
// Category used to implicitly colour-code and group drivers
393+
assertEquals(driverSlice.get("cat"), driverType);
394+
assertEquals(driverSlice.get("pid"), nodeIndex);
395+
assertEquals(driverSlice.get("tid"), driverIndex);
396+
long timestampMillis = (long) driverSlice.get("ts");
397+
double durationMicros = (double) driverSlice.get("dur");
398+
double cpuDurationMicros = (double) driverSlice.get("tdur");
399+
assertTrue(timestampMillis >= 0);
400+
assertTrue(durationMicros >= 0);
401+
assertTrue(cpuDurationMicros >= 0);
402+
assertTrue(durationMicros >= cpuDurationMicros);
403+
404+
// This should contain the essential information from a driver, like its operators, and will be just attached to the slice/
405+
// visible when clicking on it.
406+
Map<String, Object> driverSliceArgs = (Map<String, Object>) driverSlice.get("args");
407+
assertNotNull(driverSliceArgs.get("cpu_nanos"));
408+
assertNotNull(driverSliceArgs.get("took_nanos"));
409+
assertNotNull(driverSliceArgs.get("iterations"));
410+
assertNotNull(driverSliceArgs.get("sleeps"));
411+
assertThat(((List<String>) driverSliceArgs.get("operators")), not(empty()));
412+
}
352413
}
353414

354415
public void testProfileOrdinalsGroupingOperator() throws IOException {

x-pack/plugin/esql/tools/src/main/java/org/elasticsearch/xpack/esql/tools/ProfileParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ private static void parseDriverProfile(Map<String, Object> driver, int pid, int
147147
builder.field("cpu_nanos", readIntOrLong(driver, "cpu_nanos"));
148148
builder.field("took_nanos", readIntOrLong(driver, "took_nanos"));
149149
builder.field("iterations", readIntOrLong(driver, "iterations"));
150-
// TODO: Sleeps have more details
150+
// TODO: Sleeps have more details that could be added here
151151
int sleeps = ((Map<?, ?>) driver.get("sleeps")).size();
152152
builder.field("sleeps", sleeps);
153153
builder.field("operators");

0 commit comments

Comments
 (0)