11import { describe , expect , test } from 'bun:test' ;
2+ import { sleep } from 'bun' ;
23import {
34 incrementError ,
45 incrementSuccess ,
56 startPrometheusServer ,
67 stopPrometheusServer ,
8+ trackClickHouseOperation ,
9+ trackRpcRequest ,
710} from './prometheus' ;
811
912describe ( 'Prometheus Server' , ( ) => {
@@ -12,8 +15,7 @@ describe('Prometheus Server', () => {
1215
1316 await startPrometheusServer ( port ) ;
1417
15- // Wait for server to start
16- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
18+ await sleep ( 100 ) ;
1719
1820 // Verify the Prometheus metrics endpoint is accessible
1921 const response = await fetch ( `http://localhost:${ port } /metrics` ) ;
@@ -26,7 +28,7 @@ describe('Prometheus Server', () => {
2628 await stopPrometheusServer ( ) ;
2729
2830 // Wait for server to close
29- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
31+ await sleep ( 100 ) ;
3032
3133 // Verify server is closed
3234 try {
@@ -50,8 +52,7 @@ describe('Prometheus Server', () => {
5052
5153 await startPrometheusServer ( port ) ;
5254
53- // Wait for server to start
54- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
55+ await sleep ( 100 ) ;
5556
5657 // Fetch metrics
5758 const response = await fetch ( `http://localhost:${ port } /metrics` ) ;
@@ -65,9 +66,9 @@ describe('Prometheus Server', () => {
6566 expect ( metricsText ) . toContain ( 'scraper_config_info' ) ;
6667
6768 // Verify config info has labels
68- expect ( metricsText ) . toContain ( 'clickhouse_url ' ) ;
69+ expect ( metricsText ) . toContain ( 'clickhouse_host ' ) ;
6970 expect ( metricsText ) . toContain ( 'clickhouse_database' ) ;
70- expect ( metricsText ) . toContain ( 'node_url ' ) ;
71+ expect ( metricsText ) . toContain ( 'node_host ' ) ;
7172
7273 await stopPrometheusServer ( ) ;
7374 } ) ;
@@ -78,8 +79,7 @@ describe('Prometheus Server', () => {
7879
7980 await startPrometheusServer ( port ) ;
8081
81- // Wait for server to start
82- await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) ) ;
82+ await sleep ( 100 ) ;
8383
8484 // Set metrics
8585 incrementSuccess ( serviceName ) ;
@@ -93,6 +93,9 @@ describe('Prometheus Server', () => {
9393 expect ( metricsText ) . toContain ( serviceName ) ;
9494
9595 await stopPrometheusServer ( ) ;
96+
97+ // Wait for server to fully close
98+ await sleep ( 100 ) ;
9699 } ) ;
97100
98101 test ( 'should handle starting server on already used port' , async ( ) => {
@@ -108,6 +111,9 @@ describe('Prometheus Server', () => {
108111 expect ( response . ok ) . toBe ( true ) ;
109112
110113 await stopPrometheusServer ( ) ;
114+
115+ // Wait for server to fully close
116+ await sleep ( 100 ) ;
111117 } ) ;
112118
113119 test ( 'should reject when port is already used by external process' , async ( ) => {
@@ -130,3 +136,69 @@ describe('Prometheus Server', () => {
130136 }
131137 } ) ;
132138} ) ;
139+
140+ describe ( 'Prometheus Histogram Helpers' , ( ) => {
141+ test ( 'should track ClickHouse operations with correct labels' , async ( ) => {
142+ const port = 19006 ;
143+
144+ await startPrometheusServer ( port ) ;
145+
146+ await sleep ( 100 ) ;
147+
148+ // Track some ClickHouse operations
149+ const startTime = performance . now ( ) ;
150+ trackClickHouseOperation ( 'read' , 'success' , startTime ) ;
151+ trackClickHouseOperation ( 'write' , 'success' , startTime ) ;
152+ trackClickHouseOperation ( 'read' , 'error' , startTime ) ;
153+
154+ // Fetch metrics
155+ const response = await fetch ( `http://localhost:${ port } /metrics` ) ;
156+ const metricsText = await response . text ( ) ;
157+
158+ // Verify histogram metric is present with correct name
159+ expect ( metricsText ) . toContain ( 'scraper_clickhouse_operations_seconds' ) ;
160+
161+ // Verify labels are present
162+ expect ( metricsText ) . toContain ( 'operation_type="read"' ) ;
163+ expect ( metricsText ) . toContain ( 'operation_type="write"' ) ;
164+ expect ( metricsText ) . toContain ( 'status="success"' ) ;
165+ expect ( metricsText ) . toContain ( 'status="error"' ) ;
166+
167+ await stopPrometheusServer ( ) ;
168+
169+ // Wait for server to fully close
170+ await sleep ( 100 ) ;
171+ } ) ;
172+
173+ test ( 'should track RPC requests with correct labels' , async ( ) => {
174+ const port = 19007 ;
175+
176+ await startPrometheusServer ( port ) ;
177+
178+ await sleep ( 100 ) ;
179+
180+ // Track some RPC requests
181+ const startTime = performance . now ( ) ;
182+ trackRpcRequest ( 'eth_call' , 'success' , startTime ) ;
183+ trackRpcRequest ( 'eth_getBalance' , 'success' , startTime ) ;
184+ trackRpcRequest ( 'eth_call' , 'error' , startTime ) ;
185+
186+ // Fetch metrics
187+ const response = await fetch ( `http://localhost:${ port } /metrics` ) ;
188+ const metricsText = await response . text ( ) ;
189+
190+ // Verify histogram metric is present with correct name
191+ expect ( metricsText ) . toContain ( 'scraper_rpc_requests_seconds' ) ;
192+
193+ // Verify labels are present
194+ expect ( metricsText ) . toContain ( 'method="eth_call"' ) ;
195+ expect ( metricsText ) . toContain ( 'method="eth_getBalance"' ) ;
196+ expect ( metricsText ) . toContain ( 'status="success"' ) ;
197+ expect ( metricsText ) . toContain ( 'status="error"' ) ;
198+
199+ await stopPrometheusServer ( ) ;
200+
201+ // Wait for server to fully close
202+ await sleep ( 100 ) ;
203+ } ) ;
204+ } ) ;
0 commit comments