github.com/opensearch-project/opensearch-go/v2@v2.3.0/opensearch_benchmark_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // 3 // The OpenSearch Contributors require contributions made to 4 // this file be licensed under the Apache-2.0 license or a 5 // compatible open source license. 6 // 7 // Modifications Copyright OpenSearch Contributors. See 8 // GitHub history for details. 9 10 // Licensed to Elasticsearch B.V. under one or more contributor 11 // license agreements. See the NOTICE file distributed with 12 // this work for additional information regarding copyright 13 // ownership. Elasticsearch B.V. licenses this file to you under 14 // the Apache License, Version 2.0 (the "License"); you may 15 // not use this file except in compliance with the License. 16 // You may obtain a copy of the License at 17 // 18 // http://www.apache.org/licenses/LICENSE-2.0 19 // 20 // Unless required by applicable law or agreed to in writing, 21 // software distributed under the License is distributed on an 22 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 23 // KIND, either express or implied. See the License for the 24 // specific language governing permissions and limitations 25 // under the License. 26 27 // +build !integration 28 29 package opensearch_test 30 31 import ( 32 "context" 33 "io/ioutil" 34 "net/http" 35 "strconv" 36 "strings" 37 "testing" 38 39 "github.com/opensearch-project/opensearch-go/v2" 40 "github.com/opensearch-project/opensearch-go/v2/opensearchapi" 41 ) 42 43 var defaultResponse = http.Response{ 44 Status: "200 OK", 45 StatusCode: 200, 46 ContentLength: 2, 47 Header: http.Header(map[string][]string{"Content-Type": {"application/json"}}), 48 Body: ioutil.NopCloser(strings.NewReader(`{}`)), 49 } 50 51 var infoResponse = http.Response{ 52 Status: "200 OK", 53 StatusCode: http.StatusOK, 54 Header: http.Header(map[string][]string{"Content-Type": {"application/json"}}), 55 } 56 57 type FakeTransport struct { 58 InfoResponse *http.Response 59 FakeResponse *http.Response 60 } 61 62 func (t *FakeTransport) RoundTrip(req *http.Request) (*http.Response, error) { 63 if req.URL.Path == "/" { 64 response := t.InfoResponse 65 response.Body = ioutil.NopCloser(strings.NewReader(`{ 66 "name" : "es1", 67 "cluster_name" : "opensearch-go", 68 "cluster_uuid" : "clusteruuid", 69 "version" : { 70 "number" : "1.0.0", 71 "distribution" : "opensearch", 72 "build_type" : "docker", 73 "build_hash" : "somehash", 74 "build_date" : "2021-06-09T06:34:20.411011746Z", 75 "build_snapshot" : true, 76 "lucene_version" : "8.9.0", 77 "minimum_wire_compatibility_version" : "6.8.0", 78 "minimum_index_compatibility_version" : "6.0.0-beta1" 79 } 80 }`)) 81 return t.InfoResponse, nil 82 } 83 return t.FakeResponse, nil 84 } 85 86 func newFakeTransport(b *testing.B) *FakeTransport { 87 return &FakeTransport{ 88 InfoResponse: &infoResponse, 89 FakeResponse: &defaultResponse, 90 } 91 } 92 93 func BenchmarkClient(b *testing.B) { 94 b.ReportAllocs() 95 96 b.Run("Create client with defaults", func(b *testing.B) { 97 for i := 0; i < b.N; i++ { 98 _, err := opensearch.NewClient(opensearch.Config{Transport: newFakeTransport(b)}) 99 100 if err != nil { 101 b.Fatalf("Unexpected error when creating a client: %s", err) 102 } 103 } 104 }) 105 } 106 107 func BenchmarkClientAPI(b *testing.B) { 108 b.ReportAllocs() 109 110 ctx := context.Background() 111 112 client, err := opensearch.NewClient(opensearch.Config{ 113 Addresses: []string{"http://localhost:9200"}, 114 Transport: newFakeTransport(b), 115 }) 116 if err != nil { 117 b.Fatalf("ERROR: %s", err) 118 } 119 120 b.Run("InfoRequest{}.Do()", func(b *testing.B) { 121 b.ResetTimer() 122 123 req := opensearchapi.InfoRequest{} 124 125 for i := 0; i < b.N; i++ { 126 if _, err := req.Do(ctx, client); err != nil { 127 b.Errorf("Unexpected error when getting a response: %s", err) 128 } 129 } 130 }) 131 132 b.Run("IndexRequest{...}.Do()", func(b *testing.B) { 133 b.ResetTimer() 134 var body strings.Builder 135 136 for i := 0; i < b.N; i++ { 137 docID := strconv.FormatInt(int64(i), 10) 138 139 body.Reset() 140 body.WriteString(`{"foo" : "bar `) 141 body.WriteString(docID) 142 body.WriteString(` " }`) 143 144 req := opensearchapi.IndexRequest{ 145 Index: "test", 146 DocumentID: docID, 147 Body: strings.NewReader(body.String()), 148 Refresh: "true", 149 Pretty: true, 150 Timeout: 100, 151 } 152 if _, err := req.Do(ctx, client); err != nil { 153 b.Errorf("Unexpected error when getting a response: %s", err) 154 } 155 } 156 }) 157 158 b.Run("Index(...)", func(b *testing.B) { 159 b.ResetTimer() 160 var body strings.Builder 161 162 for i := 0; i < b.N; i++ { 163 docID := strconv.FormatInt(int64(i), 10) 164 165 body.Reset() 166 body.WriteString(`{"foo" : "bar `) 167 body.WriteString(docID) 168 body.WriteString(` " }`) 169 170 _, err := client.Index( 171 "test", 172 strings.NewReader(body.String()), 173 client.Index.WithDocumentID(docID), 174 client.Index.WithRefresh("true"), 175 client.Index.WithPretty(), 176 client.Index.WithTimeout(100), 177 client.Index.WithContext(ctx), 178 ) 179 if err != nil { 180 b.Errorf("Unexpected error when getting a response: %s", err) 181 } 182 } 183 }) 184 185 b.Run("SearchRequest{...}.Do()", func(b *testing.B) { 186 b.ResetTimer() 187 188 body := `{"foo" : "bar"}` 189 indx := []string{"test"} 190 191 for i := 0; i < b.N; i++ { 192 req := opensearchapi.SearchRequest{ 193 Index: indx, 194 Body: strings.NewReader(body), 195 Size: opensearchapi.IntPtr(25), 196 Pretty: true, 197 Timeout: 100, 198 } 199 if _, err := req.Do(ctx, client); err != nil { 200 b.Errorf("Unexpected error when getting a response: %s", err) 201 } 202 } 203 }) 204 205 b.Run("Search(...)", func(b *testing.B) { 206 b.ResetTimer() 207 208 body := `{"foo" : "bar"}` 209 indx := "test" 210 211 for i := 0; i < b.N; i++ { 212 _, err := client.Search( 213 client.Search.WithIndex(indx), 214 client.Search.WithBody(strings.NewReader(body)), 215 client.Search.WithSize(25), 216 client.Search.WithPretty(), 217 client.Search.WithTimeout(100), 218 client.Search.WithContext(ctx), 219 ) 220 if err != nil { 221 b.Errorf("Unexpected error when getting a response: %s", err) 222 } 223 } 224 }) 225 226 b.Run("BulkRequest{...}.Do()", func(b *testing.B) { 227 b.ResetTimer() 228 var body strings.Builder 229 230 for i := 0; i < b.N; i++ { 231 docID := strconv.FormatInt(int64(i), 10) 232 233 body.Reset() 234 body.WriteString(`{"index" : { "_index" : "test", "_type" : "_doc", "_id" : "` + docID + `" }}`) 235 body.WriteString(`{"foo" : "bar `) 236 body.WriteString(docID) 237 body.WriteString(` " }`) 238 239 req := opensearchapi.BulkRequest{ 240 Body: strings.NewReader(body.String()), 241 Refresh: "true", 242 Pretty: true, 243 Timeout: 100, 244 } 245 if _, err := req.Do(ctx, client); err != nil { 246 b.Errorf("Unexpected error when getting a response: %s", err) 247 } 248 } 249 }) 250 251 b.Run("Bulk(...)", func(b *testing.B) { 252 b.ResetTimer() 253 var body strings.Builder 254 255 for i := 0; i < b.N; i++ { 256 docID := strconv.FormatInt(int64(i), 10) 257 258 body.Reset() 259 body.WriteString(`{"index" : { "_index" : "test", "_type" : "_doc", "_id" : "` + docID + `" }}`) 260 body.WriteString(`{"foo" : "bar `) 261 body.WriteString(docID) 262 body.WriteString(` " }`) 263 264 _, err := client.Bulk( 265 strings.NewReader(body.String()), 266 client.Bulk.WithRefresh("true"), 267 client.Bulk.WithPretty(), 268 client.Bulk.WithTimeout(100), 269 client.Bulk.WithContext(ctx), 270 ) 271 if err != nil { 272 b.Errorf("Unexpected error when getting a response: %s", err) 273 } 274 } 275 }) 276 }