• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ExpectedValuesExpectedValues25   ExpectedValues()
26     : values(NULL),
27       multi_value_length(1) {
28   }
29 
ExpectedValuesExpectedValues30   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".
VerifyTable(FILE * log_file,const ExpectedValuesMap & 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".
VerifyHeader(const std::string & line,const ExpectedValuesMap & 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.
ParseElement(const std::string & line,size_t * line_position,int multi_value_length)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 
TEST(TestDataLog,CreateReturnTest)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 
TEST(TestDataLog,VerifyCombineMethod)124 TEST(TestDataLog, VerifyCombineMethod) {
125   EXPECT_EQ(std::string("a proper table_1"),
126             DataLog::Combine("a proper table", 1));
127 }
128 
TEST(TestDataLog,VerifySingleTable)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 
TEST(TestDataLog,VerifyMultipleTables)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 
TEST(TestDataLogCWrapper,VerifyCWrapper)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