From 9144c130530bf470aaba21927c106141c1e8159e Mon Sep 17 00:00:00 2001 From: Ashraf Fouda Date: Wed, 17 Dec 2025 12:42:43 +0200 Subject: [PATCH] remove iperf Signed-off-by: Ashraf Fouda --- docs/cmds/modules/noded.md | 31 ++-- docs/tasks/README.md | 2 - docs/tasks/iperf.md | 71 -------- pkg/netlight/iperf/iperf.go | 42 ----- pkg/netlight/public/public.go | 4 - pkg/network/iperf/iperf.go | 42 ----- pkg/network/networker.go | 3 +- pkg/network/public/public.go | 4 - pkg/perf/cache_test.go | 1 - pkg/perf/iperf/graphql_wrapper.go | 12 -- pkg/perf/iperf/iperf_task.go | 251 -------------------------- pkg/perf/iperf/iperf_task_test.go | 218 ---------------------- pkg/perf/iperf/iperf_types.go | 134 -------------- pkg/perf/iperf/mock_graphql_client.go | 57 ------ 14 files changed, 16 insertions(+), 856 deletions(-) delete mode 100644 docs/tasks/iperf.md delete mode 100644 pkg/netlight/iperf/iperf.go delete mode 100644 pkg/network/iperf/iperf.go delete mode 100644 pkg/perf/iperf/graphql_wrapper.go delete mode 100644 pkg/perf/iperf/iperf_task.go delete mode 100644 pkg/perf/iperf/iperf_task_test.go delete mode 100644 pkg/perf/iperf/iperf_types.go delete mode 100644 pkg/perf/iperf/mock_graphql_client.go diff --git a/docs/cmds/modules/noded.md b/docs/cmds/modules/noded.md index 7d5d8956..2d5f6853 100644 --- a/docs/cmds/modules/noded.md +++ b/docs/cmds/modules/noded.md @@ -7,18 +7,17 @@ This module is responsible of registering the node on the grid, and handling of - Connects to `Redis` message broker over `zbus` - Prints **Node ID** or **Node network** if their flags were passed - Collects node info: - - Node capacity (CPU, memory, disk) - - Whether the node is booted via `efi` - - `DMI` Info (Desktop Management Interface) - - Name of the hypervisor used on the node - - List of available GPUs, logs GPUs info -- Starts a registrar service and publishes node info + - Node capacity (CPU, memory, disk) + - Whether the node is booted via `efi` + - `DMI` Info (Desktop Management Interface) + - Name of the hypervisor used on the node + - List of available GPUs, logs GPUs info +- Starts a registrar service and publishes node info - Registers the node on the blockchain -- Monitor node performance: - - `NTP` check - - `iperf` (network performance measurement) - - `cpubench` (CPU benchmark) - - `public ip` (validity of public ip) +- Monitor node performance: + - `NTP` check + - `cpubench` (CPU benchmark) + - `public ip` (validity of public ip) - Streams events to the blockchain - Keeps track of environment changes (substrate URLs) @@ -38,8 +37,8 @@ noded --net ### Command-line flags -| Flag | Description | Default | -| ---------- | ----------------------------------------------- | --------------------------- | -| `--broker` | Connection string to the message BROKER | `unix:///var/run/redis.sock`| -| `--id` | print node id and exit | false | -| `--net` | print node network and exit | false | \ No newline at end of file +| Flag | Description | Default | +| ---------- | --------------------------------------- | ---------------------------- | +| `--broker` | Connection string to the message BROKER | `unix:///var/run/redis.sock` | +| `--id` | print node id and exit | false | +| `--net` | print node network and exit | false | diff --git a/docs/tasks/README.md b/docs/tasks/README.md index b24bd732..a38145a6 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -37,7 +37,6 @@ To ensure that the node always has a test result available, a check is performed - `"public-ip-validation"` - `"cpu-benchmark"` - `"healthcheck"` - - `"iperf"` - Return: a single task result. @@ -71,4 +70,3 @@ Notes: - [Public IP validation](./publicips.md) - [CPU benchmark](./cpubench.md) - [Health Check](./healthcheck.md) -- [IPerf](./iperf.md) diff --git a/docs/tasks/iperf.md b/docs/tasks/iperf.md deleted file mode 100644 index 17b3e743..00000000 --- a/docs/tasks/iperf.md +++ /dev/null @@ -1,71 +0,0 @@ -# IPerf - -### Overview - -The `iperf` package is designed to facilitate network performance testing using the `iperf3` tool. with both UDP and TCP over IPv4 and IPv6. - -### Configuration - -- Name: `iperf` -- Schedule: 4 times a day -- Jitter: 20 min - -### Details - -- The package using the iperf binary to examine network performance under different conditions. -- It randomly fetch PublicConfig data for randomly public nodes on the chain + all public node from free farm. These nodes serves as the targets for the iperf tests. -- For each node, it run the test with 4 times. through (UDP/TCP) using both node IPs (v4/v6) -- result will be a slice of all public node report (4 for each) each one will include: - ``` - UploadSpeed: Upload speed (in bits per second). - DownloadSpeed: Download speed (in bits per second). - NodeID: ID of the node where the test was conducted. - NodeIpv4: IPv4 address of the node. - TestType: Type of the test (TCP or UDP). - Error: Any error encountered during the test. - CpuReport: CPU utilization report (in percentage). - ``` - -### Result sample - -```json -{ - "description": "Test public nodes network performance with both UDP and TCP over IPv4 and IPv6", - "name": "iperf", - "result": [ - { - "cpu_report": { - "host_system": 2.4433388913571044, - "host_total": 3.542919199613454, - "host_user": 1.0996094859359695, - "remote_system": 0.24430594945859846, - "remote_total": 0.3854457128784448, - "remote_user": 0.14115962407747246 - }, - "download_speed": 1041274.4792242317, - "error": "", - "node_id": 124, - "node_ip": "88.99.30.200", - "test_type": "tcp", - "upload_speed": 1048549.3668460822 - }, - { - "cpu_report": { - "host_system": 0, - "host_total": 0, - "host_user": 0, - "remote_system": 0, - "remote_total": 0, - "remote_user": 0 - }, - "download_speed": 0, - "error": "unable to connect to server - server may have stopped running or use a different port, firewall issue, etc.: Network unreachable", - "node_id": 124, - "node_ip": "2a01:4f8:10a:710::2", - "test_type": "tcp", - "upload_speed": 0 - } - ], - "timestamp": 1700507035 -} -``` diff --git a/pkg/netlight/iperf/iperf.go b/pkg/netlight/iperf/iperf.go deleted file mode 100644 index da9402f2..00000000 --- a/pkg/netlight/iperf/iperf.go +++ /dev/null @@ -1,42 +0,0 @@ -package iperf - -import ( - "fmt" - "os/exec" - - "github.com/pkg/errors" - "github.com/threefoldtech/zosbase/pkg/zinit" -) - -const ( - zinitService = "iperf" - // IperfPort is the port for the iperf service - IperfPort = 300 -) - -// Ensure creates an iperf zinit service and monitors it -func Ensure(z *zinit.Client) error { - if _, err := z.Status(zinitService); err == nil { - return nil - } - - _, err := exec.LookPath("iperf") - if err != nil { - return err - } - - cmd := fmt.Sprintf("ip netns exec public iperf -s -p %d", IperfPort) - - err = zinit.AddService(zinitService, zinit.InitService{ - Exec: cmd, - After: []string{ - "networkd", - }, - }) - - if err != nil { - return errors.Wrap(err, "failed to add iperf service") - } - - return z.Monitor(zinitService) -} diff --git a/pkg/netlight/public/public.go b/pkg/netlight/public/public.go index 39ef087b..dd09222e 100644 --- a/pkg/netlight/public/public.go +++ b/pkg/netlight/public/public.go @@ -16,7 +16,6 @@ import ( "github.com/threefoldtech/zosbase/pkg/netlight/bootstrap" "github.com/threefoldtech/zosbase/pkg/netlight/bridge" "github.com/threefoldtech/zosbase/pkg/netlight/ifaceutil" - "github.com/threefoldtech/zosbase/pkg/netlight/iperf" "github.com/threefoldtech/zosbase/pkg/netlight/macvlan" "github.com/threefoldtech/zosbase/pkg/netlight/namespace" "github.com/threefoldtech/zosbase/pkg/netlight/options" @@ -380,9 +379,6 @@ func EnsurePublicSetup(nodeID pkg.Identifier, vlan *uint16, inf *pkg.PublicConfi return nil, errors.Wrap(err, "failed to ensure public namespace setup") } - if err := iperf.Ensure(zinit.Default()); err != nil { - return nil, errors.Wrap(err, "failed to ensure iperf service") - } } return br, netlink.LinkSetUp(br) diff --git a/pkg/network/iperf/iperf.go b/pkg/network/iperf/iperf.go deleted file mode 100644 index da9402f2..00000000 --- a/pkg/network/iperf/iperf.go +++ /dev/null @@ -1,42 +0,0 @@ -package iperf - -import ( - "fmt" - "os/exec" - - "github.com/pkg/errors" - "github.com/threefoldtech/zosbase/pkg/zinit" -) - -const ( - zinitService = "iperf" - // IperfPort is the port for the iperf service - IperfPort = 300 -) - -// Ensure creates an iperf zinit service and monitors it -func Ensure(z *zinit.Client) error { - if _, err := z.Status(zinitService); err == nil { - return nil - } - - _, err := exec.LookPath("iperf") - if err != nil { - return err - } - - cmd := fmt.Sprintf("ip netns exec public iperf -s -p %d", IperfPort) - - err = zinit.AddService(zinitService, zinit.InitService{ - Exec: cmd, - After: []string{ - "networkd", - }, - }) - - if err != nil { - return errors.Wrap(err, "failed to add iperf service") - } - - return z.Monitor(zinitService) -} diff --git a/pkg/network/networker.go b/pkg/network/networker.go index d63ef2f8..fdfedc20 100644 --- a/pkg/network/networker.go +++ b/pkg/network/networker.go @@ -24,7 +24,6 @@ import ( "github.com/threefoldtech/zosbase/pkg/gridtypes/zos" "github.com/threefoldtech/zosbase/pkg/netbase/wireguard" "github.com/threefoldtech/zosbase/pkg/network/bootstrap" - "github.com/threefoldtech/zosbase/pkg/network/iperf" "github.com/threefoldtech/zosbase/pkg/network/mycelium" "github.com/threefoldtech/zosbase/pkg/network/ndmz" "github.com/threefoldtech/zosbase/pkg/network/options" @@ -124,7 +123,7 @@ func NewNetworker(identity *stubs.IdentityManagerStub, ndmz ndmz.DMZ, ygg *yggdr // always add the reserved yggdrasil and mycelium ports to the port set so we make sure they are never // picked for wireguard endpoints // we also add http, https, and traefik metrics ports 8082 to the list. - for _, port := range []int{yggdrasil.YggListenTCP, yggdrasil.YggListenTLS, yggdrasil.YggListenLinkLocal, mycelium.MyListenTCP, iperf.IperfPort, 80, 443, 8082} { + for _, port := range []int{yggdrasil.YggListenTCP, yggdrasil.YggListenTLS, yggdrasil.YggListenLinkLocal, mycelium.MyListenTCP, 80, 443, 8082} { if err := nw.portSet.Add(uint(port)); err != nil && errors.Is(err, set.ErrConflict{}) { return nil, err } diff --git a/pkg/network/public/public.go b/pkg/network/public/public.go index f351e0f9..42f43ad7 100644 --- a/pkg/network/public/public.go +++ b/pkg/network/public/public.go @@ -16,7 +16,6 @@ import ( "github.com/threefoldtech/zosbase/pkg/network/bootstrap" "github.com/threefoldtech/zosbase/pkg/network/bridge" "github.com/threefoldtech/zosbase/pkg/network/ifaceutil" - "github.com/threefoldtech/zosbase/pkg/network/iperf" "github.com/threefoldtech/zosbase/pkg/network/macvlan" "github.com/threefoldtech/zosbase/pkg/network/namespace" "github.com/threefoldtech/zosbase/pkg/network/options" @@ -380,9 +379,6 @@ func EnsurePublicSetup(nodeID pkg.Identifier, vlan *uint16, inf *pkg.PublicConfi return nil, errors.Wrap(err, "failed to ensure public namespace setup") } - if err := iperf.Ensure(zinit.Default()); err != nil { - return nil, errors.Wrap(err, "failed to ensure iperf service") - } } return br, netlink.LinkSetUp(br) diff --git a/pkg/perf/cache_test.go b/pkg/perf/cache_test.go index 46e99b96..71c1c3f0 100644 --- a/pkg/perf/cache_test.go +++ b/pkg/perf/cache_test.go @@ -227,7 +227,6 @@ func TestGenerateKey(t *testing.T) { {"cpu-benchmark", "perf.cpu-benchmark"}, {"public-ip-validation", "perf.public-ip-validation"}, {"healthcheck", "perf.healthcheck"}, - {"iperf", "perf.iperf"}, {"", "perf."}, } diff --git a/pkg/perf/iperf/graphql_wrapper.go b/pkg/perf/iperf/graphql_wrapper.go deleted file mode 100644 index f55d8d6f..00000000 --- a/pkg/perf/iperf/graphql_wrapper.go +++ /dev/null @@ -1,12 +0,0 @@ -package iperf - -import ( - "context" - - "github.com/threefoldtech/zosbase/pkg/perf/graphql" -) - -// GraphQLClient interface for mocking GraphQL operations -type GraphQLClient interface { - GetUpNodes(ctx context.Context, nodesNum int, farmID, excludeFarmID uint32, ipv4, ipv6 bool) ([]graphql.Node, error) -} diff --git a/pkg/perf/iperf/iperf_task.go b/pkg/perf/iperf/iperf_task.go deleted file mode 100644 index 06c2e682..00000000 --- a/pkg/perf/iperf/iperf_task.go +++ /dev/null @@ -1,251 +0,0 @@ -package iperf - -import ( - "context" - "encoding/json" - "fmt" - "net" - "os" - "os/exec" - "path/filepath" - "time" - - "github.com/cenkalti/backoff" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" - "github.com/threefoldtech/zosbase/pkg/environment" - "github.com/threefoldtech/zosbase/pkg/network/iperf" - "github.com/threefoldtech/zosbase/pkg/perf" - "github.com/threefoldtech/zosbase/pkg/perf/exec_wrapper" - "github.com/threefoldtech/zosbase/pkg/perf/graphql" -) - -const ( - maxRetries = 3 - initialInterval = 5 * time.Minute - maxInterval = 20 * time.Minute - maxElapsedTime = time.Duration(maxRetries) * maxInterval - iperfTimeout = 30 * time.Second - - errServerBusy = "the server is busy running a test. try again later" -) - -// IperfTest for iperf tcp/udp tests -type IperfTest struct { - // Optional dependencies for testing - graphqlClient GraphQLClient - execWrapper execwrapper.ExecWrapper -} - -// IperfResult for iperf test results -type IperfResult struct { - UploadSpeed float64 `json:"upload_speed"` // in bit/sec - DownloadSpeed float64 `json:"download_speed"` // in bit/sec - NodeID uint32 `json:"node_id"` - NodeIpv4 string `json:"node_ip"` - TestType string `json:"test_type"` - Error string `json:"error"` - CpuReport CPUUtilizationPercent `json:"cpu_report"` -} - -// NewTask creates a new iperf test -func NewTask() perf.Task { - // because go-iperf left tmp directories with perf binary in it each time - // the task had run - matches, _ := filepath.Glob("/tmp/goiperf*") - for _, match := range matches { - os.RemoveAll(match) - } - return &IperfTest{} -} - -// ID returns the ID of the tcp task -func (t *IperfTest) ID() string { - return "iperf" -} - -// Cron returns the schedule for the tcp task -func (t *IperfTest) Cron() string { - return "0 0 */6 * * *" -} - -// Description returns the task description -func (t *IperfTest) Description() string { - return "Test public nodes network performance with both UDP and TCP over IPv4 and IPv6" -} - -// Jitter returns the max number of seconds the job can sleep before actual execution. -func (t *IperfTest) Jitter() uint32 { - return 20 * 60 -} - -// Run runs the tcp test and returns the result -func (t *IperfTest) Run(ctx context.Context) (interface{}, error) { - var g GraphQLClient - var err error - - if t.graphqlClient != nil { - g = t.graphqlClient - } else { - env := environment.MustGet() - graphqlClient, err := graphql.NewGraphQl(env.GraphQL...) - if err != nil { - return nil, err - } - g = &graphqlClient - } - - // get public up nodes - freeFarmNodes, err := g.GetUpNodes(ctx, 0, 1, 0, true, true) - if err != nil { - return nil, errors.Wrap(err, "failed to list freefarm nodes from graphql") - } - - nodes, err := g.GetUpNodes(ctx, 12, 0, 1, true, true) - if err != nil { - return nil, errors.Wrap(err, "failed to list random nodes from graphql") - } - - nodes = append(nodes, freeFarmNodes...) - - if t.execWrapper != nil { - execWrap := t.execWrapper - _, err = execWrap.LookPath("iperf") - if err != nil { - return nil, err - } - } else { - _, err = exec.LookPath("iperf") - if err != nil { - return nil, err - } - } - - var results []IperfResult - for _, node := range nodes { - clientIP, _, err := net.ParseCIDR(node.PublicConfig.Ipv4) - if err != nil { - log.Error().Err(err).Msg("failed to parse ipv4 address") - continue - } - - clientIPv6, _, err := net.ParseCIDR(node.PublicConfig.Ipv6) - if err != nil { - log.Error().Err(err).Msg("failed to parse ipv6 address") - continue - } - - // TCP - res := t.runIperfTest(ctx, clientIP.String(), true) - res.NodeID = node.NodeID - results = append(results, res) - - res = t.runIperfTest(ctx, clientIPv6.String(), true) - res.NodeID = node.NodeID - results = append(results, res) - - // UDP - res = t.runIperfTest(ctx, clientIP.String(), false) - res.NodeID = node.NodeID - results = append(results, res) - - res = t.runIperfTest(ctx, clientIPv6.String(), false) - res.NodeID = node.NodeID - results = append(results, res) - } - - return results, nil -} - -func (t *IperfTest) runIperfTest(ctx context.Context, clientIP string, tcp bool) IperfResult { - opts := make([]string, 0) - opts = append(opts, - "--client", clientIP, - "--port", fmt.Sprint(iperf.IperfPort), - "--interval", "20", - "--bandwidth", "0", // unlimited because udp limit is set to 1M by default - "-R", // doing the test in reverse gives more accurate results - "--json", - ) - - if !tcp { - opts = append(opts, "--length", "16B", "--udp") - } - - var execWrap execwrapper.ExecWrapper = &execwrapper.RealExecWrapper{} - if t.execWrapper != nil { - execWrap = t.execWrapper - } - - var report iperfCommandOutput - operation := func() error { - timeoutCtx, cancel := context.WithTimeout(ctx, iperfTimeout) - defer cancel() - - res := runIperfCommand(timeoutCtx, opts, execWrap) - if res.Error == errServerBusy { - return errors.New(errServerBusy) - } - - report = res - return nil - } - - notify := func(err error, waitTime time.Duration) { - log.Debug().Err(err).Stringer("retry-in", waitTime).Msg("retrying") - } - - bo := backoff.NewExponentialBackOff() - bo.InitialInterval = initialInterval - bo.MaxInterval = maxInterval - bo.MaxElapsedTime = maxElapsedTime - - b := backoff.WithMaxRetries(bo, maxRetries) - err := backoff.RetryNotify(operation, b, notify) - if err != nil { - return IperfResult{} - } - - proto := "tcp" - if !tcp { - proto = "udp" - } - - iperfResult := IperfResult{ - UploadSpeed: report.End.SumSent.BitsPerSecond, - DownloadSpeed: report.End.SumReceived.BitsPerSecond, - CpuReport: report.End.CPUUtilizationPercent, - NodeIpv4: clientIP, - TestType: proto, - Error: report.Error, - } - if !tcp && len(report.End.Streams) > 0 { - iperfResult.DownloadSpeed = report.End.Streams[0].UDP.BitsPerSecond - } - - return iperfResult -} - -func runIperfCommand(ctx context.Context, opts []string, execWrap execwrapper.ExecWrapper) iperfCommandOutput { - output, err := execWrap.CommandContext(ctx, "iperf", opts...).CombinedOutput() - exitErr := &exec.ExitError{} - - if err != nil { - if ctx.Err() == context.DeadlineExceeded { - log.Warn().Msg("iperf command timed out for node with public IP: " + opts[1]) - } - if !errors.As(err, &exitErr) { - log.Err(err).Msg("failed to run iperf") - } - - return iperfCommandOutput{} - } - - var report iperfCommandOutput - if err := json.Unmarshal(output, &report); err != nil { - log.Err(err).Msg("failed to parse iperf output") - return iperfCommandOutput{} - } - - return report -} diff --git a/pkg/perf/iperf/iperf_task_test.go b/pkg/perf/iperf/iperf_task_test.go deleted file mode 100644 index 1c44866e..00000000 --- a/pkg/perf/iperf/iperf_task_test.go +++ /dev/null @@ -1,218 +0,0 @@ -package iperf - -import ( - "context" - "encoding/json" - "errors" - "testing" - - "github.com/stretchr/testify/assert" - execwrapper "github.com/threefoldtech/zosbase/pkg/perf/exec_wrapper" - "github.com/threefoldtech/zosbase/pkg/perf/graphql" - "go.uber.org/mock/gomock" -) - -func TestIperfTest_Run_Success(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - mockGraphQL := NewMockGraphQLClient(ctrl) - mockExec := execwrapper.NewMockExecWrapper(ctrl) - mockCmd := execwrapper.NewMockExecCmd(ctrl) - - task := &IperfTest{ - graphqlClient: mockGraphQL, - execWrapper: mockExec, - } - - testNodes := []graphql.Node{ - { - NodeID: 123, - PublicConfig: graphql.PublicConfig{ - Ipv4: "192.168.1.100/24", - Ipv6: "2001:db8::1/64", - }, - }, - } - - mockGraphQL.EXPECT(). - GetUpNodes(gomock.Any(), 0, uint32(1), uint32(0), true, true). - Return([]graphql.Node{testNodes[0]}, nil) - - mockGraphQL.EXPECT(). - GetUpNodes(gomock.Any(), 12, uint32(0), uint32(1), true, true). - Return([]graphql.Node{}, nil) - - mockExec.EXPECT(). - LookPath("iperf"). - Return("/usr/bin/iperf", nil) - - tcpOutput := createMockIperfOutput(false, 1000000, 2000000) - udpOutput := createMockIperfOutput(true, 500000, 800000) - - tcpOutputBytes, _ := json.Marshal(tcpOutput) - udpOutputBytes, _ := json.Marshal(udpOutput) - - mockExec.EXPECT(). - CommandContext(gomock.Any(), "iperf", gomock.Any()). - Return(mockCmd). - Times(4) - - mockCmd.EXPECT().CombinedOutput().Return(tcpOutputBytes, nil) - mockCmd.EXPECT().CombinedOutput().Return(tcpOutputBytes, nil) - mockCmd.EXPECT().CombinedOutput().Return(udpOutputBytes, nil) - mockCmd.EXPECT().CombinedOutput().Return(udpOutputBytes, nil) - - ctx := context.Background() - result, err := task.Run(ctx) - - assert.NoError(t, err) - assert.NotNil(t, result) - - results, ok := result.([]IperfResult) - assert.True(t, ok) - assert.Len(t, results, 4) - - firstResult := results[0] - assert.Equal(t, uint32(123), firstResult.NodeID) - assert.Equal(t, "192.168.1.100", firstResult.NodeIpv4) - assert.Equal(t, "tcp", firstResult.TestType) - assert.Equal(t, float64(1000000), firstResult.UploadSpeed) - assert.Equal(t, float64(2000000), firstResult.DownloadSpeed) -} - -func TestIperfTest_Run_GraphQLError(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - mockGraphQL := NewMockGraphQLClient(ctrl) - - // Create test task with injected dependencies - task := &IperfTest{ - graphqlClient: mockGraphQL, - } - - // Mock GraphQL error - mockGraphQL.EXPECT(). - GetUpNodes(gomock.Any(), 0, uint32(1), uint32(0), true, true). - Return(nil, errors.New("graphql connection failed")) - - // Execute the test - ctx := context.Background() - result, err := task.Run(ctx) - - // Verify error - assert.Error(t, err) - assert.Nil(t, result) - assert.Contains(t, err.Error(), "failed to list freefarm nodes from graphql") -} - -func TestIperfTest_Run_IperfNotFound(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - mockGraphQL := NewMockGraphQLClient(ctrl) - mockExec := execwrapper.NewMockExecWrapper(ctrl) - - task := &IperfTest{ - graphqlClient: mockGraphQL, - execWrapper: mockExec, - } - - mockGraphQL.EXPECT(). - GetUpNodes(gomock.Any(), 0, uint32(1), uint32(0), true, true). - Return([]graphql.Node{}, nil) - - mockGraphQL.EXPECT(). - GetUpNodes(gomock.Any(), 12, uint32(0), uint32(1), true, true). - Return([]graphql.Node{}, nil) - - mockExec.EXPECT(). - LookPath("iperf"). - Return("", errors.New("executable file not found in $PATH")) - - ctx := context.Background() - result, err := task.Run(ctx) - - assert.Error(t, err) - assert.Nil(t, result) -} - -func TestIperfTest_Run_InvalidIPAddress(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - mockGraphQL := NewMockGraphQLClient(ctrl) - mockExec := execwrapper.NewMockExecWrapper(ctrl) - - task := &IperfTest{ - graphqlClient: mockGraphQL, - execWrapper: mockExec, - } - - testNodes := []graphql.Node{ - { - NodeID: 123, - PublicConfig: graphql.PublicConfig{ - Ipv4: "invalid-ip", - Ipv6: "invalid-ipv6", - }, - }, - } - - mockGraphQL.EXPECT(). - GetUpNodes(gomock.Any(), 0, uint32(1), uint32(0), true, true). - Return(testNodes, nil) - - mockGraphQL.EXPECT(). - GetUpNodes(gomock.Any(), 12, uint32(0), uint32(1), true, true). - Return([]graphql.Node{}, nil) - - mockExec.EXPECT(). - LookPath("iperf"). - Return("/usr/bin/iperf", nil) - - ctx := context.Background() - result, err := task.Run(ctx) - - assert.NoError(t, err) - results, ok := result.([]IperfResult) - assert.True(t, ok) - assert.Len(t, results, 0) -} - -func TestNewTask(t *testing.T) { - task := NewTask() - assert.NotNil(t, task) - assert.Equal(t, "iperf", task.ID()) -} - -// Helper function to create mock iperf output -func createMockIperfOutput(isUDP bool, uploadSpeed, downloadSpeed float64) iperfCommandOutput { - output := iperfCommandOutput{ - End: End{ - SumSent: Sum{ - BitsPerSecond: uploadSpeed, - }, - SumReceived: Sum{ - BitsPerSecond: downloadSpeed, - }, - CPUUtilizationPercent: CPUUtilizationPercent{ - HostTotal: 10.5, - RemoteTotal: 8.2, - }, - }, - } - - if isUDP { - output.End.Streams = []EndStream{ - { - UDP: UDPSum{ - BitsPerSecond: downloadSpeed, - }, - }, - } - } - - return output -} diff --git a/pkg/perf/iperf/iperf_types.go b/pkg/perf/iperf/iperf_types.go deleted file mode 100644 index d79ff361..00000000 --- a/pkg/perf/iperf/iperf_types.go +++ /dev/null @@ -1,134 +0,0 @@ -package iperf - -type iperfCommandOutput struct { - Start Start `json:"start"` - Intervals []Interval `json:"intervals"` - End End `json:"end"` - Error string `json:"error"` -} - -type End struct { - Streams []EndStream `json:"streams"` - SumSent Sum `json:"sum_sent"` - SumReceived Sum `json:"sum_received"` - CPUUtilizationPercent CPUUtilizationPercent `json:"cpu_utilization_percent"` - SenderTCPCongestion string `json:"sender_tcp_congestion"` - ReceiverTCPCongestion string `json:"receiver_tcp_congestion"` -} - -type CPUUtilizationPercent struct { - HostTotal float64 `json:"host_total"` - HostUser float64 `json:"host_user"` - HostSystem float64 `json:"host_system"` - RemoteTotal float64 `json:"remote_total"` - RemoteUser float64 `json:"remote_user"` - RemoteSystem float64 `json:"remote_system"` -} - -type EndStream struct { - Sender Sum `json:"sender"` - Receiver Sum `json:"receiver"` - UDP UDPSum `json:"udp"` -} - -type UDPSum struct { - Socket int64 `json:"socket"` - Start float64 `json:"start"` - End float64 `json:"end"` - Seconds float64 `json:"seconds"` - Bytes int64 `json:"bytes"` - BitsPerSecond float64 `json:"bits_per_second"` - JitterMS float64 `json:"jitter_ms"` - LostPackets int64 `json:"lost_packets"` - Packets int64 `json:"packets"` - LostPercent float64 `json:"lost_percent"` - OutOfOrder int64 `json:"out_of_order"` - Sender bool `json:"sender"` -} - -type Sum struct { - Socket int64 `json:"socket"` - Start float64 `json:"start"` - End float64 `json:"end"` - Seconds float64 `json:"seconds"` - Bytes int64 `json:"bytes"` - BitsPerSecond float64 `json:"bits_per_second"` - Retransmits int64 `json:"retransmits"` - MaxSndCwnd int64 `json:"max_snd_cwnd"` - MaxSndWnd int64 `json:"max_snd_wnd"` - MaxRtt int64 `json:"max_rtt"` - MinRtt int64 `json:"min_rtt"` - MeanRtt int64 `json:"mean_rtt"` - Sender bool `json:"sender"` -} - -type Interval struct { - Streams []IntervalStream `json:"streams"` - Sum Sum `json:"sum"` -} - -type IntervalStream struct { - Socket int64 `json:"socket"` - Start float64 `json:"start"` - End float64 `json:"end"` - Seconds float64 `json:"seconds"` - Bytes int64 `json:"bytes"` - BitsPerSecond float64 `json:"bits_per_second"` - Retransmits int64 `json:"retransmits"` - SndCwnd int64 `json:"snd_cwnd"` - SndWnd int64 `json:"snd_wnd"` - Rtt int64 `json:"rtt"` - Rttvar int64 `json:"rttvar"` - Pmtu int64 `json:"pmtu"` - Omitted bool `json:"omitted"` - Sender bool `json:"sender"` -} - -type Start struct { - Connected []Connected `json:"connected"` - Version string `json:"version"` - SystemInfo string `json:"system_info"` - Timestamp Timestamp `json:"timestamp"` - ConnectingTo ConnectingTo `json:"connecting_to"` - Cookie string `json:"cookie"` - TCPMssDefault int64 `json:"tcp_mss_default"` - TargetBitrate int64 `json:"target_bitrate"` - FqRate int64 `json:"fq_rate"` - SockBufsize int64 `json:"sock_bufsize"` - SndbufActual int64 `json:"sndbuf_actual"` - RcvbufActual int64 `json:"rcvbuf_actual"` - TestStart TestStart `json:"test_start"` -} - -type Connected struct { - Socket int64 `json:"socket"` - LocalHost string `json:"local_host"` - LocalPort int64 `json:"local_port"` - RemoteHost string `json:"remote_host"` - RemotePort int64 `json:"remote_port"` -} - -type ConnectingTo struct { - Host string `json:"host"` - Port int64 `json:"port"` -} - -type TestStart struct { - Protocol string `json:"protocol"` - NumStreams int64 `json:"num_streams"` - Blksize int64 `json:"blksize"` - Omit int64 `json:"omit"` - Duration int64 `json:"duration"` - Bytes int64 `json:"bytes"` - Blocks int64 `json:"blocks"` - Reverse int64 `json:"reverse"` - Tos int64 `json:"tos"` - TargetBitrate int64 `json:"target_bitrate"` - Bidir int64 `json:"bidir"` - Fqrate int64 `json:"fqrate"` -} - -type Timestamp struct { - Time string `json:"time"` - Timesecs int64 `json:"timesecs"` -} diff --git a/pkg/perf/iperf/mock_graphql_client.go b/pkg/perf/iperf/mock_graphql_client.go deleted file mode 100644 index 57a1875a..00000000 --- a/pkg/perf/iperf/mock_graphql_client.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: pkg/perf/iperf/graphql_wrapper.go -// -// Generated by this command: -// -// mockgen -source=pkg/perf/iperf/graphql_wrapper.go -destination=pkg/perf/iperf/mock_graphql_client.go -package=iperf -// - -// Package iperf is a generated GoMock package. -package iperf - -import ( - context "context" - reflect "reflect" - - graphql "github.com/threefoldtech/zosbase/pkg/perf/graphql" - gomock "go.uber.org/mock/gomock" -) - -// MockGraphQLClient is a mock of GraphQLClient interface. -type MockGraphQLClient struct { - ctrl *gomock.Controller - recorder *MockGraphQLClientMockRecorder - isgomock struct{} -} - -// MockGraphQLClientMockRecorder is the mock recorder for MockGraphQLClient. -type MockGraphQLClientMockRecorder struct { - mock *MockGraphQLClient -} - -// NewMockGraphQLClient creates a new mock instance. -func NewMockGraphQLClient(ctrl *gomock.Controller) *MockGraphQLClient { - mock := &MockGraphQLClient{ctrl: ctrl} - mock.recorder = &MockGraphQLClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockGraphQLClient) EXPECT() *MockGraphQLClientMockRecorder { - return m.recorder -} - -// GetUpNodes mocks base method. -func (m *MockGraphQLClient) GetUpNodes(ctx context.Context, nodesNum int, farmID, excludeFarmID uint32, ipv4, ipv6 bool) ([]graphql.Node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUpNodes", ctx, nodesNum, farmID, excludeFarmID, ipv4, ipv6) - ret0, _ := ret[0].([]graphql.Node) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetUpNodes indicates an expected call of GetUpNodes. -func (mr *MockGraphQLClientMockRecorder) GetUpNodes(ctx, nodesNum, farmID, excludeFarmID, ipv4, ipv6 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUpNodes", reflect.TypeOf((*MockGraphQLClient)(nil).GetUpNodes), ctx, nodesNum, farmID, excludeFarmID, ipv4, ipv6) -}