Coverage Report - kg.apc.jmeter.reporters.LoadosophiaAggregator
 
Classes in this File Line Coverage Branch Coverage Complexity
LoadosophiaAggregator
95%
77/81
82%
23/28
2.857
 
 1  
 package kg.apc.jmeter.reporters;
 2  
 
 3  
 import java.text.SimpleDateFormat;
 4  
 import java.util.Arrays;
 5  
 import java.util.Date;
 6  
 import java.util.Iterator;
 7  
 import java.util.LinkedList;
 8  
 import java.util.List;
 9  
 import java.util.SortedMap;
 10  
 import java.util.Stack;
 11  
 import java.util.TreeMap;
 12  
 import net.sf.json.JSONArray;
 13  
 import net.sf.json.JSONObject;
 14  
 import org.apache.jmeter.samplers.SampleResult;
 15  
 import org.apache.jorphan.logging.LoggingManager;
 16  
 import org.apache.log.Logger;
 17  
 
 18  4
 public class LoadosophiaAggregator {
 19  
 
 20  1
     private static final Logger log = LoggingManager.getLoggerForClass();
 21  4
     private SortedMap<Long, List<SampleResult>> buffer = new TreeMap<Long, List<SampleResult>>();
 22  
     private static final long SEND_SECONDS = 5;
 23  4
     private long lastTime = 0;
 24  4
     private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
 25  
 
 26  
     public void addSample(SampleResult res) {
 27  109
         if (log.isDebugEnabled()) {
 28  0
             log.debug("Got sample to process: " + res);
 29  
         }
 30  
 
 31  109
         Long time = res.getEndTime() / 1000;
 32  109
         if (!buffer.containsKey(time)) {
 33  
             // we need to create new sec list
 34  8
             if (time < lastTime) {
 35  
                 // a problem with times sequence - taking last available
 36  0
                 Iterator<Long> it = buffer.keySet().iterator();
 37  0
                 while (it.hasNext()) {
 38  0
                     time = it.next();
 39  
                 }
 40  
             }
 41  8
             buffer.put(time, new LinkedList<SampleResult>());
 42  
         }
 43  109
         lastTime = time;
 44  109
         buffer.get(time).add(res);
 45  109
     }
 46  
 
 47  
     public boolean haveDataToSend() {
 48  104
         return buffer.size() > SEND_SECONDS + 1;
 49  
     }
 50  
 
 51  
     public JSONArray getDataToSend() {
 52  2
         JSONArray data = new JSONArray();
 53  2
         Iterator<Long> it = buffer.keySet().iterator();
 54  2
         int cnt = 0;
 55  7
         while (cnt < SEND_SECONDS && it.hasNext()) {
 56  5
             Long sec = it.next();
 57  5
             List<SampleResult> raw = buffer.get(sec);
 58  5
             data.add(getAggregateSecond(raw));
 59  5
             it.remove();
 60  5
             cnt++;
 61  5
         }
 62  2
         return data;
 63  
     }
 64  
 
 65  
     private JSONObject getAggregateSecond(List<SampleResult> raw) {
 66  
         /*
 67  
          "rc": item.http_codes,
 68  
          "net": item.net_codes
 69  
          */
 70  5
         JSONObject result = new JSONObject();
 71  5
         Date ts = new Date(raw.iterator().next().getEndTime());
 72  5
         result.put("ts", format.format(ts));
 73  
 
 74  5
         int threads = 0;
 75  5
         int avg_rt = 0;
 76  5
         Long[] rtimes = new Long[raw.size()];
 77  5
         String[] rcodes = new String[raw.size()];
 78  5
         int cnt = 0;
 79  5
         int failedCount = 0;
 80  5
         for (Iterator<SampleResult> it = raw.iterator(); it.hasNext();) {
 81  7
             SampleResult res = it.next();
 82  7
             threads += res.getAllThreads();
 83  7
             avg_rt += res.getTime();
 84  7
             rtimes[cnt] = Long.valueOf(res.getTime());
 85  7
             rcodes[cnt] = res.getResponseCode();
 86  7
             if (!res.isSuccessful()) {
 87  7
                 failedCount++;
 88  
             }
 89  7
             cnt++;
 90  7
         }
 91  5
         result.put("rps", cnt);
 92  5
         result.put("threads", threads / cnt);
 93  5
         result.put("avg_rt", avg_rt / cnt);
 94  5
         result.put("quantiles", getQuantilesJSON(rtimes));
 95  5
         result.put("net", getNetJSON(failedCount, cnt - failedCount));
 96  5
         result.put("rc", getRCJSON(rcodes));
 97  5
         result.put("planned_rps", 0); // JMeter has no such feature like Yandex.Tank
 98  5
         return result;
 99  
     }
 100  
 
 101  
     public static JSONObject getQuantilesJSON(Long[] rtimes) {
 102  7
         JSONObject result = new JSONObject();
 103  7
         Arrays.sort(rtimes);
 104  
 
 105  7
         double[] quantiles = {0.25, 0.50, 0.75, 0.80, 0.90, 0.95, 0.98, 0.99, 1.00};
 106  
 
 107  7
         Stack<Long> timings = new Stack();
 108  7
         timings.addAll(Arrays.asList(rtimes));
 109  7
         double level = 1.0;
 110  7
         long timing = 0;
 111  70
         for (int qn = quantiles.length - 1; qn >= 0; qn--) {
 112  63
             double quan = quantiles[qn];
 113  78
             while (level >= quan && !timings.empty()) {
 114  15
                 timing = timings.pop();
 115  15
                 level -= 1.0 / rtimes.length;
 116  
             }
 117  63
             result.element(String.valueOf(quan * 100), timing);
 118  
         }
 119  
 
 120  7
         return result;
 121  
     }
 122  
 
 123  
     private JSONObject getNetJSON(int failedCount, int succCount) {
 124  5
         JSONObject result = new JSONObject();
 125  5
         result.put("0", succCount);
 126  5
         result.put("1", failedCount);
 127  5
         return result;
 128  
     }
 129  
 
 130  
     private JSONObject getRCJSON(String[] rcodes) {
 131  5
         JSONObject result = new JSONObject();
 132  12
         for (int i = 0; i < rcodes.length; i++) {
 133  7
             int oldval = 0;
 134  7
             if (result.containsKey(rcodes[i]))  {
 135  2
                 oldval = (Integer) result.get(rcodes[i]);
 136  
             }
 137  7
             result.put(rcodes[i], oldval + 1);
 138  
 
 139  
         }
 140  5
         return result;
 141  
     }
 142  
 }