All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opensearch.test.rest.RestActionTestCase Maven / Gradle / Ivy

There is a newer version: 2.18.0
Show newest version
/*
 * 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.
 */

/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch 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.
 */

/*
 * Modifications Copyright OpenSearch Contributors. See
 * GitHub history for details.
 */

package org.opensearch.test.rest;

import org.opensearch.action.ActionRequest;
import org.opensearch.action.ActionType;
import org.opensearch.client.node.NodeClient;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.util.concurrent.ThreadContext;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.action.ActionResponse;
import org.opensearch.core.indices.breaker.NoneCircuitBreakerService;
import org.opensearch.identity.IdentityService;
import org.opensearch.rest.RestController;
import org.opensearch.rest.RestRequest;
import org.opensearch.tasks.Task;
import org.opensearch.tasks.TaskListener;
import org.opensearch.test.OpenSearchTestCase;
import org.opensearch.test.client.NoOpNodeClient;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.usage.UsageService;
import org.junit.After;
import org.junit.Before;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;

import static org.mockito.Mockito.mock;

/**
 * A common base class for Rest*ActionTests. Provides access to a {@link RestController}
 * that can be used to register individual REST actions, and test request handling.
 */
public abstract class RestActionTestCase extends OpenSearchTestCase {
    private RestController controller;
    protected VerifyingClient verifyingClient;

    @Before
    public void setUpController() {
        verifyingClient = new VerifyingClient(this.getTestName());
        final IdentityService identityService = new IdentityService(Settings.EMPTY, mock(ThreadPool.class), List.of());
        controller = new RestController(
            Collections.emptySet(),
            null,
            verifyingClient,
            new NoneCircuitBreakerService(),
            new UsageService(),
            identityService
        );
    }

    @After
    public void tearDownController() {
        verifyingClient.close();
    }

    /**
     * A test {@link RestController}. This controller can be used to register and delegate
     * to handlers, but uses a mock client and cannot carry out the full request.
     */
    protected RestController controller() {
        return controller;
    }

    /**
     * Sends the given request to the test controller in {@link #controller()}.
     */
    protected void dispatchRequest(RestRequest request) {
        FakeRestChannel channel = new FakeRestChannel(request, false, 1);
        ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
        controller.dispatchRequest(request, channel, threadContext);
    }

    /**
     * A mocked {@link NodeClient} which can be easily reconfigured to verify arbitrary verification
     * functions, and can be reset to allow reconfiguration partway through a test without having to construct a new object.
     * 

* By default, will throw {@link AssertionError} when any execution method is called, unless configured otherwise using * {@link #setExecuteVerifier(BiFunction)} or {@link #setExecuteLocallyVerifier(BiFunction)}. */ public static class VerifyingClient extends NoOpNodeClient { AtomicReference executeVerifier = new AtomicReference<>(); AtomicReference executeLocallyVerifier = new AtomicReference<>(); public VerifyingClient(String testName) { super(testName); reset(); } /** * Clears any previously set verifier functions set by {@link #setExecuteVerifier(BiFunction)} and/or * {@link #setExecuteLocallyVerifier(BiFunction)}. These functions are replaced with functions which will throw an * {@link AssertionError} if called. */ public void reset() { executeVerifier.set((arg1, arg2) -> { throw new AssertionError(); }); executeLocallyVerifier.set((arg1, arg2) -> { throw new AssertionError(); }); } /** * Sets the function that will be called when {@link #doExecute(ActionType, ActionRequest, ActionListener)} is called. The given * function should return either a subclass of {@link ActionResponse} or {@code null}. * @param verifier A function which is called in place of {@link #doExecute(ActionType, ActionRequest, ActionListener)} */ public void setExecuteVerifier( BiFunction, Request, Response> verifier ) { executeVerifier.set(verifier); } @Override public void doExecute( ActionType action, Request request, ActionListener listener ) { listener.onResponse((Response) executeVerifier.get().apply(action, request)); } /** * Sets the function that will be called when {@link #executeLocally(ActionType, ActionRequest, TaskListener)}is called. The given * function should return either a subclass of {@link ActionResponse} or {@code null}. * @param verifier A function which is called in place of {@link #executeLocally(ActionType, ActionRequest, TaskListener)} */ public void setExecuteLocallyVerifier( BiFunction, Request, Response> verifier ) { executeLocallyVerifier.set(verifier); } @Override public Task executeLocally( ActionType action, Request request, ActionListener listener ) { listener.onResponse((Response) executeLocallyVerifier.get().apply(action, request)); return null; } @Override public Task executeLocally( ActionType action, Request request, TaskListener listener ) { listener.onResponse(null, (Response) executeLocallyVerifier.get().apply(action, request)); return null; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy