blob: 03b72b3901b2921655d622d26578f8ace8ee75cb [file] [log] [blame]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package cellular
import (
"context"
"fmt"
"time"
"github.com/golang/protobuf/ptypes/empty"
"go.chromium.org/tast-tests/cros/common/perf"
cbiperf "go.chromium.org/tast-tests/cros/remote/cellular/callbox/iperf"
"go.chromium.org/tast-tests/cros/remote/cellular/callbox/manager"
"go.chromium.org/tast-tests/cros/remote/network/iperf"
"go.chromium.org/tast/core/testing"
)
type iperfTestCaseConfiguration1 struct {
testType cbiperf.TestType
additionalOptions []iperf.ConfigOption
}
type iperfTestCase1 struct {
iperfConfigurations []iperfTestCaseConfiguration1
}
func init() {
testing.AddTest(&testing.Test{
Func: IperfRx,
LacrosStatus: testing.LacrosVariantUnneeded,
Desc: "Conducts cellular performance tests between DUT and callbox using Iperf to compare actual throughput results with expected for a given network configuration",
Contacts: []string{"chromeos-cellular-team@google.com", "srikanthkumar@google.com"},
BugComponent: "b:167157", // ChromeOS > Platform > Connectivity > Cellular
Attr: []string{"group:cellular", "cellular_callbox", "cellular_cmw_callbox"},
ServiceDeps: []string{"tast.cros.cellular.RemoteCellularService"},
SoftwareDeps: []string{"chrome"},
Fixture: "callboxManagedFixture",
Timeout: 15 * time.Minute,
Params: []testing.Param{
{
// Establishes a LTE connection with the callbox and runs multiple tcp iperf sessions with TCPRx configuration for downlink.
Name: "tcp",
Val: iperfTestCase1{iperfConfigurations: []iperfTestCaseConfiguration1{{testType: cbiperf.TestTypeTCPRx}}},
}, {
// Establishes a LTE connection with the callbox and runs multiple tcp iperf sessions with UDPRx configuration for downlink.
Name: "udp",
Val: iperfTestCase1{iperfConfigurations: []iperfTestCaseConfiguration1{{testType: cbiperf.TestTypeUDPRx}}},
},
},
})
}
func IperfRx(ctx context.Context, s *testing.State) {
tc := s.Param().(iperfTestCase1)
tf := s.FixtValue().(*manager.TestFixture)
dutConn := s.DUT().Conn()
// Get Modem type to apply throughput values accordingly.
resp, err := tf.RemoteCellularClient.QueryModemType(ctx, &empty.Empty{})
if err != nil {
s.Fatal("Failed to get modemType: ", err)
}
s.Log("modemType is :", resp.ModemType)
max := manager.GetMaxLTERxThroughputInMbps(ctx, resp.ModemType)
// Run twice with two types of CA modes if modem supports!.
config := manager.GetCellConfiguration(ctx, manager.CallboxHardwareCMW, resp.ModemType)
if err := tf.ConnectToCallbox(ctx, dutConn, config); err != nil {
s.Fatal("Failed to initialize cellular connection: ", err)
}
testManager := cbiperf.NewTestManager(tf.Vars.Callbox, dutConn, tf.CallboxManagerClient)
additionalOptions := []iperf.ConfigOption{iperf.TestTimeOption(20 * time.Second), iperf.MaxBandwidthOption(iperf.BitRate(max) * iperf.Mbps), iperf.ClientWindowSizeOption(1.4 * iperf.MB), iperf.ServerWindowSizeOption(1.4 * iperf.MB)}
// Test is Rx/Download so DUT is server and callbox is client.
perfValues := perf.NewValues()
for _, config := range tc.iperfConfigurations {
subTest := func(ctx context.Context, s *testing.State) {
history, err := testManager.RunOnce(ctx, config.testType, tf.InterfaceName, additionalOptions)
if err != nil {
s.Fatal("Failed to run iperf session: ", err)
}
result, err := iperf.NewResultFromHistory(*history)
if err != nil {
s.Fatal("Failed to calculate iperf result statistics: ", err)
}
perfValues.Set(perf.Metric{
Name: string(config.testType),
Unit: "Mbps",
Direction: perf.BiggerIsBetter,
}, float64(result.Throughput/iperf.Mbps))
min, target, err := testManager.CalculateExpectedThroughput(ctx, config.testType)
if err != nil {
s.Fatal("Failed to calculate expected throughput: ", err)
}
if result.Throughput < min {
s.Fatalf("Throughput below required, got: %v want: %v Mbit/s", result.Throughput/iperf.Mbps, min/iperf.Mbps)
}
if result.Throughput < target {
s.Logf("WARNING: Throughput below target, got: %v want: %v Mbit/s", result.Throughput/iperf.Mbps, target/iperf.Mbps)
}
s.Logf("Finished Iperf test %v, minimum: %v target: %v actual: %v +/- %v Mbit/s",
config.testType, min/iperf.Mbps, target/iperf.Mbps, result.Throughput/iperf.Mbps, result.StdDeviation/iperf.Mbps)
}
s.Run(ctx, fmt.Sprintf("Testcase %s", config.testType), subTest)
}
if err := perfValues.Save(s.OutDir()); err != nil {
s.Fatal("Failed to save perf data: ", err)
}
}