Coverage Report - kg.apc.jmeter.vizualizers.AggregateReportGui
 
Classes in this File Line Coverage Branch Coverage Complexity
AggregateReportGui
98%
76/77
75%
3/4
1.533
AggregateReportGui$FakeGraphPanelChart
55%
11/20
50%
1/2
1.533
 
 1  
 package kg.apc.jmeter.vizualizers;
 2  
 
 3  
 import java.awt.BorderLayout;
 4  
 import java.awt.Dimension;
 5  
 import java.io.File;
 6  
 import java.io.FileNotFoundException;
 7  
 import java.io.FileWriter;
 8  
 import java.io.IOException;
 9  
 import java.text.DecimalFormat;
 10  
 import java.text.Format;
 11  
 import java.util.ArrayList;
 12  
 import java.util.Collection;
 13  
 import java.util.Map;
 14  
 import java.util.concurrent.ConcurrentHashMap;
 15  
 import javax.swing.*;
 16  
 import javax.swing.border.Border;
 17  
 import javax.swing.border.EmptyBorder;
 18  
 import javax.swing.table.TableCellRenderer;
 19  
 import kg.apc.charting.GraphPanelChart;
 20  
 import kg.apc.jmeter.graphs.AbstractGraphPanelVisualizer;
 21  
 import org.apache.jmeter.gui.util.HeaderAsPropertyRenderer;
 22  
 import org.apache.jmeter.samplers.SampleResult;
 23  
 import org.apache.jmeter.save.CSVSaveService;
 24  
 import org.apache.jmeter.testelement.TestElement;
 25  
 import org.apache.jmeter.util.JMeterUtils;
 26  
 import org.apache.jmeter.visualizers.SamplingStatCalculator;
 27  
 import org.apache.jmeter.visualizers.StatGraphVisualizer;
 28  
 import org.apache.jmeter.visualizers.StatVisualizer;
 29  
 import org.apache.jorphan.gui.NumberRenderer;
 30  
 import org.apache.jorphan.gui.ObjectTableModel;
 31  
 import org.apache.jorphan.gui.RateRenderer;
 32  
 import org.apache.jorphan.gui.RendererUtils;
 33  
 import org.apache.jorphan.logging.LoggingManager;
 34  
 import org.apache.jorphan.reflect.Functor;
 35  
 import org.apache.log.Logger;
 36  
 
 37  
 /**
 38  
  * OMG, I had to copy full contents of StatVisualizer just to make its data
 39  
  * visible to JMeterPluginsCMD. This class is just invisible in menu;
 40  
  *
 41  
  * @see StatVisualizer
 42  
  */
 43  4
 public class AggregateReportGui extends AbstractGraphPanelVisualizer {
 44  
 
 45  11
     private Collection<String> emptyCollection = new ArrayList<String>();
 46  
     private static final long serialVersionUID = 241L;
 47  1
     private static final Logger log = LoggingManager.getLoggerForClass();
 48  
     private static final String USE_GROUP_NAME = "useGroupName";
 49  
     private static final String SAVE_HEADERS = "saveHeaders";
 50  1
     private static final String[] COLUMNS = {
 51  
         "sampler_label",
 52  
         "aggregate_report_count",
 53  
         "average",
 54  
         "aggregate_report_median",
 55  
         "aggregate_report_90%_line",
 56  
         "aggregate_report_min",
 57  
         "aggregate_report_max",
 58  
         "aggregate_report_error%",
 59  
         "aggregate_report_rate",
 60  
         "aggregate_report_bandwidth",
 61  
         "aggregate_report_stddev",};
 62  11
     private final String TOTAL_ROW_LABEL = JMeterUtils.getResString("aggregate_report_total_label");
 63  
     private JTable myJTable;
 64  
     private JScrollPane myScrollPane;
 65  11
     private final JButton saveTable =
 66  11
             new JButton(JMeterUtils.getResString("aggregate_graph_save_table"));
 67  11
     private final JCheckBox saveHeaders = // should header be saved with the data?
 68  11
             new JCheckBox(JMeterUtils.getResString("aggregate_graph_save_table_header"), true);
 69  11
     private final JCheckBox useGroupName =
 70  11
             new JCheckBox(JMeterUtils.getResString("aggregate_graph_use_group_name"));
 71  
     private transient ObjectTableModel statModel;
 72  11
     private final Map<String, SamplingStatCalculator> tableRows =
 73  
             new ConcurrentHashMap<String, SamplingStatCalculator>();
 74  
 
 75  
     public AggregateReportGui() {
 76  11
         super();
 77  11
         statModel = new ObjectTableModel(COLUMNS,
 78  
                 SamplingStatCalculator.class,
 79  
                 new Functor[]{
 80  
                     new Functor("getLabel"),
 81  
                     new Functor("getCount"),
 82  
                     new Functor("getMeanAsNumber"),
 83  
                     new Functor("getMedian"),
 84  
                     new Functor("getPercentPoint",
 85  
                     new Object[]{new Float(.900)}),
 86  
                     new Functor("getMin"),
 87  
                     new Functor("getMax"),
 88  
                     new Functor("getErrorPercentage"),
 89  
                     new Functor("getRate"),
 90  
                     new Functor("getKBPerSecond"),
 91  
                     new Functor("getStandardDeviation"),},
 92  
                 new Functor[]{null, null, null, null, null, null, null, null, null, null, null},
 93  
                 new Class[]{String.class, Long.class, Long.class, Long.class, Long.class,
 94  
                     Long.class, Long.class, String.class, String.class, String.class, String.class});
 95  11
         clearData();
 96  11
         init();
 97  11
     }
 98  
 
 99  
     //do not insert this vizualiser in any JMeter menu
 100  
     @Override
 101  
     public Collection<String> getMenuCategories() {
 102  1
         return emptyCollection;
 103  
     }
 104  
     // Column renderers
 105  1
     private static final TableCellRenderer[] RENDERERS =
 106  
         new TableCellRenderer[]{
 107  
             null, // Label
 108  
             null, // count
 109  
             null, // Mean
 110  
             null, // median
 111  
             null, // 90%
 112  
             null, // Min
 113  
             null, // Max
 114  
             new NumberRenderer("#0.00%"), // Error %age
 115  
             new RateRenderer("#.0"), // Throughput
 116  
             new NumberRenderer("#.0"), // pageSize
 117  
             new NumberRenderer("#0.00"), // Std Dev.
 118  
         };
 119  
 
 120  
     // Column formats
 121  1
     static final Format[] FORMATS =
 122  
         new Format[]{
 123  
             null, // Label
 124  
             null, // count
 125  
             null, // Mean
 126  
             null, // median
 127  
             null, // 90%
 128  
             null, // Min
 129  
             null, // Max
 130  
             new DecimalFormat("#0.00%"), // Error %age
 131  
             new DecimalFormat("#.0"), // Throughput
 132  
             new DecimalFormat("#.0"), // pageSize
 133  
             new DecimalFormat("#0.00"), // Std Dev.
 134  
         };
 135  
 
 136  
     @Override
 137  
     public String getLabelResource() {
 138  1
         return "aggregate_report";
 139  
     }
 140  
 
 141  
     @Override
 142  
     public void add(SampleResult res) {
 143  4
         if (!isSampleIncluded(res)) {
 144  0
             return;
 145  
         }
 146  
 
 147  
         SamplingStatCalculator row;
 148  4
         final String sampleLabel = res.getSampleLabel(useGroupName.isSelected());
 149  4
         synchronized (tableRows) {
 150  4
             row = tableRows.get(sampleLabel);
 151  4
             if (row == null) {
 152  1
                 row = new SamplingStatCalculator(sampleLabel);
 153  1
                 tableRows.put(row.getLabel(), row);
 154  1
                 statModel.insertRow(row, statModel.getRowCount() - 1);
 155  
             }
 156  4
         }
 157  
         /*
 158  
          * Synch is needed because multiple threads can update the counts.
 159  
          */
 160  4
         synchronized (row) {
 161  4
             row.addSample(res);
 162  4
         }
 163  4
         SamplingStatCalculator tot = tableRows.get(TOTAL_ROW_LABEL);
 164  4
         synchronized (tot) {
 165  4
             tot.addSample(res);
 166  4
         }
 167  
         //statModel.fireTableDataChanged();
 168  4
     }
 169  
 
 170  
     /**
 171  
      * Clears this visualizer and its model, and forces a repaint of the table.
 172  
      */
 173  
     @Override
 174  
     public final void clearData() {
 175  12
         synchronized (tableRows) {
 176  12
             statModel.clearData();
 177  12
             tableRows.clear();
 178  12
             tableRows.put(TOTAL_ROW_LABEL, new SamplingStatCalculator(TOTAL_ROW_LABEL));
 179  12
             statModel.addRow(tableRows.get(TOTAL_ROW_LABEL));
 180  12
         }
 181  12
     }
 182  
 
 183  
     /**
 184  
      * Main visualizer setup.
 185  
      */
 186  
     private void init() {
 187  11
         this.setLayout(new BorderLayout());
 188  
 
 189  
         // MAIN PANEL
 190  11
         JPanel mainPanel = new JPanel();
 191  11
         Border margin = new EmptyBorder(10, 10, 5, 10);
 192  
 
 193  11
         mainPanel.setBorder(margin);
 194  11
         mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
 195  
 
 196  11
         mainPanel.add(makeTitlePanel());
 197  
 
 198  
         // SortFilterModel mySortedModel =
 199  
         // new SortFilterModel(myStatTableModel);
 200  11
         myJTable = new JTable(statModel);
 201  11
         myJTable.getTableHeader().setDefaultRenderer(new HeaderAsPropertyRenderer());
 202  11
         myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
 203  11
         RendererUtils.applyRenderers(myJTable, RENDERERS);
 204  11
         myScrollPane = new JScrollPane(myJTable);
 205  11
         this.add(mainPanel, BorderLayout.NORTH);
 206  11
         this.add(myScrollPane, BorderLayout.CENTER);
 207  11
         JPanel opts = new JPanel();
 208  11
         opts.add(useGroupName, BorderLayout.WEST);
 209  11
         opts.add(saveTable, BorderLayout.CENTER);
 210  11
         opts.add(saveHeaders, BorderLayout.EAST);
 211  11
         this.add(opts, BorderLayout.SOUTH);
 212  11
     }
 213  
 
 214  
     @Override
 215  
     public void modifyTestElement(TestElement c) {
 216  1
         super.modifyTestElement(c);
 217  1
         c.setProperty(USE_GROUP_NAME, useGroupName.isSelected(), false);
 218  1
         c.setProperty(SAVE_HEADERS, saveHeaders.isSelected(), true);
 219  1
     }
 220  
 
 221  
     @Override
 222  
     public void configure(TestElement el) {
 223  1
         super.configure(el);
 224  1
         useGroupName.setSelected(el.getPropertyAsBoolean(USE_GROUP_NAME, false));
 225  1
         saveHeaders.setSelected(el.getPropertyAsBoolean(SAVE_HEADERS, true));
 226  1
     }
 227  
 
 228  
     @Override
 229  
     protected JSettingsPanel createSettingsPanel() {
 230  13
         return new JSettingsPanel(this, 0);
 231  
     }
 232  
 
 233  
     @Override
 234  
     public String getWikiPage() {
 235  12
         return "JMeterPluginsCMD";
 236  
     }
 237  
 
 238  
     @Override
 239  
     public GraphPanelChart getGraphPanelChart() {
 240  93
         return new FakeGraphPanelChart();
 241  
     }
 242  
 
 243  
     @Override
 244  
     public String getStaticLabel() {
 245  34
         return "Nobody never should not see this. No, no, no.";
 246  
     }
 247  
 
 248  
     private class FakeGraphPanelChart extends GraphPanelChart {
 249  
 
 250  93
         public FakeGraphPanelChart() {
 251  93
             super(false);
 252  93
         }
 253  
 
 254  
         @Override
 255  
         public void saveGraphToCSV(File file) throws IOException {
 256  1
             log.info("Saving CSV to " + file.getAbsolutePath());
 257  
 
 258  1
             FileWriter writer = null;
 259  
             try {
 260  1
                 writer = new FileWriter(file);
 261  2
                 CSVSaveService.saveCSVStats(SynthesisReportGui.getAllTableData(statModel, FORMATS)
 262  1
                                 , writer, saveHeaders.isSelected() ? COLUMNS : null);
 263  0
             } catch (FileNotFoundException e) {
 264  0
                 log.warn(e.getMessage());
 265  0
             } catch (IOException e) {
 266  0
                 log.warn(e.getMessage());
 267  
             } finally {
 268  0
                 try {
 269  1
                     writer.close();
 270  0
                 } catch (IOException ex) {
 271  0
                     log.warn("There was problem closing file stream", ex);
 272  1
                 }
 273  0
             }
 274  1
         }
 275  
 
 276  
         @Override
 277  
         public void saveGraphToPNG(File file, int w, int h) throws IOException {
 278  0
             throw new UnsupportedOperationException("This plugin type cannot be saved as image");
 279  
         }
 280  
     }
 281  
 }