github.com/jaypipes/ghw@v0.21.1/pkg/cpu/cpu_linux_test.go (about) 1 // 2 // Use and distribution licensed under the Apache license version 2. 3 // 4 // See the COPYING file in the root project directory for full text. 5 // 6 7 package cpu_test 8 9 import ( 10 "bytes" 11 "io" 12 "os" 13 "path/filepath" 14 "strings" 15 "testing" 16 17 "github.com/jaypipes/ghw/pkg/cpu" 18 "github.com/jaypipes/ghw/pkg/option" 19 "github.com/jaypipes/ghw/pkg/topology" 20 "github.com/jaypipes/ghw/testdata" 21 ) 22 23 // nolint: gocyclo 24 func TestArmCPU(t *testing.T) { 25 if _, ok := os.LookupEnv("GHW_TESTING_SKIP_CPU"); ok { 26 t.Skip("Skipping CPU tests.") 27 } 28 29 testdataPath, err := testdata.SnapshotsDirectory() 30 if err != nil { 31 t.Fatalf("Expected nil err, but got %v", err) 32 } 33 34 multiNumaSnapshot := filepath.Join(testdataPath, "linux-arm64-c288e0776090cd558ef793b2a4e61939.tar.gz") 35 36 info, err := cpu.New(option.WithSnapshot(option.SnapshotOptions{ 37 Path: multiNumaSnapshot, 38 })) 39 40 if err != nil { 41 t.Fatalf("Expected nil err, but got %v", err) 42 } 43 if info == nil { 44 t.Fatalf("Expected non-nil CPUInfo, but got nil") 45 } 46 47 if len(info.Processors) == 0 { 48 t.Fatalf("Expected >0 processors but got 0.") 49 } 50 51 for _, p := range info.Processors { 52 if p.Vendor == "" { 53 t.Fatalf("Expected not empty vendor field.") 54 } 55 if p.TotalCores == 0 { 56 t.Fatalf("Expected >0 cores but got 0.") 57 } 58 if p.TotalHardwareThreads == 0 { 59 t.Fatalf("Expected >0 threads but got 0.") 60 } 61 if len(p.Capabilities) == 0 { 62 t.Fatalf("Expected >0 capabilities but got 0.") 63 } 64 if !p.HasCapability(p.Capabilities[0]) { 65 t.Fatalf("Expected p to have capability %s, but did not.", 66 p.Capabilities[0]) 67 } 68 if len(p.Cores) == 0 { 69 t.Fatalf("Expected >0 cores in processor, but got 0.") 70 } 71 for _, c := range p.Cores { 72 if c.TotalHardwareThreads == 0 { 73 t.Fatalf("Expected >0 threads but got 0.") 74 } 75 if len(c.LogicalProcessors) == 0 { 76 t.Fatalf("Expected >0 logical processors but got 0.") 77 } 78 } 79 } 80 } 81 82 func TestCheckCPUTopologyFilesForOfflineCPU(t *testing.T) { 83 if _, ok := os.LookupEnv("GHW_TESTING_SKIP_CPU"); ok { 84 t.Skip("Skipping CPU tests.") 85 } 86 87 testdataPath, err := testdata.SnapshotsDirectory() 88 if err != nil { 89 t.Fatalf("Expected nil err, but got %v", err) 90 } 91 92 offlineCPUSnapshot := filepath.Join(testdataPath, "linux-amd64-offlineCPUs.tar.gz") 93 94 // Capture stderr 95 rErr, wErr, err := os.Pipe() 96 if err != nil { 97 t.Fatalf("Cannot pipe StdErr. %v", err) 98 } 99 os.Stderr = wErr 100 101 info, err := cpu.New(option.WithSnapshot(option.SnapshotOptions{ 102 Path: offlineCPUSnapshot, 103 })) 104 if err != nil { 105 t.Fatalf("Expected nil err, but got %v", err) 106 } 107 if info == nil { 108 t.Fatalf("Expected non-nil CPUInfo, but got nil") 109 } 110 111 if len(info.Processors) == 0 { 112 t.Fatalf("Expected >0 processors but got 0.") 113 } 114 wErr.Close() 115 var bufErr bytes.Buffer 116 if _, err := io.Copy(&bufErr, rErr); err != nil { 117 t.Fatalf("Failed to copy data to buffer: %v", err) 118 } 119 errorOutput := bufErr.String() 120 if strings.Contains(errorOutput, "WARNING: failed to read int from file:") { 121 t.Fatalf("Unexpected warning related to missing files under topology directory was reported") 122 } 123 } 124 125 func TestNumCoresAmongOfflineCPUs(t *testing.T) { 126 if _, ok := os.LookupEnv("GHW_TESTING_SKIP_CPU"); ok { 127 t.Skip("Skipping CPU tests.") 128 } 129 130 testdataPath, err := testdata.SnapshotsDirectory() 131 if err != nil { 132 t.Fatalf("Expected nil err, but got %v", err) 133 } 134 135 offlineCPUSnapshot := filepath.Join(testdataPath, "linux-amd64-offlineCPUs.tar.gz") 136 137 // Capture stderr 138 rErr, wErr, err := os.Pipe() 139 if err != nil { 140 t.Fatalf("Cannot pipe the StdErr. %v", err) 141 } 142 info, err := topology.New(option.WithSnapshot(option.SnapshotOptions{ 143 Path: offlineCPUSnapshot, 144 })) 145 if err != nil { 146 t.Fatalf("Error determining node topology. %v", err) 147 } 148 149 if len(info.Nodes) < 1 { 150 t.Fatal("No nodes found. Must contain one or more nodes") 151 } 152 for _, node := range info.Nodes { 153 if len(node.Cores) < 1 { 154 t.Fatal("No cores found. Must contain one or more cores") 155 } 156 } 157 wErr.Close() 158 var bufErr bytes.Buffer 159 if _, err := io.Copy(&bufErr, rErr); err != nil { 160 t.Fatalf("Failed to copy data to buffer: %v", err) 161 } 162 errorOutput := bufErr.String() 163 if strings.Contains(errorOutput, "WARNING: failed to read int from file:") { 164 t.Fatalf("Unexpected warnings related to missing files under topology directory was raised") 165 } 166 }