Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include <map>
     12 #include <string>
     13 
     14 #include "system_wrappers/interface/data_log.h"
     15 #include "system_wrappers/interface/data_log_c.h"
     16 #include "system_wrappers/source/data_log_c_helpers_unittest.h"
     17 #include "gtest/gtest.h"
     18 
     19 using ::webrtc::DataLog;
     20 
     21 // A class for storing the values expected from a log table column when
     22 // verifying a log table file.
     23 struct ExpectedValues {
     24  public:
     25   ExpectedValues()
     26     : values(NULL),
     27       multi_value_length(1) {
     28   }
     29 
     30   ExpectedValues(std::vector<std::string> expected_values,
     31                  int expected_multi_value_length)
     32     : values(expected_values),
     33       multi_value_length(expected_multi_value_length) {
     34   }
     35 
     36   std::vector<std::string> values;
     37   int multi_value_length;
     38 };
     39 
     40 typedef std::map<std::string, ExpectedValues> ExpectedValuesMap;
     41 
     42 // A static class used for parsing and verifying data log files.
     43 class DataLogParser {
     44  public:
     45   // Verifies that the log table stored in the file "log_file" corresponds to
     46   // the cells and columns specified in "columns".
     47   static int VerifyTable(FILE* log_file, const ExpectedValuesMap& columns) {
     48     int row = 0;
     49     char line_buffer[kMaxLineLength];
     50     char* ret = fgets(line_buffer, kMaxLineLength, log_file);
     51     EXPECT_FALSE(ret == NULL);
     52     if (ret == NULL)
     53       return -1;
     54 
     55     std::string line(line_buffer, kMaxLineLength);
     56     VerifyHeader(line, columns);
     57     while (fgets(line_buffer, kMaxLineLength, log_file) != NULL) {
     58       line = std::string(line_buffer, kMaxLineLength);
     59       size_t line_position = 0;
     60 
     61       for (ExpectedValuesMap::const_iterator it = columns.begin();
     62            it != columns.end(); ++it) {
     63         std::string str = ParseElement(line, &line_position,
     64                                        it->second.multi_value_length);
     65         EXPECT_EQ(str, it->second.values[row]);
     66         if (str != it->second.values[row])
     67           return -1;
     68       }
     69       ++row;
     70     }
     71     return 0;
     72   }
     73 
     74   // Verifies the table header stored in "line" to correspond with the header
     75   // specified in "columns".
     76   static int VerifyHeader(const std::string& line,
     77                           const ExpectedValuesMap& columns) {
     78     size_t line_position = 0;
     79     for (ExpectedValuesMap::const_iterator it = columns.begin();
     80          it != columns.end(); ++it) {
     81       std::string str = ParseElement(line, &line_position,
     82                                      it->second.multi_value_length);
     83       EXPECT_EQ(str, it->first);
     84       if (str != it->first)
     85         return -1;
     86     }
     87     return 0;
     88   }
     89 
     90   // Parses out and returns one element from the string "line", which contains
     91   // one line read from a log table file. An element can either be a column
     92   // header or a cell of a row.
     93   static std::string ParseElement(const std::string& line,
     94                                   size_t* line_position,
     95                                   int multi_value_length) {
     96     std::string parsed_cell;
     97     parsed_cell = "";
     98     for (int i = 0; i < multi_value_length; ++i) {
     99       size_t next_separator = line.find(',', *line_position);
    100       EXPECT_NE(next_separator, std::string::npos);
    101       if (next_separator == std::string::npos)
    102         break;
    103       parsed_cell += line.substr(*line_position,
    104                                  next_separator - *line_position + 1);
    105       *line_position = next_separator + 1;
    106     }
    107     return parsed_cell;
    108   }
    109 
    110   // This constant defines the maximum line length the DataLogParser can
    111   // parse.
    112   enum { kMaxLineLength = 100 };
    113 };
    114 
    115 TEST(TestDataLog, CreateReturnTest) {
    116   for (int i = 0; i < 10; ++i)
    117     ASSERT_EQ(DataLog::CreateLog(), 0);
    118   ASSERT_EQ(DataLog::AddTable(DataLog::Combine("a proper table", 1)), 0);
    119   for (int i = 0; i < 10; ++i)
    120     DataLog::ReturnLog();
    121   ASSERT_LT(DataLog::AddTable(DataLog::Combine("table failure", 1)), 0);
    122 }
    123 
    124 TEST(TestDataLog, VerifyCombineMethod) {
    125   EXPECT_EQ(std::string("a proper table_1"),
    126             DataLog::Combine("a proper table", 1));
    127 }
    128 
    129 TEST(TestDataLog, VerifySingleTable) {
    130   DataLog::CreateLog();
    131   DataLog::AddTable(DataLog::Combine("table", 1));
    132   DataLog::AddColumn(DataLog::Combine("table", 1), "arrival", 1);
    133   DataLog::AddColumn(DataLog::Combine("table", 1), "timestamp", 1);
    134   DataLog::AddColumn(DataLog::Combine("table", 1), "size", 5);
    135   WebRtc_UWord32 sizes[5] = {1400, 1500, 1600, 1700, 1800};
    136   for (int i = 0; i < 10; ++i) {
    137     DataLog::InsertCell(DataLog::Combine("table", 1), "arrival",
    138                         static_cast<double>(i));
    139     DataLog::InsertCell(DataLog::Combine("table", 1), "timestamp",
    140                         static_cast<WebRtc_Word64>(4354 + i));
    141     DataLog::InsertCell(DataLog::Combine("table", 1), "size", sizes, 5);
    142     DataLog::NextRow(DataLog::Combine("table", 1));
    143   }
    144   DataLog::ReturnLog();
    145   // Verify file
    146   FILE* table = fopen("table_1.txt", "r");
    147   ASSERT_FALSE(table == NULL);
    148   // Read the column names and verify with the expected columns.
    149   // Note that the columns are written to file in alphabetical order.
    150   // Data expected from parsing the file
    151   const int kNumberOfRows = 10;
    152   std::string string_arrival[kNumberOfRows] = {
    153     "0,", "1,", "2,", "3,", "4,",
    154     "5,", "6,", "7,", "8,", "9,"
    155   };
    156   std::string string_timestamp[kNumberOfRows] = {
    157     "4354,", "4355,", "4356,", "4357,",
    158     "4358,", "4359,", "4360,", "4361,",
    159     "4362,", "4363,"
    160   };
    161   std::string string_sizes = "1400,1500,1600,1700,1800,";
    162   ExpectedValuesMap expected;
    163   expected["arrival,"] = ExpectedValues(
    164                            std::vector<std::string>(string_arrival,
    165                                                     string_arrival +
    166                                                     kNumberOfRows),
    167                            1);
    168   expected["size[5],,,,,"] = ExpectedValues(
    169                                std::vector<std::string>(10, string_sizes), 5);
    170   expected["timestamp,"] = ExpectedValues(
    171                              std::vector<std::string>(string_timestamp,
    172                                                       string_timestamp +
    173                                                       kNumberOfRows),
    174                              1);
    175   ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);
    176   fclose(table);
    177 }
    178 
    179 TEST(TestDataLog, VerifyMultipleTables) {
    180   DataLog::CreateLog();
    181   DataLog::AddTable(DataLog::Combine("table", 2));
    182   DataLog::AddTable(DataLog::Combine("table", 3));
    183   DataLog::AddColumn(DataLog::Combine("table", 2), "arrival", 1);
    184   DataLog::AddColumn(DataLog::Combine("table", 2), "timestamp", 1);
    185   DataLog::AddColumn(DataLog::Combine("table", 2), "size", 1);
    186   DataLog::AddTable(DataLog::Combine("table", 4));
    187   DataLog::AddColumn(DataLog::Combine("table", 3), "timestamp", 1);
    188   DataLog::AddColumn(DataLog::Combine("table", 3), "arrival", 1);
    189   DataLog::AddColumn(DataLog::Combine("table", 4), "size", 1);
    190   for (WebRtc_Word32 i = 0; i < 10; ++i) {
    191     DataLog::InsertCell(DataLog::Combine("table", 2), "arrival",
    192                         static_cast<WebRtc_Word32>(i));
    193     DataLog::InsertCell(DataLog::Combine("table", 2), "timestamp",
    194                         static_cast<WebRtc_Word32>(4354 + i));
    195     DataLog::InsertCell(DataLog::Combine("table", 2), "size",
    196                         static_cast<WebRtc_Word32>(1200 + 10 * i));
    197     DataLog::InsertCell(DataLog::Combine("table", 3), "timestamp",
    198                         static_cast<WebRtc_Word32>(4354 + i));
    199     DataLog::InsertCell(DataLog::Combine("table", 3), "arrival",
    200                         static_cast<WebRtc_Word32>(i));
    201     DataLog::InsertCell(DataLog::Combine("table", 4), "size",
    202                         static_cast<WebRtc_Word32>(1200 + 10 * i));
    203     DataLog::NextRow(DataLog::Combine("table", 4));
    204     DataLog::NextRow(DataLog::Combine("table", 2));
    205     DataLog::NextRow(DataLog::Combine("table", 3));
    206   }
    207   DataLog::ReturnLog();
    208 
    209   // Data expected from parsing the file
    210   const int kNumberOfRows = 10;
    211   std::string string_arrival[kNumberOfRows] = {
    212     "0,", "1,", "2,", "3,", "4,",
    213     "5,", "6,", "7,", "8,", "9,"
    214   };
    215   std::string string_timestamp[kNumberOfRows] = {
    216     "4354,", "4355,", "4356,", "4357,",
    217     "4358,", "4359,", "4360,", "4361,",
    218     "4362,", "4363,"
    219   };
    220   std::string string_size[kNumberOfRows] = {
    221     "1200,", "1210,", "1220,", "1230,",
    222     "1240,", "1250,", "1260,", "1270,",
    223     "1280,", "1290,"
    224   };
    225 
    226   // Verify table 2
    227   {
    228     FILE* table = fopen("table_2.txt", "r");
    229     ASSERT_FALSE(table == NULL);
    230     ExpectedValuesMap expected;
    231     expected["arrival,"] = ExpectedValues(
    232                              std::vector<std::string>(string_arrival,
    233                                                       string_arrival +
    234                                                       kNumberOfRows),
    235                              1);
    236     expected["size,"] = ExpectedValues(
    237                           std::vector<std::string>(string_size,
    238                                                    string_size + kNumberOfRows),
    239                           1);
    240     expected["timestamp,"] = ExpectedValues(
    241                                std::vector<std::string>(string_timestamp,
    242                                                         string_timestamp +
    243                                                         kNumberOfRows),
    244                                1);
    245     ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);
    246     fclose(table);
    247   }
    248 
    249   // Verify table 3
    250   {
    251     FILE* table = fopen("table_3.txt", "r");
    252     ASSERT_FALSE(table == NULL);
    253     ExpectedValuesMap expected;
    254     expected["arrival,"] = ExpectedValues(
    255                              std::vector<std::string>(string_arrival,
    256                                                       string_arrival +
    257                                                       kNumberOfRows),
    258                              1);
    259     expected["timestamp,"] = ExpectedValues(
    260                              std::vector<std::string>(string_timestamp,
    261                                                       string_timestamp +
    262                                                       kNumberOfRows),
    263                                1);
    264     ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);
    265     fclose(table);
    266   }
    267 
    268   // Verify table 4
    269   {
    270     FILE* table = fopen("table_4.txt", "r");
    271     ASSERT_FALSE(table == NULL);
    272     ExpectedValuesMap expected;
    273     expected["size,"] = ExpectedValues(
    274                           std::vector<std::string>(string_size,
    275                                                    string_size +
    276                                                    kNumberOfRows),
    277                           1);
    278     ASSERT_EQ(DataLogParser::VerifyTable(table, expected), 0);
    279     fclose(table);
    280   }
    281 }
    282 
    283 TEST(TestDataLogCWrapper, VerifyCWrapper) {
    284   // Simply call all C wrapper log functions through the C helper unittests.
    285   // Main purpose is to make sure that the linkage is correct.
    286 
    287   EXPECT_EQ(0, WebRtcDataLogCHelper_TestCreateLog());
    288   EXPECT_EQ(0, WebRtcDataLogCHelper_TestCombine());
    289   EXPECT_EQ(0, WebRtcDataLogCHelper_TestAddTable());
    290   EXPECT_EQ(0, WebRtcDataLogCHelper_TestAddColumn());
    291   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertCell_int());
    292   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertArray_int());
    293   EXPECT_EQ(0, WebRtcDataLogCHelper_TestNextRow());
    294   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertCell_float());
    295   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertArray_float());
    296   EXPECT_EQ(0, WebRtcDataLogCHelper_TestNextRow());
    297   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertCell_double());
    298   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertArray_double());
    299   EXPECT_EQ(0, WebRtcDataLogCHelper_TestNextRow());
    300   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertCell_int32());
    301   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertArray_int32());
    302   EXPECT_EQ(0, WebRtcDataLogCHelper_TestNextRow());
    303   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertCell_uint32());
    304   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertArray_uint32());
    305   EXPECT_EQ(0, WebRtcDataLogCHelper_TestNextRow());
    306   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertCell_int64());
    307   EXPECT_EQ(0, WebRtcDataLogCHelper_TestInsertArray_int64());
    308   EXPECT_EQ(0, WebRtcDataLogCHelper_TestNextRow());
    309   EXPECT_EQ(0, WebRtcDataLogCHelper_TestReturnLog());
    310 }
    311