@@ -65,52 +65,52 @@ func TestNewAggregator_Valid(t *testing.T) {
65
65
{
66
66
name : "Default SplitAB" ,
67
67
outputField : api.OutputField {Name : "MyAgg" , Operation : "sum" },
68
- expected : & aSum {aggregateBase {"MyAgg" , "MyAgg" , false , float64 (0 ), nil }},
68
+ expected : & aSum {aggregateBase {"MyAgg" , "MyAgg" , false , float64 (0 ), nil , false }},
69
69
},
70
70
{
71
71
name : "Default input" ,
72
72
outputField : api.OutputField {Name : "MyAgg" , Operation : "sum" , SplitAB : true },
73
- expected : & aSum {aggregateBase {"MyAgg" , "MyAgg" , true , float64 (0 ), nil }},
73
+ expected : & aSum {aggregateBase {"MyAgg" , "MyAgg" , true , float64 (0 ), nil , false }},
74
74
},
75
75
{
76
76
name : "Custom input" ,
77
77
outputField : api.OutputField {Name : "MyAgg" , Operation : "sum" , Input : "MyInput" },
78
- expected : & aSum {aggregateBase {"MyInput" , "MyAgg" , false , float64 (0 ), nil }},
78
+ expected : & aSum {aggregateBase {"MyInput" , "MyAgg" , false , float64 (0 ), nil , false }},
79
79
},
80
80
{
81
- name : "OperationType sum" ,
82
- outputField : api.OutputField {Name : "MyAgg" , Operation : "sum" },
83
- expected : & aSum {aggregateBase {"MyAgg" , "MyAgg" , false , float64 (0 ), nil }},
81
+ name : "OperationType sum with errors " ,
82
+ outputField : api.OutputField {Name : "MyAgg" , Operation : "sum" , ReportMissing : true },
83
+ expected : & aSum {aggregateBase {"MyAgg" , "MyAgg" , false , float64 (0 ), nil , true }},
84
84
},
85
85
{
86
- name : "OperationType count" ,
87
- outputField : api.OutputField {Name : "MyAgg" , Operation : "count" },
88
- expected : & aCount {aggregateBase {"MyAgg" , "MyAgg" , false , float64 (0 ), nil }},
86
+ name : "OperationType count with errors " ,
87
+ outputField : api.OutputField {Name : "MyAgg" , Operation : "count" , ReportMissing : true },
88
+ expected : & aCount {aggregateBase {"MyAgg" , "MyAgg" , false , float64 (0 ), nil , true }},
89
89
},
90
90
{
91
91
name : "OperationType max" ,
92
92
outputField : api.OutputField {Name : "MyAgg" , Operation : "max" },
93
- expected : & aMax {aggregateBase {"MyAgg" , "MyAgg" , false , - math .MaxFloat64 , nil }},
93
+ expected : & aMax {aggregateBase {"MyAgg" , "MyAgg" , false , - math .MaxFloat64 , nil , false }},
94
94
},
95
95
{
96
96
name : "OperationType min" ,
97
97
outputField : api.OutputField {Name : "MyAgg" , Operation : "min" },
98
- expected : & aMin {aggregateBase {"MyAgg" , "MyAgg" , false , math .MaxFloat64 , nil }},
98
+ expected : & aMin {aggregateBase {"MyAgg" , "MyAgg" , false , math .MaxFloat64 , nil , false }},
99
99
},
100
100
{
101
101
name : "Default first" ,
102
102
outputField : api.OutputField {Name : "MyCp" , Operation : "first" },
103
- expected : & aFirst {aggregateBase {"MyCp" , "MyCp" , false , nil , nil }},
103
+ expected : & aFirst {aggregateBase {"MyCp" , "MyCp" , false , nil , nil , false }},
104
104
},
105
105
{
106
106
name : "Custom input first" ,
107
107
outputField : api.OutputField {Name : "MyCp" , Operation : "first" , Input : "MyInput" },
108
- expected : & aFirst {aggregateBase {"MyInput" , "MyCp" , false , nil , nil }},
108
+ expected : & aFirst {aggregateBase {"MyInput" , "MyCp" , false , nil , nil , false }},
109
109
},
110
110
{
111
111
name : "Default last" ,
112
112
outputField : api.OutputField {Name : "MyCp" , Operation : "last" },
113
- expected : & aLast {aggregateBase {"MyCp" , "MyCp" , false , nil , nil }},
113
+ expected : & aLast {aggregateBase {"MyCp" , "MyCp" , false , nil , nil , false }},
114
114
},
115
115
}
116
116
@@ -132,6 +132,7 @@ func TestAddField_and_Update(t *testing.T) {
132
132
{Name : "maxFlowLogBytes" , Operation : "max" , Input : "Bytes" },
133
133
{Name : "FirstFlowDirection" , Operation : "first" , Input : "FlowDirection" },
134
134
{Name : "LastFlowDirection" , Operation : "last" , Input : "FlowDirection" },
135
+ {Name : "PktDropLatestDropCause" , Operation : "last" , Input : "PktDropLatestDropCause" },
135
136
}
136
137
var aggs []aggregator
137
138
for _ , of := range ofs {
@@ -158,21 +159,67 @@ func TestAddField_and_Update(t *testing.T) {
158
159
name : "flowLog 1" ,
159
160
flowLog : newMockFlowLog (ipA , portA , ipB , portB , protocolA , flowDirA , 100 , 10 , false ),
160
161
direction : dirAB ,
161
- expected : map [string ]interface {}{"Bytes_AB" : float64 (100 ), "Bytes_BA" : float64 (0 ), "Packets" : float64 (10 ), "maxFlowLogBytes" : float64 (100 ), "minFlowLogBytes" : float64 (100 ), "numFlowLogs" : float64 (1 ), "FirstFlowDirection" : 0 , "LastFlowDirection" : 0 },
162
+ expected : map [string ]interface {}{
163
+ "Bytes_AB" : float64 (100 ),
164
+ "Bytes_BA" : float64 (0 ),
165
+ "Packets" : float64 (10 ),
166
+ "maxFlowLogBytes" : float64 (100 ),
167
+ "minFlowLogBytes" : float64 (100 ),
168
+ "numFlowLogs" : float64 (1 ),
169
+ "FirstFlowDirection" : 0 ,
170
+ "LastFlowDirection" : 0 ,
171
+ "PktDropLatestDropCause" : nil ,
172
+ },
162
173
},
163
174
{
164
175
name : "flowLog 2" ,
165
- flowLog : newMockFlowLog (ipA , portA , ipB , portB , protocolA , flowDirB , 200 , 20 , false ),
176
+ flowLog : config.GenericMap {"SrcAddr" : ipA , "DstAddr" : ipB , "Bytes" : 100 , "FlowDirection" : flowDirA , "PktDropLatestDropCause" : "SKB_DROP_REASON_NO_SOCKET" },
177
+ direction : dirAB ,
178
+ expected : map [string ]interface {}{
179
+ "Bytes_AB" : float64 (200 ), // updated bytes count
180
+ "Bytes_BA" : float64 (0 ),
181
+ "Packets" : float64 (10 ),
182
+ "maxFlowLogBytes" : float64 (100 ),
183
+ "minFlowLogBytes" : float64 (100 ),
184
+ "numFlowLogs" : float64 (2 ), // updated flow count
185
+ "FirstFlowDirection" : 0 ,
186
+ "LastFlowDirection" : 0 ,
187
+ "PktDropLatestDropCause" : "SKB_DROP_REASON_NO_SOCKET" , // added drop cause
188
+ },
189
+ },
190
+ {
191
+ name : "flowLog 3" ,
192
+ flowLog : newMockFlowLog (ipA , portA , ipB , portB , protocolA , flowDirB , 300 , 20 , false ),
166
193
direction : dirBA ,
167
- expected : map [string ]interface {}{"Bytes_AB" : float64 (100 ), "Bytes_BA" : float64 (200 ), "Packets" : float64 (30 ), "maxFlowLogBytes" : float64 (200 ), "minFlowLogBytes" : float64 (100 ), "numFlowLogs" : float64 (2 ), "FirstFlowDirection" : 0 , "LastFlowDirection" : 1 },
194
+ expected : map [string ]interface {}{
195
+ "Bytes_AB" : float64 (200 ),
196
+ "Bytes_BA" : float64 (300 ), // updated reverse direction byte count
197
+ "Packets" : float64 (30 ),
198
+ "maxFlowLogBytes" : float64 (300 ), // updated max bytes from any direction
199
+ "minFlowLogBytes" : float64 (100 ),
200
+ "numFlowLogs" : float64 (3 ), // updated count
201
+ "FirstFlowDirection" : 0 ,
202
+ "LastFlowDirection" : 1 ,
203
+ "PktDropLatestDropCause" : "SKB_DROP_REASON_NO_SOCKET" , // missing field is kept to its last available value
204
+ },
168
205
},
169
206
}
170
207
171
208
conn := NewConnBuilder (nil ).Build ()
172
209
for _ , agg := range aggs {
173
210
agg .addField (conn )
174
211
}
175
- expectedInits := map [string ]interface {}{"Bytes_AB" : float64 (0 ), "Bytes_BA" : float64 (0 ), "Packets" : float64 (0 ), "maxFlowLogBytes" : float64 (- math .MaxFloat64 ), "minFlowLogBytes" : float64 (math .MaxFloat64 ), "numFlowLogs" : float64 (0 ), "FirstFlowDirection" : nil , "LastFlowDirection" : nil }
212
+ expectedInits := map [string ]interface {}{
213
+ "Bytes_AB" : float64 (0 ),
214
+ "Bytes_BA" : float64 (0 ),
215
+ "Packets" : float64 (0 ),
216
+ "maxFlowLogBytes" : float64 (- math .MaxFloat64 ),
217
+ "minFlowLogBytes" : float64 (math .MaxFloat64 ),
218
+ "numFlowLogs" : float64 (0 ),
219
+ "FirstFlowDirection" : nil ,
220
+ "LastFlowDirection" : nil ,
221
+ "PktDropLatestDropCause" : nil ,
222
+ }
176
223
require .Equal (t , expectedInits , conn .(* connType ).aggFields )
177
224
178
225
for i , test := range table {
@@ -188,7 +235,7 @@ func TestAddField_and_Update(t *testing.T) {
188
235
func TestMissingFieldError (t * testing.T ) {
189
236
test .ResetPromRegistry ()
190
237
metrics := newMetrics (opMetrics )
191
- agg , err := newAggregator (api.OutputField {Name : "Bytes" , Operation : "sum" , SplitAB : true }, metrics )
238
+ agg , err := newAggregator (api.OutputField {Name : "Bytes" , Operation : "sum" , SplitAB : true , ReportMissing : true }, metrics )
192
239
require .NoError (t , err )
193
240
194
241
conn := NewConnBuilder (metrics ).Build ()
@@ -201,6 +248,22 @@ func TestMissingFieldError(t *testing.T) {
201
248
require .Contains (t , exposed , `conntrack_aggregator_errors{error="MissingFieldError",field="Bytes"} 1` )
202
249
}
203
250
251
+ func TestSkipMissingFieldError (t * testing.T ) {
252
+ test .ResetPromRegistry ()
253
+ metrics := newMetrics (opMetrics )
254
+ agg , err := newAggregator (api.OutputField {Name : "Bytes" , Operation : "sum" , SplitAB : true }, metrics )
255
+ require .NoError (t , err )
256
+
257
+ conn := NewConnBuilder (metrics ).Build ()
258
+ agg .addField (conn )
259
+
260
+ flowLog := config.GenericMap {}
261
+ agg .update (conn , flowLog , dirAB , true )
262
+
263
+ exposed := test .ReadExposedMetrics (t )
264
+ require .NotContains (t , exposed , `conntrack_aggregator_errors{error="MissingFieldError",field="Bytes"}` )
265
+ }
266
+
204
267
func TestFloat64ConversionError (t * testing.T ) {
205
268
test .ResetPromRegistry ()
206
269
metrics := newMetrics (opMetrics )
0 commit comments