...

Source file src/go.mongodb.org/mongo-driver/mongo/writeconcern/writeconcern_test.go

Documentation: go.mongodb.org/mongo-driver/mongo/writeconcern

     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  
     7  package writeconcern_test
     8  
     9  import (
    10  	"errors"
    11  	"testing"
    12  	"time"
    13  
    14  	"go.mongodb.org/mongo-driver/bson"
    15  	"go.mongodb.org/mongo-driver/bson/bsontype"
    16  	"go.mongodb.org/mongo-driver/internal/assert"
    17  	"go.mongodb.org/mongo-driver/internal/require"
    18  	"go.mongodb.org/mongo-driver/mongo/writeconcern"
    19  )
    20  
    21  func TestWriteConcernWithOptions(t *testing.T) {
    22  	t.Parallel()
    23  
    24  	t.Run("on nil WriteConcern", func(t *testing.T) {
    25  		t.Parallel()
    26  
    27  		var wc *writeconcern.WriteConcern
    28  
    29  		wc = wc.WithOptions(writeconcern.WMajority())
    30  		assert.Equal(t, "majority", wc.GetW().(string))
    31  		assert.False(t, wc.GetJ())
    32  	})
    33  	t.Run("on existing WriteConcern", func(t *testing.T) {
    34  		t.Parallel()
    35  
    36  		wc := writeconcern.New(writeconcern.W(1), writeconcern.J(true))
    37  		assert.Equal(t, 1, wc.GetW().(int))
    38  		assert.True(t, wc.GetJ())
    39  
    40  		wc = wc.WithOptions(writeconcern.WMajority())
    41  		assert.Equal(t, "majority", wc.GetW().(string))
    42  		assert.True(t, wc.GetJ())
    43  	})
    44  	t.Run("with multiple options", func(t *testing.T) {
    45  		t.Parallel()
    46  
    47  		wc := writeconcern.New(writeconcern.W(1), writeconcern.J(true))
    48  		assert.Equal(t, 1, wc.GetW().(int))
    49  		assert.True(t, wc.GetJ())
    50  		assert.Equal(t, time.Duration(0), wc.GetWTimeout())
    51  
    52  		wc = wc.WithOptions(writeconcern.WMajority(), writeconcern.WTimeout(time.Second))
    53  		assert.Equal(t, "majority", wc.GetW().(string))
    54  		assert.True(t, wc.GetJ())
    55  		assert.Equal(t, time.Second, wc.GetWTimeout())
    56  	})
    57  }
    58  
    59  func TestWriteConcern_MarshalBSONValue(t *testing.T) {
    60  	t.Parallel()
    61  
    62  	boolPtr := func(b bool) *bool { return &b }
    63  
    64  	testCases := []struct {
    65  		name      string
    66  		wc        *writeconcern.WriteConcern
    67  		wantType  bsontype.Type
    68  		wantValue bson.D
    69  		wantError error
    70  	}{
    71  		{
    72  			name: "all fields",
    73  			wc: &writeconcern.WriteConcern{
    74  				W:        "majority",
    75  				Journal:  boolPtr(false),
    76  				WTimeout: 1 * time.Minute,
    77  			},
    78  			wantType: bson.TypeEmbeddedDocument,
    79  			wantValue: bson.D{
    80  				{Key: "w", Value: "majority"},
    81  				{Key: "j", Value: false},
    82  				{Key: "wtimeout", Value: int64(60_000)},
    83  			},
    84  		},
    85  		{
    86  			name:      "string W",
    87  			wc:        &writeconcern.WriteConcern{W: "majority"},
    88  			wantType:  bson.TypeEmbeddedDocument,
    89  			wantValue: bson.D{{Key: "w", Value: "majority"}},
    90  		},
    91  		{
    92  			name:      "int W",
    93  			wc:        &writeconcern.WriteConcern{W: 1},
    94  			wantType:  bson.TypeEmbeddedDocument,
    95  			wantValue: bson.D{{Key: "w", Value: int32(1)}},
    96  		},
    97  		{
    98  			name:      "int32 W",
    99  			wc:        &writeconcern.WriteConcern{W: int32(1)},
   100  			wantError: errors.New("WriteConcern.W must be a string or int, but is a int32"),
   101  		},
   102  		{
   103  			name:      "bool W",
   104  			wc:        &writeconcern.WriteConcern{W: false},
   105  			wantError: errors.New("WriteConcern.W must be a string or int, but is a bool"),
   106  		},
   107  		{
   108  			name:      "W=0 and J=true",
   109  			wc:        &writeconcern.WriteConcern{W: 0, Journal: boolPtr(true)},
   110  			wantError: writeconcern.ErrInconsistent,
   111  		},
   112  		{
   113  			name:      "negative W",
   114  			wc:        &writeconcern.WriteConcern{W: -1},
   115  			wantError: writeconcern.ErrNegativeW,
   116  		},
   117  		{
   118  			name:      "negative WTimeout",
   119  			wc:        &writeconcern.WriteConcern{W: 1, WTimeout: -1},
   120  			wantError: writeconcern.ErrNegativeWTimeout,
   121  		},
   122  		{
   123  			name:      "empty",
   124  			wc:        &writeconcern.WriteConcern{},
   125  			wantError: writeconcern.ErrEmptyWriteConcern,
   126  		},
   127  		{
   128  			name:      "nil",
   129  			wc:        nil,
   130  			wantError: writeconcern.ErrEmptyWriteConcern,
   131  		},
   132  	}
   133  
   134  	for _, tc := range testCases {
   135  		tc := tc // Capture range variable.
   136  
   137  		t.Run(tc.name, func(t *testing.T) {
   138  			t.Parallel()
   139  
   140  			typ, b, err := tc.wc.MarshalBSONValue()
   141  			if tc.wantError != nil {
   142  				assert.Equal(t, tc.wantError, err, "expected and actual errors do not match")
   143  				return
   144  			}
   145  			require.NoError(t, err, "bson.MarshalValue error")
   146  
   147  			assert.Equal(t, tc.wantType, typ, "expected and actual BSON types do not match")
   148  
   149  			rv := bson.RawValue{
   150  				Type:  typ,
   151  				Value: b,
   152  			}
   153  			var gotValue bson.D
   154  			err = rv.Unmarshal(&gotValue)
   155  			require.NoError(t, err, "error unmarshaling RawValue")
   156  			assert.Equal(t, tc.wantValue, gotValue, "expected and actual BSON values do not match")
   157  		})
   158  	}
   159  }
   160  
   161  func TestWriteConcern(t *testing.T) {
   162  	boolPtr := func(b bool) *bool { return &b }
   163  
   164  	testCases := []struct {
   165  		name             string
   166  		wc               *writeconcern.WriteConcern
   167  		wantAcknowledged bool
   168  		wantIsValid      bool
   169  	}{
   170  		{
   171  			name:             "Unacknowledged",
   172  			wc:               writeconcern.Unacknowledged(),
   173  			wantAcknowledged: false,
   174  			wantIsValid:      true,
   175  		},
   176  		{
   177  			name:             "W1",
   178  			wc:               writeconcern.W1(),
   179  			wantAcknowledged: true,
   180  			wantIsValid:      true,
   181  		},
   182  		{
   183  			name:             "Journaled",
   184  			wc:               writeconcern.Journaled(),
   185  			wantAcknowledged: true,
   186  			wantIsValid:      true,
   187  		},
   188  		{
   189  			name:             "Majority",
   190  			wc:               writeconcern.Majority(),
   191  			wantAcknowledged: true,
   192  			wantIsValid:      true,
   193  		},
   194  		{
   195  			name: "{w: 0, j: true}",
   196  			wc: &writeconcern.WriteConcern{
   197  				W:       0,
   198  				Journal: boolPtr(true),
   199  			},
   200  			wantAcknowledged: true,
   201  			wantIsValid:      false,
   202  		},
   203  		{
   204  			name:             "{w: custom}",
   205  			wc:               &writeconcern.WriteConcern{W: "custom"},
   206  			wantAcknowledged: true,
   207  			wantIsValid:      true,
   208  		},
   209  		{
   210  			name:             "nil",
   211  			wc:               nil,
   212  			wantAcknowledged: true,
   213  			wantIsValid:      true,
   214  		},
   215  		{
   216  			name: "invalid type",
   217  			wc: &writeconcern.WriteConcern{
   218  				W: struct{ Field string }{},
   219  			},
   220  			wantAcknowledged: true,
   221  			wantIsValid:      false,
   222  		},
   223  	}
   224  
   225  	for _, tc := range testCases {
   226  		tc := tc // Capture range variable.
   227  
   228  		t.Run(tc.name, func(t *testing.T) {
   229  			t.Parallel()
   230  
   231  			assert.Equal(t,
   232  				tc.wantAcknowledged,
   233  				tc.wc.Acknowledged(),
   234  				"expected and actual Acknowledged value are different")
   235  			assert.Equal(t,
   236  				tc.wantIsValid,
   237  				tc.wc.IsValid(),
   238  				"expected and actual IsValid value are different")
   239  		})
   240  	}
   241  }
   242  

View as plain text