Skip to content

Commit 0ecbcf0

Browse files
committed
additionnal cypress tests for featured columns
1 parent c0b9ab5 commit 0ecbcf0

File tree

5 files changed

+131
-11
lines changed

5 files changed

+131
-11
lines changed

config/sample-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ frontend:
4848
# - pktDrop
4949
# - dnsTracking
5050
# - flowRTT
51+
# - networkEvents
5152
# processor features
5253
# - multiCluster
5354
# - zones

mocks/loki/flow_records.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"result": [
66
{
77
"stream": {
8+
"K8S_ClusterName": "test-cluster",
89
"FlowDirection": "1",
910
"K8S_FlowLayer": "infra",
1011
"SrcK8S_OwnerName": "ip-10-0-1-7.ec2.internal",
@@ -40,6 +41,8 @@
4041
},
4142
{
4243
"stream": {
44+
"SrcK8S_Zone": "eu-west-1",
45+
"DstK8S_Zone": "us-east-2",
4346
"FlowDirection": "1",
4447
"K8S_FlowLayer": "infra",
4548
"SrcK8S_Namespace": "openshift-service-ca-operator",
@@ -65,7 +68,7 @@
6568
"values": [
6669
[
6770
"1708011867120999936",
68-
"{\"TimeFlowRttNs\":7114000,\"DstPort\":50104,\"TimeFlowStartMs\":1708011867121,\"Proto\":1,\"AgentIP\":\"10.0.1.7\",\"Etype\":2048,\"Bytes\":226,\"DstK8S_Name\":\"ip-10-0-1-7.ec2.internal\",\"DstAddr\":\"10.0.1.7\",\"DstK8S_HostName\":\"ip-10-0-1-7.ec2.internal\",\"DstK8S_OwnerType\":\"Node\",\"SrcAddr\":\"10.0.1.140\",\"Packets\":1,\"TimeFlowEndMs\":1708011867121,\"DstK8S_HostIP\":\"10.0.1.7\",\"Duplicate\":true,\"TimeReceived\":1708011867,\"SrcPort\":443,\"Flags\":16,\"IfDirection\":0,\"DnsErrno\":0,\"SrcMac\":\"02:7B:32:68:BE:65\",\"Interface\":\"br-ex\",\"Dscp\":0,\"DstMac\":\"02:27:A1:A8:84:B9\",\"IcmpType\":3,\"IcmpCode\":0}"
71+
"{\"TimeFlowRttNs\":7114000,\"DstPort\":50104,\"TimeFlowStartMs\":1708011867121,\"Proto\":1,\"AgentIP\":\"10.0.1.7\",\"Etype\":2048,\"Bytes\":226,\"DstK8S_Name\":\"ip-10-0-1-7.ec2.internal\",\"DstAddr\":\"10.0.1.7\",\"DstK8S_HostName\":\"ip-10-0-1-7.ec2.internal\",\"DstK8S_OwnerType\":\"Node\",\"SrcAddr\":\"10.0.1.140\",\"Packets\":1,\"TimeFlowEndMs\":1708011867121,\"DstK8S_HostIP\":\"10.0.1.7\",\"Duplicate\":true,\"TimeReceived\":1708011867,\"SrcPort\":443,\"Flags\":16,\"IfDirection\":0,\"DnsErrno\":0,\"SrcMac\":\"02:7B:32:68:BE:65\",\"Interface\":\"br-ex\",\"Dscp\":0,\"DstMac\":\"02:27:A1:A8:84:B9\",\"IcmpType\":3,\"IcmpCode\":0,\"NetworkEvents\":[{\"Feature\":\"acl\",\"Type\":\"NetpolNode\",\"Action\":\"allow\",\"Direction\":\"Ingress\"}]}"
6972
],
7073
[
7174
"1708011867120999936",
@@ -521,4 +524,4 @@
521524
}
522525
}
523526
}
524-
}
527+
}

pkg/handler/lokiclientmock/loki_client_mock.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package lokiclientmock
22

33
import (
4+
"encoding/json"
45
"os"
56
"strings"
67

8+
"github.com/netobserv/network-observability-console-plugin/pkg/decoders"
9+
"github.com/netobserv/network-observability-console-plugin/pkg/model"
710
"github.com/sirupsen/logrus"
811
)
912

@@ -14,6 +17,7 @@ type LokiClientMock struct {
1417

1518
func (o *LokiClientMock) Get(url string) ([]byte, int, error) {
1619
var path string
20+
parseNetEvents := false
1721
mlog.Debugf("Get url: %s", url)
1822

1923
isLabel := strings.Contains(url, "/label/")
@@ -58,6 +62,7 @@ func (o *LokiClientMock) Get(url string) ([]byte, int, error) {
5862
path += "_sent.json"
5963
} else {
6064
path += ".json"
65+
parseNetEvents = true
6166
}
6267
}
6368
}
@@ -68,5 +73,22 @@ func (o *LokiClientMock) Get(url string) ([]byte, int, error) {
6873
return nil, 500, err
6974
}
7075

76+
if parseNetEvents {
77+
var qr model.QueryResponse
78+
err = json.Unmarshal(file, &qr)
79+
if err != nil {
80+
return nil, 500, err
81+
}
82+
for _, s := range qr.Data.Result.(model.Streams) {
83+
for i := range s.Entries {
84+
s.Entries[i].Line = decoders.NetworkEventsToString(s.Entries[i].Line)
85+
}
86+
}
87+
file, err = json.Marshal(qr)
88+
if err != nil {
89+
return nil, 500, err
90+
}
91+
}
92+
7193
return []byte(file), 200, nil
7294
}

web/cypress/e2e/table/fields.spec.ts

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,77 @@
22
import r from './../../../../mocks/loki/flow_records.json';
33

44
describe('netflow-table', () => {
5+
const updatedData = r;
6+
updatedData.data.result.forEach(r => {
7+
r.values.forEach(v => {
8+
if(v[1].includes("NetworkEvents")){
9+
// need to inject network events manually since this is done on backend side. See NetworkEventsToString func
10+
// eslint-disable-next-line max-len
11+
v[1] = "{\"TimeFlowRttNs\":7114000,\"DstPort\":50104,\"TimeFlowStartMs\":1708011867121,\"Proto\":1,\"AgentIP\":\"10.0.1.7\",\"Etype\":2048,\"Bytes\":226,\"DstK8S_Name\":\"ip-10-0-1-7.ec2.internal\",\"DstAddr\":\"10.0.1.7\",\"DstK8S_HostName\":\"ip-10-0-1-7.ec2.internal\",\"DstK8S_OwnerType\":\"Node\",\"SrcAddr\":\"10.0.1.140\",\"Packets\":1,\"TimeFlowEndMs\":1708011867121,\"DstK8S_HostIP\":\"10.0.1.7\",\"Duplicate\":true,\"TimeReceived\":1708011867,\"SrcPort\":443,\"Flags\":16,\"IfDirection\":0,\"DnsErrno\":0,\"SrcMac\":\"02:7B:32:68:BE:65\",\"Interface\":\"br-ex\",\"Dscp\":0,\"DstMac\":\"02:27:A1:A8:84:B9\",\"IcmpType\":3,\"IcmpCode\":0,\"NetworkEvents\":[\"Allowed by default allow from local node policy, direction Ingress\"]}";
12+
}
13+
});
14+
});
15+
516
beforeEach(() => {
617
// this test bench only work with mocks
718
cy.intercept('GET', '/api/loki/flow/records?*', {
819
statusCode: 200,
920
body: r.data,
1021
});
22+
cy.intercept('/api/frontend-config', (req) => {
23+
req.continue((res) => {
24+
switch (Cypress.currentTest.title) {
25+
case 'display pktDrop':
26+
res.body.features = ['pktDrop'];
27+
break;
28+
case 'display dnsTracking':
29+
res.body.features = ['dnsTracking'];
30+
break;
31+
case 'display flowRTT':
32+
res.body.features = ['flowRTT'];
33+
break;
34+
case 'display multiCluster':
35+
res.body.features = ['multiCluster'];
36+
break;
37+
case 'display zones':
38+
res.body.features = ['zones'];
39+
break;
40+
case 'display networkEvents':
41+
res.body.features = ['networkEvents'];
42+
break;
43+
default:
44+
// disable all features by default
45+
res.body.featutes = [];
46+
break;
47+
}
48+
});
49+
});
1150
cy.openNetflowTrafficPage(true);
1251

13-
//move to table view
52+
// move to table view
1453
cy.get('.tableTabButton').click();
15-
//clear default app filters
54+
// clear default app filters
1655
cy.get('#clear-all-filters-button').click();
1756
});
1857

19-
it('display content correctly', () => {
58+
it('display standard content', () => {
2059
// select first row
21-
cy.get('#netflow-table-row-0').click()
22-
// check for side panel content
60+
cy.get('#netflow-table-row-0').click();
2361

24-
// Dates
62+
// check for side panel content
63+
// dates
2564
//cy.checkRecordField('StartTime', 'Start Time', ['Feb 15, 2024', '4:44:27.121 PM']);
2665
//cy.checkRecordField('EndTime', 'End Time', ['Feb 15, 2024', '4:44:27.121 PM']);
2766

28-
// Source accordion
67+
// source accordion
2968
cy.get('[data-test-id="group-2"]').contains("Source");
3069
cy.checkRecordField('SrcK8S_Name', 'Name', ['N', 'ip-10-0-1-7.ec2.internal']);
3170
cy.checkRecordField('SrcK8S_Type', 'Kind', ['Node']);
3271
cy.checkRecordField('SrcAddr', 'IP', ['10.0.1.7']);
3372
cy.checkRecordField('SrcPort', 'Port', ['50104']);
3473
cy.checkRecordField('SrcMac', 'MAC', ['02:27:A1:A8:84:B9']);
3574

36-
// Destination accordion
75+
// destination accordion
3776
cy.get('[data-test-id="group-3"]').contains("Destination");
3877
cy.checkRecordField('DstAddr', 'IP', ['10.0.1.140']);
3978
cy.checkRecordField('DstPort', 'Port', ['https', '443']);
@@ -56,4 +95,59 @@ describe('netflow-table', () => {
5695
cy.checkRecordField('Bytes', 'Bytes', ['66 bytes sent']);
5796
cy.checkRecordField('Packets', 'Packets', ['1 packets sent']);
5897
});
98+
99+
it('display pktDrop', () => {
100+
// select third row
101+
cy.get('#netflow-table-row-2').click();
102+
103+
// check for drop bytes and packets
104+
cy.checkRecordField('Bytes', 'Bytes', ['32 bytes dropped']);
105+
cy.checkRecordField('Packets', 'Packets', ['1 packets dropped', 'SKB_DROP_REASON_TCP_INVALID_SEQUENCE']);
106+
});
107+
108+
it('display dnsTracking', () => {
109+
// select 19th row
110+
cy.get('#netflow-table-row-19').click();
111+
112+
// check for id, latency and errors
113+
cy.checkRecordField('DNSId', 'Id', ['48706']);
114+
cy.checkRecordField('DNSLatency', 'Latency', ['< 1ms']);
115+
cy.checkRecordField('DNSResponseCode', 'Response Code', ['No Error']);
116+
cy.checkRecordField('DNSErrNo', 'Error', ['0']);
117+
});
118+
119+
it('display flowRTT', () => {
120+
// select second row
121+
cy.get('#netflow-table-row-2').click();
122+
123+
// check for rtt
124+
cy.checkRecordField('TimeFlowRttMs', 'Flow RTT', ['4.05ms']);
125+
});
126+
127+
it('display multiCluster', () => {
128+
// select 9th row
129+
cy.get('#netflow-table-row-9').click();
130+
131+
// check for cluster name
132+
cy.checkRecordField('ClusterName', 'Cluster', ['test-cluster']);
133+
});
134+
135+
it('display zones', () => {
136+
// select second row
137+
cy.get('#netflow-table-row-2').click();
138+
139+
// check for source zone
140+
cy.checkRecordField('SrcZone', 'Zone', ['eu-west-1']);
141+
142+
// check for destination zone
143+
cy.checkRecordField('DstZone', 'Zone', ['us-east-2']);
144+
});
145+
146+
it('display networkEvents', () => {
147+
// select third row
148+
cy.get('#netflow-table-row-3').click();
149+
150+
// check for source zone
151+
cy.checkRecordField('NetworkEvents', 'Network Events', ['Allowed by default allow from local node policy, direction Ingress']);
152+
});
59153
})

web/src/components/__tests-data__/flows.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import flowsJson from '../../../../mocks/loki/flow_records.json';
22
import { FlowDirection, Record } from '../../api/ipfix';
33
import { parseStream, RecordsResult, StreamResult } from '../../api/loki';
44

5-
export const FlowsMock: Record[] = (flowsJson.data.result as StreamResult[]).flatMap(r => parseStream(r));
5+
export const FlowsMock: Record[] = flowsJson.data.result.flatMap(r => parseStream(r as unknown as StreamResult));
66

77
export const FlowsResultMock: RecordsResult = {
88
records: FlowsMock,

0 commit comments

Comments
 (0)