1package command
2
3import (
4	"testing"
5
6	"github.com/hashicorp/nomad/api"
7	"github.com/hashicorp/nomad/helper"
8	"github.com/stretchr/testify/assert"
9	"github.com/stretchr/testify/require"
10)
11
12func TestDeviceQualifiedID(t *testing.T) {
13
14	require := require.New(t)
15
16	require.Equal("vendor/type/name[id]", deviceQualifiedID("vendor", "type", "name", "id"))
17	require.Equal("vendor/type[id]", deviceQualifiedID("vendor", "type", "", "id"))
18	require.Equal("vendor[id]", deviceQualifiedID("vendor", "", "", "id"))
19}
20
21func TestBuildDeviceStatsSummaryMap(t *testing.T) {
22	hostDeviceStats := []*api.DeviceGroupStats{
23		{
24			Vendor: "vendor1",
25			Type:   "type1",
26			Name:   "name1",
27			InstanceStats: map[string]*api.DeviceStats{
28				"id1": {
29					Summary: &api.StatValue{
30						StringVal: helper.StringToPtr("stat1"),
31					},
32				},
33				"id2": {
34					Summary: &api.StatValue{
35						IntNumeratorVal: helper.Int64ToPtr(2),
36					},
37				},
38			},
39		},
40		{
41			Vendor: "vendor2",
42			Type:   "type2",
43			InstanceStats: map[string]*api.DeviceStats{
44				"id1": {
45					Summary: &api.StatValue{
46						StringVal: helper.StringToPtr("stat3"),
47					},
48				},
49				"id2": {
50					Summary: &api.StatValue{
51						IntNumeratorVal: helper.Int64ToPtr(4),
52					},
53				},
54			},
55		},
56	}
57
58	expected := map[string]*api.StatValue{
59		"vendor1/type1/name1[id1]": {
60			StringVal: helper.StringToPtr("stat1"),
61		},
62		"vendor1/type1/name1[id2]": {
63			IntNumeratorVal: helper.Int64ToPtr(2),
64		},
65		"vendor2/type2[id1]": {
66			StringVal: helper.StringToPtr("stat3"),
67		},
68		"vendor2/type2[id2]": {
69			IntNumeratorVal: helper.Int64ToPtr(4),
70		},
71	}
72
73	require.EqualValues(t, expected, buildDeviceStatsSummaryMap(hostDeviceStats))
74}
75
76func TestFormatDeviceStats(t *testing.T) {
77	statValue := func(v string) *api.StatValue {
78		return &api.StatValue{
79			StringVal: helper.StringToPtr(v),
80		}
81	}
82
83	stat := &api.StatObject{
84		Attributes: map[string]*api.StatValue{
85			"a0": statValue("va0"),
86			"k0": statValue("v0"),
87		},
88		Nested: map[string]*api.StatObject{
89			"nested1": {
90				Attributes: map[string]*api.StatValue{
91					"k1_0": statValue("v1_0"),
92					"k1_1": statValue("v1_1"),
93				},
94				Nested: map[string]*api.StatObject{
95					"nested1_1": {
96						Attributes: map[string]*api.StatValue{
97							"k11_0": statValue("v11_0"),
98							"k11_1": statValue("v11_1"),
99						},
100					},
101				},
102			},
103			"nested2": {
104				Attributes: map[string]*api.StatValue{
105					"k2": statValue("v2"),
106				},
107			},
108		},
109	}
110
111	result := formatDeviceStats("TestDeviceID", stat)
112
113	// check that device id always appears first
114	require.Equal(t, "Device|TestDeviceID", result[0])
115
116	// check rest of values
117	expected := []string{
118		"Device|TestDeviceID",
119		"a0|va0",
120		"k0|v0",
121		"nested1.k1_0|v1_0",
122		"nested1.k1_1|v1_1",
123		"nested1.nested1_1.k11_0|v11_0",
124		"nested1.nested1_1.k11_1|v11_1",
125		"nested2.k2|v2",
126	}
127
128	require.Equal(t, expected, result)
129}
130
131func TestNodeStatusCommand_GetDeviceResourcesForNode(t *testing.T) {
132	hostDeviceStats := []*api.DeviceGroupStats{
133		{
134			Vendor: "vendor1",
135			Type:   "type1",
136			Name:   "name1",
137			InstanceStats: map[string]*api.DeviceStats{
138				"id1": {
139					Summary: &api.StatValue{
140						StringVal: helper.StringToPtr("stat1"),
141					},
142				},
143				"id2": {
144					Summary: &api.StatValue{
145						IntNumeratorVal: helper.Int64ToPtr(2),
146					},
147				},
148			},
149		},
150		{
151			Vendor: "vendor2",
152			Type:   "type2",
153			InstanceStats: map[string]*api.DeviceStats{
154				"id1": {
155					Summary: &api.StatValue{
156						StringVal: helper.StringToPtr("stat3"),
157					},
158				},
159				"id2": {
160					Summary: &api.StatValue{
161						IntNumeratorVal: helper.Int64ToPtr(4),
162					},
163				},
164			},
165		},
166	}
167
168	node := &api.Node{
169		NodeResources: &api.NodeResources{
170			Devices: []*api.NodeDeviceResource{
171				{
172					Vendor: "vendor2",
173					Type:   "type2",
174					Instances: []*api.NodeDevice{
175						{ID: "id1"},
176						{ID: "id2"},
177					},
178				},
179				{
180					Vendor: "vendor1",
181					Type:   "type1",
182					Name:   "name1",
183					Instances: []*api.NodeDevice{
184						{ID: "id1"},
185						{ID: "id2"},
186					},
187				},
188			},
189		},
190	}
191
192	formattedDevices := getDeviceResourcesForNode(hostDeviceStats, node)
193	expected := []string{
194		"vendor1/type1/name1[id1]|stat1",
195		"vendor1/type1/name1[id2]|2",
196		"vendor2/type2[id1]|stat3",
197		"vendor2/type2[id2]|4",
198	}
199
200	assert.Equal(t, expected, formattedDevices)
201}
202
203func TestNodeStatusCommand_GetDeviceResources(t *testing.T) {
204	hostDeviceStats := []*api.DeviceGroupStats{
205		{
206			Vendor: "vendor1",
207			Type:   "type1",
208			Name:   "name1",
209			InstanceStats: map[string]*api.DeviceStats{
210				"id1": {
211					Summary: &api.StatValue{
212						StringVal: helper.StringToPtr("stat1"),
213					},
214				},
215				"id2": {
216					Summary: &api.StatValue{
217						IntNumeratorVal: helper.Int64ToPtr(2),
218					},
219				},
220			},
221		},
222		{
223			Vendor: "vendor2",
224			Type:   "type2",
225			InstanceStats: map[string]*api.DeviceStats{
226				"id1": {
227					Summary: &api.StatValue{
228						StringVal: helper.StringToPtr("stat3"),
229					},
230				},
231				"id2": {
232					Summary: &api.StatValue{
233						IntNumeratorVal: helper.Int64ToPtr(4),
234					},
235				},
236			},
237		},
238	}
239
240	formattedDevices := getDeviceResources(hostDeviceStats)
241	expected := []string{
242		"vendor1/type1/name1[id1]|stat1",
243		"vendor1/type1/name1[id2]|2",
244		"vendor2/type2[id1]|stat3",
245		"vendor2/type2[id2]|4",
246	}
247
248	assert.Equal(t, expected, formattedDevices)
249}
250func TestGetDeviceAttributes(t *testing.T) {
251	d := &api.NodeDeviceResource{
252		Vendor: "Vendor",
253		Type:   "Type",
254		Name:   "Name",
255
256		Attributes: map[string]*api.Attribute{
257			"utilization": {
258				FloatVal: helper.Float64ToPtr(0.78),
259				Unit:     "%",
260			},
261			"filesystem": {
262				StringVal: helper.StringToPtr("ext4"),
263			},
264		},
265	}
266
267	formattedDevices := getDeviceAttributes(d)
268	expected := []string{
269		"Device Group|Vendor/Type/Name",
270		"filesystem|ext4",
271		"utilization|0.78 %",
272	}
273
274	assert.Equal(t, expected, formattedDevices)
275}
276