/*
* 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.
*/
package org.elasticsearch.rest;
import com.carrotsearch.randomizedtesting.generators.CodepointSetGenerator;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.test.ESTestCase;
import org.mockito.InOrder;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
/**
* Tests {@link DeprecationRestHandler}.
*/
public class DeprecationRestHandlerTests extends ESTestCase {
private final RestHandler handler = mock(RestHandler.class);
/**
* Note: Headers should only use US ASCII (and this inevitably becomes one!).
*/
private final String deprecationMessage = randomAlphaOfLengthBetween(1, 30);
private final DeprecationLogger deprecationLogger = mock(DeprecationLogger.class);
public void testNullHandler() {
expectThrows(NullPointerException.class, () -> new DeprecationRestHandler(null, deprecationMessage, deprecationLogger));
}
public void testInvalidDeprecationMessageThrowsException() {
String invalidDeprecationMessage = randomFrom("", null, " ");
expectThrows(IllegalArgumentException.class,
() -> new DeprecationRestHandler(handler, invalidDeprecationMessage, deprecationLogger));
}
public void testNullDeprecationLogger() {
expectThrows(NullPointerException.class, () -> new DeprecationRestHandler(handler, deprecationMessage, null));
}
public void testHandleRequestLogsWarningThenForwards() throws Exception {
RestRequest request = mock(RestRequest.class);
RestChannel channel = mock(RestChannel.class);
NodeClient client = mock(NodeClient.class);
DeprecationRestHandler deprecatedHandler = new DeprecationRestHandler(handler, deprecationMessage, deprecationLogger);
// test it
deprecatedHandler.handleRequest(request, channel, client);
InOrder inOrder = inOrder(handler, request, channel, deprecationLogger);
// log, then forward
inOrder.verify(deprecationLogger).deprecated(deprecationMessage);
inOrder.verify(handler).handleRequest(request, channel, client);
inOrder.verifyNoMoreInteractions();
}
public void testValidHeaderValue() {
ASCIIHeaderGenerator generator = new ASCIIHeaderGenerator();
String value = generator.ofCodeUnitsLength(random(), 1, 50);
if (value.trim().length() == 0) {
// empty text, not a valid header
assertFalse(DeprecationRestHandler.validHeaderValue(value));
Exception e = expectThrows(IllegalArgumentException.class, () -> DeprecationRestHandler.requireValidHeader(value));
assertEquals("header value must contain only US ASCII text", e.getMessage());
} else {
assertTrue(DeprecationRestHandler.validHeaderValue(value));
assertSame(value, DeprecationRestHandler.requireValidHeader(value));
}
}
public void testInvalidHeaderValue() {
ASCIIHeaderGenerator generator = new ASCIIHeaderGenerator();
String value = generator.ofCodeUnitsLength(random(), 0, 25) +
randomFrom('\t', '\0', '\n', (char)27 /* ESC */, (char)31 /* unit separator*/, (char)127 /* DEL */) +
generator.ofCodeUnitsLength(random(), 0, 25);
assertFalse(DeprecationRestHandler.validHeaderValue(value));
expectThrows(IllegalArgumentException.class, () -> DeprecationRestHandler.requireValidHeader(value));
}
public void testInvalidHeaderValueNull() {
assertFalse(DeprecationRestHandler.validHeaderValue(null));
expectThrows(IllegalArgumentException.class, () -> DeprecationRestHandler.requireValidHeader(null));
}
public void testInvalidHeaderValueEmpty() {
String blank = randomFrom("", "\t", " ");
assertFalse(DeprecationRestHandler.validHeaderValue(blank));
expectThrows(IllegalArgumentException.class, () -> DeprecationRestHandler.requireValidHeader(blank));
}
/**
* {@code ASCIIHeaderGenerator} only uses characters expected to be valid in headers (simplified US-ASCII).
*/
private static class ASCIIHeaderGenerator extends CodepointSetGenerator {
/**
* Create a character array for characters [{@code from}, {@code to}].
*
* @param from Starting code point (inclusive).
* @param to Ending code point (inclusive).
* @return Never {@code null}.
*/
static char[] asciiFromTo(int from, int to) {
char[] chars = new char[to - from + 1];
for (int i = from; i <= to; ++i) {
chars[i - from] = (char)i;
}
return chars;
}
/**
* Create a generator for characters [32, 126].
*/
ASCIIHeaderGenerator() {
super(asciiFromTo(32, 126));
}
}
}