github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/maas/constraints_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package maas
     5  
     6  import (
     7  	"net/url"
     8  
     9  	"github.com/juju/gomaasapi/v2"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/core/constraints"
    14  )
    15  
    16  type environSuite struct {
    17  	maasSuite
    18  }
    19  
    20  var _ = gc.Suite(&environSuite{})
    21  
    22  func (*environSuite) TestConvertConstraints(c *gc.C) {
    23  	for i, test := range []struct {
    24  		cons     constraints.Value
    25  		expected gomaasapi.AllocateMachineArgs
    26  	}{{
    27  		cons:     constraints.Value{Arch: stringp("arm")},
    28  		expected: gomaasapi.AllocateMachineArgs{Architecture: "arm"},
    29  	}, {
    30  		cons:     constraints.Value{CpuCores: uint64p(4)},
    31  		expected: gomaasapi.AllocateMachineArgs{MinCPUCount: 4},
    32  	}, {
    33  		cons:     constraints.Value{Mem: uint64p(1024)},
    34  		expected: gomaasapi.AllocateMachineArgs{MinMemory: 1024},
    35  	}, { // Spaces are converted to bindings and not_networks, but only in acquireNode
    36  		cons:     constraints.Value{Spaces: stringslicep("foo", "bar", "^baz", "^oof")},
    37  		expected: gomaasapi.AllocateMachineArgs{},
    38  	}, {
    39  		cons: constraints.Value{Tags: stringslicep("tag1", "tag2", "^tag3", "^tag4")},
    40  		expected: gomaasapi.AllocateMachineArgs{
    41  			Tags:    []string{"tag1", "tag2"},
    42  			NotTags: []string{"tag3", "tag4"},
    43  		},
    44  	}, { // CpuPower is ignored.
    45  		cons:     constraints.Value{CpuPower: uint64p(1024)},
    46  		expected: gomaasapi.AllocateMachineArgs{},
    47  	}, { // RootDisk is ignored.
    48  		cons:     constraints.Value{RootDisk: uint64p(8192)},
    49  		expected: gomaasapi.AllocateMachineArgs{},
    50  	}, {
    51  		cons: constraints.Value{Tags: stringslicep("foo", "bar")},
    52  		expected: gomaasapi.AllocateMachineArgs{
    53  			Tags: []string{"foo", "bar"},
    54  		},
    55  	}, {
    56  		cons: constraints.Value{
    57  			Arch:     stringp("arm"),
    58  			CpuCores: uint64p(4),
    59  			Mem:      uint64p(1024),
    60  			CpuPower: uint64p(1024),
    61  			RootDisk: uint64p(8192),
    62  			Spaces:   stringslicep("foo", "^bar"),
    63  			Tags:     stringslicep("^tag1", "tag2"),
    64  		},
    65  		expected: gomaasapi.AllocateMachineArgs{
    66  			Architecture: "arm",
    67  			MinCPUCount:  4,
    68  			MinMemory:    1024,
    69  			Tags:         []string{"tag2"},
    70  			NotTags:      []string{"tag1"},
    71  		},
    72  	}} {
    73  		c.Logf("test #%d: cons2=%s", i, test.cons.String())
    74  		c.Check(convertConstraints(test.cons), jc.DeepEquals, test.expected)
    75  	}
    76  }
    77  
    78  var nilStringSlice []string
    79  
    80  func (*environSuite) TestConvertTagsToParams(c *gc.C) {
    81  	for i, test := range []struct {
    82  		tags     *[]string
    83  		expected url.Values
    84  	}{{
    85  		tags:     nil,
    86  		expected: url.Values{},
    87  	}, {
    88  		tags:     &nilStringSlice,
    89  		expected: url.Values{},
    90  	}, {
    91  		tags:     &[]string{},
    92  		expected: url.Values{},
    93  	}, {
    94  		tags:     stringslicep(""),
    95  		expected: url.Values{},
    96  	}, {
    97  		tags: stringslicep("foo"),
    98  		expected: url.Values{
    99  			"tags": {"foo"},
   100  		},
   101  	}, {
   102  		tags: stringslicep("^bar"),
   103  		expected: url.Values{
   104  			"not_tags": {"bar"},
   105  		},
   106  	}, {
   107  		tags: stringslicep("foo", "^bar", "baz", "^oof"),
   108  		expected: url.Values{
   109  			"tags":     {"foo,baz"},
   110  			"not_tags": {"bar,oof"},
   111  		},
   112  	}, {
   113  		tags: stringslicep("", "^bar", "^", "^oof"),
   114  		expected: url.Values{
   115  			"not_tags": {"bar,oof"},
   116  		},
   117  	}, {
   118  		tags: stringslicep("foo", "^", " b a z  ", "^^ ^"),
   119  		expected: url.Values{
   120  			"tags":     {"foo, b a z  "},
   121  			"not_tags": {"^ ^"},
   122  		},
   123  	}, {
   124  		tags: stringslicep("", "^bar", "  ", " ^ o of "),
   125  		expected: url.Values{
   126  			"tags":     {"  , ^ o of "},
   127  			"not_tags": {"bar"},
   128  		},
   129  	}, {
   130  		tags: stringslicep("foo", "foo", "^bar", "^bar"),
   131  		expected: url.Values{
   132  			"tags":     {"foo,foo"},
   133  			"not_tags": {"bar,bar"},
   134  		},
   135  	}} {
   136  		c.Logf("test #%d: tags=%v", i, test.tags)
   137  		var vals = url.Values{}
   138  		convertTagsToParams(vals, test.tags)
   139  		c.Check(vals, jc.DeepEquals, test.expected)
   140  	}
   141  }
   142  
   143  func uint64p(val uint64) *uint64 {
   144  	return &val
   145  }
   146  
   147  func stringp(val string) *string {
   148  	return &val
   149  }
   150  
   151  func stringslicep(values ...string) *[]string {
   152  	return &values
   153  }
   154  
   155  func (suite *environSuite) TestParseDelimitedValues(c *gc.C) {
   156  	for i, test := range []struct {
   157  		about     string
   158  		input     []string
   159  		positives []string
   160  		negatives []string
   161  	}{{
   162  		about:     "nil input",
   163  		input:     nil,
   164  		positives: []string{},
   165  		negatives: []string{},
   166  	}, {
   167  		about:     "empty input",
   168  		input:     []string{},
   169  		positives: []string{},
   170  		negatives: []string{},
   171  	}, {
   172  		about:     "values list with embedded whitespace",
   173  		input:     []string{"   val1  ", " val2", " ^ not Val 3  ", "  ", " ", "^", "", "^ notVal4   "},
   174  		positives: []string{"   val1  ", " val2", " ^ not Val 3  ", "  ", " "},
   175  		negatives: []string{" notVal4   "},
   176  	}, {
   177  		about:     "only positives",
   178  		input:     []string{"val1", "val2", "val3"},
   179  		positives: []string{"val1", "val2", "val3"},
   180  		negatives: []string{},
   181  	}, {
   182  		about:     "only negatives",
   183  		input:     []string{"^val1", "^val2", "^val3"},
   184  		positives: []string{},
   185  		negatives: []string{"val1", "val2", "val3"},
   186  	}, {
   187  		about:     "multi-caret negatives",
   188  		input:     []string{"^foo^", "^v^a^l2", "  ^^ ^", "^v^al3", "^^", "^"},
   189  		positives: []string{"  ^^ ^"},
   190  		negatives: []string{"foo^", "v^a^l2", "v^al3", "^"},
   191  	}, {
   192  		about:     "both positives and negatives",
   193  		input:     []string{"^val1", "val2", "^val3", "val4"},
   194  		positives: []string{"val2", "val4"},
   195  		negatives: []string{"val1", "val3"},
   196  	}, {
   197  		about:     "single positive value",
   198  		input:     []string{"val1"},
   199  		positives: []string{"val1"},
   200  		negatives: []string{},
   201  	}, {
   202  		about:     "single negative value",
   203  		input:     []string{"^val1"},
   204  		positives: []string{},
   205  		negatives: []string{"val1"},
   206  	}} {
   207  		c.Logf("test %d: %s", i, test.about)
   208  		positives, negatives := parseDelimitedValues(test.input)
   209  		c.Check(positives, jc.DeepEquals, test.positives)
   210  		c.Check(negatives, jc.DeepEquals, test.negatives)
   211  	}
   212  }