/* Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. Contact: SYSTAP, LLC DBA Blazegraph 2501 Calvert ST NW #106 Washington, DC 20008 licenses@blazegraph.com This program 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; version 2 of the License. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Created on May 9, 2008 */ package com.bigdata.counters.linux; import com.bigdata.counters.*; import junit.framework.AssertionFailedError; import junit.framework.TestCase2; import java.io.ByteArrayInputStream; import java.io.IOException; import java.text.DateFormat; import java.text.ParseException; import java.util.Arrays; import java.util.Date; import java.util.Map; import java.util.regex.Pattern; /** * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ */ public class TestParsing extends TestCase2 { public TestParsing() { super(); } public TestParsing(String name) { super(name); } /** * Test for {@link SysstatUtil#splitDataLine(String)}. */ public void test_splitDataLine01(){ final String header = "06:35:15 PID %user %system %CPU CPU Command"; final String[] fields = SysstatUtil.splitDataLine(header); if (log.isInfoEnabled()) log.info(Arrays.toString(fields)); assertEquals(new String[] { "06:35:15", "PID", "%user", "%system", "%CPU", "CPU", "Command" }, fields); } /** * Test for {@link SysstatUtil#splitDataLine(String)}. */ public void test_splitDataLine02(){ final String data = "06:35:15 501 0.00 0.01 0.00 1 kjournald"; final String[] fields = SysstatUtil.splitDataLine(data); if(log.isInfoEnabled()) log.info(Arrays.toString(fields)); assertEquals(new String[] {"06:35:15", "501", "0.00", "0.01", "0.00", "1", "kjournald"}, fields); } /** * Test for {@link SysstatUtil#splitDataLine(String)}. */ public void test_splitDataLineLeadingSpaces(){ final String header = " 06:35:15 PID %user %system %CPU CPU Command"; final String[] fields = SysstatUtil.splitDataLine(header); if (log.isInfoEnabled()) log.info(Arrays.toString(fields)); System.out.println(Arrays.toString(fields)); assertEquals(new String[] { "06:35:15", "PID", "%user", "%system", "%CPU", "CPU", "Command" }, fields); } /** * Test parse of the sysstat ISO date format. * * @todo test only writes on the console - you need to verify the outcome by * hand. */ public void test_pidStat_data_parse() { final DateFormat f = SysstatUtil.newDateFormat(); System.err.println("Format: " + f.format(new Date())); try { System.err.println("Parsed: " + f.parse("06:35:15 AM")); System.err.println("Parsed: " + f.parse("02:08:24 PM")); } catch (ParseException e) { log.error("Could not parse?"); } } /** * Test based on some sample data. */ public void test_vmstat_header_and_data_parse() { final Pattern pattern = VMStatCollector.pattern; final String header =// " r b swpd free buff cache si so bi bo in cs us sy id wa st"; final String data =// " 1 0 96 178580 206520 1170604 56 12 0 7 1 0 1 0 99 3 0"; // test header parse. { final String[] fields = pattern.split(header.trim(), 0/* limit */); for (int i = 0; i < fields.length; i++) { if(log.isInfoEnabled()) log.info("fields[" + i + "]=[" + fields[i] + "]"); } assertField(header, fields, 2, "swpd"); assertField(header, fields, 3, "free"); assertField(header, fields, 6, "si"); assertField(header, fields, 7, "so"); assertField(header, fields, 12, "us"); assertField(header, fields, 13, "sy"); assertField(header, fields, 14, "id"); assertField(header, fields, 15, "wa"); } // test data parse. { final String[] fields = pattern.split(data.trim(), 0/* limit */); assertField(data, fields, 2, "96"); assertField(data, fields, 3, "178580"); assertField(data, fields, 6, "56"); assertField(data, fields, 7, "12"); assertField(data, fields, 12, "1"); assertField(data, fields, 13, "0"); assertField(data, fields, 14, "99"); assertField(data, fields, 15, "3"); } } public void test_get_data_map() { String header = "15:55:52 UID PID %usr %system %guest %CPU CPU Command\n"; String data = "15:55:54 1000 3308 0.50 0.00 0.00 0.25 0 java\n"; Map<String, String> fields = SysstatUtil.getDataMap(header, data); assertEquals(fields.get("%usr"), "0.50"); assertEquals(fields.size(), 9); } public void test_get_data_incorrect() { String header = "15:55:52 UID PID %usr %system %guest %CPU CPU\n"; String data = "15:55:54 1000 3308 0.50 0.00 0.00 0.25 0 java\n"; try { Map<String, String> fields = SysstatUtil.getDataMap(header, data); assertTrue("Exception should be thrown", false); } catch (IllegalArgumentException e ) { e.printStackTrace(); } } /** * Used to verify that the header corresponds to our expectations. Logs * errors when the expectations are not met. * * @param header * The header line. * @param fields * The fields parsed from that header. * @param field * The field number in [0:#fields-1]. * @param expected * The expected value of the header for that field. */ static protected void assertField(final String header, final String[] fields, final int field, final String expected) { if (header == null) throw new IllegalArgumentException(); if (fields == null) throw new IllegalArgumentException(); if (expected == null) throw new IllegalArgumentException(); if (field < 0) throw new IllegalArgumentException(); if (field >= fields.length) throw new AssertionFailedError("There are only " + fields.length + " fields, but field=" + field + "\n" + header); if (!expected.equals(fields[field])) { throw new AssertionFailedError("Expected field=" + field + " to be [" + expected + "], actual=" + fields[field] + "\n" + header); } } public void test_pid_stat_collector_valid() throws IOException, InterruptedException { final String output = "Linux 3.16.0-4-amd64 (hostname) 27.10.2015 _x86_64_ (4 CPU)\n" + "\n" + "15:55:52 UID PID %usr %system %guest %CPU CPU Command\n" + "15:55:54 1000 3308 0.50 0.00 0.00 0.25 0 java\n" + "\n" + "15:55:52 UID PID minflt/s majflt/s VSZ RSS %MEM Command\n" + "15:55:54 1000 3308 8.00 0.00 2825204 1289368 15.73 java\n" + "\n"; test_pid_stat_collector(output); } public void test_pid_stat_collector_extra_column() throws IOException, InterruptedException { final String output = "Linux 3.16.0-4-amd64 (hostname) 27.10.2015 _x86_64_ (4 CPU)\n" + "\n" + "15:55:52 somecolumn UID PID %usr %system %guest %CPU CPU Command\n" + "15:55:54 100500 1000 3308 0.50 0.00 0.00 0.25 0 java\n" + "\n" + "15:55:52 UID PID minflt/s majflt/s VSZ RSS %MEM Command\n" + "15:55:54 1000 3308 8.00 0.00 2825204 1289368 15.73 java\n" + "\n"; test_pid_stat_collector(output); } protected void test_pid_stat_collector(String output) throws IOException, InterruptedException { final PIDStatCollector pidStatCollector = new PIDStatCollector(1, 1, new KernelVersion("2.6.32")) { @Override public AbstractProcessReader getProcessReader() { return new PIDStatReader() { @Override protected ActiveProcess getActiveProcess() { return new ActiveProcess() { @Override public boolean isAlive() { return true; } }; } }; } }; final PIDStatCollector.PIDStatReader pidStatReader = (PIDStatCollector.PIDStatReader) pidStatCollector.getProcessReader(); pidStatReader.start(new ByteArrayInputStream(output.getBytes())); Thread t = new Thread(pidStatReader); CounterSet counterSet; try { t.start(); Thread.sleep(100); counterSet = pidStatCollector.getCounters(); } finally { t.interrupt(); } double cpu_usr = (Double)((ICounter) counterSet.getChild(IProcessCounters.CPU).getChild("% User Time")).getInstrument().getValue(); long rss = (Long)((ICounter) counterSet.getChild(IProcessCounters.Memory).getChild("Resident Set Size")).getInstrument().getValue(); assertEquals(cpu_usr, 0.005d); assertEquals(rss, 1289368*1024); } }