1// Copyright (C) MongoDB, Inc. 2017-present. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7package readpref 8 9import ( 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/require" 14 "go.mongodb.org/mongo-driver/internal/testutil/assert" 15 "go.mongodb.org/mongo-driver/tag" 16) 17 18func TestPrimary(t *testing.T) { 19 require := require.New(t) 20 subject := Primary() 21 22 require.Equal(PrimaryMode, subject.Mode()) 23 _, set := subject.MaxStaleness() 24 require.False(set) 25 require.Empty(subject.TagSets()) 26} 27 28func TestPrimaryPreferred(t *testing.T) { 29 require := require.New(t) 30 subject := PrimaryPreferred() 31 32 require.Equal(PrimaryPreferredMode, subject.Mode()) 33 _, set := subject.MaxStaleness() 34 require.False(set) 35 require.Empty(subject.TagSets()) 36} 37 38func TestPrimaryPreferred_with_options(t *testing.T) { 39 require := require.New(t) 40 subject := PrimaryPreferred( 41 WithMaxStaleness(time.Duration(10)), 42 WithTags("a", "1", "b", "2"), 43 ) 44 45 require.Equal(PrimaryPreferredMode, subject.Mode()) 46 ms, set := subject.MaxStaleness() 47 require.True(set) 48 require.Equal(time.Duration(10), ms) 49 require.Equal([]tag.Set{{tag.Tag{Name: "a", Value: "1"}, tag.Tag{Name: "b", Value: "2"}}}, subject.TagSets()) 50} 51 52func TestSecondaryPreferred(t *testing.T) { 53 require := require.New(t) 54 subject := SecondaryPreferred() 55 56 require.Equal(SecondaryPreferredMode, subject.Mode()) 57 _, set := subject.MaxStaleness() 58 require.False(set) 59 require.Empty(subject.TagSets()) 60} 61 62func TestSecondaryPreferred_with_options(t *testing.T) { 63 require := require.New(t) 64 subject := SecondaryPreferred( 65 WithMaxStaleness(time.Duration(10)), 66 WithTags("a", "1", "b", "2"), 67 ) 68 69 require.Equal(SecondaryPreferredMode, subject.Mode()) 70 ms, set := subject.MaxStaleness() 71 require.True(set) 72 require.Equal(time.Duration(10), ms) 73 require.Equal([]tag.Set{{tag.Tag{Name: "a", Value: "1"}, tag.Tag{Name: "b", Value: "2"}}}, subject.TagSets()) 74} 75 76func TestSecondary(t *testing.T) { 77 require := require.New(t) 78 subject := Secondary() 79 80 require.Equal(SecondaryMode, subject.Mode()) 81 _, set := subject.MaxStaleness() 82 require.False(set) 83 require.Empty(subject.TagSets()) 84} 85 86func TestSecondary_with_options(t *testing.T) { 87 require := require.New(t) 88 subject := Secondary( 89 WithMaxStaleness(time.Duration(10)), 90 WithTags("a", "1", "b", "2"), 91 ) 92 93 require.Equal(SecondaryMode, subject.Mode()) 94 ms, set := subject.MaxStaleness() 95 require.True(set) 96 require.Equal(time.Duration(10), ms) 97 require.Equal([]tag.Set{{tag.Tag{Name: "a", Value: "1"}, tag.Tag{Name: "b", Value: "2"}}}, subject.TagSets()) 98} 99 100func TestNearest(t *testing.T) { 101 require := require.New(t) 102 subject := Nearest() 103 104 require.Equal(NearestMode, subject.Mode()) 105 _, set := subject.MaxStaleness() 106 require.False(set) 107 require.Empty(subject.TagSets()) 108} 109 110func TestNearest_with_options(t *testing.T) { 111 require := require.New(t) 112 subject := Nearest( 113 WithMaxStaleness(time.Duration(10)), 114 WithTags("a", "1", "b", "2"), 115 ) 116 117 require.Equal(NearestMode, subject.Mode()) 118 ms, set := subject.MaxStaleness() 119 require.True(set) 120 require.Equal(time.Duration(10), ms) 121 require.Equal([]tag.Set{{tag.Tag{Name: "a", Value: "1"}, tag.Tag{Name: "b", Value: "2"}}}, subject.TagSets()) 122} 123 124func TestHedge(t *testing.T) { 125 t.Run("hedge specified with primary mode errors", func(t *testing.T) { 126 _, err := New(PrimaryMode, WithHedgeEnabled(true)) 127 assert.Equal(t, errInvalidReadPreference, err, "expected error %v, got %v", errInvalidReadPreference, err) 128 }) 129 t.Run("valid hedge document and mode succeeds", func(t *testing.T) { 130 rp, err := New(SecondaryMode, WithHedgeEnabled(true)) 131 assert.Nil(t, err, "expected no error, got %v", err) 132 enabled := rp.HedgeEnabled() 133 assert.NotNil(t, enabled, "expected HedgeEnabled to return a non-nil value, got nil") 134 assert.True(t, *enabled, "expected HedgeEnabled to return true, got false") 135 }) 136} 137 138func TestReadPref_String(t *testing.T) { 139 t.Run("ReadPref.String() with all options", func(t *testing.T) { 140 readPref := Nearest( 141 WithMaxStaleness(120*time.Second), 142 WithTagSets(tag.Set{{"a", "1"}, {"b", "2"}}, tag.Set{{"q", "5"}, {"r", "6"}}), 143 WithHedgeEnabled(true), 144 ) 145 expected := "nearest(maxStaleness=2m0s tagSet=a=1,b=2 tagSet=q=5,r=6 hedgeEnabled=true)" 146 assert.Equal(t, expected, readPref.String(), "expected %q, got %q", expected, readPref.String()) 147 }) 148 t.Run("ReadPref.String() with one option", func(t *testing.T) { 149 readPref := Secondary(WithTags("a", "1", "b", "2")) 150 expected := "secondary(tagSet=a=1,b=2)" 151 assert.Equal(t, expected, readPref.String(), "expected %q, got %q", expected, readPref.String()) 152 }) 153 t.Run("ReadPref.String() with no options", func(t *testing.T) { 154 readPref := Primary() 155 expected := "primary" 156 assert.Equal(t, expected, readPref.String(), "expected %q, got %q", expected, readPref.String()) 157 }) 158} 159