Mercurial > hg > release > thermostat-1.0
changeset 420:8d7ef9bd02ea
Add 'show-heap-histogram' command
Reviewed-by: rkennke
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-June/001990.html
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Thu, 21 Jun 2012 18:15:30 -0400 |
parents | 7a02efec5e28 |
children | b2e13d14cdb5 015256277c62 |
files | client/heapdumper/src/main/java/com/redhat/thermostat/client/heap/ShowHeapHistogramCommand.java client/heapdumper/src/main/resources/META-INF/services/com.redhat.thermostat.common.cli.Command client/heapdumper/src/test/java/com/redhat/thermostat/client/heap/ShowHeapHistogramCommandTest.java |
diffstat | 3 files changed, 239 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/heapdumper/src/main/java/com/redhat/thermostat/client/heap/ShowHeapHistogramCommand.java Thu Jun 21 18:15:30 2012 -0400 @@ -0,0 +1,127 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.heap; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.cli.ArgumentSpec; +import com.redhat.thermostat.common.cli.Arguments; +import com.redhat.thermostat.common.cli.Command; +import com.redhat.thermostat.common.cli.CommandContext; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.HostVMArguments; +import com.redhat.thermostat.common.cli.SimpleArgumentSpec; +import com.redhat.thermostat.common.dao.HeapDAO; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.model.HeapInfo; + +public class ShowHeapHistogramCommand implements Command { + + private static final String NAME = "show-heap-histogram"; + private static final String DESCRIPTION = "show the heap histogram"; + private static final String USAGE = DESCRIPTION; + + @Override + public String getName() { + return NAME; + } + + @Override + public String getDescription() { + return DESCRIPTION; + } + + @Override + public String getUsage() { + return USAGE; + } + + @Override + public Collection<ArgumentSpec> getAcceptedArguments() { + List<ArgumentSpec> args = new ArrayList<>(); + args.addAll(HostVMArguments.getArgumentSpecs()); + args.add(new SimpleArgumentSpec("heapId", "heapId", "the heap id", true, true)); + return args; + } + + @Override + public boolean isStorageRequired() { + return true; + } + + @Override + public void run(CommandContext ctx) throws CommandException { + Arguments args = ctx.getArguments(); + VmRef vmRef = new HostVMArguments(args).getVM(); + String heapId = args.getArgument("heapId"); + + HeapDAO heapDAO = ApplicationContext.getInstance().getDAOFactory().getHeapDAO(); + Collection<HeapInfo> allHeapInfos = heapDAO.getAllHeapInfo(vmRef); + for (HeapInfo heapInfo : allHeapInfos) { + if (heapInfo.getHeapDumpId().equals(heapId)) { + printHeapHistogram(heapDAO, heapInfo, ctx.getConsole().getOutput()); + } + } + } + + private void printHeapHistogram(HeapDAO heapDAO, HeapInfo heapInfo, PrintStream out) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + InputStream in = new BufferedInputStream(heapDAO.getHistogram(heapInfo)); + try { + int data; + while ((data = in.read()) != -1) { + out.print((char)data); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + @Override + public void disable() { + /* NO-OP */ + } + +}
--- a/client/heapdumper/src/main/resources/META-INF/services/com.redhat.thermostat.common.cli.Command Thu Jun 21 18:14:39 2012 -0400 +++ b/client/heapdumper/src/main/resources/META-INF/services/com.redhat.thermostat.common.cli.Command Thu Jun 21 18:15:30 2012 -0400 @@ -1,2 +1,3 @@ com.redhat.thermostat.client.heap.ListHeapDumpsCommand com.redhat.thermostat.client.heap.DumpHeapCommand +com.redhat.thermostat.client.heap.ShowHeapHistogramCommand
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/heapdumper/src/test/java/com/redhat/thermostat/client/heap/ShowHeapHistogramCommandTest.java Thu Jun 21 18:15:30 2012 -0400 @@ -0,0 +1,111 @@ +/* + * Copyright 2012 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.client.heap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Calendar; + +import org.junit.Test; + +import com.redhat.thermostat.common.appctx.ApplicationContext; +import com.redhat.thermostat.common.cli.Command; +import com.redhat.thermostat.common.cli.CommandException; +import com.redhat.thermostat.common.cli.SimpleArguments; +import com.redhat.thermostat.common.dao.DAOFactory; +import com.redhat.thermostat.common.dao.HeapDAO; +import com.redhat.thermostat.common.dao.HostRef; +import com.redhat.thermostat.common.dao.VmRef; +import com.redhat.thermostat.common.model.HeapInfo; +import com.redhat.thermostat.test.TestCommandContextFactory; + +public class ShowHeapHistogramCommandTest { + + @Test + public void verifyBasics() { + Command command = new ShowHeapHistogramCommand(); + + assertEquals("show-heap-histogram", command.getName()); + assertNotNull(command.getDescription()); + assertNotNull(command.getUsage()); + } + + @Test + public void verifyWorks() throws CommandException { + String histogram = "this is the histogram text expected"; + + HostRef hostRef = mock(HostRef.class); + when(hostRef.getStringID()).thenReturn("host-id"); + VmRef vmRef = mock(VmRef.class); + when(vmRef.getStringID()).thenReturn("1"); + + HeapInfo heapInfo = mock(HeapInfo.class); + Calendar timestamp = Calendar.getInstance(); + timestamp.set(2012, 5, 7, 15, 32, 0); + when(heapInfo.getTimestamp()).thenReturn(timestamp.getTimeInMillis()); + when(heapInfo.getHeapDumpId()).thenReturn("heap-id-1"); + + HeapDAO heapDao = mock(HeapDAO.class); + + when(heapDao.getAllHeapInfo(isA(VmRef.class))).thenReturn(Arrays.asList(heapInfo)); + when(heapDao.getHistogram(heapInfo)).thenReturn(new ByteArrayInputStream(histogram.getBytes(Charset.forName("UTF-8")))); + DAOFactory daoFactory = mock(DAOFactory.class); + when(daoFactory.getHeapDAO()).thenReturn(heapDao); + + ApplicationContext.getInstance().setDAOFactory(daoFactory); + + Command command = new ShowHeapHistogramCommand(); + TestCommandContextFactory factory = new TestCommandContextFactory(); + + SimpleArguments args = new SimpleArguments(); + args.addArgument("hostId", "host-id"); + args.addArgument("vmId", "1"); + args.addArgument("heapId", "heap-id-1"); + + command.run(factory.createContext(args)); + + assertEquals(histogram, factory.getOutput()); + } + +}