You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@hertzbeat.apache.org by go...@apache.org on 2025/02/06 07:51:05 UTC
(hertzbeat) 04/04: [alert] add multi query expr threshold unit test
This is an automated email from the ASF dual-hosted git repository.
gongchao pushed a commit to branch multi-query
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
commit b2c5957d3dc6e160a516be8e01f91e5cbbc50d5c
Author: tomsun28 <to...@outlook.com>
AuthorDate: Thu Feb 6 15:47:09 2025 +0800
[alert] add multi query expr threshold unit test
Signed-off-by: tomsun28 <to...@outlook.com>
---
.../alert/service/impl/DataSourceServiceImpl.java | 148 +++++++++--
.../alert/service/DataSourceServiceTest.java | 278 ++++++++++++++++++++-
2 files changed, 399 insertions(+), 27 deletions(-)
diff --git a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java
index a82518c902..5c241e5605 100644
--- a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java
+++ b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java
@@ -18,11 +18,8 @@
package org.apache.hertzbeat.alert.service.impl;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedList;
-import java.util.Set;
import java.util.Stack;
-import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.service.DataSourceService;
import org.apache.hertzbeat.warehouse.db.QueryExecutor;
@@ -46,7 +43,7 @@ public class DataSourceServiceImpl implements DataSourceService {
@Autowired(required = false)
private List<QueryExecutor> executors;
- private static final Pattern EXPR_TOKEN = Pattern.compile("\\(|\\)|[a-zA-Z_][a-zA-Z0-9_{}\\[\\]\".]*|\\d+(\\.\\d+)?|>=|<=|==|!=|>|<|and|or|unless");
+ private static final Pattern EXPR_TOKEN = Pattern.compile("\\(|\\)|[a-zA-Z_][a-zA-Z0-9_=~{}\\[\\]\".]*|\\d+(\\.\\d+)?|>=|<=|==|!=|>|<|and|or|unless");
private static final String THRESHOLD = "__threshold__";
private static final String VALUE = "__value__";
@@ -63,7 +60,7 @@ public class DataSourceServiceImpl implements DataSourceService {
throw new IllegalArgumentException("Unsupported datasource: " + datasource);
}
// replace all white space
- expr = expr.replaceAll("\\s+", "");
+ expr = expr.replaceAll("\\s+", " ");
try {
return evaluate(expr, executor);
} catch (Exception e) {
@@ -89,14 +86,6 @@ public class DataSourceServiceImpl implements DataSourceService {
}
// remove the left parenthesis
operators.pop();
- } else if (token.matches("\\d+(\\.\\d+)?")) {
- double value = Double.parseDouble(token);
- List<Map<String, Object>> numAsList = new ArrayList<>();
- numAsList.add(Map.of(THRESHOLD, value));
- values.push(numAsList);
- } else if (token.matches("[a-zA-Z_][a-zA-Z0-9_{}\\[\\]\".]*")) {
- List<Map<String, Object>> results = executor.execute(token);
- values.push(results);
} else if (token.matches(">=|<=|==|!=|>|<")) {
operators.push(token);
} else if (token.equals("and") || token.equals("or") || token.equals("unless")) {
@@ -104,6 +93,14 @@ public class DataSourceServiceImpl implements DataSourceService {
applyOperator(values, operators.pop());
}
operators.push(token);
+ } else if (token.matches("\\d+(\\.\\d+)?")) {
+ double value = Double.parseDouble(token);
+ List<Map<String, Object>> numAsList = new ArrayList<>();
+ numAsList.add(Map.of(THRESHOLD, value));
+ values.push(numAsList);
+ } else if (token.matches("[a-zA-Z_][a-zA-Z0-9_=~{}\\[\\]\".]*")) {
+ List<Map<String, Object>> results = executor.execute(token);
+ values.push(results);
}
}
while (!operators.isEmpty()) {
@@ -114,15 +111,18 @@ public class DataSourceServiceImpl implements DataSourceService {
private int precedence(String op) {
return switch (op) {
- case "or", "unless" -> 1;
- case "and" -> 2;
- case ">", "<", ">=", "<=", "==", "!=" -> 3;
+ case "or" -> 1;
+ case "unless" -> 2;
+ case "and" -> 3;
+ case ">", "<", ">=", "<=", "==", "!=" -> 4;
default -> 0;
};
}
private void applyOperator(Stack<List<Map<String, Object>>> values, String op) {
- if (values.size() < 2) return;
+ if (values.size() < 2) {
+ return;
+ };
List<Map<String, Object>> rightOperand = values.pop();
List<Map<String, Object>> leftOperand = values.pop();
if (rightOperand.size() == 1 && rightOperand.get(0).containsKey(THRESHOLD)) {
@@ -146,15 +146,117 @@ public class DataSourceServiceImpl implements DataSourceService {
}
return;
}
-
+ Map<String, Object> leftMap = null;
+ boolean leftMatch = false;
+ Map<String, Object> rightMap = null;
+ boolean rightMatch = false;
switch (op) {
- case "and" -> values.push(leftOperand.stream().filter(rightOperand::contains).collect(Collectors.toList()));
+ case "and" -> {
+ for (Map<String, Object> item : leftOperand) {
+ if (leftMap == null) {
+ leftMap = item;
+ }
+ if (item.get(VALUE) != null) {
+ leftMap = item;
+ leftMatch = true;
+ break;
+ }
+ }
+ for (Map<String, Object> item : rightOperand) {
+ if (rightMap == null) {
+ rightMap = item;
+ }
+ if (item.get(VALUE) != null) {
+ rightMap = item;
+ rightMatch = true;
+ break;
+ }
+ }
+ if (leftMatch && rightMatch) {
+ rightMap.putAll(leftMap);
+ values.push(new LinkedList<>(List.of(rightMap)));
+ } else if (leftMap != null) {
+ leftMap.put(VALUE, null);
+ values.push(new LinkedList<>(List.of(leftMap)));
+ } else if (rightMap != null) {
+ rightMap.put(VALUE, null);
+ values.push(new LinkedList<>(List.of(rightMap)));
+ }
+ }
case "or" -> {
- Set<Map<String, Object>> resultSet = new HashSet<>(leftOperand);
- resultSet.addAll(rightOperand);
- values.push(new ArrayList<>(resultSet));
+ for (Map<String, Object> item : leftOperand) {
+ if (leftMap == null) {
+ leftMap = item;
+ }
+ if (item.get(VALUE) != null) {
+ leftMap = item;
+ leftMatch = true;
+ break;
+ }
+ }
+ for (Map<String, Object> item : rightOperand) {
+ if (rightMap == null) {
+ rightMap = item;
+ }
+ if (item.get(VALUE) != null) {
+ rightMap = item;
+ rightMatch = true;
+ break;
+ }
+ }
+ if (leftMatch && rightMatch) {
+ rightMap.putAll(leftMap);
+ values.push(new LinkedList<>(List.of(rightMap)));
+ } else if (leftMatch) {
+ values.push(new LinkedList<>(List.of(leftMap)));
+ } else if (rightMatch) {
+ values.push(new LinkedList<>(List.of(rightMap)));
+ } else {
+ if (leftMap != null && rightMap != null) {
+ rightMap.putAll(leftMap);
+ values.push(new LinkedList<>(List.of(rightMap)));
+ } else if (leftMap != null) {
+ values.push(new LinkedList<>(List.of(leftMap)));
+ } else if (rightMap != null){
+ values.push(new LinkedList<>(List.of(rightMap)));
+ }
+ }
+ }
+ case "unless" -> {
+ for (Map<String, Object> item : leftOperand) {
+ if (leftMap == null) {
+ leftMap = item;
+ }
+ if (item.get(VALUE) != null) {
+ leftMap = item;
+ leftMatch = true;
+ break;
+ }
+ }
+ for (Map<String, Object> item : rightOperand) {
+ if (rightMap == null) {
+ rightMap = item;
+ }
+ if (item.get(VALUE) != null) {
+ rightMap = item;
+ rightMatch = true;
+ break;
+ }
+ }
+ if (leftMatch && !rightMatch) {
+ values.push(new LinkedList<>(List.of(leftMap)));
+ } else {
+ if (leftMap != null) {
+ leftMap.put(VALUE, null);
+ values.push(new LinkedList<>(List.of(leftMap)));
+ } else {
+ if (rightMap != null) {
+ rightMap.put(VALUE, null);
+ values.push(new LinkedList<>(List.of(rightMap)));
+ }
+ }
+ }
}
- case "unless" -> values.push(leftOperand.stream().filter(item -> !rightOperand.contains(item)).collect(Collectors.toList()));
default -> throw new IllegalArgumentException("Unsupported operator: " + op);
}
}
diff --git a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/DataSourceServiceTest.java b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/DataSourceServiceTest.java
index 812f231bd6..129759e4bd 100644
--- a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/DataSourceServiceTest.java
+++ b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/DataSourceServiceTest.java
@@ -1,6 +1,7 @@
package org.apache.hertzbeat.alert.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.util.HashMap;
import org.apache.hertzbeat.alert.service.impl.DataSourceServiceImpl;
@@ -216,9 +217,8 @@ class DataSourceServiceTest {
dataSourceService.setExecutors(List.of(mockExecutor));
List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 and node_cpu_seconds_total{mode=\"idle\"} < 120");
- assertEquals(2, result.size());
+ assertEquals(1, result.size());
assertEquals(100.0, result.get(0).get("__value__"));
- assertNull(result.get(1).get("__value__"));
}
@Test
@@ -234,8 +234,278 @@ class DataSourceServiceTest {
dataSourceService.setExecutors(List.of(mockExecutor));
List<Map<String, Object>> result = dataSourceService.calculate("promql", "(node_cpu_seconds_total{mode=\"user\"} > 50) and (node_cpu_seconds_total{mode=\"idle\"} < 120)");
- assertEquals(2, result.size());
+ assertEquals(1, result.size());
assertEquals(100.0, result.get(0).get("__value__"));
- assertNull(result.get(1).get("__value__"));
+ }
+
+ @Test
+ void calculate13() {
+ List<Map<String, Object>> prometheusData = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute(Mockito.anyString())).thenReturn(prometheusData);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 150 and node_cpu_seconds_total{mode=\"idle\"} < 220");
+ assertEquals(1, result.size());
+ assertEquals(200.0, result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate14() {
+ List<Map<String, Object>> prometheusData = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute(Mockito.anyString())).thenReturn(prometheusData);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "(node_cpu_seconds_total{mode=\"user\"} > 150) and (node_cpu_seconds_total{mode=\"idle\"} < 220)");
+ assertEquals(1, result.size());
+ assertEquals(200.0, result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate15() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 and node_cpu_seconds_total{mode=\"idle\"} < 220");
+ assertEquals(1, result.size());
+ assertNull(result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate16() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 and node_cpu_seconds_total{mode=\"idle\"} < 20");
+ assertEquals(1, result.size());
+ assertNull(result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate17() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 150 or node_cpu_seconds_total{mode=\"idle\"} < 20");
+ assertEquals(1, result.size());
+ assertEquals(200.0, result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate18() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 or node_cpu_seconds_total{mode=\"idle\"} < 120");
+ assertEquals(1, result.size());
+ assertEquals(100.0, result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate19() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 or node_cpu_seconds_total{mode=\"idle\"} < 20");
+ assertEquals(1, result.size());
+ assertNull(result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate20() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "key", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "book", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 or node_cpu_seconds_total{mode=\"idle\"} < 320");
+ assertEquals(1, result.size());
+ assertNotNull(result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate21() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "key", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "book", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 unless node_cpu_seconds_total{mode=\"idle\"} < 320");
+ assertEquals(1, result.size());
+ assertNull(result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate22() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "key", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "book", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 50 unless node_cpu_seconds_total{mode=\"idle\"} < 20");
+ assertEquals(1, result.size());
+ assertNotNull(result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate23() {
+ List<Map<String, Object>> prometheusData1 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "instance", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ List<Map<String, Object>> prometheusData2 = List.of(
+ new HashMap<>(Map.of("__value__", 100.0, "timestamp", 1343554, "key", "node1")),
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "book", "node2"))
+ );
+
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"user\"}")).thenReturn(prometheusData1);
+ Mockito.when(mockExecutor.execute("node_cpu_seconds_total{mode=\"idle\"}")).thenReturn(prometheusData2);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 unless node_cpu_seconds_total{mode=\"idle\"} < 20");
+ assertEquals(1, result.size());
+ assertNull(result.get(0).get("__value__"));
+ }
+
+ @Test
+ void calculate24() {
+ List<Map<String, Object>> prometheusData = List.of();
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute(Mockito.anyString())).thenReturn(prometheusData);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total > 150");
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ void calculate25() {
+ List<Map<String, Object>> prometheusData = List.of();
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute(Mockito.anyString())).thenReturn(prometheusData);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total{mode=\"user\"} > 250 unless node_cpu_seconds_total{mode=\"idle\"} < 20");
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ void calculate26() {
+ List<Map<String, Object>> prometheusData = List.of(
+ new HashMap<>(Map.of("__value__", 200.0, "timestamp", 1343555, "instance", "node2"))
+ );
+ QueryExecutor mockExecutor = Mockito.mock(QueryExecutor.class);
+ Mockito.when(mockExecutor.support("promql")).thenReturn(true);
+ Mockito.when(mockExecutor.execute(Mockito.anyString())).thenReturn(prometheusData);
+ dataSourceService.setExecutors(List.of(mockExecutor));
+
+ List<Map<String, Object>> result = dataSourceService.calculate("promql", "node_cpu_seconds_total > 150");
+ assertEquals(1, result.size());
+ assertEquals(200.0, result.get(0).get("__value__"));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@hertzbeat.apache.org
For additional commands, e-mail: notifications-help@hertzbeat.apache.org