1// Copyright 2012-present Oliver Eilhard. All rights reserved.
2// Use of this source code is governed by a MIT-license.
3// See http://olivere.mit-license.org/license.txt for details.
4
5package elastic
6
7import (
8	"testing"
9)
10
11func TestBulkUpdateRequestSerialization(t *testing.T) {
12	tests := []struct {
13		Request  BulkableRequest
14		Expected []string
15	}{
16		// #0
17		{
18			Request: NewBulkUpdateRequest().Index("index1").Type("tweet").Id("1").Doc(struct {
19				Counter int64 `json:"counter"`
20			}{
21				Counter: 42,
22			}),
23			Expected: []string{
24				`{"update":{"_id":"1","_index":"index1","_type":"tweet"}}`,
25				`{"doc":{"counter":42}}`,
26			},
27		},
28		// #1
29		{
30			Request: NewBulkUpdateRequest().Index("index1").Type("tweet").Id("1").
31				RetryOnConflict(3).
32				DocAsUpsert(true).
33				Doc(struct {
34					Counter int64 `json:"counter"`
35				}{
36					Counter: 42,
37				}),
38			Expected: []string{
39				`{"update":{"_id":"1","_index":"index1","_retry_on_conflict":3,"_type":"tweet"}}`,
40				`{"doc":{"counter":42},"doc_as_upsert":true}`,
41			},
42		},
43		// #2
44		{
45			Request: NewBulkUpdateRequest().Index("index1").Type("tweet").Id("1").
46				RetryOnConflict(3).
47				Script(NewScript(`ctx._source.retweets += param1`).Lang("javascript").Param("param1", 42)).
48				Upsert(struct {
49					Counter int64 `json:"counter"`
50				}{
51					Counter: 42,
52				}),
53			Expected: []string{
54				`{"update":{"_id":"1","_index":"index1","_retry_on_conflict":3,"_type":"tweet"}}`,
55				`{"script":{"inline":"ctx._source.retweets += param1","lang":"javascript","params":{"param1":42}},"upsert":{"counter":42}}`,
56			},
57		},
58		// #3
59		{
60			Request: NewBulkUpdateRequest().Index("index1").Type("tweet").Id("1").DetectNoop(true).Doc(struct {
61				Counter int64 `json:"counter"`
62			}{
63				Counter: 42,
64			}),
65			Expected: []string{
66				`{"update":{"_id":"1","_index":"index1","_type":"tweet"}}`,
67				`{"detect_noop":true,"doc":{"counter":42}}`,
68			},
69		},
70		// #4
71		{
72			Request: NewBulkUpdateRequest().Index("index1").Type("tweet").Id("1").
73				RetryOnConflict(3).
74				ScriptedUpsert(true).
75				Script(NewScript(`ctx._source.retweets += param1`).Lang("javascript").Param("param1", 42)).
76				Upsert(struct {
77					Counter int64 `json:"counter"`
78				}{
79					Counter: 42,
80				}),
81			Expected: []string{
82				`{"update":{"_id":"1","_index":"index1","_retry_on_conflict":3,"_type":"tweet"}}`,
83				`{"script":{"inline":"ctx._source.retweets += param1","lang":"javascript","params":{"param1":42}},"scripted_upsert":true,"upsert":{"counter":42}}`,
84			},
85		},
86	}
87
88	for i, test := range tests {
89		lines, err := test.Request.Source()
90		if err != nil {
91			t.Fatalf("#%d: expected no error, got: %v", i, err)
92		}
93		if lines == nil {
94			t.Fatalf("#%d: expected lines, got nil", i)
95		}
96		if len(lines) != len(test.Expected) {
97			t.Fatalf("#%d: expected %d lines, got %d", i, len(test.Expected), len(lines))
98		}
99		for j, line := range lines {
100			if line != test.Expected[j] {
101				t.Errorf("#%d: expected line #%d to be\n%s\nbut got:\n%s", i, j, test.Expected[j], line)
102			}
103		}
104	}
105}
106
107var bulkUpdateRequestSerializationResult string
108
109func BenchmarkBulkUpdateRequestSerialization(b *testing.B) {
110	r := NewBulkUpdateRequest().Index("index1").Type("tweet").Id("1").Doc(struct {
111		Counter int64 `json:"counter"`
112	}{
113		Counter: 42,
114	})
115	var s string
116	for n := 0; n < b.N; n++ {
117		s = r.String()
118		r.source = nil // Don't let caching spoil the benchmark
119	}
120	bulkUpdateRequestSerializationResult = s // ensure the compiler doesn't optimize
121}
122