Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2013-2014 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 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 
     21 #include <gtest/gtest.h>
     22 
     23 static const char begin[] = "--------- beginning of ";
     24 
     25 TEST(logcat, sorted_order) {
     26     FILE *fp;
     27 
     28     ASSERT_TRUE(NULL != (fp = popen(
     29       "logcat -v time -b radio -b events -b system -b main -d 2>/dev/null",
     30       "r")));
     31 
     32     class timestamp {
     33     private:
     34         int month;
     35         int day;
     36         int hour;
     37         int minute;
     38         int second;
     39         int millisecond;
     40         bool ok;
     41 
     42     public:
     43         void init(const char *buffer)
     44         {
     45             ok = false;
     46             if (buffer != NULL) {
     47                 ok = sscanf(buffer, "%d-%d %d:%d:%d.%d ",
     48                     &month, &day, &hour, &minute, &second, &millisecond) == 6;
     49             }
     50         }
     51 
     52         timestamp(const char *buffer)
     53         {
     54             init(buffer);
     55         }
     56 
     57         bool operator< (timestamp &T)
     58         {
     59             return !ok || !T.ok
     60              || (month < T.month)
     61              || ((month == T.month)
     62               && ((day < T.day)
     63                || ((day == T.day)
     64                 && ((hour < T.hour)
     65                  || ((hour == T.hour)
     66                   && ((minute < T.minute)
     67                    || ((minute == T.minute)
     68                     && ((second < T.second)
     69                      || ((second == T.second)
     70                       && (millisecond < T.millisecond))))))))));
     71         }
     72 
     73         bool valid(void)
     74         {
     75             return ok;
     76         }
     77     } last(NULL);
     78 
     79     char *last_buffer = NULL;
     80     char buffer[5120];
     81 
     82     int count = 0;
     83     int next_lt_last = 0;
     84 
     85     while (fgets(buffer, sizeof(buffer), fp)) {
     86         if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
     87             continue;
     88         }
     89         if (!last.valid()) {
     90             free(last_buffer);
     91             last_buffer = strdup(buffer);
     92             last.init(buffer);
     93         }
     94         timestamp next(buffer);
     95         if (next < last) {
     96             if (last_buffer) {
     97                 fprintf(stderr, "<%s", last_buffer);
     98             }
     99             fprintf(stderr, ">%s", buffer);
    100             ++next_lt_last;
    101         }
    102         if (next.valid()) {
    103             free(last_buffer);
    104             last_buffer = strdup(buffer);
    105             last.init(buffer);
    106         }
    107         ++count;
    108     }
    109     free(last_buffer);
    110 
    111     pclose(fp);
    112 
    113     static const int max_ok = 2;
    114 
    115     // Allow few fails, happens with readers active
    116     fprintf(stderr, "%s: %d/%d out of order entries\n",
    117             (next_lt_last)
    118                 ? ((next_lt_last <= max_ok)
    119                     ? "WARNING"
    120                     : "ERROR")
    121                 : "INFO",
    122             next_lt_last, count);
    123 
    124     EXPECT_GE(max_ok, next_lt_last);
    125 
    126     // sample statistically too small
    127     EXPECT_LT(100, count);
    128 }
    129