Home | History | Annotate | Download | only in monkey
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.bugreport.monkey;
     18 
     19 import com.android.bugreport.anr.Anr;
     20 import com.android.bugreport.anr.AnrParser;
     21 import com.android.bugreport.bugreport.Bugreport;
     22 import com.android.bugreport.util.Line;
     23 import com.android.bugreport.util.Lines;
     24 import com.android.bugreport.util.Utils;
     25 
     26 import java.io.BufferedReader;
     27 import java.io.IOException;
     28 import java.util.ArrayList;
     29 import java.util.regex.Pattern;
     30 import java.util.regex.Matcher;
     31 
     32 /**
     33  * Parser for a monkey log file.
     34  */
     35 public class MonkeyLogParser {
     36     private static final Pattern NOT_RESPONDING_RE
     37             = Pattern.compile("// NOT RESPONDING: \\S+ \\(pid \\d+\\)");
     38     private static final Pattern ABORTED_RE
     39             = Pattern.compile("\\*\\* Monkey aborted due to error\\.");
     40 
     41     public MonkeyLogParser() {
     42     }
     43 
     44     /**
     45      * Parses the monkey file, adding in what's there into an already
     46      * created bugreport.
     47      */
     48     public void parse(Bugreport bugreport, Lines<? extends Line> in) throws IOException {
     49         // Get the lines
     50         final Lines<Line> lines = extractAnrLines(in);
     51         if (!lines.hasNext()) {
     52             return;
     53         }
     54 
     55         final Line line = lines.next();
     56         final String text = line.text;
     57 
     58         // ANRs
     59         final Matcher anrStart = NOT_RESPONDING_RE.matcher(text);
     60         if (Utils.matches(anrStart, text)) {
     61             final AnrParser anrParser = new AnrParser();
     62             final ArrayList<Anr> anrs = anrParser.parse(lines, true);
     63             if (anrs.size() >= 1) {
     64                 // Pick the first one.
     65                 bugreport.anr = bugreport.monkeyAnr = anrs.get(0);
     66             }
     67         }
     68     }
     69 
     70     /**
     71      * Pull out the ANR lines from a monkey log.
     72      */
     73     private static Lines<Line> extractAnrLines(Lines<? extends Line> lines) throws IOException {
     74         final int STATE_INITIAL = 0;
     75         final int STATE_ANR = 1;
     76         final int STATE_DONE = 2;
     77 
     78         ArrayList<Line> list = new ArrayList<Line>();
     79 
     80         final Matcher anrStart = NOT_RESPONDING_RE.matcher("");
     81         final Matcher monkeyEnd = ABORTED_RE.matcher("");
     82 
     83         int state = STATE_INITIAL;
     84         int lineno = 0;
     85         while (state != STATE_DONE && lines.hasNext()) {
     86             final Line line = lines.next();
     87             lineno++;
     88             switch (state) {
     89                 case STATE_INITIAL:
     90                     anrStart.reset(line.text);
     91                     if (anrStart.matches()) {
     92                         state = STATE_ANR;
     93                         list.add(new Line(lineno, line.text));
     94                     }
     95                     break;
     96                 case STATE_ANR:
     97                     monkeyEnd.reset(line.text);
     98                     if (monkeyEnd.matches()) {
     99                         state = STATE_DONE;
    100                     } else {
    101                         list.add(new Line(lineno, line.text));
    102                     }
    103                     break;
    104                 default:
    105                     break;
    106             }
    107         }
    108 
    109         return new Lines<Line>(list);
    110     }
    111 }
    112