1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 #ident "$Id$"
4 /*======
5 This file is part of PerconaFT.
6 
7 
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9 
10     PerconaFT is free software: you can redistribute it and/or modify
11     it under the terms of the GNU General Public License, version 2,
12     as published by the Free Software Foundation.
13 
14     PerconaFT is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with PerconaFT.  If not, see <http://www.gnu.org/licenses/>.
21 
22 ----------------------------------------
23 
24     PerconaFT is free software: you can redistribute it and/or modify
25     it under the terms of the GNU Affero General Public License, version 3,
26     as published by the Free Software Foundation.
27 
28     PerconaFT is distributed in the hope that it will be useful,
29     but WITHOUT ANY WARRANTY; without even the implied warranty of
30     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31     GNU Affero General Public License for more details.
32 
33     You should have received a copy of the GNU Affero General Public License
34     along with PerconaFT.  If not, see <http://www.gnu.org/licenses/>.
35 ======= */
36 
37 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
38 
39 #include "logger/logcursor.h"
40 #include "test.h"
41 
now(void)42 static uint64_t now(void) {
43     struct timeval tv;
44     int r = gettimeofday(&tv, NULL);
45     assert(r == 0);
46     return tv.tv_sec * 1000000ULL + tv.tv_usec;
47 }
48 
49 // log a couple of timestamp entries and verify the log by walking
50 // a cursor through the log entries
51 
52 int
test_main(int argc,const char * argv[])53 test_main (int argc, const char *argv[]) {
54     default_parse_args(argc, argv);
55 
56     int r;
57     toku_os_recursive_delete(TOKU_TEST_FILENAME);
58     r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU);    assert(r==0);
59     TOKULOGGER logger;
60     LSN lsn = ZERO_LSN;
61 
62     // log a couple of timestamp log entries
63 
64     r = toku_logger_create(&logger);
65     assert(r == 0);
66 
67     r = toku_logger_open(TOKU_TEST_FILENAME, logger);
68     assert(r == 0);
69 
70     BYTESTRING bs0 = { .len = 5, .data = (char *) "hello" };
71     toku_log_comment(logger, &lsn, 0, now(), bs0);
72 
73     sleep(11);
74 
75     BYTESTRING bs1 = { .len = 5, .data = (char *) "world" };
76     toku_log_comment(logger, &lsn, 0, now(), bs1);
77 
78     r = toku_logger_close(&logger);
79     assert(r == 0);
80 
81     // verify the log forwards
82     TOKULOGCURSOR lc = NULL;
83     struct log_entry *le;
84 
85     r = toku_logcursor_create(&lc, TOKU_TEST_FILENAME);
86     assert(r == 0 && lc != NULL);
87 
88     r = toku_logcursor_next(lc, &le);
89     assert(r == 0 && le->cmd == LT_comment);
90     assert(le->u.comment.comment.len == 5 && memcmp(le->u.comment.comment.data, "hello", 5) == 0);
91     uint64_t t = le->u.comment.timestamp;
92 
93     r = toku_logcursor_next(lc, &le);
94     assert(r == 0 && le->cmd == LT_comment);
95     assert(le->u.comment.comment.len == 5 && memcmp(le->u.comment.comment.data, "world", 5) == 0);
96     if (verbose)
97         printf("%" PRIu64 "\n", le->u.comment.timestamp - t);
98     assert(le->u.comment.timestamp - t >= 10*1000000);
99 
100     r = toku_logcursor_next(lc, &le);
101     assert(r != 0);
102 
103     r = toku_logcursor_destroy(&lc);
104     assert(r == 0 && lc == NULL);
105 
106     // verify the log backwards
107     r = toku_logcursor_create(&lc, TOKU_TEST_FILENAME);
108     assert(r == 0 && lc != NULL);
109 
110     r = toku_logcursor_prev(lc, &le);
111     assert(r == 0 && le->cmd == LT_comment);
112     assert(le->u.comment.comment.len == 5 && memcmp(le->u.comment.comment.data, "world", 5) == 0);
113     t = le->u.comment.timestamp;
114 
115     r = toku_logcursor_prev(lc, &le);
116     assert(r == 0 && le->cmd == LT_comment);
117     assert(le->u.comment.comment.len == 5 && memcmp(le->u.comment.comment.data, "hello", 5) == 0);
118     if (verbose)
119         printf("%" PRIu64 "\n", t - le->u.comment.timestamp);
120     assert(t - le->u.comment.timestamp >= 10*1000000);
121 
122     r = toku_logcursor_prev(lc, &le);
123     assert(r != 0);
124 
125     r = toku_logcursor_destroy(&lc);
126     assert(r == 0 && lc == NULL);
127 
128     toku_os_recursive_delete(TOKU_TEST_FILENAME);
129 
130     return 0;
131 }
132