1 /*
2  * Copyright 2013 MongoDB, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #ifndef BSON_TESTS_H
19 #define BSON_TESTS_H
20 
21 
22 #include <bson.h>
23 #include <stdio.h>
24 #include <time.h>
25 
26 
27 BSON_BEGIN_DECLS
28 
29 
30 #define BSON_ASSERT_CMPSTR(a, b)                                          \
31    do {                                                                   \
32       if (((a) != (b)) && !!strcmp ((a), (b))) {                          \
33          fprintf (stderr,                                                 \
34                   "FAIL\n\nAssert Failure: (line#%d) \"%s\" != \"%s\"\n", \
35                   __LINE__,                                               \
36                   a,                                                      \
37                   b);                                                     \
38          abort ();                                                        \
39       }                                                                   \
40    } while (0)
41 
42 
43 #define BSON_ASSERT_CMPINT(a, eq, b)                                          \
44    do {                                                                       \
45       if (!((a) eq (b))) {                                                    \
46          fprintf (stderr,                                                     \
47                   "FAIL\n\nAssert Failure: (line#%d)" #a " " #eq " " #b "\n", \
48                   __LINE__);                                                  \
49          abort ();                                                            \
50       }                                                                       \
51    } while (0)
52 
53 
54 #ifdef BSON_OS_WIN32
55 #include <stdarg.h>
56 #include <share.h>
57 static __inline int
bson_open(const char * filename,int flags,...)58 bson_open (const char *filename, int flags, ...)
59 {
60    int fd = -1;
61    int mode = 0;
62 
63    if (_sopen_s (
64           &fd, filename, flags | _O_BINARY, _SH_DENYNO, _S_IREAD | _S_IWRITE) ==
65        NO_ERROR) {
66       return fd;
67    }
68 
69    return -1;
70 }
71 #define bson_close _close
72 #define bson_read(f, b, c) ((ssize_t) _read ((f), (b), (int) (c)))
73 #define bson_write _write
74 #else
75 #define bson_open open
76 #define bson_read read
77 #define bson_close close
78 #define bson_write write
79 #endif
80 
81 
82 #define bson_eq_bson(bson, expected)                                          \
83    do {                                                                       \
84       char *bson_json, *expected_json;                                        \
85       const uint8_t *bson_data = bson_get_data ((bson));                      \
86       const uint8_t *expected_data = bson_get_data ((expected));              \
87       int unequal;                                                            \
88       unsigned o;                                                             \
89       int off = -1;                                                           \
90       unequal = ((expected)->len != (bson)->len) ||                           \
91                 memcmp (bson_get_data ((expected)),                           \
92                         bson_get_data ((bson)),                               \
93                         (expected)->len);                                     \
94       if (unequal) {                                                          \
95          bson_json = bson_as_canonical_extended_json (bson, NULL);            \
96          expected_json = bson_as_canonical_extended_json ((expected), NULL);  \
97          for (o = 0; o < (bson)->len && o < (expected)->len; o++) {           \
98             if (bson_data[o] != expected_data[o]) {                           \
99                off = o;                                                       \
100                break;                                                         \
101             }                                                                 \
102          }                                                                    \
103          if (off == -1) {                                                     \
104             off = BSON_MAX ((expected)->len, (bson)->len) - 1;                \
105          }                                                                    \
106          fprintf (stderr,                                                     \
107                   "bson objects unequal (byte %u):\n(%s)\n(%s)\n",            \
108                   off,                                                        \
109                   bson_json,                                                  \
110                   expected_json);                                             \
111          {                                                                    \
112             int fd1 = bson_open ("failure.bad.bson", O_RDWR | O_CREAT, 0640); \
113             int fd2 =                                                         \
114                bson_open ("failure.expected.bson", O_RDWR | O_CREAT, 0640);   \
115             BSON_ASSERT (fd1 != -1);                                               \
116             BSON_ASSERT (fd2 != -1);                                               \
117             BSON_ASSERT ((bson)->len == bson_write (fd1, bson_data, (bson)->len)); \
118             BSON_ASSERT ((expected)->len ==                                        \
119                     bson_write (fd2, expected_data, (expected)->len));        \
120             bson_close (fd1);                                                 \
121             bson_close (fd2);                                                 \
122          }                                                                    \
123          BSON_ASSERT (0);                                                          \
124       }                                                                       \
125    } while (0)
126 
127 
128 static BSON_INLINE void
run_test(const char * name,void (* func)(void))129 run_test (const char *name, void (*func) (void))
130 {
131    struct timeval begin;
132    struct timeval end;
133    struct timeval diff;
134    long usec;
135    double format;
136 
137    fprintf (stdout, "%-42s : ", name);
138    fflush (stdout);
139    bson_gettimeofday (&begin);
140    func ();
141    bson_gettimeofday (&end);
142    fprintf (stdout, "PASS");
143 
144    diff.tv_sec = end.tv_sec - begin.tv_sec;
145    diff.tv_usec = usec = end.tv_usec - begin.tv_usec;
146    if (usec < 0) {
147       diff.tv_sec -= 1;
148       diff.tv_usec = usec + 1000000;
149    }
150 
151    format = diff.tv_sec + (diff.tv_usec / 1000000.0);
152    fprintf (stdout, " : %lf\n", format);
153 }
154 
155 
156 BSON_END_DECLS
157 
158 #endif /* BSON_TESTS_H */
159