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  }