github.com/google/cadvisor@v0.49.1/utils/sysinfo/sysinfo_test.go (about)

     1  // Copyright 2014 Google Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package sysinfo
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"os"
    21  	"sort"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  
    26  	info "github.com/google/cadvisor/info/v1"
    27  	"github.com/google/cadvisor/utils/sysfs"
    28  	"github.com/google/cadvisor/utils/sysfs/fakesysfs"
    29  )
    30  
    31  func TestGetHugePagesInfo(t *testing.T) {
    32  	fakeSys := fakesysfs.FakeSysFs{}
    33  	hugePages := []os.FileInfo{
    34  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
    35  		&fakesysfs.FileInfo{EntryName: "hugepages-1048576kB"},
    36  	}
    37  	fakeSys.SetHugePages(hugePages, nil)
    38  
    39  	hugePageNr := map[string]string{
    40  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages":    "1",
    41  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages": "1",
    42  	}
    43  	fakeSys.SetHugePagesNr(hugePageNr, nil)
    44  
    45  	hugePagesInfo, err := GetHugePagesInfo(&fakeSys, "/fakeSysfs/devices/system/node/node0/hugepages/")
    46  	assert.Nil(t, err)
    47  	assert.Equal(t, 2, len(hugePagesInfo))
    48  }
    49  
    50  func TestGetHugePagesInfoWithHugePagesDirectory(t *testing.T) {
    51  	fakeSys := fakesysfs.FakeSysFs{}
    52  	hugePagesInfo, err := GetHugePagesInfo(&fakeSys, "/fakeSysfs/devices/system/node/node0/hugepages/")
    53  	assert.Nil(t, err)
    54  	assert.Equal(t, 0, len(hugePagesInfo))
    55  }
    56  
    57  func TestGetHugePagesInfoWithWrongDirName(t *testing.T) {
    58  	fakeSys := fakesysfs.FakeSysFs{}
    59  	hugePages := []os.FileInfo{
    60  		&fakesysfs.FileInfo{EntryName: "hugepages-abckB"},
    61  	}
    62  	fakeSys.SetHugePages(hugePages, nil)
    63  
    64  	hugePagesInfo, err := GetHugePagesInfo(&fakeSys, "/fakeSysfs/devices/system/node/node0/hugepages/")
    65  	assert.NotNil(t, err)
    66  	assert.Equal(t, 0, len(hugePagesInfo))
    67  }
    68  
    69  func TestGetHugePagesInfoWithReadingNrHugePagesError(t *testing.T) {
    70  	fakeSys := fakesysfs.FakeSysFs{}
    71  	hugePages := []os.FileInfo{
    72  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
    73  		&fakesysfs.FileInfo{EntryName: "hugepages-1048576kB"},
    74  	}
    75  	fakeSys.SetHugePages(hugePages, nil)
    76  
    77  	hugePageNr := map[string]string{
    78  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages":    "1",
    79  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages": "1",
    80  	}
    81  	fakeSys.SetHugePagesNr(hugePageNr, fmt.Errorf("Error in reading nr_hugepages"))
    82  
    83  	hugePagesInfo, err := GetHugePagesInfo(&fakeSys, "/fakeSysfs/devices/system/node/node0/hugepages/")
    84  	assert.NotNil(t, err)
    85  	assert.Equal(t, 0, len(hugePagesInfo))
    86  }
    87  
    88  func TestGetHugePagesInfoWithWrongNrHugePageValue(t *testing.T) {
    89  	fakeSys := fakesysfs.FakeSysFs{}
    90  	hugePages := []os.FileInfo{
    91  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
    92  		&fakesysfs.FileInfo{EntryName: "hugepages-1048576kB"},
    93  	}
    94  	fakeSys.SetHugePages(hugePages, nil)
    95  
    96  	hugePageNr := map[string]string{
    97  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages":    "*****",
    98  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages": "1",
    99  	}
   100  	fakeSys.SetHugePagesNr(hugePageNr, nil)
   101  
   102  	hugePagesInfo, err := GetHugePagesInfo(&fakeSys, "/fakeSysfs/devices/system/node/node0/hugepages/")
   103  	assert.NotNil(t, err)
   104  	assert.Equal(t, 0, len(hugePagesInfo))
   105  }
   106  
   107  func TestGetNodesInfo(t *testing.T) {
   108  	testCases := []struct {
   109  		cache              sysfs.CacheInfo
   110  		nodesPaths         []string
   111  		cpusPaths          map[string][]string
   112  		coresThreads       map[string]string
   113  		memTotal           string
   114  		hugePages          []os.FileInfo
   115  		hugePageNr         map[string]string
   116  		physicalPackageIDs map[string]string
   117  		nodes              int
   118  		cores              int
   119  		distances          []string
   120  		expectedNodes      string
   121  	}{
   122  		{
   123  			sysfs.CacheInfo{
   124  				Id:    0,
   125  				Size:  32 * 1024,
   126  				Type:  "unified",
   127  				Level: 3,
   128  				Cpus:  2,
   129  			},
   130  			[]string{
   131  				"/fakeSysfs/devices/system/node/node0",
   132  				"/fakeSysfs/devices/system/node/node1"},
   133  			map[string][]string{
   134  				"/fakeSysfs/devices/system/node/node0": {
   135  					"/fakeSysfs/devices/system/node/node0/cpu0",
   136  					"/fakeSysfs/devices/system/node/node0/cpu1",
   137  				},
   138  				"/fakeSysfs/devices/system/node/node1": {
   139  					"/fakeSysfs/devices/system/node/node0/cpu2",
   140  					"/fakeSysfs/devices/system/node/node0/cpu3",
   141  				},
   142  			},
   143  			map[string]string{
   144  				"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   145  				"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   146  				"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   147  				"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   148  			},
   149  			"MemTotal:       32817192 kB",
   150  			[]os.FileInfo{
   151  				&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
   152  			},
   153  			map[string]string{
   154  				"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages": "1",
   155  				"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages": "1",
   156  			},
   157  			map[string]string{
   158  				"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   159  				"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   160  				"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   161  				"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   162  			},
   163  			2,
   164  			4,
   165  			[]string{
   166  				"10 11",
   167  				"11 10",
   168  			},
   169  			`
   170  	[
   171        {
   172          "node_id": 0,
   173          "memory": 33604804608,
   174          "hugepages": [
   175            {
   176              "page_size": 2048,
   177              "num_pages": 1
   178            }
   179          ],
   180          "distances": [
   181            10,
   182            11
   183          ],
   184          "cores": [
   185            {
   186              "core_id": 0,
   187              "thread_ids": [
   188                0,
   189                1
   190              ],
   191              "caches": null,
   192              "uncore_caches": null,
   193              "socket_id": 0
   194            }
   195          ],
   196          "caches": [
   197            {
   198              "id": 0,
   199              "size": 32768,
   200              "type": "unified",
   201              "level": 3
   202            }
   203          ]
   204        },
   205        {
   206          "node_id": 1,
   207          "memory": 33604804608,
   208          "hugepages": [
   209            {
   210              "page_size": 2048,
   211              "num_pages": 1
   212            }
   213          ],
   214          "distances": [
   215            11,
   216            10
   217          ],
   218          "cores": [
   219            {
   220              "core_id": 1,
   221              "thread_ids": [
   222                2,
   223                3
   224              ],
   225              "caches": null,
   226              "uncore_caches": null,
   227              "socket_id": 1
   228            }
   229          ],
   230          "caches": [
   231            {
   232              "id": 0,
   233              "size": 32768,
   234              "type": "unified",
   235              "level": 3
   236            }
   237          ]
   238        }
   239      ]
   240      `,
   241  		},
   242  		{
   243  			sysfs.CacheInfo{
   244  				Id:    0,
   245  				Size:  32 * 1024,
   246  				Type:  "unified",
   247  				Level: 3,
   248  				Cpus:  6,
   249  			},
   250  			[]string{
   251  				"/fakeSysfs/devices/system/node/node0"},
   252  			map[string][]string{
   253  				"/fakeSysfs/devices/system/node/node0": {
   254  					"/fakeSysfs/devices/system/node/node0/cpu0",
   255  					"/fakeSysfs/devices/system/node/node0/cpu1",
   256  					"/fakeSysfs/devices/system/node/node0/cpu2",
   257  					"/fakeSysfs/devices/system/node/node0/cpu3",
   258  					"/fakeSysfs/devices/system/node/node0/cpu4",
   259  					"/fakeSysfs/devices/system/node/node0/cpu5",
   260  				},
   261  			},
   262  			map[string]string{
   263  				"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   264  				"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   265  				"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   266  				"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   267  				"/fakeSysfs/devices/system/node/node0/cpu4": "2",
   268  				"/fakeSysfs/devices/system/node/node0/cpu5": "2",
   269  			},
   270  			"MemTotal:       32817192 kB",
   271  			[]os.FileInfo{
   272  				&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
   273  			},
   274  			map[string]string{
   275  				"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages": "1",
   276  			},
   277  			map[string]string{
   278  				"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   279  				"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   280  				"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   281  				"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   282  				"/fakeSysfs/devices/system/node/node0/cpu4": "2",
   283  				"/fakeSysfs/devices/system/node/node0/cpu5": "2",
   284  			},
   285  			1,
   286  			6,
   287  			[]string{
   288  				"10",
   289  			},
   290  			`
   291  	[
   292        {
   293          "node_id": 0,
   294          "memory": 33604804608,
   295          "distances": [
   296            10
   297          ],
   298          "hugepages": [
   299            {
   300              "page_size": 2048,
   301              "num_pages": 1
   302            }
   303          ],
   304          "cores": [
   305            {
   306              "core_id": 0,
   307              "thread_ids": [
   308                0,
   309                1
   310              ],
   311              "caches": null,
   312              "socket_id": 0,
   313              "uncore_caches": null
   314            },
   315            {
   316              "core_id": 1,
   317              "thread_ids": [
   318                2,
   319                3
   320              ],
   321              "caches": null,
   322              "socket_id": 1,
   323              "uncore_caches": null
   324            },
   325            {
   326              "core_id": 2,
   327              "thread_ids": [
   328                4,
   329                5
   330              ],
   331              "caches": null,
   332              "socket_id": 2,
   333              "uncore_caches": null
   334            }
   335          ],
   336          "caches": [
   337            {
   338              "id": 0,
   339              "size": 32768,
   340              "type": "unified",
   341              "level": 3
   342            }
   343          ]
   344        }
   345      ]
   346      `,
   347  		},
   348  	}
   349  
   350  	for _, test := range testCases {
   351  		fakeSys := &fakesysfs.FakeSysFs{}
   352  		fakeSys.SetCacheInfo(test.cache)
   353  		fakeSys.SetNodesPaths(test.nodesPaths, nil)
   354  		fakeSys.SetCPUsPaths(test.cpusPaths, nil)
   355  		fakeSys.SetCoreThreads(test.coresThreads, nil)
   356  		fakeSys.SetMemory(test.memTotal, nil)
   357  		fakeSys.SetHugePages(test.hugePages, nil)
   358  		fakeSys.SetHugePagesNr(test.hugePageNr, nil)
   359  		fakeSys.SetPhysicalPackageIDs(test.physicalPackageIDs, nil)
   360  		for i, node := range test.nodesPaths {
   361  			fakeSys.SetDistances(node, test.distances[i], nil)
   362  		}
   363  
   364  		nodes, cores, err := GetNodesInfo(fakeSys)
   365  		assert.Nil(t, err)
   366  		assert.Equal(t, test.nodes, len(nodes))
   367  		assert.Equal(t, test.cores, cores)
   368  
   369  		nodesJSON, err := json.Marshal(nodes)
   370  		assert.Nil(t, err)
   371  		assert.JSONEq(t, test.expectedNodes, string(nodesJSON))
   372  	}
   373  }
   374  
   375  func TestGetNodesInfoWithOfflineCPUs(t *testing.T) {
   376  	fakeSys := &fakesysfs.FakeSysFs{}
   377  	c := sysfs.CacheInfo{
   378  		Id:    0,
   379  		Size:  32 * 1024,
   380  		Type:  "unified",
   381  		Level: 3,
   382  		Cpus:  1,
   383  	}
   384  	fakeSys.SetCacheInfo(c)
   385  
   386  	nodesPaths := []string{
   387  		"/fakeSysfs/devices/system/node/node0",
   388  		"/fakeSysfs/devices/system/node/node1",
   389  	}
   390  	fakeSys.SetNodesPaths(nodesPaths, nil)
   391  
   392  	cpusPaths := map[string][]string{
   393  		"/fakeSysfs/devices/system/node/node0": {
   394  			"/fakeSysfs/devices/system/node/node0/cpu0",
   395  			"/fakeSysfs/devices/system/node/node0/cpu1",
   396  		},
   397  		"/fakeSysfs/devices/system/node/node1": {
   398  			"/fakeSysfs/devices/system/node/node0/cpu2",
   399  			"/fakeSysfs/devices/system/node/node0/cpu3",
   400  		},
   401  	}
   402  	fakeSys.SetCPUsPaths(cpusPaths, nil)
   403  
   404  	coreThread := map[string]string{
   405  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   406  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   407  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   408  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   409  	}
   410  	fakeSys.SetCoreThreads(coreThread, nil)
   411  	fakeSys.SetOnlineCPUs(map[string]interface{}{
   412  		"/fakeSysfs/devices/system/node/node0/cpu0": nil,
   413  		"/fakeSysfs/devices/system/node/node0/cpu2": nil,
   414  	})
   415  
   416  	memTotal := "MemTotal:       32817192 kB"
   417  	fakeSys.SetMemory(memTotal, nil)
   418  
   419  	hugePages := []os.FileInfo{
   420  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
   421  	}
   422  	fakeSys.SetHugePages(hugePages, nil)
   423  
   424  	hugePageNr := map[string]string{
   425  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages": "1",
   426  		"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages": "1",
   427  	}
   428  	fakeSys.SetHugePagesNr(hugePageNr, nil)
   429  
   430  	physicalPackageIDs := map[string]string{
   431  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   432  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   433  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   434  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   435  	}
   436  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)
   437  
   438  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node0", "10 11", nil)
   439  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node1", "11 10", nil)
   440  
   441  	nodes, cores, err := GetNodesInfo(fakeSys)
   442  	assert.Nil(t, err)
   443  	assert.Equal(t, 2, len(nodes))
   444  	assert.Equal(t, 2, cores)
   445  
   446  	nodesJSON, err := json.Marshal(nodes)
   447  	assert.Nil(t, err)
   448  	expectedNodes := `
   449  	[
   450        {
   451          "node_id": 0,
   452          "memory": 33604804608,
   453          "hugepages": [
   454            {
   455              "page_size": 2048,
   456              "num_pages": 1
   457            }
   458          ],
   459          "distances": [
   460            10,
   461            11
   462          ],
   463          "cores": [
   464            {
   465              "core_id": 0,
   466              "thread_ids": [
   467                0
   468              ],
   469              "caches": null,
   470              "socket_id": 0,
   471              "uncore_caches": null
   472            }
   473          ],
   474          "caches": [
   475            {
   476              "id": 0,
   477              "size": 32768,
   478              "type": "unified",
   479              "level": 3
   480            }
   481          ]
   482        },
   483        {
   484          "node_id": 1,
   485          "memory": 33604804608,
   486          "hugepages": [
   487            {
   488              "page_size": 2048,
   489              "num_pages": 1
   490            }
   491          ],
   492          "distances": [
   493            11,
   494            10
   495          ],
   496          "cores": [
   497            {
   498              "core_id": 1,
   499              "thread_ids": [
   500                2
   501              ],
   502              "caches": null,
   503              "socket_id": 1,
   504              "uncore_caches": null
   505            }
   506          ],
   507          "caches": [
   508            {
   509              "id": 0,
   510              "size": 32768,
   511              "type": "unified",
   512              "level": 3
   513            }
   514          ]
   515        }
   516      ]
   517      `
   518  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
   519  }
   520  
   521  func TestGetNodesWithoutMemoryInfo(t *testing.T) {
   522  	fakeSys := &fakesysfs.FakeSysFs{}
   523  	c := sysfs.CacheInfo{
   524  		Size:  32 * 1024,
   525  		Type:  "unified",
   526  		Level: 3,
   527  		Cpus:  2,
   528  	}
   529  	fakeSys.SetCacheInfo(c)
   530  
   531  	nodesPaths := []string{
   532  		"/fakeSysfs/devices/system/node/node0",
   533  		"/fakeSysfs/devices/system/node/node1",
   534  	}
   535  	fakeSys.SetNodesPaths(nodesPaths, nil)
   536  
   537  	cpusPaths := map[string][]string{
   538  		"/fakeSysfs/devices/system/node/node0": {
   539  			"/fakeSysfs/devices/system/node/node0/cpu0",
   540  			"/fakeSysfs/devices/system/node/node0/cpu1",
   541  		},
   542  		"/fakeSysfs/devices/system/node/node1": {
   543  			"/fakeSysfs/devices/system/node/node0/cpu2",
   544  			"/fakeSysfs/devices/system/node/node0/cpu3",
   545  		},
   546  	}
   547  	fakeSys.SetCPUsPaths(cpusPaths, nil)
   548  
   549  	coreThread := map[string]string{
   550  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   551  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   552  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   553  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   554  	}
   555  	fakeSys.SetCoreThreads(coreThread, nil)
   556  
   557  	hugePages := []os.FileInfo{
   558  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
   559  	}
   560  	fakeSys.SetHugePages(hugePages, nil)
   561  
   562  	hugePageNr := map[string]string{
   563  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages": "1",
   564  		"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages": "1",
   565  	}
   566  	fakeSys.SetHugePagesNr(hugePageNr, nil)
   567  
   568  	nodes, cores, err := GetNodesInfo(fakeSys)
   569  	assert.NotNil(t, err)
   570  	assert.Equal(t, []info.Node([]info.Node(nil)), nodes)
   571  	assert.Equal(t, 0, cores)
   572  }
   573  
   574  func TestGetNodesInfoWithoutCacheInfo(t *testing.T) {
   575  	fakeSys := &fakesysfs.FakeSysFs{}
   576  
   577  	nodesPaths := []string{
   578  		"/fakeSysfs/devices/system/node/node0",
   579  		"/fakeSysfs/devices/system/node/node1",
   580  	}
   581  	fakeSys.SetNodesPaths(nodesPaths, nil)
   582  
   583  	cpusPaths := map[string][]string{
   584  		"/fakeSysfs/devices/system/node/node0": {
   585  			"/fakeSysfs/devices/system/node/node0/cpu0",
   586  			"/fakeSysfs/devices/system/node/node0/cpu1",
   587  		},
   588  		"/fakeSysfs/devices/system/node/node1": {
   589  			"/fakeSysfs/devices/system/node/node0/cpu2",
   590  			"/fakeSysfs/devices/system/node/node0/cpu3",
   591  		},
   592  	}
   593  	fakeSys.SetCPUsPaths(cpusPaths, nil)
   594  
   595  	coreThread := map[string]string{
   596  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   597  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   598  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   599  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   600  	}
   601  	fakeSys.SetCoreThreads(coreThread, nil)
   602  
   603  	memTotal := "MemTotal:       32817192 kB"
   604  	fakeSys.SetMemory(memTotal, nil)
   605  
   606  	hugePages := []os.FileInfo{
   607  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
   608  	}
   609  	fakeSys.SetHugePages(hugePages, nil)
   610  
   611  	hugePageNr := map[string]string{
   612  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages": "1",
   613  		"/fakeSysfs/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages": "1",
   614  	}
   615  	fakeSys.SetHugePagesNr(hugePageNr, nil)
   616  
   617  	physicalPackageIDs := map[string]string{
   618  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   619  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   620  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   621  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   622  	}
   623  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)
   624  
   625  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node0", "10 11", nil)
   626  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node1", "11 10", nil)
   627  
   628  	nodes, cores, err := GetNodesInfo(fakeSys)
   629  	assert.Nil(t, err)
   630  	assert.Equal(t, 2, len(nodes))
   631  	assert.Equal(t, 4, cores)
   632  
   633  	nodesJSON, err := json.Marshal(nodes)
   634  	assert.Nil(t, err)
   635  	expectedNodes := `
   636  	[
   637        {
   638          "node_id": 0,
   639          "memory": 33604804608,
   640          "hugepages": [
   641            {
   642              "page_size": 2048,
   643              "num_pages": 1
   644            }
   645          ],
   646          "distances": [
   647            10,
   648            11
   649          ],
   650          "cores": [
   651  	  {
   652              "core_id": 0,
   653              "thread_ids": [
   654                0,
   655                1
   656              ],
   657              "caches": null,
   658              "uncore_caches": null,
   659              "socket_id": 0
   660            }
   661          ],
   662          "caches": null
   663        },
   664        {
   665          "node_id": 1,
   666          "memory": 33604804608,
   667          "hugepages": [
   668            {
   669              "page_size": 2048,
   670              "num_pages": 1
   671            }
   672          ],
   673          "distances": [
   674            11,
   675            10
   676          ],
   677          "cores": [
   678            {
   679              "core_id": 1,
   680              "thread_ids": [
   681                2,
   682                3
   683              ],
   684              "caches": null,
   685              "uncore_caches": null,
   686              "socket_id": 1
   687            }
   688          ],
   689          "caches": null
   690        }
   691      ]`
   692  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
   693  }
   694  
   695  func TestGetNodesInfoWithoutHugePagesInfo(t *testing.T) {
   696  	fakeSys := &fakesysfs.FakeSysFs{}
   697  	c := sysfs.CacheInfo{
   698  		Id:    0,
   699  		Size:  32 * 1024,
   700  		Type:  "unified",
   701  		Level: 2,
   702  		Cpus:  2,
   703  	}
   704  	fakeSys.SetCacheInfo(c)
   705  
   706  	nodesPaths := []string{
   707  		"/fakeSysfs/devices/system/node/node0",
   708  		"/fakeSysfs/devices/system/node/node1",
   709  	}
   710  	fakeSys.SetNodesPaths(nodesPaths, nil)
   711  
   712  	cpusPaths := map[string][]string{
   713  		"/fakeSysfs/devices/system/node/node0": {
   714  			"/fakeSysfs/devices/system/node/node0/cpu0",
   715  			"/fakeSysfs/devices/system/node/node0/cpu1",
   716  		},
   717  		"/fakeSysfs/devices/system/node/node1": {
   718  			"/fakeSysfs/devices/system/node/node0/cpu2",
   719  			"/fakeSysfs/devices/system/node/node0/cpu3",
   720  		},
   721  	}
   722  	fakeSys.SetCPUsPaths(cpusPaths, nil)
   723  
   724  	coreThread := map[string]string{
   725  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   726  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   727  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   728  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   729  	}
   730  	fakeSys.SetCoreThreads(coreThread, nil)
   731  
   732  	memTotal := "MemTotal:       32817192 kB"
   733  	fakeSys.SetMemory(memTotal, nil)
   734  
   735  	physicalPackageIDs := map[string]string{
   736  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
   737  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
   738  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
   739  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
   740  	}
   741  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)
   742  
   743  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node0", "10 11", nil)
   744  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node1", "11 10", nil)
   745  
   746  	nodes, cores, err := GetNodesInfo(fakeSys)
   747  	assert.Nil(t, err)
   748  	assert.Equal(t, 2, len(nodes))
   749  	assert.Equal(t, 4, cores)
   750  
   751  	nodesJSON, err := json.Marshal(nodes)
   752  	assert.Nil(t, err)
   753  	expectedNodes := `
   754  	[
   755        {
   756          "node_id": 0,
   757          "memory": 33604804608,
   758          "distances": [
   759            10,
   760            11
   761          ],
   762          "hugepages": null,
   763          "cores": [
   764            {
   765              "core_id": 0,
   766              "thread_ids": [
   767                0,
   768                1
   769              ],
   770              "caches": [
   771                {
   772                  "id": 0,
   773                  "size": 32768,
   774                  "type": "unified",
   775                  "level": 2
   776                }
   777              ],
   778              "uncore_caches": null,
   779              "socket_id": 0
   780            }
   781          ],
   782          "caches": null
   783        },
   784        {
   785          "node_id": 1,
   786          "memory": 33604804608,
   787          "hugepages": null,
   788          "distances": [
   789            11,
   790            10
   791          ],
   792          "cores": [
   793            {
   794              "core_id": 1,
   795              "thread_ids": [
   796                2,
   797                3
   798              ],
   799              "caches": [
   800                {
   801                  "id": 0,
   802                  "size": 32768,
   803                  "type": "unified",
   804                  "level": 2
   805                }
   806              ],
   807              "uncore_caches": null,
   808              "socket_id": 1
   809            }
   810          ],
   811          "caches": null
   812        }
   813      ]`
   814  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
   815  }
   816  
   817  func TestGetNodesInfoWithoutNodes(t *testing.T) {
   818  	fakeSys := &fakesysfs.FakeSysFs{}
   819  
   820  	c := sysfs.CacheInfo{
   821  		Id:    0,
   822  		Size:  32 * 1024,
   823  		Type:  "unified",
   824  		Level: 1,
   825  		Cpus:  2,
   826  	}
   827  	fakeSys.SetCacheInfo(c)
   828  
   829  	nodesPaths := []string{}
   830  	fakeSys.SetNodesPaths(nodesPaths, nil)
   831  
   832  	cpusPaths := map[string][]string{
   833  		cpusPath: {
   834  			cpusPath + "/cpu0",
   835  			cpusPath + "/cpu1",
   836  			cpusPath + "/cpu2",
   837  			cpusPath + "/cpu3",
   838  		},
   839  	}
   840  	fakeSys.SetCPUsPaths(cpusPaths, nil)
   841  
   842  	coreThread := map[string]string{
   843  		cpusPath + "/cpu0": "0",
   844  		cpusPath + "/cpu1": "0",
   845  		cpusPath + "/cpu2": "1",
   846  		cpusPath + "/cpu3": "1",
   847  	}
   848  	fakeSys.SetCoreThreads(coreThread, nil)
   849  
   850  	physicalPackageIDs := map[string]string{
   851  		"/sys/devices/system/cpu/cpu0": "0",
   852  		"/sys/devices/system/cpu/cpu1": "0",
   853  		"/sys/devices/system/cpu/cpu2": "1",
   854  		"/sys/devices/system/cpu/cpu3": "1",
   855  	}
   856  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)
   857  
   858  	nodes, cores, err := GetNodesInfo(fakeSys)
   859  	assert.Nil(t, err)
   860  	assert.Equal(t, 2, len(nodes))
   861  	assert.Equal(t, 4, cores)
   862  
   863  	sort.Slice(nodes, func(i, j int) bool {
   864  		return nodes[i].Id < nodes[j].Id
   865  	})
   866  
   867  	nodesJSON, err := json.Marshal(nodes)
   868  	assert.Nil(t, err)
   869  
   870  	expectedNodes := `[
   871  		{
   872  			"node_id":0,
   873  			"memory":0,
   874              "distances": null,
   875  			"hugepages":null,
   876  			"cores":[
   877  			   {
   878  				  "core_id":0,
   879  				  "thread_ids":[
   880  					 0,
   881  					 1
   882  				  ],
   883  				  "caches":[
   884  					 {
   885  						"id": 0,
   886  						"size":32768,
   887  						"type":"unified",
   888  						"level":1
   889  					 }
   890  				  ],
   891  				  "socket_id": 0,
   892  				  "uncore_caches": null
   893  			   }
   894  			],
   895  			"caches":null
   896  		 },
   897  		 {
   898  			"node_id":1,
   899  			"memory":0,
   900              "distances": null,
   901  			"hugepages":null,
   902  			"cores":[
   903  			   {
   904  				  "core_id":1,
   905  				  "thread_ids":[
   906  					 2,
   907  					 3
   908  				  ],
   909  				  "caches":[
   910  					 {
   911  						"id": 0,
   912  						"size":32768,
   913  						"type":"unified",
   914  						"level":1
   915  					 }
   916  				  ],
   917  				  "uncore_caches": null,
   918  				  "socket_id": 1
   919  			   }
   920  			],
   921  			"caches":null
   922  		 }
   923  	]`
   924  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
   925  }
   926  
   927  func TestGetNodesInfoWithoutNodesWhenPhysicalPackageIDMissingForOneCPU(t *testing.T) {
   928  	fakeSys := &fakesysfs.FakeSysFs{}
   929  
   930  	nodesPaths := []string{}
   931  	fakeSys.SetNodesPaths(nodesPaths, nil)
   932  
   933  	cpusPaths := map[string][]string{
   934  		cpusPath: {
   935  			cpusPath + "/cpu0",
   936  			cpusPath + "/cpu1",
   937  		},
   938  	}
   939  	fakeSys.SetCPUsPaths(cpusPaths, nil)
   940  
   941  	coreThread := map[string]string{
   942  		cpusPath + "/cpu0": "0",
   943  		cpusPath + "/cpu1": "0",
   944  	}
   945  
   946  	coreThreadErrors := map[string]error{
   947  		cpusPath + "/cpu0": nil,
   948  		cpusPath + "/cpu1": nil,
   949  	}
   950  	fakeSys.SetCoreThreads(coreThread, coreThreadErrors)
   951  
   952  	physicalPackageIDs := map[string]string{
   953  		cpusPath + "/cpu0": "0",
   954  		cpusPath + "/cpu1": "0",
   955  	}
   956  
   957  	physicalPackageIDErrors := map[string]error{
   958  		cpusPath + "/cpu0": nil,
   959  		cpusPath + "/cpu1": os.ErrNotExist,
   960  	}
   961  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)
   962  
   963  	nodes, cores, err := GetNodesInfo(fakeSys)
   964  	assert.Nil(t, err)
   965  	assert.Equal(t, 1, len(nodes))
   966  	assert.Equal(t, 2, cores)
   967  
   968  	sort.Slice(nodes, func(i, j int) bool {
   969  		return nodes[i].Id < nodes[j].Id
   970  	})
   971  
   972  	nodesJSON, err := json.Marshal(nodes)
   973  	assert.Nil(t, err)
   974  
   975  	fmt.Println(string(nodesJSON))
   976  
   977  	expectedNodes := `[
   978  		{
   979  			"node_id":0,
   980  			"memory":0,
   981              "distances": null,
   982  			"hugepages":null,
   983  			"cores":[
   984  			   {
   985  				  "core_id":0,
   986  				  "thread_ids":[
   987  					 0
   988  				  ],
   989  				  "caches": null,
   990  				  "socket_id": 0,
   991  				  "uncore_caches": null
   992  			   }
   993  			],
   994  			"caches":null
   995  		}
   996  	]`
   997  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
   998  }
   999  
  1000  func TestGetNodesInfoWithoutNodesWhenPhysicalPackageIDMissing(t *testing.T) {
  1001  	fakeSys := &fakesysfs.FakeSysFs{}
  1002  
  1003  	nodesPaths := []string{}
  1004  	fakeSys.SetNodesPaths(nodesPaths, nil)
  1005  
  1006  	cpusPaths := map[string][]string{
  1007  		cpusPath: {
  1008  			cpusPath + "/cpu0",
  1009  			cpusPath + "/cpu1",
  1010  		},
  1011  	}
  1012  	fakeSys.SetCPUsPaths(cpusPaths, nil)
  1013  
  1014  	coreThread := map[string]string{
  1015  		cpusPath + "/cpu0": "0",
  1016  		cpusPath + "/cpu1": "0",
  1017  	}
  1018  
  1019  	coreThreadErrors := map[string]error{
  1020  		cpusPath + "/cpu0": nil,
  1021  		cpusPath + "/cpu1": nil,
  1022  	}
  1023  	fakeSys.SetCoreThreads(coreThread, coreThreadErrors)
  1024  
  1025  	physicalPackageIDs := map[string]string{
  1026  		cpusPath + "/cpu0": "0",
  1027  		cpusPath + "/cpu1": "0",
  1028  	}
  1029  
  1030  	physicalPackageIDErrors := map[string]error{
  1031  		cpusPath + "/cpu0": os.ErrNotExist,
  1032  		cpusPath + "/cpu1": os.ErrNotExist,
  1033  	}
  1034  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)
  1035  
  1036  	nodes, cores, err := GetNodesInfo(fakeSys)
  1037  	assert.Nil(t, err)
  1038  	assert.Equal(t, 0, len(nodes))
  1039  	assert.Equal(t, 2, cores)
  1040  }
  1041  
  1042  func TestGetNodesWhenTopologyDirMissingForOneCPU(t *testing.T) {
  1043  	/*
  1044  		Unit test for case in which:
  1045  		- there are two cpus (cpu0 and cpu1) in /sys/devices/system/node/node0/ and /sys/devices/system/cpu
  1046  		- topology directory is missing for cpu1 but it exists for cpu0
  1047  	*/
  1048  	fakeSys := &fakesysfs.FakeSysFs{}
  1049  
  1050  	nodesPaths := []string{
  1051  		"/fakeSysfs/devices/system/node/node0",
  1052  	}
  1053  	fakeSys.SetNodesPaths(nodesPaths, nil)
  1054  
  1055  	cpusPaths := map[string][]string{
  1056  		"/fakeSysfs/devices/system/node/node0": {
  1057  			"/fakeSysfs/devices/system/node/node0/cpu0",
  1058  			"/fakeSysfs/devices/system/node/node0/cpu1",
  1059  		},
  1060  	}
  1061  	fakeSys.SetCPUsPaths(cpusPaths, nil)
  1062  
  1063  	coreThread := map[string]string{
  1064  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1065  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1066  	}
  1067  
  1068  	coreThreadErrors := map[string]error{
  1069  		"/fakeSysfs/devices/system/node/node0/cpu0": nil,
  1070  		"/fakeSysfs/devices/system/node/node0/cpu1": os.ErrNotExist,
  1071  	}
  1072  	fakeSys.SetCoreThreads(coreThread, coreThreadErrors)
  1073  
  1074  	memTotal := "MemTotal:       32817192 kB"
  1075  	fakeSys.SetMemory(memTotal, nil)
  1076  
  1077  	hugePages := []os.FileInfo{
  1078  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
  1079  	}
  1080  	fakeSys.SetHugePages(hugePages, nil)
  1081  
  1082  	hugePageNr := map[string]string{
  1083  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages": "1",
  1084  	}
  1085  	fakeSys.SetHugePagesNr(hugePageNr, nil)
  1086  
  1087  	physicalPackageIDs := map[string]string{
  1088  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1089  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1090  	}
  1091  
  1092  	physicalPackageIDErrors := map[string]error{
  1093  		"/fakeSysfs/devices/system/node/node0/cpu0": nil,
  1094  		"/fakeSysfs/devices/system/node/node0/cpu1": os.ErrNotExist,
  1095  	}
  1096  
  1097  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)
  1098  
  1099  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node0", "10", nil)
  1100  
  1101  	nodes, cores, err := GetNodesInfo(fakeSys)
  1102  	assert.Nil(t, err)
  1103  
  1104  	assert.Equal(t, 1, len(nodes))
  1105  	assert.Equal(t, 1, cores)
  1106  
  1107  	sort.Slice(nodes, func(i, j int) bool {
  1108  		return nodes[i].Id < nodes[j].Id
  1109  	})
  1110  
  1111  	nodesJSON, err := json.Marshal(nodes)
  1112  	assert.Nil(t, err)
  1113  
  1114  	expectedNodes := `[
  1115  		{
  1116  		   "node_id":0,
  1117  		   "memory":33604804608,
  1118             "distances" : [
  1119               10
  1120             ],
  1121  		   "hugepages":[
  1122  			  {
  1123  				 "page_size":2048,
  1124  				 "num_pages":1
  1125  			  }
  1126  		   ],
  1127  		   "cores":[
  1128  			  {
  1129  				 "core_id":0,
  1130  				 "thread_ids":[
  1131  					0
  1132  				 ],
  1133  				 "caches":null,
  1134  				 "socket_id":0,
  1135  				 "uncore_caches":null
  1136  			  }
  1137  		   ],
  1138  		   "caches": null
  1139  		}
  1140  	 ]`
  1141  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
  1142  }
  1143  
  1144  func TestGetNodesWhenPhysicalPackageIDMissingForOneCPU(t *testing.T) {
  1145  	fakeSys := &fakesysfs.FakeSysFs{}
  1146  
  1147  	nodesPaths := []string{
  1148  		"/fakeSysfs/devices/system/node/node0",
  1149  	}
  1150  	fakeSys.SetNodesPaths(nodesPaths, nil)
  1151  
  1152  	cpusPaths := map[string][]string{
  1153  		"/fakeSysfs/devices/system/node/node0": {
  1154  			"/fakeSysfs/devices/system/node/node0/cpu0",
  1155  			"/fakeSysfs/devices/system/node/node0/cpu1",
  1156  		},
  1157  	}
  1158  	fakeSys.SetCPUsPaths(cpusPaths, nil)
  1159  
  1160  	coreThread := map[string]string{
  1161  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1162  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1163  	}
  1164  
  1165  	coreThreadErrors := map[string]error{
  1166  		"/fakeSysfs/devices/system/node/node0/cpu0": nil,
  1167  		"/fakeSysfs/devices/system/node/node0/cpu1": nil,
  1168  	}
  1169  	fakeSys.SetCoreThreads(coreThread, coreThreadErrors)
  1170  
  1171  	memTotal := "MemTotal:       32817192 kB"
  1172  	fakeSys.SetMemory(memTotal, nil)
  1173  
  1174  	hugePages := []os.FileInfo{
  1175  		&fakesysfs.FileInfo{EntryName: "hugepages-2048kB"},
  1176  	}
  1177  	fakeSys.SetHugePages(hugePages, nil)
  1178  
  1179  	hugePageNr := map[string]string{
  1180  		"/fakeSysfs/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages": "1",
  1181  	}
  1182  	fakeSys.SetHugePagesNr(hugePageNr, nil)
  1183  
  1184  	physicalPackageIDs := map[string]string{
  1185  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1186  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1187  	}
  1188  
  1189  	physicalPackageIDErrors := map[string]error{
  1190  		"/fakeSysfs/devices/system/node/node0/cpu0": nil,
  1191  		"/fakeSysfs/devices/system/node/node0/cpu1": os.ErrNotExist,
  1192  	}
  1193  
  1194  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, physicalPackageIDErrors)
  1195  
  1196  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node0", "10", nil)
  1197  
  1198  	nodes, cores, err := GetNodesInfo(fakeSys)
  1199  	assert.Nil(t, err)
  1200  
  1201  	assert.Equal(t, 1, len(nodes))
  1202  	assert.Equal(t, 1, cores)
  1203  
  1204  	sort.Slice(nodes, func(i, j int) bool {
  1205  		return nodes[i].Id < nodes[j].Id
  1206  	})
  1207  
  1208  	nodesJSON, err := json.Marshal(nodes)
  1209  	assert.Nil(t, err)
  1210  
  1211  	expectedNodes := `[
  1212  		{
  1213  		   "node_id":0,
  1214  		   "memory":33604804608,
  1215             "distances" : [
  1216               10
  1217             ],
  1218  		   "hugepages":[
  1219  			  {
  1220  				 "page_size":2048,
  1221  				 "num_pages":1
  1222  			  }
  1223  		   ],
  1224  		   "cores":[
  1225  			  {
  1226  				 "core_id":0,
  1227  				 "thread_ids":[
  1228  					0
  1229  				 ],
  1230  				 "caches":null,
  1231  				 "socket_id":0,
  1232  				 "uncore_caches": null
  1233  			  }
  1234  		   ],
  1235  		   "caches": null
  1236  		}
  1237  	 ]`
  1238  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
  1239  }
  1240  
  1241  func TestGetNodeMemInfo(t *testing.T) {
  1242  	fakeSys := &fakesysfs.FakeSysFs{}
  1243  	memTotal := "MemTotal:       32817192 kB"
  1244  	fakeSys.SetMemory(memTotal, nil)
  1245  
  1246  	mem, err := getNodeMemInfo(fakeSys, "/fakeSysfs/devices/system/node/node0")
  1247  	assert.Nil(t, err)
  1248  	assert.Equal(t, uint64(32817192*1024), mem)
  1249  }
  1250  
  1251  func TestGetNodeMemInfoWithMissingMemTotaInMemInfo(t *testing.T) {
  1252  	fakeSys := &fakesysfs.FakeSysFs{}
  1253  	memTotal := "MemXXX:       32817192 kB"
  1254  	fakeSys.SetMemory(memTotal, nil)
  1255  
  1256  	mem, err := getNodeMemInfo(fakeSys, "/fakeSysfs/devices/system/node/node0")
  1257  	assert.NotNil(t, err)
  1258  	assert.Equal(t, uint64(0), mem)
  1259  }
  1260  
  1261  func TestGetNodeMemInfoWhenMemInfoMissing(t *testing.T) {
  1262  	fakeSys := &fakesysfs.FakeSysFs{}
  1263  	memTotal := ""
  1264  	fakeSys.SetMemory(memTotal, fmt.Errorf("Cannot read meminfo file"))
  1265  
  1266  	mem, err := getNodeMemInfo(fakeSys, "/fakeSysfs/devices/system/node/node0")
  1267  	assert.Nil(t, err)
  1268  	assert.Equal(t, uint64(0), mem)
  1269  }
  1270  
  1271  func TestGetCoresInfoWhenCoreIDIsNotDigit(t *testing.T) {
  1272  	sysFs := &fakesysfs.FakeSysFs{}
  1273  	nodesPaths := []string{
  1274  		"/fakeSysfs/devices/system/node/node0",
  1275  	}
  1276  	sysFs.SetNodesPaths(nodesPaths, nil)
  1277  
  1278  	cpusPaths := map[string][]string{
  1279  		"/fakeSysfs/devices/system/node/node0": {
  1280  			"/fakeSysfs/devices/system/node/node0/cpu0",
  1281  		},
  1282  	}
  1283  	sysFs.SetCPUsPaths(cpusPaths, nil)
  1284  
  1285  	coreThread := map[string]string{
  1286  		"/fakeSysfs/devices/system/node/node0/cpu0": "abc",
  1287  	}
  1288  	sysFs.SetCoreThreads(coreThread, nil)
  1289  
  1290  	cores, err := getCoresInfo(sysFs, []string{"/fakeSysfs/devices/system/node/node0/cpu0"})
  1291  	assert.NotNil(t, err)
  1292  	assert.Equal(t, []info.Core(nil), cores)
  1293  }
  1294  
  1295  func TestGetCoresInfoWithOnlineOfflineFile(t *testing.T) {
  1296  	sysFs := &fakesysfs.FakeSysFs{}
  1297  	nodesPaths := []string{
  1298  		"/fakeSysfs/devices/system/node/node0",
  1299  	}
  1300  	sysFs.SetNodesPaths(nodesPaths, nil)
  1301  
  1302  	cpusPaths := map[string][]string{
  1303  		"/fakeSysfs/devices/system/node/node0": {
  1304  			"/fakeSysfs/devices/system/node/node0/cpu0",
  1305  			"/fakeSysfs/devices/system/node/node0/cpu1",
  1306  		},
  1307  	}
  1308  	sysFs.SetCPUsPaths(cpusPaths, nil)
  1309  
  1310  	coreThread := map[string]string{
  1311  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1312  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1313  	}
  1314  	sysFs.SetCoreThreads(coreThread, nil)
  1315  	sysFs.SetOnlineCPUs(map[string]interface{}{"/fakeSysfs/devices/system/node/node0/cpu0": nil})
  1316  	sysFs.SetPhysicalPackageIDs(map[string]string{
  1317  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1318  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1319  	}, nil)
  1320  
  1321  	cores, err := getCoresInfo(
  1322  		sysFs,
  1323  		[]string{"/fakeSysfs/devices/system/node/node0/cpu0", "/fakeSysfs/devices/system/node/node0/cpu1"},
  1324  	)
  1325  	assert.NoError(t, err)
  1326  	expected := []info.Core{
  1327  		{
  1328  			Id:       0,
  1329  			Threads:  []int{0},
  1330  			Caches:   nil,
  1331  			SocketID: 0,
  1332  		},
  1333  	}
  1334  	assert.Equal(t, expected, cores)
  1335  }
  1336  
  1337  func TestGetBlockDeviceInfo(t *testing.T) {
  1338  	fakeSys := fakesysfs.FakeSysFs{}
  1339  	disks, err := GetBlockDeviceInfo(&fakeSys)
  1340  	if err != nil {
  1341  		t.Errorf("expected call to GetBlockDeviceInfo() to succeed. Failed with %s", err)
  1342  	}
  1343  	if len(disks) != 1 {
  1344  		t.Errorf("expected to get one disk entry. Got %d", len(disks))
  1345  	}
  1346  	key := "8:0"
  1347  	disk, ok := disks[key]
  1348  	if !ok {
  1349  		t.Fatalf("expected key 8:0 to exist in the disk map.")
  1350  	}
  1351  	if disk.Name != "sda" {
  1352  		t.Errorf("expected to get disk named sda. Got %q", disk.Name)
  1353  	}
  1354  	size := uint64(1234567 * 512)
  1355  	if disk.Size != size {
  1356  		t.Errorf("expected to get disk size of %d. Got %d", size, disk.Size)
  1357  	}
  1358  	if disk.Scheduler != "cfq" {
  1359  		t.Errorf("expected to get scheduler type of cfq. Got %q", disk.Scheduler)
  1360  	}
  1361  }
  1362  
  1363  func TestGetNetworkDevices(t *testing.T) {
  1364  	fakeSys := fakesysfs.FakeSysFs{}
  1365  	fakeSys.SetEntryName("eth0")
  1366  	devs, err := GetNetworkDevices(&fakeSys)
  1367  	if err != nil {
  1368  		t.Errorf("expected call to GetNetworkDevices() to succeed. Failed with %s", err)
  1369  	}
  1370  	if len(devs) != 1 {
  1371  		t.Errorf("expected to get one network device. Got %d", len(devs))
  1372  	}
  1373  	eth := devs[0]
  1374  	if eth.Name != "eth0" {
  1375  		t.Errorf("expected to find device with name eth0. Found name %q", eth.Name)
  1376  	}
  1377  	if eth.Mtu != 1024 {
  1378  		t.Errorf("expected mtu to be set to 1024. Found %d", eth.Mtu)
  1379  	}
  1380  	if eth.Speed != 1000 {
  1381  		t.Errorf("expected device speed to be set to 1000. Found %d", eth.Speed)
  1382  	}
  1383  	if eth.MacAddress != "42:01:02:03:04:f4" {
  1384  		t.Errorf("expected mac address to be '42:01:02:03:04:f4'. Found %q", eth.MacAddress)
  1385  	}
  1386  }
  1387  
  1388  func TestIgnoredNetworkDevices(t *testing.T) {
  1389  	fakeSys := fakesysfs.FakeSysFs{}
  1390  	ignoredDevices := []string{"veth1234", "lo", "docker0", "nerdctl0"}
  1391  	for _, name := range ignoredDevices {
  1392  		fakeSys.SetEntryName(name)
  1393  		devs, err := GetNetworkDevices(&fakeSys)
  1394  		if err != nil {
  1395  			t.Errorf("expected call to GetNetworkDevices() to succeed. Failed with %s", err)
  1396  		}
  1397  		if len(devs) != 0 {
  1398  			t.Errorf("expected dev %s to be ignored, but got info %+v", name, devs)
  1399  		}
  1400  	}
  1401  }
  1402  
  1403  func TestGetCacheInfo(t *testing.T) {
  1404  	fakeSys := &fakesysfs.FakeSysFs{}
  1405  	cacheInfo := sysfs.CacheInfo{
  1406  		Id:    0,
  1407  		Size:  1024,
  1408  		Type:  "Data",
  1409  		Level: 3,
  1410  		Cpus:  16,
  1411  	}
  1412  	fakeSys.SetCacheInfo(cacheInfo)
  1413  	caches, err := GetCacheInfo(fakeSys, 0)
  1414  	if err != nil {
  1415  		t.Errorf("expected call to GetCacheInfo() to succeed. Failed with %s", err)
  1416  	}
  1417  	if len(caches) != 1 {
  1418  		t.Errorf("expected to get one cache. Got %d", len(caches))
  1419  	}
  1420  	if caches[0] != cacheInfo {
  1421  		t.Errorf("expected to find cacheinfo %+v. Got %+v", cacheInfo, caches[0])
  1422  	}
  1423  }
  1424  
  1425  func TestGetNetworkStats(t *testing.T) {
  1426  	expectedStats := info.InterfaceStats{
  1427  		Name:      "eth0",
  1428  		RxBytes:   1024,
  1429  		RxPackets: 1024,
  1430  		RxErrors:  1024,
  1431  		RxDropped: 1024,
  1432  		TxBytes:   1024,
  1433  		TxPackets: 1024,
  1434  		TxErrors:  1024,
  1435  		TxDropped: 1024,
  1436  	}
  1437  	fakeSys := &fakesysfs.FakeSysFs{}
  1438  	netStats, err := getNetworkStats("eth0", fakeSys)
  1439  	if err != nil {
  1440  		t.Errorf("call to getNetworkStats() failed with %s", err)
  1441  	}
  1442  	if expectedStats != netStats {
  1443  		t.Errorf("expected to get stats %+v, got %+v", expectedStats, netStats)
  1444  	}
  1445  }
  1446  
  1447  func TestGetSocketFromCPU(t *testing.T) {
  1448  	topology := []info.Node{
  1449  		{
  1450  			Id:        0,
  1451  			Memory:    0,
  1452  			HugePages: nil,
  1453  			Cores: []info.Core{
  1454  				{
  1455  					Id:       0,
  1456  					Threads:  []int{0, 1},
  1457  					Caches:   nil,
  1458  					SocketID: 0,
  1459  				},
  1460  				{
  1461  					Id:       1,
  1462  					Threads:  []int{2, 3},
  1463  					Caches:   nil,
  1464  					SocketID: 0,
  1465  				},
  1466  			},
  1467  			Caches: nil,
  1468  		},
  1469  		{
  1470  			Id:        1,
  1471  			Memory:    0,
  1472  			HugePages: nil,
  1473  			Cores: []info.Core{
  1474  				{
  1475  					Id:       0,
  1476  					Threads:  []int{4, 5},
  1477  					Caches:   nil,
  1478  					SocketID: 1,
  1479  				},
  1480  				{
  1481  					Id:       1,
  1482  					Threads:  []int{6, 7},
  1483  					Caches:   nil,
  1484  					SocketID: 1,
  1485  				},
  1486  			},
  1487  			Caches: nil,
  1488  		},
  1489  	}
  1490  	socket := GetSocketFromCPU(topology, 6)
  1491  	assert.Equal(t, socket, 1)
  1492  
  1493  	// Check if return "-1" when there is no data about passed CPU.
  1494  	socket = GetSocketFromCPU(topology, 8)
  1495  	assert.Equal(t, socket, -1)
  1496  }
  1497  
  1498  func TestGetOnlineCPUs(t *testing.T) {
  1499  	topology := []info.Node{
  1500  		{
  1501  			Id:        0,
  1502  			Memory:    0,
  1503  			HugePages: nil,
  1504  			Cores: []info.Core{
  1505  				{
  1506  					Id:       0,
  1507  					Threads:  []int{0, 1},
  1508  					Caches:   nil,
  1509  					SocketID: 0,
  1510  				},
  1511  				{
  1512  					Id:       1,
  1513  					Threads:  []int{2, 3},
  1514  					Caches:   nil,
  1515  					SocketID: 0,
  1516  				},
  1517  			},
  1518  			Caches: nil,
  1519  		},
  1520  		{
  1521  			Id:        1,
  1522  			Memory:    0,
  1523  			HugePages: nil,
  1524  			Cores: []info.Core{
  1525  				{
  1526  					Id:       0,
  1527  					Threads:  []int{4, 5},
  1528  					Caches:   nil,
  1529  					SocketID: 1,
  1530  				},
  1531  				{
  1532  					Id:       1,
  1533  					Threads:  []int{6, 7},
  1534  					Caches:   nil,
  1535  					SocketID: 1,
  1536  				},
  1537  			},
  1538  			Caches: nil,
  1539  		},
  1540  	}
  1541  	onlineCPUs := GetOnlineCPUs(topology)
  1542  	assert.Equal(t, onlineCPUs, []int{0, 1, 2, 3, 4, 5, 6, 7})
  1543  }
  1544  
  1545  func TestGetNodesInfoWithUncoreCacheInfo(t *testing.T) {
  1546  	fakeSys := &fakesysfs.FakeSysFs{}
  1547  	c := sysfs.CacheInfo{
  1548  		Id:    0,
  1549  		Size:  32 * 1024,
  1550  		Type:  "unified",
  1551  		Level: 3,
  1552  		Cpus:  8,
  1553  	}
  1554  	fakeSys.SetCacheInfo(c)
  1555  
  1556  	nodesPaths := []string{
  1557  		"/fakeSysfs/devices/system/node/node0",
  1558  		"/fakeSysfs/devices/system/node/node1",
  1559  	}
  1560  	fakeSys.SetNodesPaths(nodesPaths, nil)
  1561  
  1562  	memTotal := "MemTotal:       32817192 kB"
  1563  	fakeSys.SetMemory(memTotal, nil)
  1564  
  1565  	cpusPaths := map[string][]string{
  1566  		"/fakeSysfs/devices/system/node/node0": {
  1567  			"/fakeSysfs/devices/system/node/node0/cpu0",
  1568  			"/fakeSysfs/devices/system/node/node0/cpu1",
  1569  		},
  1570  		"/fakeSysfs/devices/system/node/node1": {
  1571  			"/fakeSysfs/devices/system/node/node0/cpu2",
  1572  			"/fakeSysfs/devices/system/node/node0/cpu3",
  1573  		},
  1574  	}
  1575  	fakeSys.SetCPUsPaths(cpusPaths, nil)
  1576  
  1577  	coreThread := map[string]string{
  1578  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1579  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1580  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
  1581  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
  1582  	}
  1583  	fakeSys.SetCoreThreads(coreThread, nil)
  1584  	physicalPackageIDs := map[string]string{
  1585  		"/fakeSysfs/devices/system/node/node0/cpu0": "0",
  1586  		"/fakeSysfs/devices/system/node/node0/cpu1": "0",
  1587  		"/fakeSysfs/devices/system/node/node0/cpu2": "1",
  1588  		"/fakeSysfs/devices/system/node/node0/cpu3": "1",
  1589  	}
  1590  	fakeSys.SetPhysicalPackageIDs(physicalPackageIDs, nil)
  1591  
  1592  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node0", "10 11", nil)
  1593  	fakeSys.SetDistances("/fakeSysfs/devices/system/node/node1", "11 10", nil)
  1594  
  1595  	nodes, cores, err := GetNodesInfo(fakeSys)
  1596  	assert.Nil(t, err)
  1597  	fmt.Println(err)
  1598  	assert.Equal(t, 2, len(nodes))
  1599  	assert.Equal(t, 4, cores)
  1600  
  1601  	nodesJSON, err := json.Marshal(nodes)
  1602  	assert.Nil(t, err)
  1603  	expectedNodes := `
  1604  	[
  1605        {
  1606          "node_id": 0,
  1607          "memory": 33604804608,
  1608          "distances" : [
  1609            10,
  1610            11
  1611          ],
  1612          "hugepages": null,
  1613          "cores": [
  1614            {
  1615              "core_id": 0,
  1616              "thread_ids": [
  1617                0,
  1618                1
  1619              ],
  1620              "caches": null,
  1621              "uncore_caches": [
  1622                  {
  1623                    "id": 0,
  1624                    "size": 32768,
  1625                    "type": "unified",
  1626                    "level": 3
  1627                  }
  1628              ],
  1629              "socket_id": 0
  1630            }
  1631          ],
  1632          "caches": null
  1633        },
  1634        {
  1635          "node_id": 1,
  1636          "memory": 33604804608,
  1637          "distances" : [
  1638            11,
  1639            10
  1640          ],
  1641          "hugepages": null,
  1642          "cores": [
  1643            {
  1644              "core_id": 1,
  1645              "thread_ids": [
  1646                2,
  1647                3
  1648              ],
  1649              "caches": null,
  1650              "uncore_caches": [
  1651                  {
  1652                    "id": 0,
  1653                    "size": 32768,
  1654                    "type": "unified",
  1655                    "level": 3
  1656                  }
  1657              ],
  1658              "socket_id": 1
  1659            }
  1660          ],
  1661          "caches": null
  1662        }
  1663      ]`
  1664  	assert.JSONEq(t, expectedNodes, string(nodesJSON))
  1665  }
  1666  
  1667  func TestGetDistances(t *testing.T) {
  1668  	fakeSys := &fakesysfs.FakeSysFs{}
  1669  	node := "/fakeSysfs/devices/system/node/node0"
  1670  	fakeSys.SetDistances(node, "10 11", nil)
  1671  
  1672  	distances, err := getDistances(fakeSys, node)
  1673  	assert.Nil(t, err)
  1674  	assert.Len(t, distances, 2)
  1675  	assert.Equal(t, uint64(10), distances[0])
  1676  	assert.Equal(t, uint64(11), distances[1])
  1677  }
  1678  
  1679  func TestGetDistancesMissingDistances(t *testing.T) {
  1680  	fakeSys := &fakesysfs.FakeSysFs{}
  1681  	node := "/fakeSysfs/devices/system/node/node0"
  1682  	fakeSys.SetDistances(node, "10 11", fmt.Errorf("no distances file"))
  1683  
  1684  	distances, err := getDistances(fakeSys, node)
  1685  	assert.Nil(t, err)
  1686  	assert.Len(t, distances, 0)
  1687  }