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  }