2 This file is part of systemd.
4 Copyright 2012 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "sd-journal.h"
25 #include "alloc-util.h"
26 #include "journal-file.h"
27 #include "journal-internal.h"
30 #include "parse-util.h"
36 static void verify_contents(sd_journal
*j
, unsigned skip
) {
42 SD_JOURNAL_FOREACH(j
) {
48 assert_se(sd_journal_get_cursor(j
, &k
) >= 0);
49 printf("cursor: %s\n", k
);
52 assert_se(sd_journal_get_data(j
, "MAGIC", &d
, &l
) >= 0);
53 printf("\t%.*s\n", (int) l
, (const char*) d
);
55 assert_se(sd_journal_get_data(j
, "NUMBER", &d
, &l
) >= 0);
56 assert_se(k
= strndup(d
, l
));
60 assert_se(safe_atou(k
+ 7, &u
) >= 0);
67 assert_se(sd_journal_get_cursor(j
, &c
) >= 0);
68 assert_se(sd_journal_test_cursor(j
, c
) > 0);
73 assert_se(i
== N_ENTRIES
);
76 int main(int argc
, char *argv
[]) {
77 JournalFile
*one
, *two
, *three
;
78 char t
[] = "/tmp/journal-stream-XXXXXX";
80 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
84 dual_timestamp previous_ts
= DUAL_TIMESTAMP_NULL
;
86 /* journal_file_open requires a valid machine id */
87 if (access("/etc/machine-id", F_OK
) != 0)
88 return EXIT_TEST_SKIP
;
90 log_set_max_level(LOG_DEBUG
);
92 assert_se(mkdtemp(t
));
93 assert_se(chdir(t
) >= 0);
95 assert_se(journal_file_open(-1, "one.journal", O_RDWR
|O_CREAT
, 0666, true, false, NULL
, NULL
, NULL
, NULL
, &one
) == 0);
96 assert_se(journal_file_open(-1, "two.journal", O_RDWR
|O_CREAT
, 0666, true, false, NULL
, NULL
, NULL
, NULL
, &two
) == 0);
97 assert_se(journal_file_open(-1, "three.journal", O_RDWR
|O_CREAT
, 0666, true, false, NULL
, NULL
, NULL
, NULL
, &three
) == 0);
99 for (i
= 0; i
< N_ENTRIES
; i
++) {
102 struct iovec iovec
[2];
104 dual_timestamp_get(&ts
);
106 if (ts
.monotonic
<= previous_ts
.monotonic
)
107 ts
.monotonic
= previous_ts
.monotonic
+ 1;
109 if (ts
.realtime
<= previous_ts
.realtime
)
110 ts
.realtime
= previous_ts
.realtime
+ 1;
114 assert_se(asprintf(&p
, "NUMBER=%u", i
) >= 0);
115 iovec
[0].iov_base
= p
;
116 iovec
[0].iov_len
= strlen(p
);
118 assert_se(asprintf(&q
, "MAGIC=%s", i
% 5 == 0 ? "quux" : "waldo") >= 0);
120 iovec
[1].iov_base
= q
;
121 iovec
[1].iov_len
= strlen(q
);
124 assert_se(journal_file_append_entry(three
, &ts
, iovec
, 2, NULL
, NULL
, NULL
) == 0);
127 assert_se(journal_file_append_entry(two
, &ts
, iovec
, 2, NULL
, NULL
, NULL
) == 0);
129 assert_se(journal_file_append_entry(one
, &ts
, iovec
, 2, NULL
, NULL
, NULL
) == 0);
136 (void) journal_file_close(one
);
137 (void) journal_file_close(two
);
138 (void) journal_file_close(three
);
140 assert_se(sd_journal_open_directory(&j
, t
, 0) >= 0);
142 assert_se(sd_journal_add_match(j
, "MAGIC=quux", 0) >= 0);
143 SD_JOURNAL_FOREACH_BACKWARDS(j
) {
144 _cleanup_free_
char *c
;
146 assert_se(sd_journal_get_data(j
, "NUMBER", &data
, &l
) >= 0);
147 printf("\t%.*s\n", (int) l
, (const char*) data
);
149 assert_se(sd_journal_get_cursor(j
, &c
) >= 0);
150 assert_se(sd_journal_test_cursor(j
, c
) > 0);
153 SD_JOURNAL_FOREACH(j
) {
154 _cleanup_free_
char *c
;
156 assert_se(sd_journal_get_data(j
, "NUMBER", &data
, &l
) >= 0);
157 printf("\t%.*s\n", (int) l
, (const char*) data
);
159 assert_se(sd_journal_get_cursor(j
, &c
) >= 0);
160 assert_se(sd_journal_test_cursor(j
, c
) > 0);
163 sd_journal_flush_matches(j
);
165 verify_contents(j
, 1);
167 printf("NEXT TEST\n");
168 assert_se(sd_journal_add_match(j
, "MAGIC=quux", 0) >= 0);
170 assert_se(z
= journal_make_match_string(j
));
171 printf("resulting match expression is: %s\n", z
);
174 verify_contents(j
, 5);
176 printf("NEXT TEST\n");
177 sd_journal_flush_matches(j
);
178 assert_se(sd_journal_add_match(j
, "MAGIC=waldo", 0) >= 0);
179 assert_se(sd_journal_add_match(j
, "NUMBER=10", 0) >= 0);
180 assert_se(sd_journal_add_match(j
, "NUMBER=11", 0) >= 0);
181 assert_se(sd_journal_add_match(j
, "NUMBER=12", 0) >= 0);
183 assert_se(z
= journal_make_match_string(j
));
184 printf("resulting match expression is: %s\n", z
);
187 verify_contents(j
, 0);
189 assert_se(sd_journal_query_unique(j
, "NUMBER") >= 0);
190 SD_JOURNAL_FOREACH_UNIQUE(j
, data
, l
)
191 printf("%.*s\n", (int) l
, (const char*) data
);
193 assert_se(rm_rf(t
, REMOVE_ROOT
|REMOVE_PHYSICAL
) >= 0);