mirror of
https://github.com/clearml/go-nvlib
synced 2025-04-28 01:41:47 +00:00
Merge branch 'add-assert-mig-profile-format' into 'main'
Add function for AssertValidMigProfileFormat See merge request nvidia/cloud-native/go-nvlib!38
This commit is contained in:
commit
bdc2553e78
pkg/nvlib/device
@ -22,6 +22,7 @@ import (
|
||||
|
||||
// Interface provides the API to the 'device' package
|
||||
type Interface interface {
|
||||
AssertValidMigProfileFormat(profile string) error
|
||||
GetDevices() ([]Device, error)
|
||||
GetMigDevices() ([]MigDevice, error)
|
||||
GetMigProfiles() ([]MigProfile, error)
|
||||
|
@ -119,6 +119,12 @@ func (d *devicelib) NewMigProfile(giProfileID, ciProfileID, ciEngProfileID int,
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// AssertValidMigProfileFormat checks if the string is in the proper format to represent a MIG profile
|
||||
func (d *devicelib) AssertValidMigProfileFormat(profile string) error {
|
||||
_, _, _, _, err := parseMigProfile(profile)
|
||||
return err
|
||||
}
|
||||
|
||||
// ParseMigProfile converts a string representation of a MigProfile into an object
|
||||
func (d *devicelib) ParseMigProfile(profile string) (MigProfile, error) {
|
||||
profiles, err := d.GetMigProfiles()
|
||||
@ -181,16 +187,7 @@ func (p *MigProfileInfo) Equals(other MigProfile) bool {
|
||||
|
||||
// Matches checks if a MigProfile matches the string passed in
|
||||
func (p *MigProfileInfo) Matches(profile string) bool {
|
||||
// If we are handed the empty string, there is nothing to check
|
||||
if profile == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Split by + to separate out attributes
|
||||
split := strings.SplitN(profile, "+", 2)
|
||||
|
||||
// Check to make sure the c, g, and gb values match
|
||||
c, g, gb, err := parseMigProfileFields(split[0])
|
||||
c, g, gb, attrs, err := parseMigProfile(profile)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@ -203,17 +200,6 @@ func (p *MigProfileInfo) Matches(profile string) bool {
|
||||
if gb != p.GB {
|
||||
return false
|
||||
}
|
||||
|
||||
// If we have no attributes we are done
|
||||
if len(split) == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
// Make sure we have the same set of attributes
|
||||
attrs, err := parseMigProfileAttributes(split[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if len(attrs) != len(p.Attributes) {
|
||||
return false
|
||||
}
|
||||
@ -224,10 +210,38 @@ func (p *MigProfileInfo) Matches(profile string) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func parseMigProfile(profile string) (int, int, int, []string, error) {
|
||||
// If we are handed the empty string, we cannot parse it
|
||||
if profile == "" {
|
||||
return -1, -1, -1, nil, fmt.Errorf("profile is the empty string")
|
||||
}
|
||||
|
||||
// Split by + to separate out attributes
|
||||
split := strings.SplitN(profile, "+", 2)
|
||||
|
||||
// Check to make sure the c, g, and gb values match
|
||||
c, g, gb, err := parseMigProfileFields(split[0])
|
||||
if err != nil {
|
||||
return -1, -1, -1, nil, fmt.Errorf("cannot parse fields of '%v': %v", profile, err)
|
||||
}
|
||||
|
||||
// If we have no attributes we are done
|
||||
if len(split) == 1 {
|
||||
return c, g, gb, nil, nil
|
||||
}
|
||||
|
||||
// Make sure we have the same set of attributes
|
||||
attrs, err := parseMigProfileAttributes(split[1])
|
||||
if err != nil {
|
||||
return -1, -1, -1, nil, fmt.Errorf("cannot parse attributes of '%v': %v", profile, err)
|
||||
}
|
||||
|
||||
return c, g, gb, attrs, nil
|
||||
}
|
||||
|
||||
func parseMigProfileField(s string, field string) (int, error) {
|
||||
if strings.TrimSpace(s) != s {
|
||||
return -1, fmt.Errorf("leading or trailing spaces on '%%d%s'", field)
|
||||
|
@ -28,232 +28,266 @@ func TestParseMigProfile(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
device string
|
||||
valid bool
|
||||
validFormat bool
|
||||
validDevice bool
|
||||
}{
|
||||
{
|
||||
"Empty device type",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Valid 1g.5gb",
|
||||
"1g.5gb",
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Valid 1c.1g.5gb",
|
||||
"1c.1g.5gb",
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Valid 1g.5gb+me",
|
||||
"1g.5gb+me",
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Valid 1c.1g.5gb+me",
|
||||
"1c.1g.5gb+me",
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"Invalid 0g.0gb",
|
||||
"0g.0gb",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 0c.0g.0gb",
|
||||
"0c.0g.0gb",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 10000g.500000gb",
|
||||
"10000g.500000gb",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 10000c.10000g.500000gb",
|
||||
"10000c.10000g.500000gb",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid ' 1c.1g.5gb'",
|
||||
" 1c.1g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1 c.1g.5gb'",
|
||||
"1 c.1g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c .1g.5gb'",
|
||||
"1c .1g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c. 1g.5gb'",
|
||||
"1c. 1g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c.1 g.5gb'",
|
||||
"1c.1 g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c.1g .5gb'",
|
||||
"1c.1g .5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c.1g. 5gb'",
|
||||
"1c.1g. 5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c.1g.5 gb'",
|
||||
"1c.1g.5 gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c.1g.5g b'",
|
||||
"1c.1g.5g b",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c.1g.5gb '",
|
||||
"1c.1g.5gb ",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid '1c . 1g . 5gb'",
|
||||
"1c . 1g . 5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1c.f1g.5gb",
|
||||
"1c.f1g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1r.1g.5gb",
|
||||
"1r.1g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gbk",
|
||||
"1g.5gbk",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5",
|
||||
"1g.5",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid g.5gb",
|
||||
"1g.5",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid g.5gb",
|
||||
"g.5gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.gb",
|
||||
"1g.gb",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+me,me",
|
||||
"1g.5gb+me,me",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+me,you,them",
|
||||
"1g.5gb+me,you,them",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1c.1g.5gb+me,you,them",
|
||||
"1c.1g.5gb+me,you,them",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+",
|
||||
"1g.5gb+",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb +",
|
||||
"1g.5gb+",
|
||||
"1g.5gb +",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+ ",
|
||||
"1g.5gb+",
|
||||
"1g.5gb+ ",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+ ,",
|
||||
"1g.5gb+",
|
||||
"1g.5gb+ ,",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+,",
|
||||
"1g.5gb+",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+,,",
|
||||
"1g.5gb+",
|
||||
"1g.5gb+,,",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+me,",
|
||||
"1g.5gb+",
|
||||
"1g.5gb+me,",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+me,,",
|
||||
"1g.5gb+",
|
||||
"1g.5gb+me,,",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+me, ",
|
||||
"1g.5gb+",
|
||||
"1g.5gb+me, ",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb+2me",
|
||||
"1g.5gb+2me",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Inavlid 1g.5gb*me",
|
||||
"1g.5gb*me",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1c.1g.5gb*me",
|
||||
"1c.1g.5gb*me",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1g.5gb*me,you,them",
|
||||
"1g.5gb*me,you,them",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid 1c.1g.5gb*me,you,them",
|
||||
"1c.1g.5gb*me,you,them",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Invalid bogus",
|
||||
"bogus",
|
||||
false,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
@ -308,8 +342,14 @@ func TestParseMigProfile(t *testing.T) {
|
||||
d := New(WithNvml(mockNvml), WithVerifySymbols(false))
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
_, err := d.ParseMigProfile(tc.device)
|
||||
if tc.valid {
|
||||
err := d.AssertValidMigProfileFormat(tc.device)
|
||||
if tc.validFormat {
|
||||
require.Nil(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
}
|
||||
_, err = d.ParseMigProfile(tc.device)
|
||||
if tc.validDevice {
|
||||
require.Nil(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
|
Loading…
Reference in New Issue
Block a user