DatabaseInfrastructureSection.utils.test.ts 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import { describe, expect, it } from 'vitest'
  2. import {
  3. parseConnectionsData,
  4. parseInfrastructureMetrics,
  5. parseNumericValue,
  6. } from './DatabaseInfrastructureSection.utils'
  7. import type {
  8. InfraMonitoringMultiResponse,
  9. InfraMonitoringSingleResponse,
  10. } from '@/data/analytics/infra-monitoring-query'
  11. describe('parseNumericValue', () => {
  12. it('returns number value as-is', () => {
  13. expect(parseNumericValue(42)).toBe(42)
  14. expect(parseNumericValue(0)).toBe(0)
  15. expect(parseNumericValue(3.14)).toBe(3.14)
  16. })
  17. it('parses valid string numbers', () => {
  18. expect(parseNumericValue('42')).toBe(42)
  19. expect(parseNumericValue('3.14')).toBe(3.14)
  20. expect(parseNumericValue('0')).toBe(0)
  21. })
  22. it('returns 0 for invalid string values', () => {
  23. expect(parseNumericValue('invalid')).toBe(0)
  24. expect(parseNumericValue('')).toBe(0)
  25. expect(parseNumericValue('NaN')).toBe(0)
  26. })
  27. it('returns 0 for undefined', () => {
  28. expect(parseNumericValue(undefined)).toBe(0)
  29. })
  30. })
  31. describe('parseInfrastructureMetrics', () => {
  32. it('returns null for undefined data', () => {
  33. expect(parseInfrastructureMetrics(undefined)).toBe(null)
  34. })
  35. it('parses valid metrics from response', () => {
  36. const mockResponse: InfraMonitoringMultiResponse = {
  37. data: [],
  38. series: {
  39. avg_cpu_usage: { format: 'percent', total: 150, totalAverage: 50, yAxisLimit: 100 },
  40. ram_usage: { format: 'bytes', total: 180, totalAverage: 60, yAxisLimit: 100 },
  41. disk_fs_used_system: {
  42. format: 'bytes',
  43. total: 20,
  44. totalAverage: 20,
  45. yAxisLimit: 100,
  46. },
  47. disk_fs_used_wal: {
  48. format: 'bytes',
  49. total: 10,
  50. totalAverage: 10,
  51. yAxisLimit: 100,
  52. },
  53. pg_database_size: {
  54. format: 'bytes',
  55. total: 30,
  56. totalAverage: 30,
  57. yAxisLimit: 100,
  58. },
  59. disk_fs_size: {
  60. format: 'bytes',
  61. total: 200,
  62. totalAverage: 200,
  63. yAxisLimit: 100,
  64. },
  65. disk_io_consumption: {
  66. format: 'percent',
  67. total: 210,
  68. totalAverage: 70,
  69. yAxisLimit: 100,
  70. },
  71. },
  72. }
  73. const result = parseInfrastructureMetrics(mockResponse)
  74. expect(result).toEqual({
  75. cpu: { current: 50, max: 100 },
  76. ram: { current: 60, max: 100 },
  77. disk: { current: 30, max: 100 },
  78. diskIo: { current: 70, max: 100 },
  79. })
  80. })
  81. it('handles string values in metrics', () => {
  82. const mockResponse: InfraMonitoringMultiResponse = {
  83. data: [],
  84. series: {
  85. avg_cpu_usage: { format: 'percent', total: 150, totalAverage: '50.5', yAxisLimit: 100 },
  86. ram_usage: { format: 'bytes', total: 180, totalAverage: '60.8', yAxisLimit: 100 },
  87. disk_fs_used_system: {
  88. format: 'bytes',
  89. total: 20,
  90. totalAverage: '20.4',
  91. yAxisLimit: 100,
  92. },
  93. disk_fs_used_wal: {
  94. format: 'bytes',
  95. total: 10,
  96. totalAverage: '10.2',
  97. yAxisLimit: 100,
  98. },
  99. pg_database_size: {
  100. format: 'bytes',
  101. total: 30,
  102. totalAverage: '30.5',
  103. yAxisLimit: 100,
  104. },
  105. disk_fs_size: {
  106. format: 'bytes',
  107. total: 200,
  108. totalAverage: '200.0',
  109. yAxisLimit: 100,
  110. },
  111. disk_io_consumption: {
  112. format: 'percent',
  113. total: 210,
  114. totalAverage: '70.2',
  115. yAxisLimit: 100,
  116. },
  117. },
  118. }
  119. const result = parseInfrastructureMetrics(mockResponse)
  120. expect(result).toEqual({
  121. cpu: { current: 50.5, max: 100 },
  122. ram: { current: 60.8, max: 100 },
  123. disk: { current: 30.55, max: 100 },
  124. diskIo: { current: 70.2, max: 100 },
  125. })
  126. })
  127. it('returns 0 for missing metrics', () => {
  128. const mockResponse: InfraMonitoringMultiResponse = {
  129. data: [],
  130. series: {},
  131. }
  132. const result = parseInfrastructureMetrics(mockResponse)
  133. expect(result).toEqual({
  134. cpu: { current: 0, max: 100 },
  135. ram: { current: 0, max: 100 },
  136. disk: { current: 0, max: 100 },
  137. diskIo: { current: 0, max: 100 },
  138. })
  139. })
  140. it('handles partial metrics data', () => {
  141. const mockResponse: InfraMonitoringMultiResponse = {
  142. data: [],
  143. series: {
  144. avg_cpu_usage: { format: 'percent', total: 150, totalAverage: 50, yAxisLimit: 100 },
  145. },
  146. }
  147. const result = parseInfrastructureMetrics(mockResponse)
  148. expect(result).toEqual({
  149. cpu: { current: 50, max: 100 },
  150. ram: { current: 0, max: 100 },
  151. disk: { current: 0, max: 100 },
  152. diskIo: { current: 0, max: 100 },
  153. })
  154. })
  155. it('handles single-response format (legacy)', () => {
  156. const mockResponse: InfraMonitoringSingleResponse = {
  157. data: [],
  158. format: 'percent',
  159. total: 150,
  160. totalAverage: 50,
  161. yAxisLimit: 100,
  162. }
  163. const result = parseInfrastructureMetrics(mockResponse)
  164. expect(result).toEqual({
  165. cpu: { current: 0, max: 100 },
  166. ram: { current: 0, max: 100 },
  167. disk: { current: 0, max: 100 },
  168. diskIo: { current: 0, max: 100 },
  169. })
  170. })
  171. })
  172. describe('parseConnectionsData', () => {
  173. it('returns zeros when data is undefined', () => {
  174. expect(parseConnectionsData(undefined, undefined)).toEqual({ current: 0, max: 0 })
  175. expect(parseConnectionsData(undefined, { maxConnections: 100 })).toEqual({
  176. current: 0,
  177. max: 0,
  178. })
  179. })
  180. it('parses connections data correctly', () => {
  181. const mockInfraData: InfraMonitoringMultiResponse = {
  182. data: [],
  183. series: {
  184. pg_stat_database_num_backends: {
  185. format: 'number',
  186. total: 150,
  187. totalAverage: 25.5,
  188. yAxisLimit: 100,
  189. },
  190. },
  191. }
  192. const mockMaxData = { maxConnections: 100 }
  193. const result = parseConnectionsData(mockInfraData, mockMaxData)
  194. expect(result).toEqual({ current: 26, max: 100 }) // 25.5 rounded to 26
  195. })
  196. it('handles string values for connections', () => {
  197. const mockInfraData: InfraMonitoringMultiResponse = {
  198. data: [],
  199. series: {
  200. pg_stat_database_num_backends: {
  201. format: 'number',
  202. total: 150,
  203. totalAverage: '30.7',
  204. yAxisLimit: 100,
  205. },
  206. },
  207. }
  208. const mockMaxData = { maxConnections: 100 }
  209. const result = parseConnectionsData(mockInfraData, mockMaxData)
  210. expect(result).toEqual({ current: 31, max: 100 }) // 30.7 rounded to 31
  211. })
  212. it('returns current connections even when maxConnectionsData is undefined', () => {
  213. const mockInfraData: InfraMonitoringMultiResponse = {
  214. data: [],
  215. series: {
  216. pg_stat_database_num_backends: {
  217. format: 'number',
  218. total: 150,
  219. totalAverage: 25,
  220. yAxisLimit: 100,
  221. },
  222. },
  223. }
  224. const result = parseConnectionsData(mockInfraData, undefined)
  225. expect(result).toEqual({ current: 25, max: 0 })
  226. })
  227. it('returns 0 max when maxConnections is missing from data object', () => {
  228. const mockInfraData: InfraMonitoringMultiResponse = {
  229. data: [],
  230. series: {
  231. pg_stat_database_num_backends: {
  232. format: 'number',
  233. total: 150,
  234. totalAverage: 25,
  235. yAxisLimit: 100,
  236. },
  237. },
  238. }
  239. const mockMaxData = {}
  240. const result = parseConnectionsData(mockInfraData, mockMaxData)
  241. expect(result).toEqual({ current: 25, max: 0 })
  242. })
  243. it('returns 0 current when connections metric is missing', () => {
  244. const mockInfraData: InfraMonitoringMultiResponse = {
  245. data: [],
  246. series: {},
  247. }
  248. const mockMaxData = { maxConnections: 100 }
  249. const result = parseConnectionsData(mockInfraData, mockMaxData)
  250. expect(result).toEqual({ current: 0, max: 100 })
  251. })
  252. it('handles single-response format (legacy)', () => {
  253. const mockInfraData: InfraMonitoringSingleResponse = {
  254. data: [],
  255. format: 'number',
  256. total: 150,
  257. totalAverage: 25,
  258. yAxisLimit: 100,
  259. }
  260. const mockMaxData = { maxConnections: 100 }
  261. const result = parseConnectionsData(mockInfraData, mockMaxData)
  262. expect(result).toEqual({ current: 0, max: 100 })
  263. })
  264. })