• 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 "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:
ExpectedValuesExpectedValues26   ExpectedValues()
27     : values(),
28       multi_value_length(1) {
29   }
30 
ExpectedValuesExpectedValues31   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".
VerifyTable(FILE * log_file,const ExpectedValuesMap & 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".
VerifyHeader(const std::string & line,const ExpectedValuesMap & 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.
ParseElement(const std::string & line,size_t * line_position,int multi_value_length)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 
TEST(TestDataLog,CreateReturnTest)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 
TEST(TestDataLog,VerifyCombineMethod)125 TEST(TestDataLog, VerifyCombineMethod) {
126   EXPECT_EQ(std::string("a proper table_1"),
127             DataLog::Combine("a proper table", 1));
128 }
129 
TEST(TestDataLog,VerifySingleTable)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 
TEST(TestDataLog,VerifyMultipleTables)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 
TEST(TestDataLogCWrapper,VerifyCWrapper)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