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