// This file is part of OpenTSDB.
// Copyright (C) 2011-2012 The OpenTSDB Authors.
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 of the License, or (at your
// option) any later version. This program is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details. You should have received a copy
// of the GNU Lesser General Public License along with this program. If not,
// see <http://www.gnu.org/licenses/>.
package net.opentsdb.tsd;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
import java.util.Map;
import net.opentsdb.core.TSDB;
import net.opentsdb.utils.Config;
import net.opentsdb.utils.PluginLoader;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.util.CharsetUtil;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({TSDB.class, Config.class, HttpQuery.class})
public final class TestHttpQuery {
private TSDB tsdb = null;
final static private Method guessMimeTypeFromUri;
static {
try {
guessMimeTypeFromUri = HttpQuery.class.getDeclaredMethod(
"guessMimeTypeFromUri", String.class);
guessMimeTypeFromUri.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException("Failed in static initializer", e);
}
}
final static private Method guessMimeTypeFromContents;
static {
try {
guessMimeTypeFromContents = HttpQuery.class.getDeclaredMethod(
"guessMimeTypeFromContents", ChannelBuffer.class);
guessMimeTypeFromContents.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException("Failed in static initializer", e);
}
}
final static private Method sendBuffer;
static {
try {
sendBuffer = HttpQuery.class.getDeclaredMethod(
"sendBuffer", HttpResponseStatus.class, ChannelBuffer.class);
sendBuffer.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException("Failed in static initializer", e);
}
}
@Before
public void before() throws Exception {
tsdb = NettyMocks.getMockedHTTPTSDB();
}
@Test
public void getQueryString() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/api/v1/put?param=value¶m2=value2");
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
Map<String, List<String>> params = query.getQueryString();
assertNotNull(params);
assertEquals("value", params.get("param").get(0));
assertEquals("value2", params.get("param2").get(0));
}
@Test
public void getQueryStringEmpty() {
Map<String, List<String>> params =
NettyMocks.getQuery(tsdb, "/api/v1/put").getQueryString();
assertNotNull(params);
assertEquals(0, params.size());
}
@Test
public void getQueryStringMulti() {
Map<String, List<String>> params =
NettyMocks.getQuery(tsdb,
"/api/v1/put?param=v1¶m=v2¶m=v3").getQueryString();
assertNotNull(params);
assertEquals(1, params.size());
assertEquals(3, params.get("param").size());
}
@Test (expected = NullPointerException.class)
public void getQueryStringNULL() {
NettyMocks.getQuery(tsdb, null).getQueryString();
}
@Test
public void getQueryStringParam() {
assertEquals("value",
NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2")
.getQueryStringParam("param"));
}
@Test
public void getQueryStringParamNull() {
assertNull(NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2").
getQueryStringParam("nothere"));
}
@Test
public void getRequiredQueryStringParam() {
assertEquals("value",
NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2").
getRequiredQueryStringParam("param"));
}
@Test (expected = BadRequestException.class)
public void getRequiredQueryStringParamMissing() {
NettyMocks.getQuery(tsdb, "/api/v1/put?param=value¶m2=value2").
getRequiredQueryStringParam("nothere");
}
@Test
public void hasQueryStringParam() {
assertTrue(NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2").
hasQueryStringParam("param"));
}
@Test
public void hasQueryStringMissing() {
assertFalse(NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2").
hasQueryStringParam("nothere"));
}
@Test
public void getQueryStringParams() {
List<String> params = NettyMocks.getQuery(tsdb,
"/api/v1/put?param=v1¶m=v2¶m=v3").
getQueryStringParams("param");
assertNotNull(params);
assertEquals(3, params.size());
}
@Test
public void getQueryStringParamsNull() {
List<String> params = NettyMocks.getQuery(tsdb,
"/api/v1/put?param=v1¶m=v2¶m=v3").
getQueryStringParams("nothere");
assertNull(params);
}
@Test
public void getQueryPathA() {
assertEquals("/api/v1/put",
NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2").
getQueryPath());
}
@Test
public void getQueryPathB() {
assertEquals("/", NettyMocks.getQuery(tsdb, "/").getQueryPath());
}
@Test (expected = NullPointerException.class)
public void getQueryPathNull() {
NettyMocks.getQuery(tsdb, null).getQueryPath();
}
@Test
public void explodePath() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2");
final String[] path = query.explodePath();
assertNotNull(path);
assertEquals(3, path.length);
assertEquals("api", path[0]);
assertEquals("v1", path[1]);
assertEquals("put", path[2]);
}
@Test
public void explodePathEmpty() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/");
final String[] path = query.explodePath();
assertNotNull(path);
assertEquals(1, path.length);
assertEquals("", path[0]);
}
@Test (expected = NullPointerException.class)
public void explodePathNull() {
NettyMocks.getQuery(tsdb, null).explodePath();
}
@Test
public void getQueryBaseRouteRoot() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/");
assertEquals("", query.getQueryBaseRoute());
assertEquals(0, query.apiVersion());
}
@Test
public void explodeAPIPath() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/v1/put?param=value¶m2=value2");
final String[] path = query.explodeAPIPath();
assertNotNull(path);
assertEquals("put", path[0]);
}
@Test
public void explodeAPIPathNoVersion() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/put?param=value¶m2=value2");
final String[] path = query.explodeAPIPath();
assertNotNull(path);
assertEquals("put", path[0]);
}
@Test
public void explodeAPIPathExtended() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/v1/uri/assign");
final String[] path = query.explodeAPIPath();
assertNotNull(path);
assertEquals("uri", path[0]);
assertEquals("assign", path[1]);
}
@Test
public void explodeAPIPathExtendedNoVersion() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/uri/assign");
final String[] path = query.explodeAPIPath();
assertNotNull(path);
assertEquals("uri", path[0]);
assertEquals("assign", path[1]);
}
@Test
public void explodeAPIPathCase() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/Api/Uri");
final String[] path = query.explodeAPIPath();
assertNotNull(path);
assertEquals("Uri", path[0]);
}
@Test
public void explodeAPIPathRoot() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api");
final String[] path = query.explodeAPIPath();
assertNotNull(path);
assertTrue(path[0].isEmpty());
}
@Test
public void explodeAPIPathRootVersion() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/v1");
final String[] path = query.explodeAPIPath();
assertNotNull(path);
assertTrue(path[0].isEmpty());
}
@Test (expected = IllegalArgumentException.class)
public void explodeAPIPathNotAPI() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/q?hello=world");
query.explodeAPIPath();
}
@Test (expected = IllegalArgumentException.class)
public void explodeAPIPathHome() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/");
query.explodeAPIPath();
}
@Test
public void getQueryBaseRouteRootQS() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/?param=value");
assertEquals("", query.getQueryBaseRoute());
assertEquals(0, query.apiVersion());
}
@Test
public void getQueryBaseRouteQ() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/q");
assertEquals("q", query.getQueryBaseRoute());
assertEquals(0, query.apiVersion());
}
@Test
public void getQueryBaseRouteQSlash() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/q/");
assertEquals("q", query.getQueryBaseRoute());
assertEquals(0, query.apiVersion());
}
@Test
public void getQueryBaseRouteLogs() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/logs");
assertEquals("logs", query.getQueryBaseRoute());
assertEquals(0, query.apiVersion());
}
@Test (expected = BadRequestException.class)
public void getQueryBaseRouteAPIVNotImplemented() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/api/v3/put");
assertEquals("api/put", query.getQueryBaseRoute());
assertEquals(1, query.apiVersion());
}
@Test
public void getQueryBaseRouteAPICap() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/API/V1/PUT");
assertEquals("api/put", query.getQueryBaseRoute());
assertEquals(1, query.apiVersion());
}
@Test
public void getQueryBaseRouteAPIDefaultV() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/api/put");
assertEquals("api/put", query.getQueryBaseRoute());
assertEquals(1, query.apiVersion());
}
@Test
public void getQueryBaseRouteAPIQS() {
final HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/v1/put?metric=mine");
assertEquals("api/put", query.getQueryBaseRoute());
assertEquals(1, query.apiVersion());
}
@Test
public void getQueryBaseRouteAPINoEP() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/api");
assertEquals("api", query.getQueryBaseRoute());
assertEquals(1, query.apiVersion());
}
@Test
public void getQueryBaseRouteAPINoEPSlash() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/api/");
assertEquals("api", query.getQueryBaseRoute());
assertEquals(1, query.apiVersion());
}
@Test
public void getQueryBaseRouteFavicon() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/favicon.ico");
assertEquals("favicon.ico", query.getQueryBaseRoute());
assertEquals(0, query.apiVersion());
}
@Test
public void getQueryBaseRouteVersion() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/api/version/query");
assertEquals("api/version", query.getQueryBaseRoute());
assertEquals(1, query.apiVersion());
}
@Test (expected = BadRequestException.class)
public void getQueryBaseRouteVBadNumber() {
final HttpQuery query = NettyMocks.getQuery(tsdb, "/api/v2d/query");
query.getQueryBaseRoute();
}
@Test (expected = NullPointerException.class)
public void getQueryBaseRouteNull() {
NettyMocks.getQuery(tsdb, null).getQueryBaseRoute();
}
@Test (expected = BadRequestException.class)
public void getQueryBaseRouteBad() {
NettyMocks.getQuery(tsdb, "notavalidquery").getQueryBaseRoute();
}
@Test (expected = BadRequestException.class)
public void getQueryBaseRouteEmpty() {
NettyMocks.getQuery(tsdb, "").getQueryBaseRoute();
}
@Test
public void getCharsetDefault() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
req.headers().add("Content-Type", "text/plain");
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertEquals(Charset.forName("UTF-8"), query.getCharset());
}
@Test
public void getCharsetDefaultNoHeader() {
assertEquals(Charset.forName("UTF-8"),
NettyMocks.getQuery(tsdb, "/").getCharset());
}
@Test
public void getCharsetSupplied() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
req.headers().add("Content-Type", "text/plain; charset=UTF-16");
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertEquals(Charset.forName("UTF-16"), query.getCharset());
}
@Test (expected = UnsupportedCharsetException.class)
public void getCharsetInvalid() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
req.headers().add("Content-Type", "text/plain; charset=foobar");
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertEquals(Charset.forName("UTF-16"), query.getCharset());
}
@Test
public void hasContent() {
HttpQuery query = NettyMocks.postQuery(tsdb, "/", "Hello World", "");
assertTrue(query.hasContent());
}
@Test
public void hasContentFalse() {
HttpQuery query = NettyMocks.postQuery(tsdb, "/", null, "");
assertFalse(query.hasContent());
}
@Test
public void hasContentNotReadable() {
HttpQuery query = NettyMocks.postQuery(tsdb, "/", "", "");
assertFalse(query.hasContent());
}
@Test
public void getContentEncoding() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
req.headers().add("Content-Type", "text/plain; charset=UTF-16");
final ChannelBuffer buf = ChannelBuffers.copiedBuffer("S\u00ED Se\u00F1or",
CharsetUtil.UTF_16);
req.setContent(buf);
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertEquals("S\u00ED Se\u00F1or", query.getContent());
}
@Test
public void getContentDefault() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
final ChannelBuffer buf = ChannelBuffers.copiedBuffer("S\u00ED Se\u00F1or",
CharsetUtil.UTF_8);
req.setContent(buf);
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertEquals("S\u00ED Se\u00F1or", query.getContent());
}
@Test
public void getContentBadEncoding() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
final ChannelBuffer buf = ChannelBuffers.copiedBuffer("S\u00ED Se\u00F1or",
CharsetUtil.ISO_8859_1);
req.setContent(buf);
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertThat("S\u00ED Se\u00F1or", not(equalTo(query.getContent())));
}
@Test
public void getContentEmpty() {
assertTrue(NettyMocks.getQuery(tsdb, "/").getContent().isEmpty());
}
@Test
public void getAPIMethodGet() {
assertEquals(HttpMethod.GET,
NettyMocks.getQuery(tsdb, "/").getAPIMethod());
}
@Test
public void getAPIMethodPost() {
assertEquals(HttpMethod.POST,
NettyMocks.postQuery(tsdb, "/", null).getAPIMethod());
}
@Test
public void getAPIMethodPut() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.PUT, "/");
HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertEquals(HttpMethod.PUT, query.getAPIMethod());
}
@Test
public void getAPIMethodDelete() {
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.DELETE, "/");
HttpQuery query = new HttpQuery(tsdb, req, channelMock);
assertEquals(HttpMethod.DELETE, query.getAPIMethod());
}
@Test
public void getAPIMethodOverrideGet() {
assertEquals(HttpMethod.GET,
NettyMocks.getQuery(tsdb, "/?method_override=get").getAPIMethod());
}
@Test
public void getAPIMethodOverridePost() {
assertEquals(HttpMethod.POST,
NettyMocks.getQuery(tsdb, "/?method_override=post").getAPIMethod());
}
@Test
public void getAPIMethodOverridePut() {
assertEquals(HttpMethod.PUT,
NettyMocks.getQuery(tsdb, "/?method_override=put").getAPIMethod());
}
@Test
public void getAPIMethodOverrideDelete() {
assertEquals(HttpMethod.DELETE,
NettyMocks.getQuery(tsdb, "/?method_override=delete").getAPIMethod());
}
@Test
public void getAPIMethodOverrideDeleteCase() {
assertEquals(HttpMethod.DELETE,
NettyMocks.getQuery(tsdb, "/?method_override=DeLeTe").getAPIMethod());
}
@Test (expected = BadRequestException.class)
public void getAPIMethodOverrideMissingValue() {
NettyMocks.getQuery(tsdb, "/?method_override").getAPIMethod();
}
@Test (expected = BadRequestException.class)
public void getAPIMethodOverrideInvalidMEthod() {
NettyMocks.getQuery(tsdb, "/?method_override=notaverb").getAPIMethod();
}
@Test
public void guessMimeTypeFromUriPNG() throws Exception {
assertEquals("image/png",
guessMimeTypeFromUri.invoke(null, "abcd.png"));
}
@Test
public void guessMimeTypeFromUriHTML() throws Exception {
assertEquals("text/html; charset=UTF-8",
guessMimeTypeFromUri.invoke(null, "abcd.html"));
}
@Test
public void guessMimeTypeFromUriCSS() throws Exception {
assertEquals("text/css",
guessMimeTypeFromUri.invoke(null, "abcd.css"));
}
@Test
public void guessMimeTypeFromUriJS() throws Exception {
assertEquals("text/javascript",
guessMimeTypeFromUri.invoke(null, "abcd.js"));
}
@Test
public void guessMimeTypeFromUriGIF() throws Exception {
assertEquals("image/gif",
guessMimeTypeFromUri.invoke(null, "abcd.gif"));
}
@Test
public void guessMimeTypeFromUriICO() throws Exception {
assertEquals("image/x-icon",
guessMimeTypeFromUri.invoke(null, "abcd.ico"));
}
@Test
public void guessMimeTypeFromUriOther() throws Exception {
assertNull(guessMimeTypeFromUri.invoke(null, "abcd.jpg"));
}
@Test (expected = IllegalArgumentException.class)
public void guessMimeTypeFromUriNull() throws Exception {
guessMimeTypeFromUri.invoke(null, (Object[])null);
}
@Test
public void guessMimeTypeFromUriEmpty() throws Exception {
assertNull(guessMimeTypeFromUri.invoke(null, ""));
}
@Test
public void guessMimeTypeFromContentsHTML() throws Exception {
assertEquals("text/html; charset=UTF-8",
guessMimeTypeFromContents.invoke(
NettyMocks.getQuery(tsdb, ""),
ChannelBuffers.copiedBuffer(
"<HTML>...", Charset.forName("UTF-8"))));
}
@Test
public void guessMimeTypeFromContentsJSONObj() throws Exception {
assertEquals("application/json",
guessMimeTypeFromContents.invoke(
NettyMocks.getQuery(tsdb, ""),
ChannelBuffers.copiedBuffer(
"{\"hello\":\"world\"}", Charset.forName("UTF-8"))));
}
@Test
public void guessMimeTypeFromContentsJSONArray() throws Exception {
assertEquals("application/json",
guessMimeTypeFromContents.invoke(
NettyMocks.getQuery(tsdb, ""),
ChannelBuffers.copiedBuffer(
"[\"hello\",\"world\"]", Charset.forName("UTF-8"))));
}
@Test
public void guessMimeTypeFromContentsPNG() throws Exception {
assertEquals("image/png",
guessMimeTypeFromContents.invoke(
NettyMocks.getQuery(tsdb, ""),
ChannelBuffers.copiedBuffer(
new byte[] {(byte) 0x89, 0x00})));
}
@Test
public void guessMimeTypeFromContentsText() throws Exception {
assertEquals("text/plain",
guessMimeTypeFromContents.invoke(
NettyMocks.getQuery(tsdb, ""),
ChannelBuffers.copiedBuffer(
"Just plain text", Charset.forName("UTF-8"))));
}
@Test
public void guessMimeTypeFromContentsEmpty() throws Exception {
assertEquals("text/plain",
guessMimeTypeFromContents.invoke(
NettyMocks.getQuery(tsdb, ""),
ChannelBuffers.copiedBuffer(
"", Charset.forName("UTF-8"))));
}
@Test (expected = NullPointerException.class)
public void guessMimeTypeFromContentsNull() throws Exception {
ChannelBuffer buf = null;
guessMimeTypeFromContents.invoke(
NettyMocks.getQuery(tsdb, ""), buf);
}
@Test
public void initializeSerializerMaps() throws Exception {
HttpQuery.initializeSerializerMaps(null);
}
@Test
public void setSerializer() throws Exception {
HttpQuery.initializeSerializerMaps(null);
HttpQuery query = NettyMocks.getQuery(tsdb, "/aggregators");
query.setSerializer();
assertEquals(HttpJsonSerializer.class.getCanonicalName(),
query.serializer().getClass().getCanonicalName());
}
@Test
public void setFormatterQS() throws Exception {
HttpQuery.initializeSerializerMaps(null);
HttpQuery query = NettyMocks.getQuery(tsdb, "/aggregators?formatter=json");
query.setSerializer();
assertEquals(HttpJsonSerializer.class.getCanonicalName(),
query.serializer().getClass().getCanonicalName());
}
@Test
public void setSerializerDummyQS() throws Exception {
PluginLoader.loadJAR("plugin_test.jar");
HttpQuery.initializeSerializerMaps(null);
HttpQuery query = NettyMocks.getQuery(tsdb, "/aggregators?serializer=dummy");
query.setSerializer();
assertEquals("net.opentsdb.tsd.DummyHttpSerializer",
query.serializer().getClass().getCanonicalName());
}
@Test
public void setSerializerCT() throws Exception {
HttpQuery.initializeSerializerMaps(null);
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
req.headers().add("Content-Type", "application/json");
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
query.setSerializer();
assertEquals(HttpJsonSerializer.class.getCanonicalName(),
query.serializer().getClass().getCanonicalName());
}
@Test
public void setSerializerDummyCT() throws Exception {
PluginLoader.loadJAR("plugin_test.jar");
HttpQuery.initializeSerializerMaps(null);
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
req.headers().add("Content-Type", "application/tsdbdummy");
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
query.setSerializer();
assertEquals("net.opentsdb.tsd.DummyHttpSerializer",
query.serializer().getClass().getCanonicalName());
}
@Test
public void setSerializerDefaultCT() throws Exception {
HttpQuery.initializeSerializerMaps(null);
final Channel channelMock = NettyMocks.fakeChannel();
final HttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.GET, "/");
req.headers().add("Content-Type", "invalid/notfoundtype");
final HttpQuery query = new HttpQuery(tsdb, req, channelMock);
query.setSerializer();
assertEquals(HttpJsonSerializer.class.getCanonicalName(),
query.serializer().getClass().getCanonicalName());
}
@Test (expected = BadRequestException.class)
public void setSerializerNotFound() throws Exception {
HttpQuery.initializeSerializerMaps(null);
HttpQuery query = NettyMocks.getQuery(tsdb,
"/api/suggest?serializer=notfound");
query.setSerializer();
}
@Test
public void internalErrorDeprecated() {
HttpQuery query = NettyMocks.getQuery(tsdb, "");
try {
throw new Exception("Internal Error");
} catch (Exception e) {
query.internalError(e);
}
assertEquals(HttpResponseStatus.INTERNAL_SERVER_ERROR,
query.response().getStatus());
assertEquals(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 63));
}
@Test
public void internalErrorDeprecatedJSON() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/?json");
try {
throw new Exception("Internal Error");
} catch (Exception e) {
query.internalError(e);
}
assertEquals(HttpResponseStatus.INTERNAL_SERVER_ERROR,
query.response().getStatus());
assertEquals(
"{\"err\":\"java.lang.Exception: Internal Error",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 43));
}
@Test
public void internalErrorDefaultSerializer() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/api/error");
query.getQueryBaseRoute();
try {
throw new Exception("Internal Error");
} catch (Exception e) {
query.internalError(e);
}
assertEquals(HttpResponseStatus.INTERNAL_SERVER_ERROR,
query.response().getStatus());
assertEquals(
"{\"error\":{\"code\":500,\"message\":\"Internal Error\"",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 47));
}
@Test (expected = NullPointerException.class)
public void internalErrorNull() {
HttpQuery query = NettyMocks.getQuery(tsdb, "");
query.internalError(null);
}
@Test
public void badRequestDeprecated() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
try {
throw new BadRequestException("Bad user error");
} catch (BadRequestException e) {
query.badRequest(e);
}
assertEquals(HttpResponseStatus.BAD_REQUEST, query.response().getStatus());
assertEquals(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 63));
}
@Test
public void badRequestDeprecatedJSON() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/?json");
try {
throw new BadRequestException("Bad user error");
} catch (BadRequestException e) {
query.badRequest(e);
}
assertEquals(HttpResponseStatus.BAD_REQUEST, query.response().getStatus());
assertEquals(
"{\"err\":\"Bad user error\"}",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test
public void badRequestDefaultSerializer() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/api/error");
query.getQueryBaseRoute();
try {
throw new BadRequestException("Bad user error");
} catch (BadRequestException e) {
query.badRequest(e);
}
assertEquals(HttpResponseStatus.BAD_REQUEST, query.response().getStatus());
assertEquals(
"{\"error\":{\"code\":400,\"message\":\"Bad user error\"",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 47));
}
@Test
public void badRequestDefaultSerializerDiffStatus() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/api/error");
query.getQueryBaseRoute();
try {
throw new BadRequestException(HttpResponseStatus.FORBIDDEN,
"Bad user error");
} catch (BadRequestException e) {
query.badRequest(e);
}
assertEquals(HttpResponseStatus.FORBIDDEN, query.response().getStatus());
assertEquals(
"{\"error\":{\"code\":403,\"message\":\"Bad user error\"",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 47));
}
@Test
public void badRequestDefaultSerializerDetails() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/api/error");
query.getQueryBaseRoute();
try {
throw new BadRequestException(HttpResponseStatus.FORBIDDEN,
"Bad user error", "Got Details");
} catch (BadRequestException e) {
query.badRequest(e);
}
assertEquals(HttpResponseStatus.FORBIDDEN, query.response().getStatus());
assertEquals(
"{\"error\":{\"code\":403,\"message\":\"Bad user error\",\"details\":\"Got Details\"",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 71));
}
@Test (expected = NullPointerException.class)
public void badRequestNull() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.badRequest((BadRequestException)null);
}
@Test
public void badRequestDeprecatedString() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.badRequest("Bad user error");
assertEquals(HttpResponseStatus.BAD_REQUEST, query.response().getStatus());
assertEquals(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 63));
}
@Test
public void badRequestDeprecatedJSONString() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/?json");
query.badRequest("Bad user error");
assertEquals(HttpResponseStatus.BAD_REQUEST, query.response().getStatus());
assertEquals(
"{\"err\":\"Bad user error\"}",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test
public void badRequestDefaultSerializerString() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/api/error");
query.getQueryBaseRoute();
query.badRequest("Bad user error");
assertEquals(HttpResponseStatus.BAD_REQUEST, query.response().getStatus());
assertEquals(
"{\"error\":{\"code\":400,\"message\":\"Bad user error\"",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 47));
}
@Test
public void badRequestNullString() {
// this won't throw an error, just report "null" back to the user with a
// stack trace
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.badRequest((String)null);
}
@Test
public void notFoundDeprecated() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.notFound();
assertEquals(HttpResponseStatus.NOT_FOUND, query.response().getStatus());
assertEquals(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">",
query.response().getContent().toString(Charset.forName("UTF-8"))
.substring(0, 63));
}
@Test
public void notFoundDeprecatedJSON() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/?json");
query.notFound();
assertEquals(HttpResponseStatus.NOT_FOUND, query.response().getStatus());
assertEquals(
"{\"err\":\"Page Not Found\"}",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test
public void notFoundDefaultSerializer() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/api/error");
query.getQueryBaseRoute();
query.notFound();
assertEquals(HttpResponseStatus.NOT_FOUND, query.response().getStatus());
assertEquals(
"{\"error\":{\"code\":404,\"message\":\"Endpoint not found\"}}",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test
public void redirect() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.redirect("/redirect");
assertEquals(HttpResponseStatus.OK, query.response().getStatus());
assertEquals("/redirect", query.response().headers().get("Location"));
assertEquals("<html></head><meta http-equiv=\"refresh\" content=\"0; url="
+ "/redirect\"></head></html>",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void redirectNull() {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.redirect(null);
}
@Test
public void escapeJson() {
StringBuilder sb = new StringBuilder();
String json = "\" \\ ";
json += Character.toString('\b') + " ";
json += Character.toString('\f') + " ";
json += Character.toString('\n') + " ";
json += Character.toString('\r') + " ";
json += Character.toString('\t');
HttpQuery.escapeJson(json, sb);
assertEquals("\\\" \\\\ \\b \\f \\n \\r \\t", sb.toString());
}
@Test
public void sendReplyBytes() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply("Hello World".getBytes());
assertEquals(HttpResponseStatus.OK, query.response().getStatus());
assertEquals("Hello World",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendReplyBytesNull() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply((byte[])null);
}
@Test
public void sendReplyStatusBytes() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(HttpResponseStatus.CREATED, "Hello World".getBytes());
assertEquals(HttpResponseStatus.CREATED, query.response().getStatus());
assertEquals("Hello World",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendReplyStatusBytesNullStatus() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(null, "Hello World".getBytes());
}
@Test (expected = NullPointerException.class)
public void sendReplyStatusBytesNullBytes() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(HttpResponseStatus.CREATED, (byte[])null);
}
@Test
public void sendReplySB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(new StringBuilder("Hello World"));
assertEquals(HttpResponseStatus.OK, query.response().getStatus());
assertEquals("Hello World",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendReplySBNull() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply((StringBuilder)null);
}
@Test
public void sendReplyString() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply("Hello World");
assertEquals(HttpResponseStatus.OK, query.response().getStatus());
assertEquals("Hello World",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendReplyStringNull() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply((String)null);
}
@Test
public void sendReplyStatusSB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(HttpResponseStatus.CREATED,
new StringBuilder("Hello World"));
assertEquals(HttpResponseStatus.CREATED, query.response().getStatus());
assertEquals("Hello World",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendReplyStatusSBNullStatus() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(null, new StringBuilder("Hello World"));
}
@Test (expected = NullPointerException.class)
public void sendReplyStatusSBNullSB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(HttpResponseStatus.CREATED, (StringBuilder)null);
}
@Test
public void sendReplyCB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
ChannelBuffer cb = ChannelBuffers.copiedBuffer("Hello World",
Charset.forName("UTF-8"));
query.sendReply(cb);
assertEquals(HttpResponseStatus.OK, query.response().getStatus());
assertEquals("Hello World",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendReplyCBNull() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply((ChannelBuffer)null);
}
@Test
public void sendReplyStatusCB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
ChannelBuffer cb = ChannelBuffers.copiedBuffer("Hello World",
Charset.forName("UTF-8"));
query.sendReply(HttpResponseStatus.CREATED, cb);
assertEquals(HttpResponseStatus.CREATED, query.response().getStatus());
assertEquals("Hello World",
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendReplyStatusCBNullStatus() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
ChannelBuffer cb = ChannelBuffers.copiedBuffer("Hello World",
Charset.forName("UTF-8"));
query.sendReply(null, cb);
}
@Test (expected = NullPointerException.class)
public void sendReplyStatusCBNullCB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendReply(HttpResponseStatus.CREATED, (ChannelBuffer)null);
}
@Test
public void sendStatusOnly() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendStatusOnly(HttpResponseStatus.NO_CONTENT);
assertEquals(HttpResponseStatus.NO_CONTENT, query.response().getStatus());
assertEquals(0, query.response().getContent().capacity());
assertNull(query.response().headers().get("Content-Type"));
}
@Test (expected = NullPointerException.class)
public void sendStatusOnlyNull() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "/");
query.sendStatusOnly(null);
}
@Test
public void sendBuffer() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "");
ChannelBuffer cb = ChannelBuffers.copiedBuffer("Hello World",
Charset.forName("UTF-8"));
sendBuffer.invoke(query, HttpResponseStatus.OK, cb);
assertEquals(HttpResponseStatus.OK, query.response().getStatus());
assertEquals(cb.toString(Charset.forName("UTF-8")),
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test
public void sendBufferEmptyCB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "");
ChannelBuffer cb = ChannelBuffers.copiedBuffer("",
Charset.forName("UTF-8"));
sendBuffer.invoke(query, HttpResponseStatus.OK, cb);
assertEquals(HttpResponseStatus.OK, query.response().getStatus());
assertEquals(cb.toString(Charset.forName("UTF-8")),
query.response().getContent().toString(Charset.forName("UTF-8")));
}
@Test (expected = NullPointerException.class)
public void sendBufferNullStatus() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "");
ChannelBuffer cb = ChannelBuffers.copiedBuffer("Hello World",
Charset.forName("UTF-8"));
sendBuffer.invoke(query, null, cb);
}
@Test (expected = NullPointerException.class)
public void sendBufferNullCB() throws Exception {
HttpQuery query = NettyMocks.getQuery(tsdb, "");
sendBuffer.invoke(query, HttpResponseStatus.OK, null);
}
@Test
public void getSerializerStatus() throws Exception {
HttpQuery.initializeSerializerMaps(tsdb);
assertNotNull(HttpQuery.getSerializerStatus());
}
}