github.com/jaypipes/ghw@v0.21.1/pkg/topology/topology_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 topology_test
     8  
     9  import (
    10  	"encoding/json"
    11  	"path/filepath"
    12  	"testing"
    13  
    14  	"github.com/jaypipes/ghw/pkg/memory"
    15  	"github.com/jaypipes/ghw/pkg/option"
    16  	"github.com/jaypipes/ghw/pkg/topology"
    17  
    18  	"github.com/jaypipes/ghw/testdata"
    19  )
    20  
    21  // nolint: gocyclo
    22  func TestTopologyNUMADistances(t *testing.T) {
    23  	testdataPath, err := testdata.SnapshotsDirectory()
    24  	if err != nil {
    25  		t.Fatalf("Expected nil err, but got %v", err)
    26  	}
    27  
    28  	multiNumaSnapshot := filepath.Join(testdataPath, "linux-amd64-intel-xeon-L5640.tar.gz")
    29  	// from now on we use constants reflecting the content of the snapshot we requested,
    30  	// which we reviewed beforehand. IOW, you need to know the content of the
    31  	// snapshot to fully understand this test. Inspect it using
    32  	// GHW_SNAPSHOT_PATH="/path/to/linux-amd64-intel-xeon-L5640.tar.gz" ghwc topology
    33  
    34  	info, err := topology.New(option.WithSnapshot(option.SnapshotOptions{
    35  		Path: multiNumaSnapshot,
    36  	}))
    37  
    38  	if err != nil {
    39  		t.Fatalf("Expected nil err, but got %v", err)
    40  	}
    41  	if info == nil {
    42  		t.Fatalf("Expected non-nil TopologyInfo, but got nil")
    43  	}
    44  
    45  	if len(info.Nodes) != 2 {
    46  		t.Fatalf("Expected 2 nodes but got 0.")
    47  	}
    48  
    49  	for _, n := range info.Nodes {
    50  		if len(n.Distances) != len(info.Nodes) {
    51  			t.Fatalf("Expected distances to all known nodes")
    52  		}
    53  	}
    54  
    55  	if info.Nodes[0].Distances[0] != info.Nodes[1].Distances[1] {
    56  		t.Fatalf("Expected symmetric distance to self, got %v and %v", info.Nodes[0].Distances, info.Nodes[1].Distances)
    57  	}
    58  
    59  	if info.Nodes[0].Distances[1] != info.Nodes[1].Distances[0] {
    60  		t.Fatalf("Expected symmetric distance to the other node, got %v and %v", info.Nodes[0].Distances, info.Nodes[1].Distances)
    61  	}
    62  }
    63  
    64  // we have this test in topology_linux_test.go (and not in topology_test.go) because `topologyFillInfo`
    65  // is not implemented on darwin; so having it in the platform-independent tests would lead to false negatives.
    66  func TestTopologyMarshalUnmarshal(t *testing.T) {
    67  	data, err := topology.New(option.WithNullAlerter())
    68  	if err != nil {
    69  		t.Fatalf("Expected no error creating topology.Info, but got %v", err)
    70  	}
    71  
    72  	jdata, err := json.Marshal(data)
    73  	if err != nil {
    74  		t.Fatalf("Expected no error marshaling topology.Info, but got %v", err)
    75  	}
    76  
    77  	var topo *topology.Info
    78  
    79  	err = json.Unmarshal(jdata, &topo)
    80  	if err != nil {
    81  		t.Fatalf("Expected no error unmarshaling topology.Info, but got %v", err)
    82  	}
    83  }
    84  
    85  // nolint: gocyclo
    86  func TestTopologyPerNUMAMemory(t *testing.T) {
    87  	testdataPath, err := testdata.SnapshotsDirectory()
    88  	if err != nil {
    89  		t.Fatalf("Expected nil err, but got %v", err)
    90  	}
    91  
    92  	multiNumaSnapshot := filepath.Join(testdataPath, "linux-amd64-intel-xeon-L5640.tar.gz")
    93  	// from now on we use constants reflecting the content of the snapshot we requested,
    94  	// which we reviewed beforehand. IOW, you need to know the content of the
    95  	// snapshot to fully understand this test. Inspect it using
    96  	// GHW_SNAPSHOT_PATH="/path/to/linux-amd64-intel-xeon-L5640.tar.gz" ghwc topology
    97  
    98  	memInfo, err := memory.New(option.WithSnapshot(option.SnapshotOptions{
    99  		Path: multiNumaSnapshot,
   100  	}))
   101  
   102  	if err != nil {
   103  		t.Fatalf("Expected nil err, but got %v", err)
   104  	}
   105  	if memInfo == nil {
   106  		t.Fatalf("Expected non-nil MemoryInfo, but got nil")
   107  	}
   108  
   109  	info, err := topology.New(option.WithSnapshot(option.SnapshotOptions{
   110  		Path: multiNumaSnapshot,
   111  	}))
   112  
   113  	if err != nil {
   114  		t.Fatalf("Expected nil err, but got %v", err)
   115  	}
   116  	if info == nil {
   117  		t.Fatalf("Expected non-nil TopologyInfo, but got nil")
   118  	}
   119  
   120  	if len(info.Nodes) != 2 {
   121  		t.Fatalf("Expected 2 nodes but got 0.")
   122  	}
   123  
   124  	for _, node := range info.Nodes {
   125  		if node.Memory == nil {
   126  			t.Fatalf("missing memory information for node %d", node.ID)
   127  		}
   128  
   129  		if node.Memory.TotalPhysicalBytes <= 0 {
   130  			t.Fatalf("negative physical size for node %d", node.ID)
   131  		}
   132  		if node.Memory.TotalPhysicalBytes > memInfo.TotalPhysicalBytes {
   133  			t.Fatalf("physical size for node %d exceeds system's", node.ID)
   134  		}
   135  		if node.Memory.TotalUsableBytes <= 0 {
   136  			t.Fatalf("negative usable size for node %d", node.ID)
   137  		}
   138  		if node.Memory.TotalUsableBytes > memInfo.TotalUsableBytes {
   139  			t.Fatalf("usable size for node %d exceeds system's", node.ID)
   140  		}
   141  		if node.Memory.TotalUsableBytes > node.Memory.TotalPhysicalBytes {
   142  			t.Fatalf("excessive usable size for node %d", node.ID)
   143  		}
   144  		if node.Memory.DefaultHugePageSize == 0 {
   145  			t.Fatalf("unexpected default HP size for node %d", node.ID)
   146  		}
   147  		if len(node.Memory.HugePageAmountsBySize) != 2 {
   148  			t.Fatalf("expected 2 huge page info records, but got '%d' for node %d", len(node.Memory.HugePageAmountsBySize), node.ID)
   149  		}
   150  	}
   151  }