/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using System; using System.Collections.Generic; using OpenSearch.Net; using FluentAssertions; using OpenSearch.Client; using Tests.Core.Extensions; using Tests.Core.ManagedOpenSearch.Clusters; using Tests.Domain; using Tests.Framework.EndpointTests; using Tests.Framework.EndpointTests.TestState; namespace Tests.Document.Multiple.Bulk { public class BulkApiTests : ApiIntegrationTestBase { public BulkApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } protected override bool ExpectIsValid => true; protected override object ExpectJson => new[] { new Dictionary { { "index", new { _id = Project.Instance.Name, pipeline = "pipeline", routing = Project.Instance.Name } } }, Project.InstanceAnonymous, new Dictionary { { "update", new { _id = Project.Instance.Name } } }, new { doc = new { leadDeveloper = new { firstName = "martijn" } } }, new Dictionary { { "create", new { _id = Project.Instance.Name + "1", routing = Project.Instance.Name } } }, Project.InstanceAnonymous, new Dictionary { { "delete", new { _id = Project.Instance.Name + "1", routing = Project.Instance.Name } } }, new Dictionary { { "create", new { _id = Project.Instance.Name + "2", routing = Project.Instance.Name } } }, Project.InstanceAnonymous, new Dictionary { { "update", new { _id = Project.Instance.Name + "2", routing = Project.Instance.Name } } }, new Dictionary { { "script", new { source = "ctx._source.numberOfCommits = params.commits", @params = new { commits = 30 }, lang = "painless" } } }, }; protected override int ExpectStatusCode => 200; protected override Func Fluent => d => d .Index(CallIsolatedValue) .Pipeline("default-pipeline") .Index(b => b.Document(Project.Instance).Pipeline("pipeline")) .Update(b => b.Doc(new { leadDeveloper = new { firstName = "martijn" } }).Id(Project.Instance.Name)) .Create(b => b.Document(Project.Instance).Id(Project.Instance.Name + "1")) .Delete(b => b.Id(Project.Instance.Name + "1").Routing(Project.Instance.Name)) .Create(b => b.Document(Project.Instance).Id(Project.Instance.Name + "2")) .Update(b => b .Id(Project.Instance.Name + "2") .Routing(Project.Instance.Name) .Script(s => s .Source("ctx._source.numberOfCommits = params.commits") .Params(p => p.Add("commits", 30)) .Lang("painless") ) ); protected override HttpMethod HttpMethod => HttpMethod.POST; protected override BulkRequest Initializer => new BulkRequest(CallIsolatedValue) { Pipeline = "default-pipeline", Operations = new List { new BulkIndexOperation(Project.Instance) { Pipeline = "pipeline" }, new BulkUpdateOperation(Project.Instance.Name) { Doc = new { leadDeveloper = new { firstName = "martijn" } } }, new BulkCreateOperation(Project.Instance) { Id = Project.Instance.Name + "1", }, new BulkDeleteOperation(Project.Instance.Name + "1") { Routing = Project.Instance.Name }, new BulkCreateOperation(Project.Instance) { Id = Project.Instance.Name + "2", }, new BulkUpdateOperation(Project.Instance.Name + "2") { Routing = Project.Instance.Name, Script = new InlineScript("ctx._source.numberOfCommits = params.commits") { Params = new Dictionary { { "commits", 30 } }, Lang = "painless" } } } }; protected override bool SupportsDeserialization => false; protected override string UrlPath => $"/{CallIsolatedValue}/_bulk?pipeline=default-pipeline"; protected override LazyResponses ClientUsage() => Calls( (client, f) => client.Bulk(f), (client, f) => client.BulkAsync(f), (client, r) => client.Bulk(r), (client, r) => client.BulkAsync(r) ); protected override void IntegrationSetup(IOpenSearchClient client, CallUniqueValues values) { var pipelineResponse = client.Ingest.PutPipeline("default-pipeline", p => p .Processors(pr => pr .Set(t => t.Field(f => f.Description).Value("Default")) ) ); pipelineResponse.ShouldBeValid("Failed to set up pipeline named 'default-pipeline' required for bulk {p"); pipelineResponse = client.Ingest.PutPipeline("pipeline", p => p .Processors(pr => pr .Set(t => t.Field(f => f.Description).Value("Overridden")) ) ); pipelineResponse.ShouldBeValid($"Failed to set up pipeline named 'pipeline' required for bulk"); base.IntegrationSetup(client, values); } protected override void ExpectResponse(BulkResponse response) { response.Took.Should().BeGreaterThan(0); response.Errors.Should().BeFalse(); response.ItemsWithErrors.Should().NotBeNull().And.BeEmpty(); response.Items.Should().NotBeEmpty(); foreach (var item in response.Items) { item.Index.Should().Be(CallIsolatedValue); if (Cluster.ClusterConfiguration.Version < "2.0.0") item.Type.Should().Be("_doc"); item.Status.Should().BeGreaterThan(100); item.Version.Should().BeGreaterThan(0); item.Id.Should().NotBeNullOrWhiteSpace(); item.IsValid.Should().BeTrue(); item.Shards.Should().NotBeNull(); item.Shards.Total.Should().BeGreaterThan(0); item.Shards.Successful.Should().BeGreaterThan(0); item.SequenceNumber.Should().BeGreaterOrEqualTo(0); item.PrimaryTerm.Should().BeGreaterThan(0); item.Result.Should().NotBeNullOrEmpty(); } var project1 = Client.Source(Project.Instance.Name, p => p.Index(CallIsolatedValue)).Body; project1.LeadDeveloper.FirstName.Should().Be("martijn"); project1.Description.Should().Be("Overridden"); var project2 = Client.Source(Project.Instance.Name + "2", p => p .Index(CallIsolatedValue) .Routing(Project.Instance.Name) ).Body; project2.Description.Should().Be("Default"); project2.NumberOfCommits.Should().Be(30); } } }