Skip to content

Commit 748abd3

Browse files
committed
libcontainer/configs: add validator unit tests for intelRdt
Signed-off-by: Markus Lehtonen <markus.lehtonen@intel.com>
1 parent e2b0791 commit 748abd3

2 files changed

Lines changed: 152 additions & 3 deletions

File tree

libcontainer/configs/validate/validator.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ import (
1919

2020
type check func(config *configs.Config) error
2121

22+
// Cache the result of intelrdt IsEnabled functions to avoid repeated sysfs
23+
// access and enable mocking for unit tests.
24+
type intelRdtStatus struct {
25+
sync.Once
26+
rdtEnabled bool
27+
catEnabled bool
28+
mbaEnabled bool
29+
}
30+
31+
var intelRdt = &intelRdtStatus{}
32+
2233
func Validate(config *configs.Config) error {
2334
checks := []check{
2435
cgroupsCheck,
@@ -283,18 +294,18 @@ func sysctl(config *configs.Config) error {
283294

284295
func intelrdtCheck(config *configs.Config) error {
285296
if config.IntelRdt != nil {
286-
if !intelrdt.IsEnabled() {
297+
if !intelRdt.isEnabled() {
287298
return fmt.Errorf("intelRdt is specified in config, but Intel RDT is not enabled")
288299
}
289300

290301
if config.IntelRdt.ClosID == "." || config.IntelRdt.ClosID == ".." || (config.IntelRdt.ClosID != "/" && strings.Contains(config.IntelRdt.ClosID, "/")) {
291302
return fmt.Errorf("invalid intelRdt.ClosID %q", config.IntelRdt.ClosID)
292303
}
293304

294-
if !intelrdt.IsCATEnabled() && config.IntelRdt.L3CacheSchema != "" {
305+
if !intelRdt.isCATEnabled() && config.IntelRdt.L3CacheSchema != "" {
295306
return errors.New("intelRdt.l3CacheSchema is specified in config, but Intel RDT/CAT is not enabled")
296307
}
297-
if !intelrdt.IsMBAEnabled() && config.IntelRdt.MemBwSchema != "" {
308+
if !intelRdt.isMBAEnabled() && config.IntelRdt.MemBwSchema != "" {
298309
return errors.New("intelRdt.memBwSchema is specified in config, but Intel RDT/MBA is not enabled")
299310
}
300311
}
@@ -458,3 +469,26 @@ func ioPriority(config *configs.Config) error {
458469

459470
return nil
460471
}
472+
473+
func (i *intelRdtStatus) init() {
474+
i.Do(func() {
475+
i.rdtEnabled = intelrdt.IsEnabled()
476+
i.catEnabled = intelrdt.IsCATEnabled()
477+
i.mbaEnabled = intelrdt.IsMBAEnabled()
478+
})
479+
}
480+
481+
func (i *intelRdtStatus) isEnabled() bool {
482+
i.init()
483+
return i.rdtEnabled
484+
}
485+
486+
func (i *intelRdtStatus) isCATEnabled() bool {
487+
i.init()
488+
return i.catEnabled
489+
}
490+
491+
func (i *intelRdtStatus) isMBAEnabled() bool {
492+
i.init()
493+
return i.mbaEnabled
494+
}

libcontainer/configs/validate/validator_test.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,3 +1043,118 @@ func TestDevValidName(t *testing.T) {
10431043
})
10441044
}
10451045
}
1046+
1047+
func TestValidateIntelRdt(t *testing.T) {
1048+
// Call init to trigger the sync.Once and enable overriding the rdt status
1049+
intelRdt.init()
1050+
1051+
testCases := []struct {
1052+
name string
1053+
rdtEnabled bool
1054+
catEnabled bool
1055+
mbaEnabled bool
1056+
config *configs.IntelRdt
1057+
isErr bool
1058+
}{
1059+
{
1060+
name: "rdt not supported, no config",
1061+
rdtEnabled: false,
1062+
config: nil,
1063+
isErr: false,
1064+
},
1065+
{
1066+
name: "rdt not supported, with config",
1067+
rdtEnabled: false,
1068+
config: &configs.IntelRdt{},
1069+
isErr: true,
1070+
},
1071+
{
1072+
name: "empty config",
1073+
rdtEnabled: true,
1074+
config: &configs.IntelRdt{},
1075+
isErr: false,
1076+
},
1077+
{
1078+
name: "root clos",
1079+
rdtEnabled: true,
1080+
config: &configs.IntelRdt{
1081+
ClosID: "/",
1082+
},
1083+
isErr: false,
1084+
},
1085+
{
1086+
name: "invalid ClosID (.)",
1087+
rdtEnabled: true,
1088+
config: &configs.IntelRdt{
1089+
ClosID: ".",
1090+
},
1091+
isErr: true,
1092+
},
1093+
{
1094+
name: "invalid ClosID (..)",
1095+
rdtEnabled: true,
1096+
config: &configs.IntelRdt{
1097+
ClosID: "..",
1098+
},
1099+
isErr: true,
1100+
},
1101+
{
1102+
name: "invalid ClosID (contains /)",
1103+
rdtEnabled: true,
1104+
config: &configs.IntelRdt{
1105+
ClosID: "foo/bar",
1106+
},
1107+
isErr: true,
1108+
},
1109+
{
1110+
name: "cat not supported",
1111+
rdtEnabled: true,
1112+
catEnabled: false,
1113+
config: &configs.IntelRdt{
1114+
L3CacheSchema: "0=ff",
1115+
},
1116+
isErr: true,
1117+
},
1118+
{
1119+
name: "mba not supported",
1120+
rdtEnabled: true,
1121+
mbaEnabled: false,
1122+
config: &configs.IntelRdt{
1123+
MemBwSchema: "0=100",
1124+
},
1125+
isErr: true,
1126+
},
1127+
{
1128+
name: "valid config",
1129+
rdtEnabled: true,
1130+
catEnabled: true,
1131+
mbaEnabled: true,
1132+
config: &configs.IntelRdt{
1133+
ClosID: "clos-1",
1134+
L3CacheSchema: "0=ff",
1135+
MemBwSchema: "0=100",
1136+
},
1137+
isErr: false,
1138+
},
1139+
}
1140+
for _, tc := range testCases {
1141+
t.Run(tc.name, func(t *testing.T) {
1142+
intelRdt.rdtEnabled = tc.rdtEnabled
1143+
intelRdt.catEnabled = tc.catEnabled
1144+
intelRdt.mbaEnabled = tc.mbaEnabled
1145+
1146+
config := &configs.Config{
1147+
Rootfs: "/var",
1148+
IntelRdt: tc.config,
1149+
}
1150+
1151+
err := Validate(config)
1152+
if tc.isErr && err == nil {
1153+
t.Error("expected error, got nil")
1154+
}
1155+
if !tc.isErr && err != nil {
1156+
t.Error(err)
1157+
}
1158+
})
1159+
}
1160+
}

0 commit comments

Comments
 (0)