1
+ import { fail } from 'assert' ;
2
+ import { expect } from 'chai' ;
3
+ import * as nock from 'nock' ;
4
+ import { KubeConfig } from './config' ;
5
+ import { V1Status , HttpError , V1Pod } from './gen/api' ;
6
+ import { Metrics , NodeMetricsList , PodMetricsList } from './metrics' ;
7
+ import { topPods } from './top' ;
8
+ import { CoreV1Api , } from './gen/api' ;
9
+
10
+
11
+ const emptyPodMetrics : PodMetricsList = {
12
+ kind : 'PodMetricsList' ,
13
+ apiVersion : 'metrics.k8s.io/v1beta1' ,
14
+ metadata : {
15
+ selfLink : '/apis/metrics.k8s.io/v1beta1/pods' ,
16
+ } ,
17
+ items : [ ] ,
18
+ } ;
19
+
20
+ const mockedPodMetrics : PodMetricsList = {
21
+ kind : 'PodMetricsList' ,
22
+ apiVersion : 'metrics.k8s.io/v1beta1' ,
23
+ metadata : { selfLink : '/apis/metrics.k8s.io/v1beta1/pods/' } ,
24
+ items : [
25
+ {
26
+ metadata : {
27
+ name : 'dice-roller-7c76898b4d-shm9p' ,
28
+ namespace : 'default' ,
29
+ selfLink : '/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/dice-roller-7c76898b4d-shm9p' ,
30
+ creationTimestamp : '2021-09-26T11:57:27Z' ,
31
+ } ,
32
+ timestamp : '2021-09-26T11:57:21Z' ,
33
+ window : '30s' ,
34
+ containers : [ { name : 'nginx' , usage : { cpu : '10' , memory : '3912Ki' } } ] ,
35
+ } ,
36
+ {
37
+ metadata : {
38
+ name : 'other-pod-7c76898b4e-12kj' ,
39
+ namespace : 'default' ,
40
+ selfLink : '/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/other-pod-7c76898b4e-12kj' ,
41
+ creationTimestamp : '2021-09-26T11:57:27Z' ,
42
+ } ,
43
+ timestamp : '2021-09-26T11:57:21Z' ,
44
+ window : '30s' ,
45
+ containers : [
46
+ { name : 'nginx' , usage : { cpu : '15' , memory : '4012Ki' } } ,
47
+ { name : 'sidecar' , usage : { cpu : '16' , memory : '3012Ki' } } ,
48
+ ] ,
49
+ } ,
50
+ ] ,
51
+ } ;
52
+
53
+ const podList : V1Pod [ ] = [
54
+ {
55
+ "metadata" : {
56
+ "name" : "dice-roller-7c76898b4d-shm9p"
57
+ } ,
58
+ 'spec' : {
59
+ containers : [
60
+ {
61
+ name : "nginx" ,
62
+ resources : {
63
+ requests : {
64
+ memory : "100Mi" ,
65
+ cpu : "100m"
66
+ } ,
67
+ limits : {
68
+ memory : "100Mi" ,
69
+ cpu : "100m"
70
+ } ,
71
+ }
72
+ }
73
+ ]
74
+ }
75
+ } ,
76
+ {
77
+ "metadata" : {
78
+ "name" : "other-pod-7c76898b4e-12kj"
79
+ } ,
80
+ 'spec' : {
81
+ containers : [
82
+ {
83
+ name : "nginx" ,
84
+ resources : {
85
+ requests : {
86
+ memory : "100Mi" ,
87
+ cpu : "100m"
88
+ } ,
89
+ limits : {
90
+ memory : "100Mi" ,
91
+ cpu : "100m"
92
+ } ,
93
+ }
94
+ } ,
95
+ {
96
+ name : "sidecar" ,
97
+ resources : {
98
+ requests : {
99
+ memory : "50Mi" ,
100
+ cpu : "1"
101
+ } ,
102
+ limits : {
103
+ memory : "100Mi" ,
104
+ cpu : "1"
105
+ } ,
106
+ }
107
+ }
108
+ ]
109
+ }
110
+ }
111
+ ]
112
+
113
+
114
+ const TEST_NAMESPACE = 'test-namespace' ;
115
+
116
+ const testConfigOptions : any = {
117
+ clusters : [ { name : 'cluster' , server : 'https://127.0.0.1:51010' } ] ,
118
+ users : [ { name : 'user' , password : 'password' } ] ,
119
+ contexts : [ { name : 'currentContext' , cluster : 'cluster' , user : 'user' } ] ,
120
+ currentContext : 'currentContext' ,
121
+ } ;
122
+
123
+ const systemUnderTest = ( namespace ?: string , options : any = testConfigOptions ) : [ ( ) => ReturnType < typeof topPods > , nock . Scope ] => {
124
+ const kc = new KubeConfig ( ) ;
125
+ kc . loadFromOptions ( options ) ;
126
+ const metricsClient = new Metrics ( kc ) ;
127
+ const core = kc . makeApiClient ( CoreV1Api ) ;
128
+ const topPodsFunc = ( ) => topPods ( core , metricsClient , namespace ) ;
129
+
130
+ const scope = nock ( testConfigOptions . clusters [ 0 ] . server ) ;
131
+
132
+ return [ topPodsFunc , scope ] ;
133
+ } ;
134
+
135
+ describe ( 'Top' , ( ) => {
136
+ describe ( 'topPods' , ( ) => {
137
+ it ( 'should return empty when no pods' , async ( ) => {
138
+ const [ topPodsFunc , scope ] = systemUnderTest ( ) ;
139
+ const podMetrics = scope . get ( '/apis/metrics.k8s.io/v1beta1/pods' ) . reply ( 200 , emptyPodMetrics ) ;
140
+ const pods = scope . get ( '/api/v1/pods' ) . reply ( 200 , {
141
+ items : [ ]
142
+ } ) ;
143
+ const result = await topPodsFunc ( ) ;
144
+ expect ( result ) . to . deep . equal ( [ ] ) ;
145
+ podMetrics . done ( ) ;
146
+ pods . done ( ) ;
147
+ } ) ;
148
+ it ( 'should return cluster wide pod metrics' , async ( ) => {
149
+ const [ topPodsFunc , scope ] = systemUnderTest ( ) ;
150
+ const podMetrics = scope . get ( '/apis/metrics.k8s.io/v1beta1/pods' ) . reply ( 200 , mockedPodMetrics ) ;
151
+ const pods = scope . get ( '/api/v1/pods' ) . reply ( 200 , {
152
+ items : podList
153
+ } ) ;
154
+ const result = await topPodsFunc ( ) ;
155
+ expect ( result . length ) . to . equal ( 2 ) ;
156
+ expect ( result [ 0 ] . CPU ) . to . deep . equal ( {
157
+ // TODO fix this
158
+ "CurrentUsage" : 10 ,
159
+ "LimitTotal" : 0.1 ,
160
+ "RequestTotal" : 0.1
161
+ } ) ;
162
+ expect ( result [ 0 ] . Memory ) . to . deep . equal ( {
163
+ "CurrentUsage" : BigInt ( "4005888" ) ,
164
+ "RequestTotal" : BigInt ( "104857600" ) ,
165
+ "LimitTotal" : BigInt ( "104857600" ) ,
166
+ } ) ;
167
+ expect ( result [ 0 ] . Containers ) . to . deep . equal ( [
168
+ {
169
+ "CPUUsage" : 10 ,
170
+ "Container" : "nginx" ,
171
+ "Memory" : BigInt ( "4005888" )
172
+ }
173
+ ] ) ;
174
+ expect ( result [ 1 ] . CPU ) . to . deep . equal ( {
175
+ // TODO fix this
176
+ "CurrentUsage" : 31 ,
177
+ "LimitTotal" : 1.1 ,
178
+ "RequestTotal" : 1.1
179
+ } ) ;
180
+ expect ( result [ 1 ] . Memory ) . to . deep . equal ( {
181
+ "CurrentUsage" : BigInt ( "7192576" ) ,
182
+ "LimitTotal" : BigInt ( "209715200" ) ,
183
+ "RequestTotal" : BigInt ( "157286400" )
184
+ } ) ;
185
+ expect ( result [ 1 ] . Containers ) . to . deep . equal ( [
186
+ {
187
+ "CPUUsage" : 15 ,
188
+ "Container" : "nginx" ,
189
+ "Memory" : BigInt ( "4108288" ) ,
190
+ } ,
191
+ {
192
+ "CPUUsage" : 16 ,
193
+ "Container" : "sidecar" ,
194
+ "Memory" : BigInt ( "3084288" ) ,
195
+ }
196
+ ] ) ;
197
+ podMetrics . done ( ) ;
198
+ pods . done ( ) ;
199
+ } ) ;
200
+ it ( 'should return namespace pod metrics' , async ( ) => {
201
+ const [ topPodsFunc , scope ] = systemUnderTest ( TEST_NAMESPACE ) ;
202
+ const podMetrics = scope . get ( `/apis/metrics.k8s.io/v1beta1/namespaces/${ TEST_NAMESPACE } /pods` ) . reply ( 200 , mockedPodMetrics ) ;
203
+ const pods = scope . get ( `/api/v1/namespaces/${ TEST_NAMESPACE } /pods` ) . reply ( 200 , {
204
+ items : podList
205
+ } ) ;
206
+ const result = await topPodsFunc ( ) ;
207
+ expect ( result . length ) . to . equal ( 2 ) ;
208
+ expect ( result [ 0 ] . CPU ) . to . deep . equal ( {
209
+ "CurrentUsage" : 10 ,
210
+ "LimitTotal" : 0.1 ,
211
+ "RequestTotal" : 0.1
212
+ } ) ;
213
+ expect ( result [ 0 ] . Memory ) . to . deep . equal ( {
214
+ "CurrentUsage" : BigInt ( "4005888" ) ,
215
+ "RequestTotal" : BigInt ( "104857600" ) ,
216
+ "LimitTotal" : BigInt ( "104857600" ) ,
217
+ } ) ;
218
+ expect ( result [ 0 ] . Containers ) . to . deep . equal ( [
219
+ {
220
+ "CPUUsage" : 10 ,
221
+ "Container" : "nginx" ,
222
+ "Memory" : BigInt ( "4005888" )
223
+ }
224
+ ] ) ;
225
+ expect ( result [ 1 ] . CPU ) . to . deep . equal ( {
226
+ "CurrentUsage" : 31 ,
227
+ "LimitTotal" : 1.1 ,
228
+ "RequestTotal" : 1.1
229
+ } ) ;
230
+ expect ( result [ 1 ] . Memory ) . to . deep . equal ( {
231
+ "CurrentUsage" : BigInt ( "7192576" ) ,
232
+ "LimitTotal" : BigInt ( "209715200" ) ,
233
+ "RequestTotal" : BigInt ( "157286400" )
234
+ } ) ;
235
+ expect ( result [ 1 ] . Containers ) . to . deep . equal ( [
236
+ {
237
+ "CPUUsage" : 15 ,
238
+ "Container" : "nginx" ,
239
+ "Memory" : BigInt ( "4108288" ) ,
240
+ } ,
241
+ {
242
+ "CPUUsage" : 16 ,
243
+ "Container" : "sidecar" ,
244
+ "Memory" : BigInt ( "3084288" ) ,
245
+ }
246
+ ] ) ;
247
+ podMetrics . done ( ) ;
248
+ pods . done ( ) ;
249
+ } ) ;
250
+ } ) ;
251
+ } ) ;
0 commit comments