mirror of
https://github.com/status-im/consul.git
synced 2025-02-06 19:04:59 +00:00
* Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
251 lines
6.1 KiB
Go
251 lines
6.1 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package consul
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/go-version"
|
|
"github.com/hashicorp/serf/serf"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/hashicorp/consul/agent/metadata"
|
|
)
|
|
|
|
func TestUtil_CanServersUnderstandProtocol(t *testing.T) {
|
|
t.Parallel()
|
|
var members []serf.Member
|
|
|
|
// All empty list cases should return false.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("empty list should always return false")
|
|
}
|
|
}
|
|
|
|
// Add a non-server member.
|
|
members = append(members, serf.Member{
|
|
Tags: map[string]string{
|
|
"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
|
|
"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax),
|
|
},
|
|
})
|
|
|
|
// Make sure it doesn't get counted.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("non-server members should not be counted")
|
|
}
|
|
}
|
|
|
|
// Add a server member.
|
|
members = append(members, serf.Member{
|
|
Tags: map[string]string{
|
|
"role": "consul",
|
|
"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
|
|
"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax),
|
|
},
|
|
})
|
|
|
|
// Now it should report that it understands.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if !grok {
|
|
t.Fatalf("server should grok")
|
|
}
|
|
}
|
|
|
|
// Nobody should understand anything from the future.
|
|
for v := uint8(ProtocolVersionMax + 1); v <= uint8(ProtocolVersionMax+10); v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("server should not grok")
|
|
}
|
|
}
|
|
|
|
// Add an older server.
|
|
members = append(members, serf.Member{
|
|
Tags: map[string]string{
|
|
"role": "consul",
|
|
"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
|
|
"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax-1),
|
|
},
|
|
})
|
|
|
|
// The servers should no longer understand the max version.
|
|
for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
|
|
grok, err := CanServersUnderstandProtocol(members, v)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
expected := v < ProtocolVersionMax
|
|
if grok != expected {
|
|
t.Fatalf("bad: %v != %v", grok, expected)
|
|
}
|
|
}
|
|
|
|
// Try a version that's too low for the minimum.
|
|
{
|
|
grok, err := CanServersUnderstandProtocol(members, 0)
|
|
if err != nil {
|
|
t.Fatalf("err: %v", err)
|
|
}
|
|
if grok {
|
|
t.Fatalf("server should not grok")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestIsConsulNode(t *testing.T) {
|
|
t.Parallel()
|
|
m := serf.Member{
|
|
Tags: map[string]string{
|
|
"role": "node",
|
|
"dc": "east-aws",
|
|
},
|
|
}
|
|
valid, dc := isConsulNode(m)
|
|
if !valid || dc != "east-aws" {
|
|
t.Fatalf("bad: %v %v", valid, dc)
|
|
}
|
|
}
|
|
|
|
func TestGenerateUUID(t *testing.T) {
|
|
t.Parallel()
|
|
prev := generateUUID()
|
|
re, err := regexp.Compile("[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}")
|
|
require.NoError(t, err)
|
|
|
|
for i := 0; i < 100; i++ {
|
|
id := generateUUID()
|
|
if prev == id {
|
|
t.Fatalf("Should get a new ID!")
|
|
}
|
|
|
|
matched := re.MatchString(id)
|
|
if !matched {
|
|
t.Fatalf("expected match %s %v %s", id, matched, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
type testServersProvider []metadata.Server
|
|
|
|
func (p testServersProvider) CheckServers(datacenter string, fn func(*metadata.Server) bool) {
|
|
for _, srv := range p {
|
|
// filter these out - now I don't have to modify the tests. Originally the dc filtering
|
|
// happened in the ServersInDCMeetMinimumVersion, now we get a list of servers to check
|
|
// through the routing infrastructure or server lookup which will map a datacenter to a
|
|
// list of metadata.Server structs that are all in that datacenter.
|
|
if srv.Datacenter != datacenter {
|
|
continue
|
|
}
|
|
|
|
if !fn(&srv) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestServersInDCMeetMinimumVersion(t *testing.T) {
|
|
t.Parallel()
|
|
makeServer := func(versionStr string, datacenter string) metadata.Server {
|
|
return metadata.Server{
|
|
Name: "foo",
|
|
ShortName: "foo",
|
|
ID: "asdf",
|
|
Port: 10000,
|
|
Expect: 3,
|
|
RaftVersion: 3,
|
|
Status: serf.StatusAlive,
|
|
WanJoinPort: 1234,
|
|
Version: 1,
|
|
Build: *version.Must(version.NewVersion(versionStr)),
|
|
Datacenter: datacenter,
|
|
}
|
|
}
|
|
|
|
cases := []struct {
|
|
servers testServersProvider
|
|
ver *version.Version
|
|
expected bool
|
|
expectedFound bool
|
|
}{
|
|
// One server, meets reqs
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.7.3", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.7.5")),
|
|
expected: true,
|
|
expectedFound: true,
|
|
},
|
|
// One server, doesn't meet reqs
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.8.1", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.8.0")),
|
|
expected: false,
|
|
expectedFound: true,
|
|
},
|
|
// Multiple servers, meets req version
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.8.0", "primary"),
|
|
makeServer("0.7.0", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.7.5")),
|
|
expected: true,
|
|
expectedFound: true,
|
|
},
|
|
// Multiple servers, doesn't meet req version
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "primary"),
|
|
makeServer("0.8.0", "primary"),
|
|
makeServer("0.9.1", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.8.0")),
|
|
expected: false,
|
|
expectedFound: true,
|
|
},
|
|
{
|
|
servers: testServersProvider{
|
|
makeServer("0.7.5", "secondary"),
|
|
makeServer("0.8.0", "secondary"),
|
|
makeServer("0.9.1", "secondary"),
|
|
},
|
|
ver: version.Must(version.NewVersion("0.7.0")),
|
|
expected: true,
|
|
expectedFound: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
result, found := ServersInDCMeetMinimumVersion(tc.servers, "primary", tc.ver)
|
|
require.Equal(t, tc.expected, result)
|
|
require.Equal(t, tc.expectedFound, found)
|
|
}
|
|
}
|