github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/nomad/util_test.go (about) 1 package nomad 2 3 import ( 4 "net" 5 "reflect" 6 "testing" 7 8 version "github.com/hashicorp/go-version" 9 "github.com/hashicorp/nomad/helper/uuid" 10 "github.com/hashicorp/serf/serf" 11 ) 12 13 func TestIsNomadServer(t *testing.T) { 14 t.Parallel() 15 m := serf.Member{ 16 Name: "foo", 17 Addr: net.IP([]byte{127, 0, 0, 1}), 18 Status: serf.StatusAlive, 19 Tags: map[string]string{ 20 "role": "nomad", 21 "region": "aws", 22 "dc": "east-aws", 23 "rpc_addr": "1.1.1.1", 24 "port": "10000", 25 "vsn": "1", 26 "raft_vsn": "2", 27 "build": "0.7.0+ent", 28 "nonvoter": "1", 29 }, 30 } 31 valid, parts := isNomadServer(m) 32 if !valid || parts.Region != "aws" || 33 parts.Datacenter != "east-aws" || parts.Port != 10000 { 34 t.Fatalf("bad: %v %v", valid, parts) 35 } 36 if parts.Name != "foo" { 37 t.Fatalf("bad: %v", parts) 38 } 39 if parts.Bootstrap { 40 t.Fatalf("unexpected bootstrap") 41 } 42 if parts.Expect != 0 { 43 t.Fatalf("bad: %v", parts.Expect) 44 } 45 if parts.Status != serf.StatusAlive { 46 t.Fatalf("bad: %v", parts.Status) 47 } 48 if parts.RaftVersion != 2 { 49 t.Fatalf("bad: %v", parts.RaftVersion) 50 } 51 if parts.RPCAddr.String() != "1.1.1.1:10000" { 52 t.Fatalf("bad: %v", parts.RPCAddr.String()) 53 } 54 if seg := parts.Build.Segments(); len(seg) != 3 { 55 t.Fatalf("bad: %v", parts.Build) 56 } else if seg[0] != 0 && seg[1] != 7 && seg[2] != 0 { 57 t.Fatalf("bad: %v", parts.Build) 58 } 59 if !parts.NonVoter { 60 t.Fatalf("should be nonvoter") 61 } 62 63 m.Tags["bootstrap"] = "1" 64 valid, parts = isNomadServer(m) 65 if !valid || !parts.Bootstrap { 66 t.Fatalf("expected bootstrap") 67 } 68 if parts.Addr.String() != "127.0.0.1:10000" { 69 t.Fatalf("bad addr: %v", parts.Addr) 70 } 71 if parts.MajorVersion != 1 { 72 t.Fatalf("bad: %v", parts) 73 } 74 75 m.Tags["expect"] = "3" 76 delete(m.Tags, "bootstrap") 77 valid, parts = isNomadServer(m) 78 if !valid || parts.Expect != 3 { 79 t.Fatalf("bad: %v", parts.Expect) 80 } 81 82 delete(m.Tags, "nonvoter") 83 valid, parts = isNomadServer(m) 84 if !valid || parts.NonVoter { 85 t.Fatalf("should be a voter") 86 } 87 } 88 89 func TestServersMeetMinimumVersionExcludingFailed(t *testing.T) { 90 t.Parallel() 91 92 cases := []struct { 93 members []serf.Member 94 ver *version.Version 95 expected bool 96 }{ 97 // One server, meets reqs 98 { 99 members: []serf.Member{ 100 makeMember("0.7.5", serf.StatusAlive), 101 }, 102 ver: version.Must(version.NewVersion("0.7.5")), 103 expected: true, 104 }, 105 // One server in dev, meets reqs 106 { 107 members: []serf.Member{ 108 makeMember("0.8.5-dev", serf.StatusAlive), 109 }, 110 ver: version.Must(version.NewVersion("0.7.5")), 111 expected: true, 112 }, 113 // One server with meta, meets reqs 114 { 115 members: []serf.Member{ 116 makeMember("0.7.5+ent", serf.StatusAlive), 117 }, 118 ver: version.Must(version.NewVersion("0.7.5")), 119 expected: true, 120 }, 121 // One server, doesn't meet reqs 122 { 123 members: []serf.Member{ 124 makeMember("0.7.5", serf.StatusAlive), 125 }, 126 ver: version.Must(version.NewVersion("0.8.0")), 127 expected: false, 128 }, 129 // Multiple servers, meets req version, includes failed that doesn't meet req 130 { 131 members: []serf.Member{ 132 makeMember("0.7.5", serf.StatusAlive), 133 makeMember("0.8.0", serf.StatusAlive), 134 makeMember("0.7.0", serf.StatusFailed), 135 }, 136 ver: version.Must(version.NewVersion("0.7.5")), 137 expected: true, 138 }, 139 // Multiple servers, doesn't meet req version 140 { 141 members: []serf.Member{ 142 makeMember("0.7.5", serf.StatusAlive), 143 makeMember("0.8.0", serf.StatusAlive), 144 }, 145 ver: version.Must(version.NewVersion("0.8.0")), 146 expected: false, 147 }, 148 } 149 150 for _, tc := range cases { 151 result := ServersMeetMinimumVersion(tc.members, tc.ver, false) 152 if result != tc.expected { 153 t.Fatalf("bad: %v, %v, %v", result, tc.ver.String(), tc) 154 } 155 } 156 } 157 158 func TestServersMeetMinimumVersionIncludingFailed(t *testing.T) { 159 t.Parallel() 160 161 cases := []struct { 162 members []serf.Member 163 ver *version.Version 164 expected bool 165 }{ 166 // Multiple servers, meets req version 167 { 168 members: []serf.Member{ 169 makeMember("0.7.5", serf.StatusAlive), 170 makeMember("0.8.0", serf.StatusAlive), 171 makeMember("0.7.5", serf.StatusFailed), 172 }, 173 ver: version.Must(version.NewVersion("0.7.5")), 174 expected: true, 175 }, 176 // Multiple servers, doesn't meet req version 177 { 178 members: []serf.Member{ 179 makeMember("0.7.5", serf.StatusAlive), 180 makeMember("0.8.0", serf.StatusAlive), 181 makeMember("0.7.0", serf.StatusFailed), 182 }, 183 ver: version.Must(version.NewVersion("0.7.5")), 184 expected: false, 185 }, 186 } 187 188 for _, tc := range cases { 189 result := ServersMeetMinimumVersion(tc.members, tc.ver, true) 190 if result != tc.expected { 191 t.Fatalf("bad: %v, %v, %v", result, tc.ver.String(), tc) 192 } 193 } 194 } 195 196 func makeMember(version string, status serf.MemberStatus) serf.Member { 197 return serf.Member{ 198 Name: "foo", 199 Addr: net.IP([]byte{127, 0, 0, 1}), 200 Tags: map[string]string{ 201 "role": "nomad", 202 "region": "aws", 203 "dc": "east-aws", 204 "port": "10000", 205 "build": version, 206 "vsn": "1", 207 }, 208 Status: status, 209 } 210 } 211 212 func TestShuffleStrings(t *testing.T) { 213 t.Parallel() 214 // Generate input 215 inp := make([]string, 10) 216 for idx := range inp { 217 inp[idx] = uuid.Generate() 218 } 219 220 // Copy the input 221 orig := make([]string, len(inp)) 222 copy(orig, inp) 223 224 // Shuffle 225 shuffleStrings(inp) 226 227 // Ensure order is not the same 228 if reflect.DeepEqual(inp, orig) { 229 t.Fatalf("shuffle failed") 230 } 231 } 232 233 func TestMaxUint64(t *testing.T) { 234 t.Parallel() 235 if maxUint64(1, 2) != 2 { 236 t.Fatalf("bad") 237 } 238 if maxUint64(2, 2) != 2 { 239 t.Fatalf("bad") 240 } 241 if maxUint64(2, 1) != 2 { 242 t.Fatalf("bad") 243 } 244 }