package org.jolokia.jvmagent.client.command; /* * Copyright 2009-2013 Roland Huss * * Licensed 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. */ import java.io.*; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.regex.Pattern; import com.sun.tools.attach.*; import org.easymock.EasyMock; import org.easymock.IArgumentMatcher; import org.jolokia.Version; import org.jolokia.jvmagent.JvmAgent; import org.jolokia.jvmagent.client.util.*; import org.testng.annotations.*; import static org.easymock.EasyMock.*; import static org.testng.Assert.*; /** * @author roland * @since 12.08.11 */ @Test(groups = "java6") public class CommandDispatcherTest { private PrintStream outBack, errBack; private ByteArrayOutputStream outStream,errStream; @Test public void start() throws IOException, AgentInitializationException, AgentLoadException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { testCommand("start", false, 0); testCommand("start", true, 1); } @Test public void stop() throws AgentInitializationException, IOException, AgentLoadException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { testCommand("stop", false, 1); testCommand("stop", true, 0); } @Test public void toggle() throws AgentInitializationException, IOException, AgentLoadException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { testCommand("toggle", false, 0); testCommand("toggle", true, 0); } @Test public void help() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("--help")); assertEquals(d.dispatchCommand(null, null), 0); CommandDispatcher.printHelp(); assertTrue(outStream.toString().contains("Jolokia Agent Launcher")); } @Test public void version() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("--version")); assertEquals(d.dispatchCommand(null, null), 0); assertTrue(outStream.toString().contains(Version.getAgentVersion())); assertFalse(outStream.toString().contains(Version.getProtocolVersion())); } @Test public void versionVerbose() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("--version","--verbose")); assertEquals(d.dispatchCommand(null, null), 0); assertTrue(outStream.toString().contains(Version.getAgentVersion())); assertTrue(outStream.toString().contains(Version.getProtocolVersion())); } @Test public void list() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("list")); VirtualMachineHandler vmh = createMock(VirtualMachineHandler.class); List<ProcessDescription> ret = new ArrayList<ProcessDescription>(); ret.add(new ProcessDescription("12","TestProcess")); expect(vmh.listProcesses()).andReturn(ret); replay(vmh); assertEquals(d.dispatchCommand(null, vmh), 0); verify(vmh); } @Test public void descriptionWithPattern() throws AgentInitializationException, InvocationTargetException, IOException, NoSuchMethodException, AgentLoadException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("start","blub")); VirtualMachineHandler vmh = createMock(VirtualMachineHandler.class); VirtualMachine vm = createMock(VirtualMachine.class); expect(vm.getSystemProperties()).andReturn(getProperties(false)); expect(vm.getSystemProperties()).andReturn(getProperties(true)); // Agent should be loaded for successful switch vm.loadAgent(EasyMock.<String>anyObject(), EasyMock.<String>anyObject()); expect(vmh.findProcess(patternMatcher("blub"))).andReturn(new ProcessDescription("18", "bla blub blie")); replay(vm, vmh); int rc = d.dispatchCommand(vm, vmh); assertEquals(rc, 0); verify(vm, vmh); } private Pattern patternMatcher(final String pPattern) { EasyMock.reportMatcher(new IArgumentMatcher() { public boolean matches(Object argument) { Pattern p = (Pattern) argument; return p.pattern().equals(pPattern); } public void appendTo(StringBuffer buffer) { } }); return null; } @Test public void status() throws IOException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { testStatus(true,0); testStatus(false,1); } @Test(expectedExceptions = InvocationTargetException.class) public void throwException() throws IOException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("start", "42")); VirtualMachine vm = createMock(VirtualMachine.class); expect(vm.getSystemProperties()).andThrow(new IOException()); replay(vm); d.dispatchCommand(vm,null); } @Test(expectedExceptions = IllegalArgumentException.class,expectedExceptionsMessageRegExp = ".*Unknown.*") public void unknownCommand() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("blub", "42")); d.dispatchCommand(null,null); } // ====================================================================================================== private void testCommand(String pCommand, boolean pActive, int pRc, String... pProcess) throws IOException, AgentLoadException, AgentInitializationException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { String p = pProcess.length > 0 ? pProcess[0] : "42"; CommandDispatcher d = new CommandDispatcher(opts(pCommand,p)); VirtualMachineHandler vmh = createMock(VirtualMachineHandler.class); VirtualMachine vm = createMock(VirtualMachine.class); expect(vm.getSystemProperties()).andReturn(getProperties(pActive)).times(pCommand.equals("toggle") ? 2 : 1); if (!pActive && !pCommand.equals("stop")) { expect(vm.getSystemProperties()).andReturn(getProperties(true)); } if (pRc == 0) { // Agent should be loaded for successful switch vm.loadAgent(EasyMock.<String>anyObject(), EasyMock.<String>anyObject()); } replay(vm,vmh); int rc = d.dispatchCommand(vm,vmh); assertEquals(rc, pRc); verify(vm,vmh); } private void testStatus(boolean pActive,int pRc) throws IOException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { CommandDispatcher d = new CommandDispatcher(opts("status", "18")); VirtualMachine vm = createMock(VirtualMachine.class); expect(vm.getSystemProperties()).andReturn(getProperties(pActive)).anyTimes(); replay(vm); assertEquals(d.dispatchCommand(vm,null), pRc); verify(vm); } private Properties getProperties(boolean pActive) { Properties props = new Properties(); if (pActive) { props.put(JvmAgent.JOLOKIA_AGENT_URL,"blub"); } return props; } @BeforeMethod void prepareOutputStreams() { outBack = System.out; errBack = System.err; outStream = new ByteArrayOutputStream(); errStream = new ByteArrayOutputStream(); System.setOut(new PrintStream(outStream)); System.setErr(new PrintStream(errStream)); } @AfterMethod void restoreOutputStreams() { System.setOut(outBack); System.setErr(errBack); } String getError() { return errStream.toString(); } String getOut() { return outStream.toString(); } private OptionsAndArgs opts(String... args) { return new OptionsAndArgs(CommandDispatcher.getAvailableCommands(),args); } }