From cd2cf485ee53d1ea5fc822ae2d5f56733e3b3f39 Mon Sep 17 00:00:00 2001 From: David Bartley Date: Wed, 22 Apr 2020 14:14:58 -0700 Subject: [PATCH] GODRIVER-1210 Add String for readpref.Mode and readpref.Readpref (#382) --- mongo/readpref/mode.go | 18 +++++++++++++++++ mongo/readpref/mode_test.go | 35 +++++++++++++++++++++++++++++++++ mongo/readpref/readpref.go | 25 +++++++++++++++++++++++ mongo/readpref/readpref_test.go | 22 +++++++++++++++++++++ tag/tag.go | 22 +++++++++++++++++++++ tag/tag_test.go | 18 +++++++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 mongo/readpref/mode_test.go diff --git a/mongo/readpref/mode.go b/mongo/readpref/mode.go index e7030c6b49..deacf9f337 100644 --- a/mongo/readpref/mode.go +++ b/mongo/readpref/mode.go @@ -54,3 +54,21 @@ func ModeFromString(mode string) (Mode, error) { } return Mode(0), fmt.Errorf("unknown read preference %v", mode) } + +// String returns the string representation of mode. +func (mode Mode) String() string { + switch mode { + case PrimaryMode: + return "primary" + case PrimaryPreferredMode: + return "primaryPreferred" + case SecondaryMode: + return "secondary" + case SecondaryPreferredMode: + return "secondaryPreferred" + case NearestMode: + return "nearest" + default: + return "unknown" + } +} diff --git a/mongo/readpref/mode_test.go b/mongo/readpref/mode_test.go new file mode 100644 index 0000000000..8a799919bb --- /dev/null +++ b/mongo/readpref/mode_test.go @@ -0,0 +1,35 @@ +// Copyright (C) MongoDB, Inc. 2020-present. + +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package readpref + +import ( + "testing" + + "go.mongodb.org/mongo-driver/internal/testutil/assert" +) + +func TestMode_String(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + mode Mode + }{ + {"primary", PrimaryMode}, + {"primaryPreferred", PrimaryPreferredMode}, + {"secondary", SecondaryMode}, + {"secondaryPreferred", SecondaryPreferredMode}, + {"nearest", NearestMode}, + {"unknown", Mode(42)}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.name, tc.mode.String(), "expected %q, got %q", tc.name, tc.mode.String()) + }) + } +} diff --git a/mongo/readpref/readpref.go b/mongo/readpref/readpref.go index ae30df2ff7..b651b69e90 100644 --- a/mongo/readpref/readpref.go +++ b/mongo/readpref/readpref.go @@ -7,7 +7,9 @@ package readpref // import "go.mongodb.org/mongo-driver/mongo/readpref" import ( + "bytes" "errors" + "fmt" "time" "go.mongodb.org/mongo-driver/tag" @@ -104,3 +106,26 @@ func (r *ReadPref) TagSets() []tag.Set { func (r *ReadPref) HedgeEnabled() *bool { return r.hedgeEnabled } + +// String returns a human-readable description of the read preference. +func (r *ReadPref) String() string { + var b bytes.Buffer + b.WriteString(r.mode.String()) + delim := "(" + if r.maxStalenessSet { + fmt.Fprintf(&b, "%smaxStaleness=%v", delim, r.maxStaleness) + delim = " " + } + for _, tagSet := range r.tagSets { + fmt.Fprintf(&b, "%stagSet=%s", delim, tagSet.String()) + delim = " " + } + if r.hedgeEnabled != nil { + fmt.Fprintf(&b, "%shedgeEnabled=%v", delim, *r.hedgeEnabled) + delim = " " + } + if delim != "(" { + b.WriteString(")") + } + return b.String() +} diff --git a/mongo/readpref/readpref_test.go b/mongo/readpref/readpref_test.go index b0d88509ec..3df59e3194 100644 --- a/mongo/readpref/readpref_test.go +++ b/mongo/readpref/readpref_test.go @@ -134,3 +134,25 @@ func TestHedge(t *testing.T) { assert.True(t, *enabled, "expected HedgeEnabled to return true, got false") }) } + +func TestReadPref_String(t *testing.T) { + t.Run("ReadPref.String() with all options", func(t *testing.T) { + readPref := Nearest( + WithMaxStaleness(120*time.Second), + WithTagSets(tag.Set{{"a", "1"}, {"b", "2"}}, tag.Set{{"q", "5"}, {"r", "6"}}), + WithHedgeEnabled(true), + ) + expected := "nearest(maxStaleness=2m0s tagSet=a=1,b=2 tagSet=q=5,r=6 hedgeEnabled=true)" + assert.Equal(t, expected, readPref.String(), "expected %q, got %q", expected, readPref.String()) + }) + t.Run("ReadPref.String() with one option", func(t *testing.T) { + readPref := Secondary(WithTags("a", "1", "b", "2")) + expected := "secondary(tagSet=a=1,b=2)" + assert.Equal(t, expected, readPref.String(), "expected %q, got %q", expected, readPref.String()) + }) + t.Run("ReadPref.String() with no options", func(t *testing.T) { + readPref := Primary() + expected := "primary" + assert.Equal(t, expected, readPref.String(), "expected %q, got %q", expected, readPref.String()) + }) +} diff --git a/tag/tag.go b/tag/tag.go index 13bf562383..55cf7e31e4 100644 --- a/tag/tag.go +++ b/tag/tag.go @@ -6,12 +6,22 @@ package tag // import "go.mongodb.org/mongo-driver/tag" +import ( + "bytes" + "fmt" +) + // Tag is a name/vlaue pair. type Tag struct { Name string Value string } +// String returns a human-readable human-readable description of the tag. +func (tag Tag) String() string { + return fmt.Sprintf("%s=%s", tag.Name, tag.Value) +} + // NewTagSetFromMap creates a new tag set from a map. func NewTagSetFromMap(m map[string]string) Set { var set Set @@ -55,3 +65,15 @@ func (ts Set) ContainsAll(other []Tag) bool { return true } + +// String returns a human-readable human-readable description of the tagset. +func (ts Set) String() string { + var b bytes.Buffer + for i, tag := range ts { + if i > 0 { + b.WriteString(",") + } + b.WriteString(tag.String()) + } + return b.String() +} diff --git a/tag/tag_test.go b/tag/tag_test.go index bc2c1944ce..5fbf777d01 100644 --- a/tag/tag_test.go +++ b/tag/tag_test.go @@ -10,8 +10,16 @@ import ( "testing" "github.com/stretchr/testify/require" + "go.mongodb.org/mongo-driver/internal/testutil/assert" ) +func TestTag_String(t *testing.T) { + t.Parallel() + + tag := Tag{Name: "a", Value: "1"} + assert.Equal(t, "a=1", tag.String(), `expected "a=1", got %q`, tag.String()) +} + func TestTagSets_NewTagSet(t *testing.T) { t.Parallel() @@ -76,3 +84,13 @@ func TestTagSets_ContainsAll(t *testing.T) { test = Set{Tag{Name: "a", Value: "2"}, Tag{Name: "b", Value: "2"}} require.False(t, ts.ContainsAll(test)) } + +func TestTagSets_String(t *testing.T) { + t.Parallel() + + ts := Set{ + Tag{Name: "a", Value: "1"}, + Tag{Name: "b", Value: "2"}, + } + assert.Equal(t, "a=1,b=2", ts.String(), `expected "a=1,b=2", got %q`, ts.String()) +}