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 }