create lib/stringslice package (#7934)

This commit is contained in:
R.B. Boyer 2020-05-27 11:47:32 -05:00 committed by GitHub
parent 12f6d327f8
commit 77f2e54618
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 70 additions and 70 deletions

View File

@ -17,7 +17,7 @@ import (
"github.com/hashicorp/consul/agent/structs"
tokenStore "github.com/hashicorp/consul/agent/token"
"github.com/hashicorp/consul/internal/go-sso/oidcauth/oidcauthtest"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/sdk/freeport"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/consul/sdk/testutil/retry"
@ -564,7 +564,7 @@ func TestACLEndpoint_List(t *testing.T) {
if s.ID == anonymousToken || s.ID == "root" {
continue
}
if !lib.StrContains(ids, s.ID) {
if !stringslice.Contains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Name != "User token" {

View File

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/types"
@ -2440,7 +2441,7 @@ func TestCatalog_NodeServices(t *testing.T) {
t.Fatalf("bad: %v", out)
}
services := out.NodeServices.Services
if !lib.StrContains(services["db"].Tags, "primary") || services["db"].Port != 5000 {
if !stringslice.Contains(services["db"].Tags, "primary") || services["db"].Port != 5000 {
t.Fatalf("bad: %v", out)
}
if len(services["web"].Tags) != 0 || services["web"].Port != 80 {

View File

@ -12,7 +12,7 @@ import (
"github.com/hashicorp/consul/agent/consul/state"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/sdk/testutil"
"github.com/hashicorp/go-raftchunking"
"github.com/stretchr/testify/assert"
@ -456,7 +456,7 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) {
if len(fooSrv.Services) != 2 {
t.Fatalf("Bad: %v", fooSrv)
}
if !lib.StrContains(fooSrv.Services["db"].Tags, "primary") {
if !stringslice.Contains(fooSrv.Services["db"].Tags, "primary") {
t.Fatalf("Bad: %v", fooSrv)
}
if fooSrv.Services["db"].Port != 5000 {

View File

@ -11,7 +11,7 @@ import (
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/ipaddr"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/logging"
"github.com/hashicorp/go-hclog"
memdb "github.com/hashicorp/go-memdb"
@ -190,7 +190,7 @@ func (g *GatewayLocator) listGateways(primary bool) []string {
// *duplicates* (which shouldn't happen) it's not great but it
// won't break anything other than biasing our eventual random
// choice a little bit.
addrs = lib.StringSliceMergeSorted(g.primaryGateways, g.PrimaryGatewayFallbackAddresses())
addrs = stringslice.MergeSorted(g.primaryGateways, g.PrimaryGatewayFallbackAddresses())
}
} else {
addrs = g.localGateways
@ -207,7 +207,7 @@ func (g *GatewayLocator) RefreshPrimaryGatewayFallbackAddresses(addrs []string)
g.primaryMeshGatewayDiscoveredAddressesLock.Lock()
defer g.primaryMeshGatewayDiscoveredAddressesLock.Unlock()
if !lib.StringSliceEqual(addrs, g.primaryMeshGatewayDiscoveredAddresses) {
if !stringslice.Equal(addrs, g.primaryMeshGatewayDiscoveredAddresses) {
g.primaryMeshGatewayDiscoveredAddresses = addrs
g.logger.Info("updated fallback list of primary mesh gateways", "mesh_gateways", addrs)
}
@ -363,12 +363,12 @@ func (g *GatewayLocator) updateFromState(results []*structs.FederationState) {
changed := false
primaryReady := false
if !lib.StringSliceEqual(g.primaryGateways, primaryAddrs) {
if !stringslice.Equal(g.primaryGateways, primaryAddrs) {
g.primaryGateways = primaryAddrs
primaryReady = len(g.primaryGateways) > 0
changed = true
}
if !lib.StringSliceEqual(g.localGateways, localAddrs) {
if !stringslice.Equal(g.localGateways, localAddrs) {
g.localGateways = localAddrs
changed = true
}

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/types"
@ -591,10 +592,10 @@ func TestHealth_ServiceNodes(t *testing.T) {
if nodes[1].Node.Node != "foo" {
t.Fatalf("Bad: %v", nodes[1])
}
if !lib.StrContains(nodes[0].Service.Tags, "slave") {
if !stringslice.Contains(nodes[0].Service.Tags, "slave") {
t.Fatalf("Bad: %v", nodes[0])
}
if !lib.StrContains(nodes[1].Service.Tags, "master") {
if !stringslice.Contains(nodes[1].Service.Tags, "master") {
t.Fatalf("Bad: %v", nodes[1])
}
if nodes[0].Checks[0].Status != api.HealthWarning {
@ -629,10 +630,10 @@ func TestHealth_ServiceNodes(t *testing.T) {
if nodes[1].Node.Node != "foo" {
t.Fatalf("Bad: %v", nodes[1])
}
if !lib.StrContains(nodes[0].Service.Tags, "slave") {
if !stringslice.Contains(nodes[0].Service.Tags, "slave") {
t.Fatalf("Bad: %v", nodes[0])
}
if !lib.StrContains(nodes[1].Service.Tags, "master") {
if !stringslice.Contains(nodes[1].Service.Tags, "master") {
t.Fatalf("Bad: %v", nodes[1])
}
if nodes[0].Checks[0].Status != api.HealthWarning {

View File

@ -9,7 +9,7 @@ import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/consul/types"
@ -64,7 +64,7 @@ func TestInternal_NodeInfo(t *testing.T) {
if nodes[0].Node != "foo" {
t.Fatalf("Bad: %v", nodes[0])
}
if !lib.StrContains(nodes[0].Services[0].Tags, "master") {
if !stringslice.Contains(nodes[0].Services[0].Tags, "master") {
t.Fatalf("Bad: %v", nodes[0])
}
if nodes[0].Checks[0].Status != api.HealthPassing {
@ -139,7 +139,7 @@ func TestInternal_NodeDump(t *testing.T) {
switch node.Node {
case "foo":
foundFoo = true
if !lib.StrContains(node.Services[0].Tags, "master") {
if !stringslice.Contains(node.Services[0].Tags, "master") {
t.Fatalf("Bad: %v", nodes[0])
}
if node.Checks[0].Status != api.HealthPassing {
@ -148,7 +148,7 @@ func TestInternal_NodeDump(t *testing.T) {
case "bar":
foundBar = true
if !lib.StrContains(node.Services[0].Tags, "slave") {
if !stringslice.Contains(node.Services[0].Tags, "slave") {
t.Fatalf("Bad: %v", nodes[1])
}
if node.Checks[0].Status != api.HealthWarning {

View File

@ -7,7 +7,7 @@ import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/testrpc"
msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc"
)
@ -370,7 +370,7 @@ func TestSession_List(t *testing.T) {
}
for i := 0; i < len(sessions.Sessions); i++ {
s := sessions.Sessions[i]
if !lib.StrContains(ids, s.ID) {
if !stringslice.Contains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
@ -649,7 +649,7 @@ func TestSession_Renew(t *testing.T) {
}
for i := 0; i < len(sessions.Sessions); i++ {
s := sessions.Sessions[i]
if !lib.StrContains(ids, s.ID) {
if !stringslice.Contains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
@ -683,7 +683,7 @@ func TestSession_Renew(t *testing.T) {
}
s := session.Sessions[0]
if !lib.StrContains(ids, s.ID) {
if !stringslice.Contains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
@ -710,7 +710,7 @@ func TestSession_Renew(t *testing.T) {
for i := 0; i < len(sessionsL1.Sessions); i++ {
s := sessionsL1.Sessions[i]
if !lib.StrContains(ids, s.ID) {
if !stringslice.Contains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
@ -742,7 +742,7 @@ func TestSession_Renew(t *testing.T) {
if len(sessionsL2.Sessions) != 0 {
for i := 0; i < len(sessionsL2.Sessions); i++ {
s := sessionsL2.Sessions[i]
if !lib.StrContains(ids, s.ID) {
if !stringslice.Contains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {
@ -947,7 +947,7 @@ func TestSession_NodeSessions(t *testing.T) {
}
for i := 0; i < len(sessions.Sessions); i++ {
s := sessions.Sessions[i]
if !lib.StrContains(ids, s.ID) {
if !stringslice.Contains(ids, s.ID) {
t.Fatalf("bad: %v", s)
}
if s.Node != "foo" {

View File

@ -9,7 +9,7 @@ import (
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/hashicorp/consul/types"
"github.com/hashicorp/go-memdb"
uuid "github.com/hashicorp/go-uuid"
@ -1814,7 +1814,7 @@ func TestStateStore_ServiceNodes(t *testing.T) {
if nodes[0].ServiceID != "db" {
t.Fatalf("bad: %v", nodes)
}
if !lib.StrContains(nodes[0].ServiceTags, "slave") {
if !stringslice.Contains(nodes[0].ServiceTags, "slave") {
t.Fatalf("bad: %v", nodes)
}
if nodes[0].ServicePort != 8000 {
@ -1829,7 +1829,7 @@ func TestStateStore_ServiceNodes(t *testing.T) {
if nodes[1].ServiceID != "db2" {
t.Fatalf("bad: %v", nodes)
}
if !lib.StrContains(nodes[1].ServiceTags, "slave") {
if !stringslice.Contains(nodes[1].ServiceTags, "slave") {
t.Fatalf("bad: %v", nodes)
}
if nodes[1].ServicePort != 8001 {
@ -1844,7 +1844,7 @@ func TestStateStore_ServiceNodes(t *testing.T) {
if nodes[2].ServiceID != "db" {
t.Fatalf("bad: %v", nodes)
}
if !lib.StrContains(nodes[2].ServiceTags, "master") {
if !stringslice.Contains(nodes[2].ServiceTags, "master") {
t.Fatalf("bad: %v", nodes)
}
if nodes[2].ServicePort != 8000 {
@ -1947,7 +1947,7 @@ func TestStateStore_ServiceTagNodes(t *testing.T) {
if nodes[0].Address != "127.0.0.1" {
t.Fatalf("bad: %v", nodes)
}
if !lib.StrContains(nodes[0].ServiceTags, "master") {
if !stringslice.Contains(nodes[0].ServiceTags, "master") {
t.Fatalf("bad: %v", nodes)
}
if nodes[0].ServicePort != 8000 {

View File

@ -5,7 +5,7 @@ import (
"strings"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/lib"
"github.com/hashicorp/consul/lib/stringslice"
"github.com/miekg/dns"
)
@ -377,7 +377,7 @@ func (g *GatewayService) IsSame(o *GatewayService) bool {
g.GatewayKind == o.GatewayKind &&
g.Port == o.Port &&
g.Protocol == o.Protocol &&
lib.StringSliceEqual(g.Hosts, o.Hosts) &&
stringslice.Equal(g.Hosts, o.Hosts) &&
g.CAFile == o.CAFile &&
g.CertFile == o.CertFile &&
g.KeyFile == o.KeyFile &&

View File

@ -1,11 +0,0 @@
package lib
// StrContains checks if a list contains a string
func StrContains(l []string, s string) bool {
for _, v := range l {
if v == s {
return true
}
}
return false
}

View File

@ -1,15 +0,0 @@
package lib
import (
"testing"
)
func TestStrContains(t *testing.T) {
l := []string{"a", "b", "c"}
if !StrContains(l, "b") {
t.Fatalf("should contain")
}
if StrContains(l, "d") {
t.Fatalf("should not contain")
}
}

View File

@ -1,9 +1,23 @@
package lib
package stringslice
// StringSliceEqual compares two string slices for equality. Both the existence
// StrContains => Contains
// StringSliceEqual => Equal
// StringSliceMergeSorted => MergeSorted
// Contains checks if a list contains a string
func Contains(l []string, s string) bool {
for _, v := range l {
if v == s {
return true
}
}
return false
}
// Equal compares two string slices for equality. Both the existence
// of the elements and the order of those elements matter for equality. Empty
// slices are treated identically to nil slices.
func StringSliceEqual(a, b []string) bool {
func Equal(a, b []string) bool {
if len(a) != len(b) {
return false
}
@ -16,11 +30,11 @@ func StringSliceEqual(a, b []string) bool {
return true
}
// StringSliceMergeSorted takes two string slices that are assumed to be sorted
// MergeSorted takes two string slices that are assumed to be sorted
// and does a zipper merge of the two sorted slices, removing any cross-slice
// duplicates. If any individual slice contained duplicates those will be
// retained.
func StringSliceMergeSorted(a, b []string) []string {
func MergeSorted(a, b []string) []string {
if len(a) == 0 && len(b) == 0 {
return nil
} else if len(a) == 0 {

View File

@ -1,4 +1,4 @@
package lib
package stringslice
import (
"fmt"
@ -7,7 +7,17 @@ import (
"github.com/stretchr/testify/require"
)
func TestStringSliceEqual(t *testing.T) {
func TestContains(t *testing.T) {
l := []string{"a", "b", "c"}
if !Contains(l, "b") {
t.Fatalf("should contain")
}
if Contains(l, "d") {
t.Fatalf("should not contain")
}
}
func TestEqual(t *testing.T) {
for _, tc := range []struct {
a, b []string
equal bool
@ -23,13 +33,13 @@ func TestStringSliceEqual(t *testing.T) {
} {
name := fmt.Sprintf("%#v =?= %#v", tc.a, tc.b)
t.Run(name, func(t *testing.T) {
require.Equal(t, tc.equal, StringSliceEqual(tc.a, tc.b))
require.Equal(t, tc.equal, StringSliceEqual(tc.b, tc.a))
require.Equal(t, tc.equal, Equal(tc.a, tc.b))
require.Equal(t, tc.equal, Equal(tc.b, tc.a))
})
}
}
func TestStringSliceMergeSorted(t *testing.T) {
func TestMergeSorted(t *testing.T) {
for name, tc := range map[string]struct {
a, b []string
expect []string
@ -45,8 +55,8 @@ func TestStringSliceMergeSorted(t *testing.T) {
} {
tc := tc
t.Run(name, func(t *testing.T) {
require.Equal(t, tc.expect, StringSliceMergeSorted(tc.a, tc.b))
require.Equal(t, tc.expect, StringSliceMergeSorted(tc.b, tc.a))
require.Equal(t, tc.expect, MergeSorted(tc.a, tc.b))
require.Equal(t, tc.expect, MergeSorted(tc.b, tc.a))
})
}
}