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