github.com/m3db/m3@v1.5.0/src/query/api/v1/handler/namespace/get_test.go (about) 1 // Copyright (c) 2018 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package namespace 22 23 import ( 24 "io/ioutil" 25 "net/http" 26 "net/http/httptest" 27 "testing" 28 29 "github.com/m3db/m3/src/cluster/client" 30 "github.com/m3db/m3/src/cluster/kv" 31 nsproto "github.com/m3db/m3/src/dbnode/generated/proto/namespace" 32 "github.com/m3db/m3/src/x/headers" 33 "github.com/m3db/m3/src/x/instrument" 34 xjson "github.com/m3db/m3/src/x/json" 35 xtest "github.com/m3db/m3/src/x/test" 36 37 "github.com/golang/mock/gomock" 38 "github.com/stretchr/testify/assert" 39 "github.com/stretchr/testify/require" 40 ) 41 42 func setupNamespaceTest(t *testing.T, ctrl *gomock.Controller) (*client.MockClient, *kv.MockStore) { 43 mockClient := client.NewMockClient(ctrl) 44 require.NotNil(t, mockClient) 45 46 mockKV := kv.NewMockStore(ctrl) 47 require.NotNil(t, mockKV) 48 49 mockClient.EXPECT().KV().Return(mockKV, nil).AnyTimes() 50 51 return mockClient, mockKV 52 } 53 54 func TestNamespaceGetHandler(t *testing.T) { 55 ctrl := gomock.NewController(t) 56 defer ctrl.Finish() 57 58 mockClient, mockKV := setupNamespaceTest(t, ctrl) 59 getHandler := NewGetHandler(mockClient, instrument.NewOptions()) 60 mockClient.EXPECT().Store(gomock.Any()).Return(mockKV, nil) 61 62 // Test no namespace 63 w := httptest.NewRecorder() 64 65 req := httptest.NewRequest("GET", "/namespace/get", nil) 66 require.NotNil(t, req) 67 68 matcher := newStoreOptionsMatcher("", "", "test_env") 69 mockClient.EXPECT().Store(matcher).Return(mockKV, nil) 70 mockKV.EXPECT().Get(M3DBNodeNamespacesKey).Return(nil, kv.ErrNotFound) 71 getHandler.ServeHTTP(svcDefaults, w, req) 72 73 resp := w.Result() 74 body, _ := ioutil.ReadAll(resp.Body) 75 assert.Equal(t, http.StatusOK, resp.StatusCode) 76 assert.Equal(t, "{\"registry\":{\"namespaces\":{}}}", string(body)) 77 78 // Test namespace present 79 w = httptest.NewRecorder() 80 81 req = httptest.NewRequest("GET", "/namespace/get", nil) 82 req.Header.Set(headers.HeaderClusterEnvironmentName, "test_env") 83 require.NotNil(t, req) 84 85 extendedOpts := xtest.NewTestExtendedOptionsProto("foo") 86 87 registry := nsproto.Registry{ 88 Namespaces: map[string]*nsproto.NamespaceOptions{ 89 "test": { 90 BootstrapEnabled: true, 91 FlushEnabled: true, 92 SnapshotEnabled: true, 93 WritesToCommitLog: true, 94 CleanupEnabled: false, 95 RepairEnabled: false, 96 RetentionOptions: &nsproto.RetentionOptions{ 97 RetentionPeriodNanos: 172800000000000, 98 BlockSizeNanos: 7200000000000, 99 BufferFutureNanos: 600000000000, 100 BufferPastNanos: 600000000000, 101 BlockDataExpiry: true, 102 BlockDataExpiryAfterNotAccessPeriodNanos: 3600000000000, 103 }, 104 ExtendedOptions: extendedOpts, 105 StagingState: &nsproto.StagingState{Status: nsproto.StagingStatus_READY}, 106 }, 107 }, 108 } 109 110 mockValue := kv.NewMockValue(ctrl) 111 mockValue.EXPECT().Unmarshal(gomock.Any()).Return(nil).SetArg(0, registry) 112 113 mockKV.EXPECT().Get(M3DBNodeNamespacesKey).Return(mockValue, nil) 114 getHandler.ServeHTTP(svcDefaults, w, req) 115 116 resp = w.Result() 117 body, _ = ioutil.ReadAll(resp.Body) 118 assert.Equal(t, http.StatusOK, resp.StatusCode) 119 120 expected := xtest.MustPrettyJSONMap(t, 121 xjson.Map{ 122 "registry": xjson.Map{ 123 "namespaces": xjson.Map{ 124 "test": xjson.Map{ 125 "aggregationOptions": nil, 126 "bootstrapEnabled": true, 127 "cacheBlocksOnRetrieve": nil, 128 "cleanupEnabled": false, 129 "coldWritesEnabled": false, 130 "flushEnabled": true, 131 "indexOptions": nil, 132 "repairEnabled": false, 133 "retentionOptions": xjson.Map{ 134 "blockDataExpiry": true, 135 "blockDataExpiryAfterNotAccessPeriodNanos": "3600000000000", 136 "blockSizeNanos": "7200000000000", 137 "bufferFutureNanos": "600000000000", 138 "bufferPastNanos": "600000000000", 139 "futureRetentionPeriodNanos": "0", 140 "retentionPeriodNanos": "172800000000000", 141 }, 142 "runtimeOptions": nil, 143 "schemaOptions": nil, 144 "snapshotEnabled": true, 145 "stagingState": xjson.Map{"status": "READY"}, 146 "writesToCommitLog": true, 147 "extendedOptions": xtest.NewTestExtendedOptionsJSON("foo"), 148 }, 149 }, 150 }, 151 }) 152 153 actual := xtest.MustPrettyJSONString(t, string(body)) 154 155 assert.Equal(t, expected, actual, 156 xtest.Diff(expected, actual)) 157 } 158 159 func TestNamespaceGetHandlerWithDebug(t *testing.T) { 160 ctrl := gomock.NewController(t) 161 defer ctrl.Finish() 162 163 mockClient, mockKV := setupNamespaceTest(t, ctrl) 164 getHandler := NewGetHandler(mockClient, instrument.NewOptions()) 165 mockClient.EXPECT().Store(gomock.Any()).Return(mockKV, nil) 166 167 // Test namespace present 168 w := httptest.NewRecorder() 169 170 req := httptest.NewRequest("GET", "/namespace/get?debug=true", nil) 171 require.NotNil(t, req) 172 173 registry := nsproto.Registry{ 174 Namespaces: map[string]*nsproto.NamespaceOptions{ 175 "test": { 176 BootstrapEnabled: true, 177 FlushEnabled: true, 178 SnapshotEnabled: true, 179 WritesToCommitLog: true, 180 CleanupEnabled: false, 181 RepairEnabled: false, 182 RetentionOptions: &nsproto.RetentionOptions{ 183 RetentionPeriodNanos: 172800000000000, 184 BlockSizeNanos: 7200000000000, 185 BufferFutureNanos: 600000000000, 186 BufferPastNanos: 600000000000, 187 BlockDataExpiry: true, 188 BlockDataExpiryAfterNotAccessPeriodNanos: 3600000000000, 189 }, 190 StagingState: &nsproto.StagingState{Status: nsproto.StagingStatus_UNKNOWN}, 191 }, 192 }, 193 } 194 195 mockValue := kv.NewMockValue(ctrl) 196 mockValue.EXPECT().Unmarshal(gomock.Any()).Return(nil).SetArg(0, registry) 197 198 mockKV.EXPECT().Get(M3DBNodeNamespacesKey).Return(mockValue, nil) 199 getHandler.ServeHTTP(svcDefaults, w, req) 200 201 resp := w.Result() 202 body, _ := ioutil.ReadAll(resp.Body) 203 assert.Equal(t, http.StatusOK, resp.StatusCode) 204 205 expected := xtest.MustPrettyJSONMap(t, 206 xjson.Map{ 207 "registry": xjson.Map{ 208 "namespaces": xjson.Map{ 209 "test": xjson.Map{ 210 "aggregationOptions": nil, 211 "bootstrapEnabled": true, 212 "cacheBlocksOnRetrieve": nil, 213 "cleanupEnabled": false, 214 "coldWritesEnabled": false, 215 "flushEnabled": true, 216 "indexOptions": nil, 217 "repairEnabled": false, 218 "retentionOptions": xjson.Map{ 219 "blockDataExpiry": true, 220 "blockDataExpiryAfterNotAccessPeriodDuration": "1h0m0s", 221 "blockSizeDuration": "2h0m0s", 222 "bufferFutureDuration": "10m0s", 223 "bufferPastDuration": "10m0s", 224 "futureRetentionPeriodDuration": "0s", 225 "retentionPeriodDuration": "48h0m0s", 226 }, 227 "runtimeOptions": nil, 228 "schemaOptions": nil, 229 "stagingState": xjson.Map{"status": "UNKNOWN"}, 230 "snapshotEnabled": true, 231 "writesToCommitLog": true, 232 "extendedOptions": nil, 233 }, 234 }, 235 }, 236 }) 237 238 actual := xtest.MustPrettyJSONString(t, string(body)) 239 240 assert.Equal(t, expected, actual, 241 xtest.Diff(expected, actual)) 242 }