1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Marius Vollmer
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <systemd/sd-journal.h>
27 #include "journal-file.h"
28 #include "journal-internal.h"
32 /* This program tests skipping around in a multi-file journal.
35 static void log_assert_errno(const char *text, int eno, const char *file, int line, const char *func) {
36 log_meta(LOG_CRIT, file, line, func,
37 "'%s' failed at %s:%u (%s): %s.",
38 text, file, line, func, strerror(eno));
42 #define assert_ret(expr) \
45 if (_unlikely_(_r_ < 0)) \
46 log_assert_errno(#expr, -_r_, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
49 static JournalFile *test_open (const char *name)
52 assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &f));
56 static void test_close (JournalFile *f)
58 journal_file_close (f);
61 static void test_append_number(JournalFile *f, int n)
65 struct iovec iovec[1];
67 dual_timestamp_get(&ts);
69 assert_se(asprintf(&p, "NUMBER=%d", n) >= 0);
70 iovec[0].iov_base = p;
71 iovec[0].iov_len = strlen(p);
72 assert_ret(journal_file_append_entry(f, &ts, iovec, 1, NULL, NULL, NULL));
76 static void test_check_number (sd_journal *j, int n)
83 assert_ret(sd_journal_get_data(j, "NUMBER", &d, &l));
84 assert_se(k = strndup(d, l));
87 assert_se(safe_atoi(k + 7, &x) >= 0);
91 static void test_check_numbers_down (sd_journal *j, int count)
93 for (int i = 1; i <= count; i++) {
95 test_check_number(j, i);
96 assert_ret(r = sd_journal_next(j));
105 static void test_check_numbers_up (sd_journal *j, int count)
107 for (int i = count; i >= 1; i--) {
109 test_check_number(j, i);
110 assert_ret(r = sd_journal_previous(j));
119 static void setup_sequential(void) {
120 JournalFile *one, *two;
121 one = test_open("one.journal");
122 two = test_open("two.journal");
123 test_append_number(one, 1);
124 test_append_number(one, 2);
125 test_append_number(two, 3);
126 test_append_number(two, 4);
131 static void setup_interleaved(void) {
132 JournalFile *one, *two;
133 one = test_open("one.journal");
134 two = test_open("two.journal");
135 test_append_number(one, 1);
136 test_append_number(two, 2);
137 test_append_number(one, 3);
138 test_append_number(two, 4);
143 static void test_skip(void (*setup)(void))
145 char t[] = "/tmp/journal-skip-XXXXXX";
149 log_set_max_level(LOG_DEBUG);
151 assert_se(mkdtemp(t));
152 assert_se(chdir(t) >= 0);
156 /* Seek to head, iterate down.
158 assert_ret(sd_journal_open_directory(&j, t, 0));
159 assert_ret(sd_journal_seek_head(j));
160 assert_ret(sd_journal_next(j));
161 test_check_numbers_down(j, 4);
164 /* Seek to tail, iterate up.
166 assert_ret(sd_journal_open_directory(&j, t, 0));
167 assert_ret(sd_journal_seek_tail(j));
168 assert_ret(sd_journal_previous(j));
169 test_check_numbers_up(j, 4);
172 /* Seek to tail, skip to head, iterate down.
174 assert_ret(sd_journal_open_directory(&j, t, 0));
175 assert_ret(sd_journal_seek_tail(j));
176 assert_ret(r = sd_journal_previous_skip(j, 4));
178 test_check_numbers_down(j, 4);
181 /* Seek to head, skip to tail, iterate up.
183 assert_ret(sd_journal_open_directory(&j, t, 0));
184 assert_ret(sd_journal_seek_head(j));
185 assert_ret(r = sd_journal_next_skip(j, 4));
187 test_check_numbers_up(j, 4);
190 assert_ret(rm_rf_dangerous(t, false, true, false));
193 int main(int argc, char *argv[]) {
194 test_skip(setup_sequential);
195 test_skip(setup_interleaved);