github.com/m3db/m3@v1.5.0/src/dbnode/integration/encoder_limit_test.go (about) 1 // +build integration 2 3 // Copyright (c) 2020 Uber Technologies, Inc. 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 23 package integration 24 25 import ( 26 "testing" 27 "time" 28 29 "github.com/m3db/m3/src/dbnode/client" 30 "github.com/m3db/m3/src/x/ident" 31 xtime "github.com/m3db/m3/src/x/time" 32 33 "github.com/stretchr/testify/require" 34 ) 35 36 func TestEncoderLimit(t *testing.T) { 37 if testing.Short() { 38 t.SkipNow() 39 } 40 41 // We don't want a tick to happen during this test, since that will 42 // interfere with testing encoders due to the tick merging them. 43 testOpts := NewTestOptions(t).SetTickMinimumInterval(time.Minute) 44 testSetup, err := NewTestSetup(t, testOpts, nil) 45 require.NoError(t, err) 46 defer testSetup.Close() 47 48 log := testSetup.StorageOpts().InstrumentOptions().Logger() 49 require.NoError(t, testSetup.StartServer()) 50 log.Info("server is now up") 51 52 defer func() { 53 require.NoError(t, testSetup.StopServer()) 54 log.Info("server is now down") 55 }() 56 57 now := testSetup.NowFn()() 58 59 db := testSetup.DB() 60 mgr := db.Options().RuntimeOptionsManager() 61 encoderLimit := 5 62 newRuntimeOpts := mgr.Get().SetEncodersPerBlockLimit(encoderLimit) 63 mgr.Update(newRuntimeOpts) 64 65 session, err := testSetup.M3DBClient().DefaultSession() 66 require.NoError(t, err) 67 nsID := testNamespaces[0] 68 seriesID := ident.StringID("foo") 69 70 for i := 0; i < encoderLimit+5; i++ { 71 err = session.Write( 72 nsID, seriesID, 73 // Write backwards so that a new encoder gets created every write. 74 now.Add(time.Duration(50-i)*time.Second), 75 123, xtime.Second, nil, 76 ) 77 78 if i >= encoderLimit { 79 require.Error(t, err) 80 // A rejected write due to hitting the max encoder limit should be 81 // a bad request so that the client knows to not repeat the write 82 // request, since that will exacerbate the problem. 83 require.True(t, client.IsBadRequestError(err)) 84 } else { 85 require.NoError(t, err) 86 } 87 } 88 89 for i := 0; i < 10; i++ { 90 err = session.Write( 91 nsID, seriesID, 92 now.Add(time.Duration(51+i)*time.Second), 93 123, xtime.Second, nil, 94 ) 95 96 // Even though we're doing more writes, these can fit into existing 97 // encoders since they are all ahead of existing writes, so expect 98 // no errors writing. 99 require.NoError(t, err) 100 } 101 102 // Now allow an unlimited number of encoders. 103 encoderLimit = 0 104 newRuntimeOpts = mgr.Get().SetEncodersPerBlockLimit(encoderLimit) 105 mgr.Update(newRuntimeOpts) 106 107 for i := 0; i < 20; i++ { 108 err = session.Write( 109 nsID, seriesID, 110 now.Add(time.Duration(20-i)*time.Second), 111 123, xtime.Second, nil, 112 ) 113 114 // Now there's no encoder limit, so no error even though each of these 115 // additional writes creates a new encoder. 116 require.NoError(t, err) 117 } 118 }