From de33445edb07c52d9229886c03dea0165403e7bf Mon Sep 17 00:00:00 2001 From: Ram Lavi Date: Wed, 19 Jul 2023 12:08:52 +0300 Subject: [PATCH 1/3] trex: Move package to be under checkup package Currently the trex package is only used on the executor package. In preparation of expanding its use to the higher level checkup package, moving trex package to be under it. Signed-off-by: Ram Lavi --- pkg/internal/checkup/executor/executor.go | 2 +- pkg/internal/checkup/{executor => }/trex/types.go | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename pkg/internal/checkup/{executor => }/trex/types.go (100%) diff --git a/pkg/internal/checkup/executor/executor.go b/pkg/internal/checkup/executor/executor.go index 2b20ee9e..5a0bbee8 100644 --- a/pkg/internal/checkup/executor/executor.go +++ b/pkg/internal/checkup/executor/executor.go @@ -29,7 +29,7 @@ import ( "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/checkup/executor/console" "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/checkup/executor/testpmd" - "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/checkup/executor/trex" + "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/checkup/trex" "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/config" "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/status" ) diff --git a/pkg/internal/checkup/executor/trex/types.go b/pkg/internal/checkup/trex/types.go similarity index 100% rename from pkg/internal/checkup/executor/trex/types.go rename to pkg/internal/checkup/trex/types.go From a22a134fa74866f12d093fad3baea6fcf1392f43 Mon Sep 17 00:00:00 2001 From: Ram Lavi Date: Wed, 19 Jul 2023 13:54:22 +0300 Subject: [PATCH 2/3] trex/configfiles: Add trex configurable files The trex application needs some configuration files in order to run [1]. These configuration files iare represented by template files that need to be configured with the checkup's config parameter input. Introducing a new file that contains the config file templates and returns the outputted files for future use in later commits. [1] https://github.com/kiagnose/kubevirt-dpdk-checkup/tree/630d0497b2ba17a91245b93e37719ce50be4ddaa/traffic-gen/templates Signed-off-by: Ram Lavi --- pkg/internal/checkup/trex/configfiles.go | 160 ++++++++++++++++++ pkg/internal/checkup/trex/configfiles_test.go | 135 +++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 pkg/internal/checkup/trex/configfiles.go create mode 100644 pkg/internal/checkup/trex/configfiles_test.go diff --git a/pkg/internal/checkup/trex/configfiles.go b/pkg/internal/checkup/trex/configfiles.go new file mode 100644 index 00000000..f40024e1 --- /dev/null +++ b/pkg/internal/checkup/trex/configfiles.go @@ -0,0 +1,160 @@ +/* + * This file is part of the kiagnose project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2023 Red Hat, Inc. + * + */ + +package trex + +import ( + "fmt" + + "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/config" +) + +const ( + CfgFileName = "trex_cfg.yaml" + StreamPyFileName = "testpmd.py" + StreamPeerParamsPyFileName = "testpmd_addr.py" +) + +type Config struct { + masterCPU string + latencyCPU string + trafficCPUs string + numOfTrafficCPUs string + portBandwidthGB string + trafficGeneratorEastMacAddress string + trafficGeneratorWestMacAddress string + DPDKEastMacAddress string + DPDKWestMacAddress string +} + +func NewConfig(cfg config.Config) Config { + const ( + masterCPU = "0" + latencyCPU = "1" + trafficCPUs = "2,3,4,5,6,7" + numOfTrafficCPUs = "6" + ) + return Config{ + masterCPU: masterCPU, + latencyCPU: latencyCPU, + trafficCPUs: trafficCPUs, + numOfTrafficCPUs: numOfTrafficCPUs, + portBandwidthGB: fmt.Sprintf("%d", cfg.PortBandwidthGB), + trafficGeneratorEastMacAddress: cfg.TrafficGeneratorEastMacAddress.String(), + trafficGeneratorWestMacAddress: cfg.TrafficGeneratorWestMacAddress.String(), + DPDKEastMacAddress: cfg.DPDKEastMacAddress.String(), + DPDKWestMacAddress: cfg.DPDKWestMacAddress.String(), + } +} + +func (t Config) GenerateCfgFile() string { + const cfgTemplate = `- port_limit: 2 + version: 2 + interfaces: + - %q + - %q + port_bandwidth_gb: %s + port_info: + - ip: 10.10.10.2 + default_gw: 10.10.10.1 + - ip: 10.10.20.2 + default_gw: 10.10.20.1 + platform: + master_thread_id: %s + latency_thread_id: %s + dual_if: + - socket: 0 + threads: [%s] +` + return fmt.Sprintf(cfgTemplate, + config.VMIEastNICPCIAddress, + config.VMIWestNICPCIAddress, + t.portBandwidthGB, + t.masterCPU, + t.latencyCPU, + t.trafficCPUs, + ) +} + +func (t Config) GenerateStreamPyFile() string { + const streamPyTemplate = `from trex_stl_lib.api import * + +from testpmd_addr import * + +# Wild local MACs +mac_localport0=%s +mac_localport1=%s + +class STLS1(object): + + def __init__ (self): + self.fsize =64; # the size of the packet + self.number = 0 + + def create_stream (self, direction = 0): + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS + dport = 1026 + self.number + self.number = self.number + 1 + if direction == 0: + base_pkt = Ether(dst=mac_telco0,src=mac_localport0)/IP(src="16.0.0.1",dst=ip_telco0)/UDP(dport=dport,sport=1026) + else: + base_pkt = Ether(dst=mac_telco1,src=mac_localport1)/IP(src="16.1.0.1",dst=ip_telco1)/UDP(dport=dport,sport=1026) + pad = (60 - len(base_pkt)) * 'x' + + return STLStream( + packet = + STLPktBuilder( + pkt = base_pkt / pad + ), + mode = STLTXCont()) + + + def get_streams (self, direction = 0, **kwargs): + # create multiple streams, one stream per core generating traffic... + s = [] + for i in range(%s): + s.append(self.create_stream(direction = direction)) + return s + +# dynamic load - used for trex console or simulator +def register(): + return STLS1() +` + + return fmt.Sprintf(streamPyTemplate, + t.trafficGeneratorEastMacAddress, + t.trafficGeneratorWestMacAddress, + t.numOfTrafficCPUs, + ) +} + +func (t Config) GenerateStreamAddrPyFile() string { + const streamAddrPyTemplate = `# wild first XL710 mac +mac_telco0 = %s +# wild second XL710 mac +mac_telco1 = %s +# we don’t care of the IP in this phase +ip_telco0 = '10.0.0.1' +ip_telco1 = '10.1.1.1' +` + return fmt.Sprintf(streamAddrPyTemplate, + t.DPDKEastMacAddress, + t.DPDKWestMacAddress, + ) +} diff --git a/pkg/internal/checkup/trex/configfiles_test.go b/pkg/internal/checkup/trex/configfiles_test.go new file mode 100644 index 00000000..41f800d7 --- /dev/null +++ b/pkg/internal/checkup/trex/configfiles_test.go @@ -0,0 +1,135 @@ +/* + * This file is part of the kiagnose project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright 2023 Red Hat, Inc. + * + */ + +package trex_test + +import ( + "net" + "testing" + + assert "github.com/stretchr/testify/require" + + "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/checkup/trex" + "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/config" +) + +func TestGetTrexCfgFile(t *testing.T) { + cfgs := createSampleConfigs() + cfgFile := cfgs.GenerateCfgFile() + + const expectedCfgFile = `- port_limit: 2 + version: 2 + interfaces: + - "0000:06:00.0" + - "0000:07:00.0" + port_bandwidth_gb: 40 + port_info: + - ip: 10.10.10.2 + default_gw: 10.10.10.1 + - ip: 10.10.20.2 + default_gw: 10.10.20.1 + platform: + master_thread_id: 0 + latency_thread_id: 1 + dual_if: + - socket: 0 + threads: [2,3,4,5,6,7] +` + assert.Equal(t, expectedCfgFile, cfgFile) +} + +func TestGetTestpmdStreamPyFile(t *testing.T) { + cfgs := createSampleConfigs() + pyFile := cfgs.GenerateStreamPyFile() + + const expectedPyFile = `from trex_stl_lib.api import * + +from testpmd_addr import * + +# Wild local MACs +mac_localport0=00:00:00:00:00:00 +mac_localport1=00:00:00:00:00:01 + +class STLS1(object): + + def __init__ (self): + self.fsize =64; # the size of the packet + self.number = 0 + + def create_stream (self, direction = 0): + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS + dport = 1026 + self.number + self.number = self.number + 1 + if direction == 0: + base_pkt = Ether(dst=mac_telco0,src=mac_localport0)/IP(src="16.0.0.1",dst=ip_telco0)/UDP(dport=dport,sport=1026) + else: + base_pkt = Ether(dst=mac_telco1,src=mac_localport1)/IP(src="16.1.0.1",dst=ip_telco1)/UDP(dport=dport,sport=1026) + pad = (60 - len(base_pkt)) * 'x' + + return STLStream( + packet = + STLPktBuilder( + pkt = base_pkt / pad + ), + mode = STLTXCont()) + + + def get_streams (self, direction = 0, **kwargs): + # create multiple streams, one stream per core generating traffic... + s = [] + for i in range(6): + s.append(self.create_stream(direction = direction)) + return s + +# dynamic load - used for trex console or simulator +def register(): + return STLS1() +` + assert.Equal(t, expectedPyFile, pyFile) +} + +func TestGetTestpmdStreamAddrPyFile(t *testing.T) { + cfgs := createSampleConfigs() + addrPyFile := cfgs.GenerateStreamAddrPyFile() + + const expectedAddrPyFile = `# wild first XL710 mac +mac_telco0 = 00:00:00:00:00:02 +# wild second XL710 mac +mac_telco1 = 00:00:00:00:00:03 +# we don’t care of the IP in this phase +ip_telco0 = '10.0.0.1' +ip_telco1 = '10.1.1.1' +` + assert.Equal(t, expectedAddrPyFile, addrPyFile) +} + +func createSampleConfigs() trex.Config { + trafficGeneratorEastMacAddress, _ := net.ParseMAC("00:00:00:00:00:00") + trafficGeneratorWestMacAddress, _ := net.ParseMAC("00:00:00:00:00:01") + DPDKEastMacAddress, _ := net.ParseMAC("00:00:00:00:00:02") + DPDKWestMacAddress, _ := net.ParseMAC("00:00:00:00:00:03") + cfg := config.Config{ + PortBandwidthGB: 40, + TrafficGeneratorEastMacAddress: trafficGeneratorEastMacAddress, + TrafficGeneratorWestMacAddress: trafficGeneratorWestMacAddress, + DPDKEastMacAddress: DPDKEastMacAddress, + DPDKWestMacAddress: DPDKWestMacAddress, + } + return trex.NewConfig(cfg) +} From b1a2f40cdf554a177e5af27892207b462f887d01 Mon Sep 17 00:00:00 2001 From: Ram Lavi Date: Wed, 19 Jul 2023 13:57:07 +0300 Subject: [PATCH 3/3] checkup, configmap: Add traffic-gen configmap Data Signed-off-by: Ram Lavi --- pkg/internal/checkup/checkup.go | 8 ++++++++ pkg/internal/checkup/configmap/configmap.go | 3 ++- pkg/internal/checkup/configmap/configmap_test.go | 5 +++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pkg/internal/checkup/checkup.go b/pkg/internal/checkup/checkup.go index 1b04b02a..6119b2e6 100644 --- a/pkg/internal/checkup/checkup.go +++ b/pkg/internal/checkup/checkup.go @@ -33,6 +33,7 @@ import ( kvcorev1 "kubevirt.io/api/core/v1" "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/checkup/configmap" + "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/checkup/trex" "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/config" "github.com/kiagnose/kubevirt-dpdk-checkup/pkg/internal/status" ) @@ -290,10 +291,17 @@ func ObjectFullName(namespace, name string) string { } func newTrafficGenConfigMap(name string, checkupConfig config.Config) *k8scorev1.ConfigMap { + trexConfig := trex.NewConfig(checkupConfig) + trafficGenConfigData := map[string]string{ + trex.CfgFileName: trexConfig.GenerateCfgFile(), + trex.StreamPyFileName: trexConfig.GenerateStreamPyFile(), + trex.StreamPeerParamsPyFileName: trexConfig.GenerateStreamAddrPyFile(), + } return configmap.New( name, checkupConfig.PodName, checkupConfig.PodUID, + trafficGenConfigData, ) } diff --git a/pkg/internal/checkup/configmap/configmap.go b/pkg/internal/checkup/configmap/configmap.go index bb4dd871..1075de86 100644 --- a/pkg/internal/checkup/configmap/configmap.go +++ b/pkg/internal/checkup/configmap/configmap.go @@ -26,7 +26,7 @@ import ( "k8s.io/apimachinery/pkg/types" ) -func New(name, ownerName, ownerUID string) *k8scorev1.ConfigMap { +func New(name, ownerName, ownerUID string, data map[string]string) *k8scorev1.ConfigMap { return &k8scorev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -39,5 +39,6 @@ func New(name, ownerName, ownerUID string) *k8scorev1.ConfigMap { }, }, }, + Data: data, } } diff --git a/pkg/internal/checkup/configmap/configmap_test.go b/pkg/internal/checkup/configmap/configmap_test.go index da3a22fc..355dbbbf 100644 --- a/pkg/internal/checkup/configmap/configmap_test.go +++ b/pkg/internal/checkup/configmap/configmap_test.go @@ -36,8 +36,9 @@ func TestNew(t *testing.T) { name := "my-cm" ownerName := "my-pod" ownerUID := "1234567890" + data := map[string]string{"some-key": "some-value"} - actualConfigMap := configmap.New(name, ownerName, ownerUID) + actualConfigMap := configmap.New(name, ownerName, ownerUID, data) expectedConfigMap := &k8scorev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -51,7 +52,7 @@ func TestNew(t *testing.T) { }, }, }, - Data: nil, + Data: map[string]string{"some-key": "some-value"}, } assert.Equal(t, expectedConfigMap, actualConfigMap)