open-nomad/command/helper_devices_test.go

291 lines
5.9 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package command
import (
"testing"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/nomad/ci"
"github.com/hashicorp/nomad/helper/pointer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDeviceQualifiedID(t *testing.T) {
ci.Parallel(t)
require := require.New(t)
require.Equal("vendor/type/name[id]", deviceQualifiedID("vendor", "type", "name", "id"))
require.Equal("vendor/type[id]", deviceQualifiedID("vendor", "type", "", "id"))
require.Equal("vendor[id]", deviceQualifiedID("vendor", "", "", "id"))
}
func TestBuildDeviceStatsSummaryMap(t *testing.T) {
ci.Parallel(t)
hostDeviceStats := []*api.DeviceGroupStats{
{
Vendor: "vendor1",
Type: "type1",
Name: "name1",
InstanceStats: map[string]*api.DeviceStats{
"id1": {
Summary: &api.StatValue{
StringVal: pointer.Of("stat1"),
},
},
"id2": {
Summary: &api.StatValue{
IntNumeratorVal: pointer.Of(int64(2)),
},
},
},
},
{
Vendor: "vendor2",
Type: "type2",
InstanceStats: map[string]*api.DeviceStats{
"id1": {
Summary: &api.StatValue{
StringVal: pointer.Of("stat3"),
},
},
"id2": {
Summary: &api.StatValue{
IntNumeratorVal: pointer.Of(int64(4)),
},
},
},
},
}
expected := map[string]*api.StatValue{
"vendor1/type1/name1[id1]": {
StringVal: pointer.Of("stat1"),
},
"vendor1/type1/name1[id2]": {
IntNumeratorVal: pointer.Of(int64(2)),
},
"vendor2/type2[id1]": {
StringVal: pointer.Of("stat3"),
},
"vendor2/type2[id2]": {
IntNumeratorVal: pointer.Of(int64(4)),
},
}
require.EqualValues(t, expected, buildDeviceStatsSummaryMap(hostDeviceStats))
}
func TestFormatDeviceStats(t *testing.T) {
ci.Parallel(t)
statValue := func(v string) *api.StatValue {
return &api.StatValue{
StringVal: pointer.Of(v),
}
}
stat := &api.StatObject{
Attributes: map[string]*api.StatValue{
"a0": statValue("va0"),
"k0": statValue("v0"),
},
Nested: map[string]*api.StatObject{
"nested1": {
Attributes: map[string]*api.StatValue{
"k1_0": statValue("v1_0"),
"k1_1": statValue("v1_1"),
},
Nested: map[string]*api.StatObject{
"nested1_1": {
Attributes: map[string]*api.StatValue{
"k11_0": statValue("v11_0"),
"k11_1": statValue("v11_1"),
},
},
},
},
"nested2": {
Attributes: map[string]*api.StatValue{
"k2": statValue("v2"),
},
},
},
}
result := formatDeviceStats("TestDeviceID", stat)
// check that device id always appears first
require.Equal(t, "Device|TestDeviceID", result[0])
// check rest of values
expected := []string{
"Device|TestDeviceID",
"a0|va0",
"k0|v0",
"nested1.k1_0|v1_0",
"nested1.k1_1|v1_1",
"nested1.nested1_1.k11_0|v11_0",
"nested1.nested1_1.k11_1|v11_1",
"nested2.k2|v2",
}
require.Equal(t, expected, result)
}
func TestNodeStatusCommand_GetDeviceResourcesForNode(t *testing.T) {
ci.Parallel(t)
hostDeviceStats := []*api.DeviceGroupStats{
{
Vendor: "vendor1",
Type: "type1",
Name: "name1",
InstanceStats: map[string]*api.DeviceStats{
"id1": {
Summary: &api.StatValue{
StringVal: pointer.Of("stat1"),
},
},
"id2": {
Summary: &api.StatValue{
IntNumeratorVal: pointer.Of(int64(2)),
},
},
},
},
{
Vendor: "vendor2",
Type: "type2",
InstanceStats: map[string]*api.DeviceStats{
"id1": {
Summary: &api.StatValue{
StringVal: pointer.Of("stat3"),
},
},
"id2": {
Summary: &api.StatValue{
IntNumeratorVal: pointer.Of(int64(4)),
},
},
},
},
}
node := &api.Node{
NodeResources: &api.NodeResources{
Devices: []*api.NodeDeviceResource{
{
Vendor: "vendor2",
Type: "type2",
Instances: []*api.NodeDevice{
{ID: "id1"},
{ID: "id2"},
},
},
{
Vendor: "vendor1",
Type: "type1",
Name: "name1",
Instances: []*api.NodeDevice{
{ID: "id1"},
{ID: "id2"},
},
},
},
},
}
formattedDevices := getDeviceResourcesForNode(hostDeviceStats, node)
expected := []string{
"vendor1/type1/name1[id1]|stat1",
"vendor1/type1/name1[id2]|2",
"vendor2/type2[id1]|stat3",
"vendor2/type2[id2]|4",
}
assert.Equal(t, expected, formattedDevices)
}
func TestNodeStatusCommand_GetDeviceResources(t *testing.T) {
ci.Parallel(t)
hostDeviceStats := []*api.DeviceGroupStats{
{
Vendor: "vendor1",
Type: "type1",
Name: "name1",
InstanceStats: map[string]*api.DeviceStats{
"id1": {
Summary: &api.StatValue{
StringVal: pointer.Of("stat1"),
},
},
"id2": {
Summary: &api.StatValue{
IntNumeratorVal: pointer.Of(int64(2)),
},
},
},
},
{
Vendor: "vendor2",
Type: "type2",
InstanceStats: map[string]*api.DeviceStats{
"id1": {
Summary: &api.StatValue{
StringVal: pointer.Of("stat3"),
},
},
"id2": {
Summary: &api.StatValue{
IntNumeratorVal: pointer.Of(int64(4)),
},
},
},
},
}
formattedDevices := getDeviceResources(hostDeviceStats)
expected := []string{
"vendor1/type1/name1[id1]|stat1",
"vendor1/type1/name1[id2]|2",
"vendor2/type2[id1]|stat3",
"vendor2/type2[id2]|4",
}
assert.Equal(t, expected, formattedDevices)
}
func TestGetDeviceAttributes(t *testing.T) {
ci.Parallel(t)
d := &api.NodeDeviceResource{
Vendor: "Vendor",
Type: "Type",
Name: "Name",
Attributes: map[string]*api.Attribute{
"utilization": {
FloatVal: pointer.Of(float64(0.78)),
Unit: "%",
},
"filesystem": {
StringVal: pointer.Of("ext4"),
},
},
}
formattedDevices := getDeviceAttributes(d)
expected := []string{
"Device Group|Vendor/Type/Name",
"filesystem|ext4",
"utilization|0.78 %",
}
assert.Equal(t, expected, formattedDevices)
}