27971bae9ad2f24f9e03d002e6564b35bf75acfd
[platform/upstream/iotivity.git] / resource / csdk / logger / test / loggertests.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21
22 extern "C" {
23     #include "logger.h"
24 }
25
26
27 #include "gtest/gtest.h"
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36
37 #include <iostream>
38 #include <stdint.h>
39 using namespace std;
40
41
42 //-----------------------------------------------------------------------------
43 // file_exist citation -
44 // http://stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c-cross-platform/230070#230070
45 //-----------------------------------------------------------------------------
46 bool file_exist(const char *filename) {
47   struct stat   buffer;
48   return (stat(filename, &buffer) == 0);
49 }
50
51 //-----------------------------------------------------------------------------
52 // stdio redirection citation - http://www.cplusplus.com/forum/general/94879/
53 //-----------------------------------------------------------------------------
54 static int fd;
55 static int defout;
56
57 bool directStdOutToFile(const char *filename) {
58     if (!filename) {
59         return false;
60     }
61
62     if ((defout = dup(1)) < 0) {
63         fprintf(stderr, "Can't dup(2) - (%s)\n", strerror(errno));
64         return false;
65     }
66     if ((fd = open(filename, O_RDWR | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) < 0) {
67         fprintf(stderr, "Can't open(2) - (%s)\n", strerror(errno));
68         return false;
69     }
70     // redirect output to the file
71     if (dup2(fd, 1) < 0)  {
72         fprintf(stderr, "Can't dup2(2) - (%s)\n", strerror(errno));
73         return false;
74     }
75     close(fd);  // Descriptor no longer needed
76
77     fflush(stdout);          // FLUSH ALL OUTPUT TO file
78
79     return true;
80 }
81
82 bool directStdOutToConsole() {
83     fflush(stdout);          // FLUSH ALL OUTPUT TO file
84
85     // redirect output back to stdout
86     if (dup2(defout, 1) < 0) {
87         fprintf(stderr, "Can't dup2(2) - (%s)\n", strerror(errno));
88         return false;
89     }
90     close(defout);  // Copy of stdout no longer needed
91
92     return true;
93 }
94
95 //-----------------------------------------------------------------------------
96 // CalcFileMD5 citation - http://stackoverflow.com/questions/3395690/md5sum-of-file-in-linux-c
97 //-----------------------------------------------------------------------------
98 #include <stdio.h>
99 #include <ctype.h>
100
101 #define STR_VALUE(val) #val
102 #define STR(name) STR_VALUE(name)
103
104 #define PATH_LEN 256
105 #define MD5_LEN 32
106
107 bool CalcFileMD5(const char *file_name, char *md5_sum) {
108     #define MD5SUM_CMD_FMT "md5sum %." STR(PATH_LEN) "s 2>/dev/null"
109     char cmd[PATH_LEN + sizeof (MD5SUM_CMD_FMT)];
110     snprintf(cmd, sizeof(cmd), MD5SUM_CMD_FMT, file_name);
111     #undef MD5SUM_CMD_FMT
112
113     FILE *p = popen(cmd, "r");
114     if (p == NULL) return 0;
115
116     int i, ch;
117     for (i = 0; i < MD5_LEN && isxdigit(ch = fgetc(p)); i++) {
118         *md5_sum++ = ch;
119     }
120
121     *md5_sum = '\0';
122     pclose(p);
123     return (i == MD5_LEN);
124 }
125
126
127 //-----------------------------------------------------------------------------
128 //  Tests
129 //-----------------------------------------------------------------------------
130 TEST(LoggerTest, StringArg) {
131     char testFile[] = "tst_stringarg.txt";
132     char stdFile[]  = "std_stringarg.txt";
133
134     // Try deleting test file
135     remove(testFile);
136
137     directStdOutToFile(testFile);
138     const char *tag = "StringArg";
139         OC_LOG(INFO, tag, "This is a fixed string call");
140     directStdOutToConsole();
141
142     bool testFileExists = file_exist(testFile);
143     EXPECT_TRUE(testFileExists);
144     bool stdFileExists = file_exist(stdFile);
145     EXPECT_TRUE(stdFileExists);
146
147     if (testFileExists && stdFileExists) {
148         char testFileMD5[MD5_LEN + 1] = {0};
149         char stdFileMD5[MD5_LEN + 1] = {0};
150
151         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
152         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
153
154         EXPECT_STREQ(stdFileMD5, testFileMD5);
155     }
156 }
157
158 TEST(LoggerTest, StringArgNoTag) {
159     char testFile[] = "tst_stringargnotag.txt";
160     char stdFile[]  = "std_stringargnotag.txt";
161
162     directStdOutToFile(testFile);
163     OC_LOG(INFO, 0, "This is a fixed string call");
164     directStdOutToConsole();
165
166     bool testFileExists = file_exist(testFile);
167     EXPECT_TRUE(testFileExists);
168     bool stdFileExists = file_exist(stdFile);
169     EXPECT_TRUE(stdFileExists);
170
171     if (testFileExists && stdFileExists) {
172         char testFileMD5[MD5_LEN + 1] = {0};
173         char stdFileMD5[MD5_LEN + 1] = {0};
174
175         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
176         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
177
178         EXPECT_STREQ(stdFileMD5, testFileMD5);
179     }
180 }
181
182 TEST(LoggerTest, StringArgNoLogStr) {
183     char testFile[] = "tst_stringargnologstr.txt";
184     char stdFile[]  = "std_stringargnologstr.txt";
185
186     directStdOutToFile(testFile);
187     const char *tag = "StringArgNoLogStr";
188     OC_LOG(INFO, tag, 0);
189     directStdOutToConsole();
190
191     bool testFileExists = file_exist(testFile);
192     EXPECT_TRUE(testFileExists);
193     bool stdFileExists = file_exist(stdFile);
194     EXPECT_TRUE(stdFileExists);
195
196     if (testFileExists && stdFileExists) {
197         char testFileMD5[MD5_LEN + 1] = {0};
198         char stdFileMD5[MD5_LEN + 1] = {0};
199
200         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
201         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
202
203         EXPECT_STREQ(stdFileMD5, testFileMD5);
204     }
205 }
206
207 TEST(LoggerTest, StringArgNoTagNoLogStr) {
208     char testFile[] = "tst_stringargnotagnologstr.txt";
209     char stdFile[]  = "std_stringargnotagnologstr.txt";
210
211     directStdOutToFile(testFile);
212     OC_LOG(INFO, 0, 0);
213     directStdOutToConsole();
214
215     bool testFileExists = file_exist(testFile);
216     EXPECT_TRUE(testFileExists);
217     bool stdFileExists = file_exist(stdFile);
218     EXPECT_TRUE(stdFileExists);
219
220     if (testFileExists && stdFileExists) {
221         char testFileMD5[MD5_LEN + 1] = {0};
222         char stdFileMD5[MD5_LEN + 1] = {0};
223
224         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
225         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
226
227         EXPECT_STREQ(stdFileMD5, testFileMD5);
228     }
229 }
230
231 TEST(LoggerTest, StringArgLevels) {
232     char testFile[] = "tst_stringarglevels.txt";
233     char stdFile[]  = "std_stringarglevels.txt";
234
235     directStdOutToFile(testFile);
236     const char *tag = "StringArgLevels";
237     // DEBUG, INFO, WARNING, ERROR, FATAL
238     OC_LOG(DEBUG, tag, "this is a DEBUG message");
239     OC_LOG(INFO, tag, "this is a INFO message");
240     OC_LOG(WARNING, tag, "this is a WARNING message");
241     OC_LOG(ERROR, tag, "this is a ERROR message");
242     OC_LOG(FATAL, tag, "this is a FATAL message");
243     directStdOutToConsole();
244
245     bool testFileExists = file_exist(testFile);
246     EXPECT_TRUE(testFileExists);
247     bool stdFileExists = file_exist(stdFile);
248     EXPECT_TRUE(stdFileExists);
249
250     if (testFileExists && stdFileExists) {
251         char testFileMD5[MD5_LEN + 1] = {0};
252         char stdFileMD5[MD5_LEN + 1] = {0};
253
254         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
255         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
256
257         EXPECT_STREQ(stdFileMD5, testFileMD5);
258     }
259 }
260
261 TEST(LoggerTest, StringArgMultiline) {
262     char testFile[] = "tst_stringargmultiline.txt";
263     char stdFile[]  = "std_stringargmultiline.txt";
264
265     directStdOutToFile(testFile);
266     const char *tag = "StringArgMultiline";
267     OC_LOG(DEBUG, tag, "this is a DEBUG message\non multiple\nlines");
268     directStdOutToConsole();
269
270     bool testFileExists = file_exist(testFile);
271     EXPECT_TRUE(testFileExists);
272     bool stdFileExists = file_exist(stdFile);
273     EXPECT_TRUE(stdFileExists);
274
275     if (testFileExists && stdFileExists) {
276         char testFileMD5[MD5_LEN + 1] = {0};
277         char stdFileMD5[MD5_LEN + 1] = {0};
278
279         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
280         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
281
282         EXPECT_STREQ(stdFileMD5, testFileMD5);
283     }
284 }
285
286 TEST(LoggerTest, VariableArg) {
287     char testFile[] = "tst_variablearg.txt";
288     char stdFile[]  = "std_variablearg.txt";
289
290     directStdOutToFile(testFile);
291     const char *tag = "VariableArg";
292     // DEBUG, INFO, WARNING, ERROR, FATAL
293     OC_LOG_V(DEBUG, tag, "this is a char: %c", 'A');
294     OC_LOG_V(DEBUG, tag, "this is an integer: %d", 123);
295     OC_LOG_V(DEBUG, tag, "this is a string: %s", "hello");
296     OC_LOG_V(DEBUG, tag, "this is a float: %5.2f", 123.45);
297     directStdOutToConsole();
298
299     bool testFileExists = file_exist(testFile);
300     EXPECT_TRUE(testFileExists);
301     bool stdFileExists = file_exist(stdFile);
302     EXPECT_TRUE(stdFileExists);
303
304     if (testFileExists && stdFileExists) {
305         char testFileMD5[MD5_LEN + 1] = {0};
306         char stdFileMD5[MD5_LEN + 1] = {0};
307
308         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
309         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
310
311         EXPECT_STREQ(stdFileMD5, testFileMD5);
312     }
313 }
314
315 TEST(LoggerTest, LogBuffer) {
316     char testFile[] = "tst_logbuffer.txt";
317     char stdFile[]  = "std_logbuffer.txt";
318
319     directStdOutToFile(testFile);
320     const char *tag = "LogBuffer";
321
322     // Log buffer
323     uint8_t buffer[50];
324     for (int i = 0; i < (int)(sizeof buffer); i++) {
325         buffer[i] = i;
326     }
327     OC_LOG_BUFFER(DEBUG, tag, buffer, sizeof buffer);
328
329     // Log buffer, 128 bytes is a good boundary (8 rows of 16 values)
330     uint8_t buffer1[128];
331     for (int i = 0; i < (int)(sizeof buffer1); i++) {
332         buffer1[i] = i;
333     }
334     OC_LOG_BUFFER(DEBUG, tag, buffer1, sizeof buffer1);
335
336     // 1 below 128 byte boundary
337     uint8_t buffer2[127];
338     for (int i = 0; i < (int)(sizeof buffer2); i++) {
339         buffer2[i] = i;
340     }
341     OC_LOG_BUFFER(DEBUG, tag, buffer2, sizeof buffer2);
342
343     // 1 above 128 byte boundary
344     uint8_t buffer3[129];
345     for (int i = 0; i < (int)(sizeof buffer3); i++) {
346         buffer3[i] = i;
347     }
348     OC_LOG_BUFFER(DEBUG, tag, buffer3, sizeof buffer3);
349
350     directStdOutToConsole();
351
352     bool testFileExists = file_exist(testFile);
353     EXPECT_TRUE(testFileExists);
354     bool stdFileExists = file_exist(stdFile);
355     EXPECT_TRUE(stdFileExists);
356
357     if (testFileExists && stdFileExists) {
358         char testFileMD5[MD5_LEN + 1] = {0};
359         char stdFileMD5[MD5_LEN + 1] = {0};
360
361         EXPECT_TRUE(CalcFileMD5(testFile, testFileMD5));
362         EXPECT_TRUE(CalcFileMD5(stdFile, stdFileMD5));
363
364         EXPECT_STREQ(stdFileMD5, testFileMD5);
365     }
366 }