// This file is part of OpenTSDB. // Copyright (C) 2014 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.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.mock; import org.hbase.async.HBaseClient; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import net.opentsdb.core.TSDB; import net.opentsdb.utils.Config; import net.opentsdb.utils.PluginLoader; @PowerMockIgnore({"javax.management.*", "javax.xml.*", "ch.qos.*", "org.slf4j.*", "com.sum.*", "org.xml.*"}) @RunWith(PowerMockRunner.class) @PrepareForTest({ TSDB.class, Config.class, HBaseClient.class, RpcManager.class }) public class TestRpcManager { private TSDB mock_tsdb_no_plugins; // Set in individual test methods; shutdown by after() if set. private RpcManager mgr_under_test; @Before public void before() { Config config = mock(Config.class); when(config.getString("tsd.core.enable_api")) .thenReturn("true"); when(config.getString("tsd.core.enable_ui")) .thenReturn("true"); when(config.getString("tsd.no_diediedie")) .thenReturn("false"); TSDB tsdb = mock(TSDB.class); when(tsdb.getConfig()).thenReturn(config); mock_tsdb_no_plugins = tsdb; } @After public void after() throws Exception { if (mgr_under_test != null) { mgr_under_test.shutdown().join(); } } @Test public void loadHttpRpcPlugins() throws Exception { Config config = mock(Config.class); when(config.hasProperty("tsd.http.rpc.plugins")) .thenReturn(true); when(config.getString("tsd.http.rpc.plugins")) .thenReturn("net.opentsdb.tsd.DummyHttpRpcPlugin"); when(config.getString("tsd.core.enable_api")) .thenReturn("true"); when(config.getString("tsd.core.enable_ui")) .thenReturn("true"); when(config.getString("tsd.no_diediedie")) .thenReturn("false"); TSDB tsdb = mock(TSDB.class); when(tsdb.getConfig()).thenReturn(config); PluginLoader.loadJAR("plugin_test.jar"); mgr_under_test = RpcManager.instance(tsdb); HttpRpcPlugin plugin = mgr_under_test.lookupHttpRpcPlugin("dummy/test"); assertNotNull(plugin); } @Test public void loadRpcPlugin() throws Exception { Config config = mock(Config.class); when(config.hasProperty("tsd.rpc.plugins")) .thenReturn(true); when(config.getString("tsd.rpc.plugins")) .thenReturn("net.opentsdb.tsd.DummyRpcPlugin"); when(config.hasProperty("tsd.rpcplugin.DummyRPCPlugin.hosts")) .thenReturn(true); when(config.getString("tsd.rpcplugin.DummyRPCPlugin.hosts")) .thenReturn("blah"); when(config.getInt("tsd.rpcplugin.DummyRPCPlugin.port")) .thenReturn(1000); when(config.getString("tsd.core.enable_api")) .thenReturn("true"); when(config.getString("tsd.core.enable_ui")) .thenReturn("true"); when(config.getString("tsd.no_diediedie")) .thenReturn("false"); TSDB tsdb = mock(TSDB.class); when(tsdb.getConfig()).thenReturn(config); PluginLoader.loadJAR("plugin_test.jar"); mgr_under_test= RpcManager.instance(tsdb); assertFalse(mgr_under_test.getRpcPlugins().isEmpty()); } @Test public void isHttpRpcPluginPathValid() { mgr_under_test = RpcManager.instance(mock_tsdb_no_plugins); assertTrue(mgr_under_test.isHttpRpcPluginPath("/plugin/my/http/plugin")); assertTrue(mgr_under_test.isHttpRpcPluginPath("plugin/my/http/plugin")); assertTrue(mgr_under_test.isHttpRpcPluginPath("/plugin/my?hey=hi&howdy=ho")); assertTrue(mgr_under_test.isHttpRpcPluginPath("plugin/my?hey=hi&howdy=ho")); assertTrue(mgr_under_test.isHttpRpcPluginPath("plugin/my/?hey=hi&howdy=ho")); } @Test public void isHttpRpcPluginPathInvalid() { mgr_under_test = RpcManager.instance(mock_tsdb_no_plugins); assertFalse(mgr_under_test.isHttpRpcPluginPath("/plugin/")); assertFalse(mgr_under_test.isHttpRpcPluginPath("plugin/")); assertFalse(mgr_under_test.isHttpRpcPluginPath("plugin")); assertFalse(mgr_under_test.isHttpRpcPluginPath("/plugin")); assertFalse(mgr_under_test.isHttpRpcPluginPath("/plugin?howdy=ho")); assertFalse(mgr_under_test.isHttpRpcPluginPath("/plugin/?howdy=ho")); assertFalse(mgr_under_test.isHttpRpcPluginPath("api/query")); } @Test public void validateHttpRpcPluginPathValid() { mgr_under_test = RpcManager.instance(mock_tsdb_no_plugins); mgr_under_test.validateHttpRpcPluginPath("/my/test/path"); mgr_under_test.validateHttpRpcPluginPath("my/test/path"); mgr_under_test.validateHttpRpcPluginPath("my/test/path"); mgr_under_test.validateHttpRpcPluginPath("api/query"); } @Test public void validateHttpRpcPluginPathInvalid() { mgr_under_test = RpcManager.instance(mock_tsdb_no_plugins); try { mgr_under_test.validateHttpRpcPluginPath("/plugin/my/test"); assertTrue(false); } catch (IllegalArgumentException e) { } try { mgr_under_test.validateHttpRpcPluginPath("plugin/my/test"); assertTrue(false); } catch (IllegalArgumentException e) { } try { mgr_under_test.validateHttpRpcPluginPath("plugin/"); assertTrue(false); } catch (IllegalArgumentException e) { } try { mgr_under_test.validateHttpRpcPluginPath("/plugin/"); assertTrue(false); } catch (IllegalArgumentException e) { } try { mgr_under_test.validateHttpRpcPluginPath("/plugin"); assertTrue(false); } catch (IllegalArgumentException e) { } try { mgr_under_test.validateHttpRpcPluginPath("plugin"); assertTrue(false); } catch (IllegalArgumentException e) { } } @Test public void canonicalizePluginPathsValid() throws Exception { mgr_under_test = RpcManager.instance(mock_tsdb_no_plugins); assertEquals("my/test/path", mgr_under_test.canonicalizePluginPath("/my/test/path")); assertEquals("my/test/path", mgr_under_test.canonicalizePluginPath("/my/test/path/")); assertEquals("my/test/path", mgr_under_test.canonicalizePluginPath("my/test/path/")); assertEquals("my/test/path", mgr_under_test.canonicalizePluginPath("my/test/path")); assertEquals("my", mgr_under_test.canonicalizePluginPath("/my/")); assertEquals("my", mgr_under_test.canonicalizePluginPath("my/")); assertEquals("my", mgr_under_test.canonicalizePluginPath("my")); } @Test(expected=IllegalArgumentException.class) public void canonicalizePluginPathIsRoot() { mgr_under_test = RpcManager.instance(mock_tsdb_no_plugins); assertEquals(RpcManager.PLUGIN_BASE_WEBPATH + "/", mgr_under_test.canonicalizePluginPath("")); } @Test public void validHttpPathEndToEnd() { mgr_under_test = RpcManager.instance(mock_tsdb_no_plugins); mgr_under_test.validateHttpRpcPluginPath("myplugin"); assertEquals("myplugin", mgr_under_test.canonicalizePluginPath("myplugin")); mgr_under_test.validateHttpRpcPluginPath("/myplugin"); assertEquals("myplugin", mgr_under_test.canonicalizePluginPath("/myplugin")); mgr_under_test.validateHttpRpcPluginPath("myplugin/subcommand"); assertEquals("myplugin/subcommand", mgr_under_test.canonicalizePluginPath("myplugin/subcommand")); mgr_under_test.validateHttpRpcPluginPath("/myplugin/subcommand"); assertEquals("myplugin/subcommand", mgr_under_test.canonicalizePluginPath("/myplugin/subcommand")); } }