1 #include "test_helper.h"
2 #include "../../smsd/core.h"
3 
4 #define TS20190715120000 1563192000
5 #define TS20191215120000 1576411200
6 
7 void SMSDSQL_Time2String(GSM_SMSDConfig * Config, time_t timestamp, char *static_buff, size_t size);
8 time_t SMSDSQL_ParseDate(GSM_SMSDConfig * Config, const char *date);
9 
10 int get_local_timezone_offset(time_t posix_time);
11 
print_time(const struct tm * tm)12 void print_time(const struct tm *tm)
13 {
14 	char buffer[128] = {0};
15   strftime(buffer, 128, "'%Y-%m-%d %H:%M:%S'", tm);
16   puts(buffer);
17 }
18 
mk_dt(int year,int month,int day,int hour,int minute,int second,int offset)19 GSM_DateTime *mk_dt(
20   int year, int month, int day,
21   int hour, int minute, int second,
22   int offset)
23 {
24   static GSM_DateTime dt;
25 
26   dt.Year = year;
27   dt.Month = month;
28   dt.Day = day;
29   dt.Hour = hour;
30   dt.Minute = minute;
31   dt.Second = second;
32   dt.Timezone = offset*3600;
33 
34   return &dt;
35 }
36 
get_sql_string(char * dest,const char * driver_name,time_t posix_time)37 void get_sql_string(char *dest, const char* driver_name, time_t posix_time)
38 {
39   GSM_SMSDConfig config;
40   memset(&config, 0, sizeof(GSM_SMSDConfig));
41   config.driver = driver_name;
42   SMSDSQL_Time2String(&config, posix_time, dest, 128);
43 }
44 
45 /**************************************************/
46 
test_fill_time_t_gmt(void)47 void test_fill_time_t_gmt(void)
48 {
49   GSM_DateTime dt = *mk_dt(2019, 12, 15, 12, 00, 00, 0);
50   struct tm tm;
51   time_t time;
52 
53   puts(__func__);
54 
55   time = Fill_Time_T(dt);
56 #ifndef WIN32
57   putenv((char*)"TZ=:Europe/London");
58 #else
59   putenv("TZ=GMT0");
60   tzset();
61 #endif
62   tm = *localtime(&time);
63 
64   test_result(tm.tm_hour == 12);
65   test_result(time == TS20191215120000);
66 }
67 
test_fill_time_t_dst(void)68 void test_fill_time_t_dst(void)
69 {
70   GSM_DateTime dt = *mk_dt(2019, 7, 15, 12, 00, 00, 0);
71   struct tm tm;
72   time_t time;
73 
74   puts(__func__);
75 
76   time = Fill_Time_T(dt);
77 #ifndef WIN32
78   putenv((char*)"TZ=:Europe/London");
79 #else
80   putenv("TZ=GMT-1");
81   tzset();
82 #endif
83   tm = *localtime(&time);
84 
85   test_result(tm.tm_hour == 13);
86   test_result(time == TS20190715120000);
87 }
88 
test_fill_time_t_cet(void)89 void test_fill_time_t_cet(void)
90 {
91   // origin timestamp +5 hours == GMT0700 == CET0800
92   GSM_DateTime dt = *mk_dt(2019, 12, 15, 12, 00, 00, 5);
93   struct tm tm;
94   time_t time;
95 
96   puts(__func__);
97 
98   time = Fill_Time_T(dt);
99 #ifndef WIN32
100   putenv((char*)"TZ=:Europe/Warsaw");
101 #else
102   putenv("TZ=CET-1");
103   tzset();
104 #endif
105   tm = *localtime(&time);
106 
107   test_result(tm.tm_hour == 8);
108   test_result(time == TS20191215120000 - 5*3600);
109 }
110 
test_fill_time_t_cest(void)111 void test_fill_time_t_cest(void)
112 {
113   // origin timestamp -3 hours == GMT1500 == CEST1700
114   GSM_DateTime dt = *mk_dt(2019, 7, 15, 12, 00, 00, -3);
115   struct tm tm;
116   time_t time;
117 
118   puts(__func__);
119 
120   time = Fill_Time_T(dt);
121 #ifndef WIN32
122   putenv((char*)"TZ=:Europe/Warsaw");
123 #else
124   putenv("TZ=CET-2");
125   tzset();
126 #endif
127   tm = *localtime(&time);
128 
129   test_result(tm.tm_hour == 17);
130   test_result(time == TS20190715120000 + 3*3600);
131 }
132 
test_local_tz_offset_cet(void)133 void test_local_tz_offset_cet(void)
134 {
135   GSM_DateTime dt = *mk_dt(2019, 12, 15, 12, 00, 00, 0);
136   int offset;
137 
138   puts(__func__);
139 
140 #ifndef WIN32
141   putenv((char*)"TZ=:Europe/Warsaw");
142 #else
143   putenv("TZ=CET-1");
144   tzset();
145 #endif
146 
147   offset = get_local_timezone_offset(Fill_Time_T(dt));
148   test_result(offset == 3600);
149 }
150 
test_local_tz_offset_cest(void)151 void test_local_tz_offset_cest(void)
152 {
153   GSM_DateTime dt = *mk_dt(2019, 7, 15, 12, 00, 00, 0);
154   int offset;
155 
156   puts(__func__);
157 
158 #ifndef WIN32
159   putenv((char *) "TZ=:Europe/Warsaw");
160 #else
161   putenv("TZ=CET-2");
162   tzset();
163 #endif
164 
165   offset = get_local_timezone_offset(Fill_Time_T(dt));
166   test_result(offset == 7200);
167 }
168 
test_sql_parse_date_no_dst(void)169 void test_sql_parse_date_no_dst(void)
170 {
171   const char* expected = "2019-12-15 12:00:00";
172   char actual[128];
173   time_t time;
174   struct tm tm;
175 
176   puts(__func__);
177 
178 #ifndef WIN32
179   putenv((char*)"TZ=:Europe/Warsaw");
180 #else
181   putenv("TZ=CET-1");
182   tzset();
183 #endif
184   time = SMSDSQL_ParseDate(NULL, expected);
185   tm = *localtime(&time);
186 
187   strftime(actual, 128, "%Y-%m-%d %H:%M:%S", &tm);
188   test_result(strcmp(expected, actual) == 0);
189 }
190 
test_sql_parse_date_with_dst(void)191 void test_sql_parse_date_with_dst(void)
192 {
193   const char* expected = "2019-07-15 12:00:00";
194   char actual[128];
195   time_t time;
196   struct tm tm;
197 
198   puts(__func__);
199 
200 #ifndef WIN32
201   putenv((char*)"TZ=:Europe/Warsaw");
202 #else
203   putenv("TZ=CET-2");
204   tzset();
205 #endif
206   time = SMSDSQL_ParseDate(NULL, expected);
207   tm = *localtime(&time);
208 
209   strftime(actual, 128, "%Y-%m-%d %H:%M:%S", &tm);
210   test_result(strcmp(expected, actual) == 0);
211 }
212 
neg_timestamp(void)213 void neg_timestamp(void)
214 {
215   char actual[128];
216 
217   puts(__func__);
218 
219   get_sql_string(actual, "pgsql", -2);
220 
221   test_result(strcmp("0000-00-00 00:00:00", actual) == 0);
222 }
223 
pgsql_timestamp(void)224 void pgsql_timestamp(void)
225 {
226   GSM_DateTime dt = *mk_dt(2019, 5, 8, 11, 48, 44, 2);
227   char actual[128];
228 
229   puts(__func__);
230 
231 #ifndef WIN32
232   putenv((char*)"TZ=:Europe/Warsaw");
233 #else
234   putenv("TZ=CET-2");
235   tzset();
236 #endif
237   get_sql_string(actual, "pgsql", Fill_Time_T(dt));
238 
239   test_result(strcmp("2019-05-08 11:48:44", actual) == 0);
240 }
241 
mysql_timestamp(void)242 void mysql_timestamp(void)
243 {
244   GSM_DateTime dt = *mk_dt(2019, 5, 8, 11, 48, 44, 0);
245   char actual[128];
246 
247   puts(__func__);
248 
249 #ifndef WIN32
250   putenv((char*)"TZ=:Europe/Warsaw");
251 #else
252   putenv("TZ=CET-2");
253   tzset();
254 #endif
255   get_sql_string(actual, "mysql", Fill_Time_T(dt));
256 
257   test_result(strcmp("2019-05-08 13:48:44", actual) == 0);
258 }
259 
oracle_timestamp(void)260 void oracle_timestamp(void)
261 {
262   GSM_DateTime dt = *mk_dt(2019, 5, 8, 11, 48, 44, -3);
263   char actual[128];
264 
265   puts(__func__);
266 
267 #ifndef WIN32
268   putenv((char*)"TZ=:Europe/London");
269 #else
270   putenv("TZ=GMT-1");
271   tzset();
272 #endif
273   get_sql_string(actual, "oracle", Fill_Time_T(dt));
274 
275   test_result(strcmp("TIMESTAMP '2019-05-08 15:48:44'", actual) == 0);
276 }
277 
odbc_timestamp(void)278 void odbc_timestamp(void)
279 {
280   GSM_DateTime dt = *mk_dt(2019, 12, 8, 11, 48, 44, 0);
281   char actual[128];
282 
283   puts(__func__);
284 
285 #ifndef WIN32
286   putenv((char*)"TZ=:Europe/London");
287 #else
288   putenv("TZ=GMT0");
289   tzset();
290 #endif
291   get_sql_string(actual, "odbc", Fill_Time_T(dt));
292 
293   test_result(strcmp("{ ts '2019-12-08 11:48:44' }", actual) == 0);
294 }
295 
access_timestamp(void)296 void access_timestamp(void)
297 {
298   GSM_DateTime dt = *mk_dt(2019, 5, 8, 11, 48, 44, 0);
299   char actual[128];
300 
301   puts(__func__);
302 
303 #ifndef WIN32
304   putenv((char*)"TZ=:Europe/Warsaw");
305 #else
306   putenv("TZ=CET-2");
307   tzset();
308 #endif
309   get_sql_string(actual, "access", Fill_Time_T(dt));
310 
311   test_result(strcmp("'2019-05-08 13:48:44'", actual) == 0);
312 }
313 
main(void)314 int main(void)
315 {
316   test_fill_time_t_gmt();
317   test_fill_time_t_dst();
318 
319   test_fill_time_t_cet();
320   test_fill_time_t_cest();
321 
322   test_local_tz_offset_cet();
323   test_local_tz_offset_cest();
324 
325   test_sql_parse_date_no_dst();
326   test_sql_parse_date_with_dst();
327 
328   neg_timestamp();
329 
330   pgsql_timestamp();
331   mysql_timestamp();
332   oracle_timestamp();
333 
334   odbc_timestamp();
335   access_timestamp();
336 }
337