已合并
实例监控单元测试及jdbc应用名配置 #349
AtomGit-Bot创建于 2023年7月17日
实例监控单元测试及jdbc应用名配置 #349
已合并
AtomGit-Bot创建于 2023年7月17日
refs/pull/349/head合入到master
7 个文件变更+439-5
Mplugins/observability-instance/InstanceExporter/src/main/java/org/opengauss/plugin/agent/util/DbUtil.java+2-1
@@ -35,7 +35,8 @@ public class DbUtil {
35 conn = DriverManager35 conn = DriverManager
36 .getConnection(36 .getConnection(
37 "jdbc:opengauss://" + "localhost" + ":" + dbConfig.getDbport() + "/"37 "jdbc:opengauss://" + "localhost" + ":" + dbConfig.getDbport() + "/"
38- + "postgres" + "?TimeZone=UTC",38+ + "postgres"
39+ + "?TimeZone=UTC&ApplicationName=DataKit Instance Monitoring Agent",
39 dbConfig.getDbUsername(), dbConfig.getDbPassword());40 dbConfig.getDbUsername(), dbConfig.getDbPassword());
40 }41 }
41 } catch (SQLException e) {42 } catch (SQLException e) {
Mplugins/observability-instance/src/main/java/com/nctigba/observability/instance/handler/session/OpenGaussSessionHandler.java+2-2
@@ -153,7 +153,7 @@ public class OpenGaussSessionHandler implements SessionHandler {
153 + " (select extract(EPOCH from(max(now() - backend_start)))::INTEGER as max_runtime, 1 as key from "153 + " (select extract(EPOCH from(max(now() - backend_start)))::INTEGER as max_runtime, 1 as key from "
154 + "pg_stat_activity where application_name not in "154 + "pg_stat_activity where application_name not in "
155 + "('WLMArbiter','workload','WorkloadMonitor','WDRSnapshot','JobScheduler','PercentileJob'"155 + "('WLMArbiter','workload','WorkloadMonitor','WDRSnapshot','JobScheduler','PercentileJob'"
156- + ",'statement flush thread','Asp','ApplyLauncher')) d "156+ + ",'statement flush thread','Asp','ApplyLauncher') and application_name not like 'DataKit%' ) d "
157 + " on c.key = d.key";157 + " on c.key = d.key";
158 private final String LONG_TXC_SQL =158 private final String LONG_TXC_SQL =
159 "SELECT pid,sessionid,usename,datname,application_name,client_addr,query, xact_start, "159 "SELECT pid,sessionid,usename,datname,application_name,client_addr,query, xact_start, "
@@ -161,7 +161,7 @@ public class OpenGaussSessionHandler implements SessionHandler {
161 + "FROM pg_stat_activity WHERE STATE <>'idle' and application_name not in "161 + "FROM pg_stat_activity WHERE STATE <>'idle' and application_name not in "
162 + "('WLMArbiter','workload',"162 + "('WLMArbiter','workload',"
163 + "'WorkloadMonitor','WDRSnapshot','JobScheduler','PercentileJob','statement flush thread','Asp',"163 + "'WorkloadMonitor','WDRSnapshot','JobScheduler','PercentileJob','statement flush thread','Asp',"
164- + "'ApplyLauncher') "164+ + "'ApplyLauncher') and application_name not like 'DataKit%' "
165 + "and now()-xact_start > interval '30 SECOND' "165 + "and now()-xact_start > interval '30 SECOND' "
166 + "ORDER BY xact_start;";166 + "ORDER BY xact_start;";
167 private final ClusterManager clusterManager;167 private final ClusterManager clusterManager;
Mplugins/observability-instance/src/main/java/com/nctigba/observability/instance/service/ClusterManager.java+2-2
@@ -92,8 +92,8 @@ public class ClusterManager {
92 /**92 /**
93 * Set the current data source and manually clear it93 * Set the current data source and manually clear it
94 *94 *
95- * @see DynamicDataSourceContextHolder#push(String)95+ * @see com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder#push(String)
96- * @see ClusterManager#pool()96+ * @see com.nctigba.observability.instance.service.ClusterManager#pool()
97 */97 */
98 public void setCurrentDatasource(String nodeId, String dbname) {98 public void setCurrentDatasource(String nodeId, String dbname) {
99 if (StringUtils.isBlank(nodeId))99 if (StringUtils.isBlank(nodeId))
Mplugins/observability-instance/src/main/resources/application.yml+2-0
@@ -31,6 +31,8 @@ spring:
31 connection-error-retry-attempts: 031 connection-error-retry-attempts: 0
32 break-after-acquire-failure: true32 break-after-acquire-failure: true
33 max-wait: 300033 max-wait: 3000
34+ connection-properties:
35+ ApplicationName: DataKit Instance Monitoring
34 jackson:36 jackson:
35 time-zone: GMT+837 time-zone: GMT+8
36 date-format: yyyy-MM-dd HH:mm:ss38 date-format: yyyy-MM-dd HH:mm:ss
Aplugins/observability-instance/src/test/java/com/nctigba/observability/instance/controller/SessionControllerTest.java+62-0
@@ -0,0 +1,62 @@
1+/*
2+ * Copyright (c) GBA-NCTI-ISDC. 2022-2023. All rights reserved.
3+ */
4+ 
5+package com.nctigba.observability.instance.controller;
6+ 
7+import com.alibaba.fastjson.JSONObject;
8+import com.nctigba.observability.instance.service.MetricsService;
9+import com.nctigba.observability.instance.service.impl.MonitoringServiceImpl;
10+import com.nctigba.observability.instance.service.impl.SessionServiceImpl;
11+import org.junit.Test;
12+import org.junit.runner.RunWith;
13+import org.mockito.InjectMocks;
14+import org.mockito.Mock;
15+import org.mockito.junit.MockitoJUnitRunner;
16+import org.opengauss.admin.common.core.domain.AjaxResult;
17+ 
18+import java.util.HashMap;
19+import java.util.List;
20+ 
21+import static org.junit.Assert.assertNotNull;
22+import static org.mockito.ArgumentMatchers.any;
23+import static org.mockito.Mockito.times;
24+import static org.mockito.Mockito.verify;
25+import static org.mockito.Mockito.when;
26+import static org.opengauss.admin.common.core.domain.AjaxResult.DATA_TAG;
27+ 
28+/**
29+ * Test
30+ *
31+ * @author liupengfei
32+ * @since 2023/6/30
33+ */
34+@RunWith(MockitoJUnitRunner.class)
35+public class SessionControllerTest {
36+ @InjectMocks
37+ SessionController sessionController;
38+ @Mock
39+ SessionServiceImpl sessionService;
40+ @Mock
41+ MetricsService metricsService;
42+ @Mock
43+ MonitoringServiceImpl monitoringService;
44+ 
45+ @Test
46+ public void sessionStatistic() {
47+ String id = "123";
48+ Long start = 111L;
49+ Long end = 222L;
50+ Integer step = 15;
51+ when(monitoringService.getRangeMonitoringData(any())).thenReturn(List.of("waitEven"));
52+ JSONObject jsonObject = new JSONObject();
53+ jsonObject.put("simple", "val");
54+ when(sessionService.simpleStatistic(id)).thenReturn(jsonObject);
55+ HashMap<String, Object> metric = new HashMap<>();
56+ metric.put("metric", "val");
57+ when(metricsService.listBatch(any(), any(), any(), any(), any())).thenReturn(metric);
58+ AjaxResult appResult = sessionController.sessionStatistic(id, start, end, step);
59+ assertNotNull(appResult.get(DATA_TAG));
60+ verify(sessionService, times(1)).simpleStatistic(any());
61+ }
62+}
Aplugins/observability-instance/src/test/java/com/nctigba/observability/instance/handler/session/OpenGaussSessionHandlerTest.java+177-0
@@ -0,0 +1,177 @@
1+/*
2+ * Copyright (c) GBA-NCTI-ISDC. 2022-2023. All rights reserved.
3+ */
4+ 
5+package com.nctigba.observability.instance.handler.session;
6+ 
7+import com.alibaba.fastjson.JSONObject;
8+import com.nctigba.common.web.exception.InstanceException;
9+import com.nctigba.observability.instance.dto.session.DetailStatisticDto;
10+import com.nctigba.observability.instance.model.InstanceNodeInfo;
11+import com.nctigba.observability.instance.service.ClusterManager;
12+import org.junit.Before;
13+import org.junit.Test;
14+import org.junit.runner.RunWith;
15+import org.mockito.InjectMocks;
16+import org.mockito.Mock;
17+import org.mockito.junit.MockitoJUnitRunner;
18+ 
19+import java.sql.Connection;
20+import java.sql.PreparedStatement;
21+import java.sql.ResultSet;
22+import java.sql.ResultSetMetaData;
23+import java.sql.SQLException;
24+import java.util.List;
25+ 
26+import static org.junit.Assert.assertEquals;
27+import static org.junit.Assert.assertNotNull;
28+import static org.mockito.Matchers.anyString;
29+import static org.mockito.Matchers.eq;
30+import static org.mockito.Mockito.times;
31+import static org.mockito.Mockito.verify;
32+import static org.mockito.Mockito.when;
33+ 
34+/**
35+ * Test
36+ *
37+ * @author liupengfei
38+ * @since 2023/6/30
39+ */
40+@RunWith(MockitoJUnitRunner.class)
41+public class OpenGaussSessionHandlerTest {
42+ @InjectMocks
43+ private OpenGaussSessionHandler sessionHandler;
44+ @Mock
45+ private Connection mockConnection;
46+ @Mock
47+ private PreparedStatement mockPreparedStatement;
48+ @Mock
49+ private ResultSet mockResultSet;
50+ @Mock
51+ private ResultSetMetaData mockResultSetMetaData;
52+ @Mock
53+ private ClusterManager clusterManager;
54+ 
55+ @Before
56+ public void setUp() throws Exception {
57+ when(mockConnection.prepareStatement(anyString())).thenReturn(mockPreparedStatement);
58+ when(mockPreparedStatement.executeQuery()).thenReturn(mockResultSet);
59+ when(mockPreparedStatement.executeQuery()).thenReturn(mockResultSet);
60+ }
61+ 
62+ @Test
63+ public void testDetailGeneral() throws SQLException {
64+ String sessionId = "123";
65+ default1Row3ColumnMockResult();
66+ when(mockResultSet.next()).thenReturn(true, false, true, false, true, false);
67+ JSONObject detailGeneral = sessionHandler.detailGeneral(mockConnection, sessionId);
68+ assertNotNull(detailGeneral);
69+ assertEquals(3, detailGeneral.size());
70+ verify(mockPreparedStatement, times(3)).executeQuery();
71+ }
72+ 
73+ private void default1Row3ColumnMockResult() throws SQLException {
74+ when(mockResultSet.getMetaData()).thenReturn(mockResultSetMetaData);
75+ when(mockResultSetMetaData.getColumnCount()).thenReturn(3);
76+ when(mockResultSetMetaData.getColumnLabel(eq(1))).thenReturn("key1");
77+ when(mockResultSetMetaData.getColumnLabel(eq(2))).thenReturn("key2");
78+ when(mockResultSetMetaData.getColumnLabel(eq(3))).thenReturn("count");
79+ when(mockResultSet.getString(eq(1))).thenReturn("value1");
80+ when(mockResultSet.getString(eq(2))).thenReturn("value2");
81+ when(mockResultSet.getString(eq(3))).thenReturn("3");
82+ }
83+ 
84+ @Test(expected = InstanceException.class)
85+ public void testDetailGeneralException() throws SQLException {
86+ String sessionId = "123";
87+ when(mockPreparedStatement.executeQuery()).thenThrow(new SQLException("Query error"));
88+ sessionHandler.detailGeneral(mockConnection, sessionId);
89+ }
90+ 
91+ @Test
92+ public void testDetailStatistic() throws SQLException {
93+ String sessionId = "123";
94+ when(mockResultSet.next()).thenReturn(true, false, true, false);
95+ when(mockResultSet.getMetaData()).thenReturn(mockResultSetMetaData);
96+ when(mockResultSetMetaData.getColumnCount()).thenReturn(3);
97+ when(mockResultSetMetaData.getColumnLabel(eq(1))).thenReturn("stat_name");
98+ when(mockResultSetMetaData.getColumnLabel(eq(2))).thenReturn("statname");
99+ when(mockResultSetMetaData.getColumnLabel(eq(3))).thenReturn("value");
100+ when(mockResultSet.getString(eq(1))).thenReturn("stat_name_1");
101+ when(mockResultSet.getString(eq(2))).thenReturn("statname_2");
102+ when(mockResultSet.getString(eq(3))).thenReturn("value");
103+ List<DetailStatisticDto> statistic = sessionHandler.detailStatistic(mockConnection, sessionId);
104+ assertNotNull(statistic);
105+ assertEquals(2, statistic.size());
106+ verify(mockPreparedStatement, times(2)).executeQuery();
107+ }
108+ 
109+ @Test
110+ public void testDetailWaiting() throws SQLException {
111+ String sessionId = "123";
112+ default1Row3ColumnMockResult();
113+ when(mockResultSet.next()).thenReturn(true, true, true, false);
114+ List<JSONObject> waiting = sessionHandler.detailWaiting(mockConnection, sessionId);
115+ assertNotNull(waiting);
116+ assertEquals(3, waiting.size());
117+ verify(mockPreparedStatement, times(1)).executeQuery();
118+ }
119+ 
120+ @Test
121+ public void testDetailBlockTree() throws SQLException {
122+ when(mockResultSet.getMetaData()).thenReturn(mockResultSetMetaData);
123+ when(mockResultSetMetaData.getColumnCount()).thenReturn(4);
124+ when(mockResultSetMetaData.getColumnLabel(eq(1))).thenReturn("id");
125+ when(mockResultSetMetaData.getColumnLabel(eq(2))).thenReturn("pathid");
126+ when(mockResultSetMetaData.getColumnLabel(eq(3))).thenReturn("parentid");
127+ when(mockResultSetMetaData.getColumnLabel(eq(4))).thenReturn("tree_id");
128+ when(mockResultSet.getString(eq(1))).thenReturn("1").thenReturn("2").thenReturn("3");
129+ when(mockResultSet.getString(eq(2))).thenReturn("/1").thenReturn("/1/2").thenReturn("/1/2/3");
130+ when(mockResultSet.getString(eq(3))).thenReturn("0").thenReturn("1").thenReturn("2");
131+ when(mockResultSet.getString(eq(4))).thenReturn("1");
132+ when(mockResultSet.next()).thenReturn(true, true, true, false);
133+ String sessionId = "1";
134+ List<JSONObject> blockTree = sessionHandler.detailBlockTree(mockConnection, sessionId);
135+ assertNotNull(blockTree);
136+ assertEquals(1, blockTree.size());
137+ assertEquals("1", blockTree.get(0).get("id"));
138+ verify(mockPreparedStatement, times(1)).executeQuery();
139+ }
140+ 
141+ @Test
142+ public void testSimpleStatistic() throws SQLException {
143+ default1Row3ColumnMockResult();
144+ when(mockResultSet.next()).thenReturn(true, true, true, false);
145+ JSONObject statistic = sessionHandler.simpleStatistic(mockConnection);
146+ assertNotNull(statistic);
147+ assertEquals(3, statistic.size());
148+ verify(mockPreparedStatement, times(1)).executeQuery();
149+ }
150+ 
151+ @Test
152+ public void testLongTxc() throws SQLException {
153+ default1Row3ColumnMockResult();
154+ when(mockResultSet.next()).thenReturn(true, true, true, false);
155+ List<JSONObject> longTxc = sessionHandler.longTxc(mockConnection);
156+ assertNotNull(longTxc);
157+ assertEquals(3, longTxc.get(0).size());
158+ verify(mockPreparedStatement, times(1)).executeQuery();
159+ }
160+ 
161+ @Test
162+ public void testGetConnection() {
163+ InstanceNodeInfo nodeInfo = new InstanceNodeInfo();
164+ nodeInfo.setIp("127.0.0.0");
165+ nodeInfo.setPort(8080);
166+ nodeInfo.setDbName("dbNameTest");
167+ when(clusterManager.getConnectionByNodeInfo(nodeInfo)).thenReturn(mockConnection);
168+ Connection connection = sessionHandler.getConnection(nodeInfo);
169+ assertEquals(mockConnection, connection);
170+ }
171+ 
172+ @Test
173+ public void testClose() throws SQLException {
174+ sessionHandler.close(mockConnection);
175+ verify(mockConnection, times(1)).close();
176+ }
177+}
Aplugins/observability-instance/src/test/java/com/nctigba/observability/instance/service/impl/SessionServiceImplTest.java+192-0
@@ -0,0 +1,192 @@
1+/*
2+ * Copyright (c) GBA-NCTI-ISDC. 2022-2023. All rights reserved.
3+ */
4+ 
5+package com.nctigba.observability.instance.service.impl;
6+ 
7+import com.alibaba.fastjson.JSONObject;
8+import com.nctigba.observability.instance.constants.DatabaseType;
9+import com.nctigba.observability.instance.dto.session.DetailStatisticDto;
10+import com.nctigba.observability.instance.factory.SessionHandlerFactory;
11+import com.nctigba.observability.instance.handler.session.SessionHandler;
12+import com.nctigba.observability.instance.model.InstanceNodeInfo;
13+import com.nctigba.observability.instance.service.ClusterManager;
14+import org.junit.Before;
15+import org.junit.Test;
16+import org.junit.runner.RunWith;
17+import org.mockito.InjectMocks;
18+import org.mockito.Mock;
19+import org.mockito.junit.MockitoJUnitRunner;
20+ 
21+import java.sql.Connection;
22+import java.util.HashMap;
23+import java.util.List;
24+import java.util.Map;
25+ 
26+import static org.junit.jupiter.api.Assertions.assertEquals;
27+import static org.junit.jupiter.api.Assertions.assertNotNull;
28+import static org.mockito.Mockito.times;
29+import static org.mockito.Mockito.verify;
30+import static org.mockito.Mockito.when;
31+ 
32+/**
33+ * Test
34+ *
35+ * @author liupengfei
36+ * @since 2023/6/30
37+ */
38+@RunWith(MockitoJUnitRunner.class)
39+public class SessionServiceImplTest {
40+ @InjectMocks
41+ private SessionServiceImpl sessionService;
42+ @Mock
43+ private SessionHandlerFactory sessionHandlerFactory;
44+ @Mock
45+ private ClusterManager opsFacade;
46+ @Mock
47+ private SessionHandler sessionHandler;
48+ private Connection connection;
49+ private InstanceNodeInfo instanceNodeInfo;
50+ private ClusterManager.OpsClusterNodeVOSub opsClusterNode;
51+ 
52+ @Before
53+ public void setUp() {
54+ instanceNodeInfo = new InstanceNodeInfo();
55+ instanceNodeInfo.setIp("127.0.0.1");
56+ instanceNodeInfo.setPort(5432);
57+ instanceNodeInfo.setDbName("testDb");
58+ instanceNodeInfo.setDbUser("testUser");
59+ instanceNodeInfo.setDbUserPassword("testPassword");
60+ instanceNodeInfo.setDbType(DatabaseType.DEFAULT.getDbType());
61+ opsClusterNode = new ClusterManager.OpsClusterNodeVOSub();
62+ opsClusterNode.setPublicIp("127.0.0.1");
63+ opsClusterNode.setDbPort(5432);
64+ opsClusterNode.setDbName("testDb");
65+ opsClusterNode.setDbUser("testUser");
66+ opsClusterNode.setDbUserPassword("testPassword");
67+ when(opsFacade.getOpsNodeById(getId())).thenReturn(opsClusterNode);
68+ when(sessionHandlerFactory.getInstance(DatabaseType.DEFAULT.getDbType())).thenReturn(sessionHandler);
69+ when(sessionHandler.getConnection(instanceNodeInfo)).thenReturn(connection);
70+ }
71+ 
72+ private static String getId() {
73+ return "12345";
74+ }
75+ 
76+ @Test
77+ public void testDetailGeneral() {
78+ JSONObject expectedResult = new JSONObject();
79+ expectedResult.put("key", "value");
80+ when(sessionHandler.detailGeneral(connection, getId())).thenReturn(expectedResult);
81+ JSONObject result = sessionService.detailGeneral(getId(), getId());
82+ assertEquals(expectedResult, result);
83+ verify(sessionHandlerFactory, times(1)).getInstance(DatabaseType.DEFAULT.getDbType());
84+ verify(sessionHandler, times(1)).getConnection(instanceNodeInfo);
85+ verify(sessionHandler, times(1)).detailGeneral(connection, getId());
86+ verify(sessionHandler, times(1)).close(connection);
87+ }
88+ 
89+ @Test
90+ public void testDetailStatistic() {
91+ // Arrange
92+ List<DetailStatisticDto> expectedResult = List.of(new DetailStatisticDto());
93+ when(sessionHandler.detailStatistic(connection, getId())).thenReturn(expectedResult);
94+ // Act
95+ List<DetailStatisticDto> result = sessionService.detailStatistic(getId(), getId());
96+ // Assert
97+ assertNotNull(result);
98+ assertEquals(expectedResult, result);
99+ verify(sessionHandler, times(1)).detailStatistic(connection, getId());
100+ verify(sessionHandler, times(1)).close(connection);
101+ }
102+ 
103+ @Test
104+ public void testDetailWaiting() {
105+ JSONObject object = new JSONObject();
106+ object.put("key", "value");
107+ List<JSONObject> expectedResult = List.of(object);
108+ when(sessionHandler.detailWaiting(connection, getId())).thenReturn(expectedResult);
109+ List<JSONObject> result = sessionService.detailWaiting(getId(), getId());
110+ assertEquals(expectedResult, result);
111+ verify(sessionHandlerFactory, times(1)).getInstance(DatabaseType.DEFAULT.getDbType());
112+ verify(sessionHandler, times(1)).getConnection(instanceNodeInfo);
113+ verify(sessionHandler, times(1)).detailWaiting(connection, getId());
114+ verify(sessionHandler, times(1)).close(connection);
115+ }
116+ 
117+ @Test
118+ public void testDetailBlockTree() {
119+ JSONObject object = new JSONObject();
120+ object.put("key", "value");
121+ List<JSONObject> expectedResult = List.of(object);
122+ when(sessionHandler.detailBlockTree(connection, getId())).thenReturn(expectedResult);
123+ List<JSONObject> result = sessionService.detailBlockTree(getId(), getId());
124+ assertEquals(expectedResult, result);
125+ verify(sessionHandlerFactory, times(1)).getInstance(DatabaseType.DEFAULT.getDbType());
126+ verify(sessionHandler, times(1)).getConnection(instanceNodeInfo);
127+ verify(sessionHandler, times(1)).detailBlockTree(connection, getId());
128+ verify(sessionHandler, times(1)).close(connection);
129+ }
130+ 
131+ @Test
132+ public void testSimpleStatistic() {
133+ JSONObject expectedResult = new JSONObject();
134+ expectedResult.put("key", "value");
135+ when(sessionHandler.simpleStatistic(connection)).thenReturn(expectedResult);
136+ JSONObject result = sessionService.simpleStatistic(getId());
137+ assertEquals(expectedResult, result);
138+ verify(sessionHandlerFactory, times(1)).getInstance(DatabaseType.DEFAULT.getDbType());
139+ verify(sessionHandler, times(1)).getConnection(instanceNodeInfo);
140+ verify(sessionHandler, times(1)).simpleStatistic(connection);
141+ verify(sessionHandler, times(1)).close(connection);
142+ }
143+ 
144+ @Test
145+ public void testLongTxc() {
146+ JSONObject object = new JSONObject();
147+ object.put("key", "value");
148+ List<JSONObject> expectedResult = List.of(object);
149+ when(sessionHandler.longTxc(connection)).thenReturn(expectedResult);
150+ List<JSONObject> result = sessionService.longTxc(getId());
151+ assertEquals(expectedResult, result);
152+ verify(sessionHandlerFactory, times(1)).getInstance(DatabaseType.DEFAULT.getDbType());
153+ verify(sessionHandler, times(1)).getConnection(instanceNodeInfo);
154+ verify(sessionHandler, times(1)).longTxc(connection);
155+ verify(sessionHandler, times(1)).close(connection);
156+ }
157+ 
158+ @Test
159+ public void testBlockAndLongTxc() {
160+ JSONObject object = new JSONObject();
161+ object.put("key", "value");
162+ List<JSONObject> longTxc = List.of(object);
163+ List<JSONObject> blockTree = List.of(object);
164+ HashMap<String, List<JSONObject>> expectedResult = new HashMap<>();
165+ expectedResult.put("blockTree", blockTree);
166+ expectedResult.put("longTxc", longTxc);
167+ when(sessionHandler.detailBlockTree(connection, null)).thenReturn(blockTree);
168+ when(sessionHandler.longTxc(connection)).thenReturn(longTxc);
169+ HashMap<String, List<JSONObject>> result = sessionService.blockAndLongTxc(getId());
170+ assertEquals(expectedResult, result);
171+ }
172+ 
173+ @Test
174+ public void testDetail() {
175+ JSONObject object = new JSONObject();
176+ object.put("key", "value");
177+ List<JSONObject> blockTree = List.of(object);
178+ List<JSONObject> waiting = List.of(object);
179+ List<DetailStatisticDto> statistic = List.of(new DetailStatisticDto());
180+ HashMap<String, Object> expectedResult = new HashMap<>();
181+ expectedResult.put("blockTree", blockTree);
182+ expectedResult.put("general", object);
183+ expectedResult.put("statistic", statistic);
184+ expectedResult.put("waiting", waiting);
185+ when(sessionHandler.detailWaiting(connection, getId())).thenReturn(waiting);
186+ when(sessionHandler.detailStatistic(connection, getId())).thenReturn(statistic);
187+ when(sessionHandler.detailBlockTree(connection, getId())).thenReturn(blockTree);
188+ when(sessionHandler.detailGeneral(connection, getId())).thenReturn(object);
189+ Map<String, Object> result = sessionService.detail(getId(), getId());
190+ assertEquals(expectedResult, result);
191+ }
192+}