Skip to content

Commit f117368

Browse files
committed
Add golden workflow integration tests for core osapi operations
Hand-written table-driven tests covering Bulk, Count, Cat, Alias, Settings, Mapping, Scroll, IndexTemplate, PIT, Aggregation, DocumentGet, Mget, Update, and DeleteByQuery. Signed-off-by: Sean Chittenden <sean.chittenden@crowdstrike.com>
1 parent 1cfa5f0 commit f117368

9 files changed

Lines changed: 1259 additions & 0 deletions

osapi/api_aggregation_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
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+
//go:build integration
8+
9+
package osapi_test
10+
11+
import (
12+
"context"
13+
"strings"
14+
"testing"
15+
16+
"github.com/stretchr/testify/require"
17+
18+
"github.com/opensearch-project/opensearch-go/v4/osapi"
19+
osapitest "github.com/opensearch-project/opensearch-go/v4/osapi/internal/test"
20+
"github.com/opensearch-project/opensearch-go/v4/osapi/testutil"
21+
)
22+
23+
func TestManual_Aggregation(t *testing.T) {
24+
client, err := testutil.NewClient(t)
25+
require.NoError(t, err)
26+
27+
index := testutil.MustUniqueString(t, "test-agg")
28+
t.Cleanup(func() {
29+
_, _ = client.Indices.Delete(context.Background(), &osapi.IndicesDeleteReq{Index: []string{index}})
30+
})
31+
32+
_, err = client.Indices.Create(t.Context(), osapi.IndicesCreateReq{
33+
Index: index,
34+
BodyReader: strings.NewReader(
35+
`{"mappings":{"properties":{"category":{"type":"keyword"},` +
36+
`"price":{"type":"integer"},"timestamp":{"type":"date"}}}}`,
37+
),
38+
})
39+
require.NoError(t, err)
40+
41+
docs := []string{
42+
`{"category":"electronics","price":100,"timestamp":"2024-01-01"}`,
43+
`{"category":"electronics","price":200,"timestamp":"2024-01-15"}`,
44+
`{"category":"books","price":15,"timestamp":"2024-02-01"}`,
45+
`{"category":"books","price":25,"timestamp":"2024-02-15"}`,
46+
`{"category":"clothing","price":50,"timestamp":"2024-03-01"}`,
47+
}
48+
49+
var ndjson strings.Builder
50+
for _, doc := range docs {
51+
ndjson.WriteString(`{"index":{"_index":"` + index + `"}}` + "\n")
52+
ndjson.WriteString(doc + "\n")
53+
}
54+
_, err = client.Bulk(t.Context(), osapi.BulkReq{
55+
Body: strings.NewReader(ndjson.String()),
56+
Params: &osapi.BulkParams{Refresh: "true"},
57+
})
58+
require.NoError(t, err)
59+
60+
tests := []struct {
61+
name string
62+
query string
63+
check func(t *testing.T, resp *osapi.SearchResp)
64+
}{
65+
{
66+
name: "terms aggregation",
67+
query: `{"size":0,"aggs":{"by_category":{"terms":{"field":"category"}}}}`,
68+
check: func(t *testing.T, resp *osapi.SearchResp) {
69+
t.Helper()
70+
require.Contains(t, resp.Aggregations, "by_category")
71+
},
72+
},
73+
{
74+
name: "date histogram aggregation",
75+
query: `{"size":0,"aggs":{"by_month":{"date_histogram":` +
76+
`{"field":"timestamp","calendar_interval":"month"}}}}`,
77+
check: func(t *testing.T, resp *osapi.SearchResp) {
78+
t.Helper()
79+
require.Contains(t, resp.Aggregations, "by_month")
80+
},
81+
},
82+
{
83+
name: "stats aggregation",
84+
query: `{"size":0,"aggs":{"price_stats":{"stats":{"field":"price"}}}}`,
85+
check: func(t *testing.T, resp *osapi.SearchResp) {
86+
t.Helper()
87+
require.Contains(t, resp.Aggregations, "price_stats")
88+
},
89+
},
90+
{
91+
name: "nested terms with stats",
92+
query: `{"size":0,"aggs":{"by_category":{"terms":{"field":"category"},` +
93+
`"aggs":{"avg_price":{"avg":{"field":"price"}}}}}}`,
94+
check: func(t *testing.T, resp *osapi.SearchResp) {
95+
t.Helper()
96+
require.Contains(t, resp.Aggregations, "by_category")
97+
},
98+
},
99+
}
100+
101+
for _, tt := range tests {
102+
t.Run(tt.name, func(t *testing.T) {
103+
resp, err := client.Search(t.Context(), &osapi.SearchReq{
104+
Index: []string{index},
105+
BodyReader: strings.NewReader(tt.query),
106+
})
107+
require.NoError(t, err)
108+
require.NotNil(t, resp.Aggregations)
109+
tt.check(t, resp)
110+
})
111+
}
112+
113+
t.Run("inspect", func(t *testing.T) {
114+
failingClient, err := osapitest.CreateFailingClient(t)
115+
require.NoError(t, err)
116+
117+
res, err := failingClient.Search(t.Context(), &osapi.SearchReq{
118+
Index: []string{index},
119+
BodyReader: strings.NewReader(`{"size":0,"aggs":{"x":{"terms":{"field":"category"}}}}`),
120+
})
121+
require.Error(t, err)
122+
require.NotNil(t, res)
123+
osapitest.VerifyInspect(t, res.Inspect())
124+
})
125+
}

osapi/api_alias_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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+
//go:build integration
8+
9+
package osapi_test
10+
11+
import (
12+
"context"
13+
"testing"
14+
15+
"github.com/stretchr/testify/require"
16+
17+
"github.com/opensearch-project/opensearch-go/v4/osapi"
18+
osapitest "github.com/opensearch-project/opensearch-go/v4/osapi/internal/test"
19+
"github.com/opensearch-project/opensearch-go/v4/osapi/testutil"
20+
)
21+
22+
func TestManual_IndicesAlias(t *testing.T) {
23+
client, err := testutil.NewClient(t)
24+
require.NoError(t, err)
25+
26+
index := testutil.MustUniqueString(t, "test-alias")
27+
t.Cleanup(func() {
28+
_, _ = client.Indices.Delete(context.Background(), &osapi.IndicesDeleteReq{Index: []string{index}})
29+
})
30+
31+
_, err = client.Indices.Create(t.Context(), osapi.IndicesCreateReq{Index: index})
32+
require.NoError(t, err)
33+
34+
tests := []struct {
35+
name string
36+
alias string
37+
}{
38+
{name: "alias-one", alias: testutil.MustUniqueString(t, "alias-one")},
39+
{name: "alias-two", alias: testutil.MustUniqueString(t, "alias-two")},
40+
}
41+
42+
for _, tt := range tests {
43+
t.Run("put/"+tt.name, func(t *testing.T) {
44+
resp, err := client.Indices.PutAlias(t.Context(), osapi.IndicesPutAliasReq{
45+
Index: []string{index},
46+
Name: tt.alias,
47+
})
48+
require.NoError(t, err)
49+
require.True(t, resp.Acknowledged)
50+
testutil.CompareRawJSONwithParsedJSON(t, resp, resp.Inspect().Response)
51+
})
52+
}
53+
54+
for _, tt := range tests {
55+
t.Run("get/"+tt.name, func(t *testing.T) {
56+
resp, err := client.Indices.GetAlias(t.Context(), &osapi.IndicesGetAliasReq{
57+
Index: []string{index},
58+
Name: []string{tt.alias},
59+
})
60+
require.NoError(t, err)
61+
require.Contains(t, resp.Entries, index)
62+
require.Contains(t, resp.Entries[index].Aliases, tt.alias)
63+
testutil.CompareRawJSONwithParsedJSON(t, resp, resp.Inspect().Response)
64+
})
65+
}
66+
67+
for _, tt := range tests {
68+
t.Run("exists/"+tt.name, func(t *testing.T) {
69+
resp, err := client.Indices.ExistsAlias(t.Context(), &osapi.IndicesExistsAliasReq{
70+
Index: []string{index},
71+
Name: []string{tt.alias},
72+
})
73+
require.NoError(t, err)
74+
require.Equal(t, 200, resp.StatusCode)
75+
})
76+
}
77+
78+
for _, tt := range tests {
79+
t.Run("delete/"+tt.name, func(t *testing.T) {
80+
resp, err := client.Indices.DeleteAlias(t.Context(), &osapi.IndicesDeleteAliasReq{
81+
Index: []string{index},
82+
Name: []string{tt.alias},
83+
})
84+
require.NoError(t, err)
85+
require.True(t, resp.Acknowledged)
86+
testutil.CompareRawJSONwithParsedJSON(t, resp, resp.Inspect().Response)
87+
})
88+
}
89+
90+
t.Run("inspect", func(t *testing.T) {
91+
failingClient, err := osapitest.CreateFailingClient(t)
92+
require.NoError(t, err)
93+
94+
res, err := failingClient.Indices.GetAlias(t.Context(), nil)
95+
require.Error(t, err)
96+
require.NotNil(t, res)
97+
osapitest.VerifyInspect(t, res.Inspect())
98+
})
99+
}

0 commit comments

Comments
 (0)