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