blob: 0d3f5d5b91e096634f37fa99e247ccd29aacfae8 [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package health
import (
"context"
"chromiumos/tast/errors"
"chromiumos/tast/local/croshealthd"
"chromiumos/tast/local/jsontypes"
"chromiumos/tast/testing"
"chromiumos/tast/testing/hwdep"
)
type temperatureChannelInfo struct {
Label *string `json:"label"`
TemperatureCelsius int32 `json:"temperature_celsius"`
}
type cStateInfo struct {
Name string `json:"name"`
TimeInStateSinceLastBootUs jsontypes.Uint64 `json:"time_in_state_since_last_boot_us"`
}
type logicalCPUInfo struct {
UserTimeUserHz jsontypes.Uint64 `json:"user_time_user_hz"`
SystemTimeUserHz jsontypes.Uint64 `json:"system_time_user_hz"`
MaxClockSpeedKhz jsontypes.Uint32 `json:"max_clock_speed_khz"`
ScalingMaxFrequencyKhz jsontypes.Uint32 `json:"scaling_max_frequency_khz"`
ScalingCurrentFrequencyKhz jsontypes.Uint32 `json:"scaling_current_frequency_khz"`
IdleTimeUserHz jsontypes.Uint64 `json:"idle_time_user_hz"`
CStates []cStateInfo `json:"c_states"`
}
type physicalCPUInfo struct {
ModelName *string `json:"model_name"`
LogicalCPUs []logicalCPUInfo `json:"logical_cpus"`
}
type keylockerinfo struct {
KeylockerConfigured bool `json:"keylocker_configured"`
}
type cpuInfo struct {
Architecture string `json:"architecture"`
NumTotalThreads jsontypes.Uint32 `json:"num_total_threads"`
TemperatureChannels []temperatureChannelInfo `json:"temperature_channels"`
PhysicalCPUs []physicalCPUInfo `json:"physical_cpus"`
KeylockerInfo keylockerinfo `json:"keylocker_info"`
}
func init() {
testing.AddTest(&testing.Test{
Func: ProbeCPUInfo,
Desc: "Check that we can probe cros_healthd for CPU info",
Contacts: []string{
"khegde@google.com",
"pmoy@google.com",
"cros-tdm-tpe-eng@google.com",
"pathan.jilani@intel.com",
"intel-chrome-system-automation-team@intel.com",
},
Attr: []string{"group:mainline"},
SoftwareDeps: []string{"chrome", "diagnostics"},
Fixture: "crosHealthdRunning",
Params: []testing.Param{{
Val: false,
}, {
Name: "keylocker",
Val: true,
ExtraHardwareDeps: hwdep.D(hwdep.Model("brya")),
}},
})
}
func verifyPhysicalCPU(physicalCPU physicalCPUInfo) error {
if len(physicalCPU.LogicalCPUs) < 1 {
return errors.Errorf("invalid LogicalCPUs, got %d; want 1+", len(physicalCPU.LogicalCPUs))
}
for _, logicalCPU := range physicalCPU.LogicalCPUs {
if err := verifyLogicalCPU(logicalCPU); err != nil {
return errors.Wrap(err, "failed to verify logical CPU")
}
}
return nil
}
func verifyLogicalCPU(logicalCPU logicalCPUInfo) error {
for _, cState := range logicalCPU.CStates {
if err := verifyCState(cState); err != nil {
return errors.Wrap(err, "failed to verify c_state")
}
}
return nil
}
func verifyCState(cState cStateInfo) error {
if cState.Name == "" {
return errors.New("empty name")
}
return nil
}
func validateCPUData(info cpuInfo) error {
// Every board should have at least one physical CPU
if len(info.PhysicalCPUs) < 1 {
return errors.Errorf("invalid PhysicalCPUs, got %d; want 1+", len(info.PhysicalCPUs))
}
if info.NumTotalThreads <= 0 {
return errors.Errorf("invalid NumTotalThreads, got %d; want 1+", info.NumTotalThreads)
}
if info.Architecture == "" {
return errors.New("empty architecture")
}
for _, physicalCPU := range info.PhysicalCPUs {
if err := verifyPhysicalCPU(physicalCPU); err != nil {
return errors.Wrap(err, "failed to verify physical CPU")
}
}
return nil
}
func validateKeyLocker(keylocker keylockerinfo) error {
if !keylocker.KeylockerConfigured {
return errors.Errorf("failed to configure keylocker: %t", keylocker)
}
return nil
}
func ProbeCPUInfo(ctx context.Context, s *testing.State) {
params := croshealthd.TelemParams{Category: croshealthd.TelemCategoryCPU}
var info cpuInfo
if err := croshealthd.RunAndParseJSONTelem(ctx, params, s.OutDir(), &info); err != nil {
s.Fatal("Failed to run telem command: ", err)
}
if err := validateCPUData(info); err != nil {
s.Fatalf("Failed to validate cpu data, err [%v]", err)
}
if s.Param().(bool) {
if err := validateKeyLocker(info.KeylockerInfo); err != nil {
s.Fatal("Failed to validate KeyLocker: ", err)
}
}
}