]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/osd/TestPGLog.cc
import ceph nautilus 14.2.2
[ceph.git] / ceph / src / test / osd / TestPGLog.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
7 *
8 * Author: Loic Dachary <loic@dachary.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library Public License for more details.
19 *
20 */
21
22#include <stdio.h>
23#include <signal.h>
24#include "gtest/gtest.h"
25#include "osd/PGLog.h"
26#include "osd/OSDMap.h"
27#include "include/coredumpctl.h"
c07f9fc5 28#include "../objectstore/store_test_fixture.h"
7c673cae 29
7c673cae 30
c07f9fc5 31struct PGLogTestBase {
7c673cae
FG
32 static hobject_t mk_obj(unsigned id) {
33 hobject_t hoid;
34 stringstream ss;
35 ss << "obj_" << id;
36 hoid.oid = ss.str();
37 hoid.set_hash(id);
c07f9fc5 38 hoid.pool = 1;
7c673cae
FG
39 return hoid;
40 }
41 static eversion_t mk_evt(unsigned ep, unsigned v) {
42 return eversion_t(ep, v);
43 }
44 static pg_log_entry_t mk_ple_mod(
c07f9fc5 45 const hobject_t &hoid, eversion_t v, eversion_t pv, osd_reqid_t reqid) {
7c673cae
FG
46 pg_log_entry_t e;
47 e.mark_unrollbackable();
48 e.op = pg_log_entry_t::MODIFY;
49 e.soid = hoid;
50 e.version = v;
51 e.prior_version = pv;
c07f9fc5 52 e.reqid = reqid;
7c673cae
FG
53 return e;
54 }
55 static pg_log_entry_t mk_ple_dt(
c07f9fc5 56 const hobject_t &hoid, eversion_t v, eversion_t pv, osd_reqid_t reqid) {
7c673cae
FG
57 pg_log_entry_t e;
58 e.mark_unrollbackable();
59 e.op = pg_log_entry_t::DELETE;
60 e.soid = hoid;
61 e.version = v;
62 e.prior_version = pv;
c07f9fc5 63 e.reqid = reqid;
7c673cae
FG
64 return e;
65 }
c07f9fc5 66 static pg_log_entry_t mk_ple_ldt(
7c673cae
FG
67 const hobject_t &hoid, eversion_t v, eversion_t pv) {
68 pg_log_entry_t e;
c07f9fc5
FG
69 e.mark_unrollbackable();
70 e.op = pg_log_entry_t::LOST_DELETE;
71 e.soid = hoid;
72 e.version = v;
73 e.prior_version = pv;
74 return e;
75 }
76 static pg_log_entry_t mk_ple_mod_rb(
77 const hobject_t &hoid, eversion_t v, eversion_t pv, osd_reqid_t reqid) {
78 pg_log_entry_t e;
7c673cae
FG
79 e.op = pg_log_entry_t::MODIFY;
80 e.soid = hoid;
81 e.version = v;
82 e.prior_version = pv;
c07f9fc5 83 e.reqid = reqid;
7c673cae
FG
84 return e;
85 }
86 static pg_log_entry_t mk_ple_dt_rb(
c07f9fc5 87 const hobject_t &hoid, eversion_t v, eversion_t pv, osd_reqid_t reqid) {
7c673cae
FG
88 pg_log_entry_t e;
89 e.op = pg_log_entry_t::DELETE;
90 e.soid = hoid;
91 e.version = v;
92 e.prior_version = pv;
c07f9fc5 93 e.reqid = reqid;
7c673cae
FG
94 return e;
95 }
d2e6a577
FG
96 static pg_log_entry_t mk_ple_err(
97 const hobject_t &hoid, eversion_t v, osd_reqid_t reqid) {
98 pg_log_entry_t e;
99 e.op = pg_log_entry_t::ERROR;
100 e.soid = hoid;
101 e.version = v;
102 e.prior_version = eversion_t(0, 0);
103 e.reqid = reqid;
104 return e;
105 }
c07f9fc5
FG
106 static pg_log_entry_t mk_ple_mod(
107 const hobject_t &hoid, eversion_t v, eversion_t pv) {
108 return mk_ple_mod(hoid, v, pv, osd_reqid_t());
109 }
110 static pg_log_entry_t mk_ple_dt(
111 const hobject_t &hoid, eversion_t v, eversion_t pv) {
112 return mk_ple_dt(hoid, v, pv, osd_reqid_t());
113 }
114 static pg_log_entry_t mk_ple_mod_rb(
115 const hobject_t &hoid, eversion_t v, eversion_t pv) {
116 return mk_ple_mod_rb(hoid, v, pv, osd_reqid_t());
117 }
118 static pg_log_entry_t mk_ple_dt_rb(
119 const hobject_t &hoid, eversion_t v, eversion_t pv) {
120 return mk_ple_dt_rb(hoid, v, pv, osd_reqid_t());
121 }
d2e6a577
FG
122 static pg_log_entry_t mk_ple_err(
123 const hobject_t &hoid, eversion_t v) {
124 return mk_ple_err(hoid, v, osd_reqid_t());
125 }
c07f9fc5
FG
126}; // PGLogTestBase
127
128
129class PGLogTest : virtual public ::testing::Test, protected PGLog, public PGLogTestBase {
130public:
131 PGLogTest() : PGLog(g_ceph_context) {}
132 void SetUp() override {
133 missing.may_include_deletes = true;
134 }
135
136#include "common/ceph_context.h"
137#include "common/config.h"
138
139 void TearDown() override {
140 clear();
141 }
142
7c673cae
FG
143
144 struct TestCase {
145 list<pg_log_entry_t> base;
146 list<pg_log_entry_t> auth;
147 list<pg_log_entry_t> div;
148
149 pg_missing_t init;
150 pg_missing_t final;
151
152 set<hobject_t> toremove;
153 list<pg_log_entry_t> torollback;
c07f9fc5 154 bool deletes_during_peering;
7c673cae
FG
155
156 private:
157 IndexedLog fullauth;
158 IndexedLog fulldiv;
159 pg_info_t authinfo;
160 pg_info_t divinfo;
161 public:
c07f9fc5 162 TestCase() : deletes_during_peering(false) {}
7c673cae 163 void setup() {
c07f9fc5
FG
164 init.may_include_deletes = !deletes_during_peering;
165 final.may_include_deletes = !deletes_during_peering;
7c673cae
FG
166 fullauth.log.insert(fullauth.log.end(), base.begin(), base.end());
167 fullauth.log.insert(fullauth.log.end(), auth.begin(), auth.end());
168 fulldiv.log.insert(fulldiv.log.end(), base.begin(), base.end());
169 fulldiv.log.insert(fulldiv.log.end(), div.begin(), div.end());
170
171 fullauth.head = authinfo.last_update = fullauth.log.rbegin()->version;
172 authinfo.last_complete = fullauth.log.rbegin()->version;
173 authinfo.log_tail = fullauth.log.begin()->version;
174 authinfo.log_tail.version--;
175 fullauth.tail = authinfo.log_tail;
176 authinfo.last_backfill = hobject_t::get_max();
177
178 fulldiv.head = divinfo.last_update = fulldiv.log.rbegin()->version;
179 divinfo.last_complete = eversion_t();
180 divinfo.log_tail = fulldiv.log.begin()->version;
181 divinfo.log_tail.version--;
182 fulldiv.tail = divinfo.log_tail;
183 divinfo.last_backfill = hobject_t::get_max();
184
185 if (init.get_items().empty()) {
186 divinfo.last_complete = divinfo.last_update;
187 } else {
188 eversion_t fmissing = init.get_items().at(init.get_rmissing().begin()->second).need;
189 for (list<pg_log_entry_t>::const_iterator i = fulldiv.log.begin();
190 i != fulldiv.log.end();
191 ++i) {
192 if (i->version < fmissing)
193 divinfo.last_complete = i->version;
194 else
195 break;
196 }
197 }
198
199 fullauth.index();
200 fulldiv.index();
201 }
202 void set_div_bounds(eversion_t head, eversion_t tail) {
203 fulldiv.tail = divinfo.log_tail = tail;
204 fulldiv.head = divinfo.last_update = head;
205 }
206 void set_auth_bounds(eversion_t head, eversion_t tail) {
207 fullauth.tail = authinfo.log_tail = tail;
208 fullauth.head = authinfo.last_update = head;
209 }
210 const IndexedLog &get_fullauth() const { return fullauth; }
211 const IndexedLog &get_fulldiv() const { return fulldiv; }
212 const pg_info_t &get_authinfo() const { return authinfo; }
213 const pg_info_t &get_divinfo() const { return divinfo; }
c07f9fc5 214 }; // struct TestCase
7c673cae
FG
215
216 struct LogHandler : public PGLog::LogEntryHandler {
217 set<hobject_t> removed;
218 list<pg_log_entry_t> rolledback;
c07f9fc5 219
7c673cae
FG
220 void rollback(
221 const pg_log_entry_t &entry) override {
222 rolledback.push_back(entry);
223 }
224 void rollforward(
225 const pg_log_entry_t &entry) override {}
226 void remove(
227 const hobject_t &hoid) override {
228 removed.insert(hoid);
229 }
230 void try_stash(const hobject_t &, version_t) override {
231 // lost/unfound cases are not tested yet
232 }
233 void trim(
234 const pg_log_entry_t &entry) override {}
235 };
236
237 template <typename missing_t>
238 void verify_missing(
239 const TestCase &tcase,
240 const missing_t &missing) {
241 ASSERT_EQ(tcase.final.get_items().size(), missing.get_items().size());
242 for (auto i = missing.get_items().begin();
243 i != missing.get_items().end();
244 ++i) {
245 EXPECT_TRUE(tcase.final.get_items().count(i->first));
246 EXPECT_EQ(tcase.final.get_items().find(i->first)->second.need, i->second.need);
247 EXPECT_EQ(tcase.final.get_items().find(i->first)->second.have, i->second.have);
248 }
249 bool correct = missing.debug_verify_from_init(tcase.init, &(std::cout));
250 ASSERT_TRUE(correct);
251 }
252
253 void verify_sideeffects(
254 const TestCase &tcase,
255 const LogHandler &handler) {
256 ASSERT_EQ(tcase.toremove.size(), handler.removed.size());
257 ASSERT_EQ(tcase.torollback.size(), handler.rolledback.size());
258
259 {
260 list<pg_log_entry_t>::const_iterator titer = tcase.torollback.begin();
261 list<pg_log_entry_t>::const_iterator hiter = handler.rolledback.begin();
262 for (; titer != tcase.torollback.end(); ++titer, ++hiter) {
263 EXPECT_EQ(titer->version, hiter->version);
264 }
265 }
266
267 {
268 set<hobject_t>::const_iterator titer = tcase.toremove.begin();
269 set<hobject_t>::const_iterator hiter = handler.removed.begin();
270 for (; titer != tcase.toremove.end(); ++titer, ++hiter) {
271 EXPECT_EQ(*titer, *hiter);
272 }
273 }
274 }
275
276 void test_merge_log(const TestCase &tcase) {
277 clear();
278 log = tcase.get_fulldiv();
279 pg_info_t info = tcase.get_divinfo();
280
281 missing = tcase.init;
282 missing.flush();
283
284 IndexedLog olog;
285 olog = tcase.get_fullauth();
286 pg_info_t oinfo = tcase.get_authinfo();
287
288 LogHandler h;
289 bool dirty_info = false;
290 bool dirty_big_info = false;
291 merge_log(
292 oinfo, olog, pg_shard_t(1, shard_id_t(0)), info,
293 &h, dirty_info, dirty_big_info);
294
295 ASSERT_EQ(info.last_update, oinfo.last_update);
296 verify_missing(tcase, missing);
297 verify_sideeffects(tcase, h);
c07f9fc5
FG
298 }
299
7c673cae
FG
300 void test_proc_replica_log(const TestCase &tcase) {
301 clear();
302 log = tcase.get_fullauth();
303 pg_info_t info = tcase.get_authinfo();
304
305 pg_missing_t omissing = tcase.init;
306
307 IndexedLog olog;
308 olog = tcase.get_fulldiv();
309 pg_info_t oinfo = tcase.get_divinfo();
310
311 proc_replica_log(
c07f9fc5 312 oinfo, olog, omissing, pg_shard_t(1, shard_id_t(0)));
7c673cae 313
11fdf7f2 314 ceph_assert(oinfo.last_update >= log.tail);
7c673cae
FG
315
316 if (!tcase.base.empty()) {
317 ASSERT_EQ(tcase.base.rbegin()->version, oinfo.last_update);
318 }
319
320 for (list<pg_log_entry_t>::const_iterator i = tcase.auth.begin();
321 i != tcase.auth.end();
322 ++i) {
c07f9fc5
FG
323 if (i->version > oinfo.last_update) {
324 if (i->is_delete() && tcase.deletes_during_peering) {
325 omissing.rm(i->soid, i->version);
326 } else {
327 omissing.add_next_event(*i);
328 }
329 }
7c673cae
FG
330 }
331 verify_missing(tcase, omissing);
c07f9fc5
FG
332 } // test_proc_replica_log
333
7c673cae
FG
334 void run_test_case(const TestCase &tcase) {
335 test_merge_log(tcase);
336 test_proc_replica_log(tcase);
337 }
c07f9fc5 338}; // class PGLogTest
7c673cae
FG
339
340struct TestHandler : public PGLog::LogEntryHandler {
341 list<hobject_t> &removed;
342 explicit TestHandler(list<hobject_t> &removed) : removed(removed) {}
343
344 void rollback(
345 const pg_log_entry_t &entry) override {}
346 void rollforward(
347 const pg_log_entry_t &entry) override {}
348 void remove(
349 const hobject_t &hoid) override {
350 removed.push_back(hoid);
351 }
352 void cant_rollback(const pg_log_entry_t &entry) {}
353 void try_stash(const hobject_t &, version_t) override {
354 // lost/unfound cases are not tested yet
355 }
356 void trim(
357 const pg_log_entry_t &entry) override {}
358};
359
360TEST_F(PGLogTest, rewind_divergent_log) {
361 /* +----------------+
362 | log |
363 +--------+-------+
364 | |object |
365 |version | hash |
366 | | |
367 tail > (1,1) | x5 |
368 | | |
369 | | |
370 | (1,4) | x9 < newhead
371 | MODIFY | |
372 | | |
373 head > (1,5) | x9 |
374 | DELETE | |
375 | | |
376 +--------+-------+
377
378 */
379 {
380 clear();
381
382 pg_info_t info;
383 list<hobject_t> remove_snap;
384 bool dirty_info = false;
385 bool dirty_big_info = false;
386
387 hobject_t divergent_object;
388 eversion_t divergent_version;
389 eversion_t newhead;
390
391 hobject_t divergent;
392 divergent.set_hash(0x9);
393
394 {
395 pg_log_entry_t e;
396 e.mark_unrollbackable();
397
398 e.version = eversion_t(1, 1);
399 e.soid.set_hash(0x5);
400 log.tail = e.version;
401 log.log.push_back(e);
402 e.version = newhead = eversion_t(1, 4);
403 e.soid = divergent;
404 e.op = pg_log_entry_t::MODIFY;
405 log.log.push_back(e);
406 e.version = divergent_version = eversion_t(1, 5);
407 e.prior_version = eversion_t(1, 4);
408 e.soid = divergent;
409 divergent_object = e.soid;
410 e.op = pg_log_entry_t::DELETE;
411 log.log.push_back(e);
412 log.head = e.version;
413 log.index();
414
415 info.last_update = log.head;
416 info.last_complete = log.head;
417 }
418
419 EXPECT_FALSE(missing.have_missing());
420 EXPECT_EQ(3U, log.log.size());
421 EXPECT_TRUE(remove_snap.empty());
422 EXPECT_EQ(log.head, info.last_update);
423 EXPECT_EQ(log.head, info.last_complete);
424 EXPECT_FALSE(is_dirty());
425 EXPECT_FALSE(dirty_info);
426 EXPECT_FALSE(dirty_big_info);
427
428 TestHandler h(remove_snap);
429 rewind_divergent_log(newhead, info, &h,
430 dirty_info, dirty_big_info);
431
432 EXPECT_TRUE(log.objects.count(divergent));
433 EXPECT_TRUE(missing.is_missing(divergent_object));
434 EXPECT_EQ(1U, log.objects.count(divergent_object));
435 EXPECT_EQ(2U, log.log.size());
436 EXPECT_TRUE(remove_snap.empty());
437 EXPECT_EQ(newhead, info.last_update);
438 EXPECT_EQ(newhead, info.last_complete);
439 EXPECT_TRUE(is_dirty());
440 EXPECT_TRUE(dirty_info);
441 EXPECT_TRUE(dirty_big_info);
442 }
443
444 /* +----------------+
445 | log |
446 +--------+-------+
447 | |object |
448 |version | hash |
449 | | |
450 tail > (1,1) | NULL |
451 | | |
452 | (1,4) | NULL < newhead
453 | | |
454 head > (1,5) | x9 |
455 | | |
456 +--------+-------+
457
458 */
459 {
460 clear();
461
462 pg_info_t info;
463 list<hobject_t> remove_snap;
464 bool dirty_info = false;
465 bool dirty_big_info = false;
466
467 hobject_t divergent_object;
468 eversion_t divergent_version;
469 eversion_t prior_version;
470 eversion_t newhead;
471 {
472 pg_log_entry_t e;
473 e.mark_unrollbackable();
474
475 info.log_tail = log.tail = eversion_t(1, 1);
476 newhead = eversion_t(1, 3);
477 e.version = divergent_version = eversion_t(1, 5);
478 e.soid.set_hash(0x9);
479 divergent_object = e.soid;
480 e.op = pg_log_entry_t::DELETE;
481 e.prior_version = prior_version = eversion_t(0, 2);
482 log.log.push_back(e);
483 log.head = e.version;
484 }
485
486 EXPECT_FALSE(missing.have_missing());
487 EXPECT_EQ(1U, log.log.size());
488 EXPECT_TRUE(remove_snap.empty());
489 EXPECT_FALSE(is_dirty());
490 EXPECT_FALSE(dirty_info);
491 EXPECT_FALSE(dirty_big_info);
492
493 TestHandler h(remove_snap);
494 rewind_divergent_log(newhead, info, &h,
495 dirty_info, dirty_big_info);
496
497 EXPECT_TRUE(missing.is_missing(divergent_object));
498 EXPECT_EQ(0U, log.objects.count(divergent_object));
499 EXPECT_TRUE(log.empty());
500 EXPECT_TRUE(remove_snap.empty());
501 EXPECT_TRUE(is_dirty());
502 EXPECT_TRUE(dirty_info);
503 EXPECT_TRUE(dirty_big_info);
504 }
505
506 // Test for 13965
507 {
508 clear();
509
510 list<hobject_t> remove_snap;
511 pg_info_t info;
512 info.log_tail = log.tail = eversion_t(1, 5);
513 info.last_update = eversion_t(1, 6);
514 bool dirty_info = false;
515 bool dirty_big_info = false;
516
517 {
518 pg_log_entry_t e;
519 e.mark_unrollbackable();
520 e.version = eversion_t(1, 5);
521 e.soid.set_hash(0x9);
522 add(e);
523 }
524 {
525 pg_log_entry_t e;
526 e.mark_unrollbackable();
527 e.version = eversion_t(1, 6);
528 e.soid.set_hash(0x10);
529 add(e);
530 }
531 TestHandler h(remove_snap);
532 roll_forward_to(eversion_t(1, 6), &h);
533 rewind_divergent_log(eversion_t(1, 5), info, &h,
534 dirty_info, dirty_big_info);
535 pg_log_t log;
536 reset_backfill_claim_log(log, &h);
537 }
538}
539
540TEST_F(PGLogTest, merge_old_entry) {
541 // entries > last_backfill are silently ignored
542 {
543 clear();
544
545 ObjectStore::Transaction t;
546 pg_log_entry_t oe;
547 oe.mark_unrollbackable();
548 pg_info_t info;
549 list<hobject_t> remove_snap;
550
551 info.last_backfill = hobject_t();
552 info.last_backfill.set_hash(100);
553 oe.soid.set_hash(2);
554 ASSERT_GT(oe.soid, info.last_backfill);
555
556 EXPECT_FALSE(is_dirty());
557 EXPECT_TRUE(remove_snap.empty());
558 EXPECT_TRUE(t.empty());
559 EXPECT_FALSE(missing.have_missing());
560 EXPECT_TRUE(log.empty());
561
562 TestHandler h(remove_snap);
563 merge_old_entry(t, oe, info, &h);
564
565 EXPECT_FALSE(is_dirty());
566 EXPECT_TRUE(remove_snap.empty());
567 EXPECT_TRUE(t.empty());
568 EXPECT_FALSE(missing.have_missing());
569 EXPECT_TRUE(log.empty());
570 }
571
572 // the new entry (from the logs) has a version that is higher than
573 // the old entry (from the log entry given in argument) : do
574 // nothing and return false
575 {
576 clear();
577
578 ObjectStore::Transaction t;
579 pg_info_t info;
580 list<hobject_t> remove_snap;
581
582 pg_log_entry_t ne;
583 ne.mark_unrollbackable();
584 ne.version = eversion_t(2,1);
585 log.add(ne);
586
587 EXPECT_FALSE(is_dirty());
588 EXPECT_TRUE(remove_snap.empty());
589 EXPECT_TRUE(t.empty());
590 EXPECT_FALSE(missing.have_missing());
591 EXPECT_EQ(1U, log.log.size());
592 EXPECT_EQ(ne.version, log.log.front().version);
593
594 // the newer entry ( from the logs ) can be DELETE
595 {
596 log.log.front().op = pg_log_entry_t::DELETE;
597 pg_log_entry_t oe;
598 oe.mark_unrollbackable();
599 oe.version = eversion_t(1,1);
600
601 TestHandler h(remove_snap);
602 merge_old_entry(t, oe, info, &h);
603 }
604
605 // if the newer entry is not DELETE, the object must be in missing
606 {
607 pg_log_entry_t &ne = log.log.front();
608 ne.op = pg_log_entry_t::MODIFY;
609 missing.add_next_event(ne);
610 pg_log_entry_t oe;
611 oe.mark_unrollbackable();
612 oe.version = eversion_t(1,1);
613
614 TestHandler h(remove_snap);
615 merge_old_entry(t, oe, info, &h);
616
617 missing.rm(ne.soid, ne.version);
618 }
619
620 missing.flush();
621 EXPECT_FALSE(is_dirty());
622 EXPECT_FALSE(remove_snap.empty());
623 EXPECT_TRUE(t.empty());
624 EXPECT_FALSE(missing.have_missing());
625 EXPECT_EQ(1U, log.log.size());
626 EXPECT_EQ(ne.version, log.log.front().version);
627
628 }
629
630 // the new entry (from the logs) has a version that is lower than
631 // the old entry (from the log entry given in argument) and
632 // old and new are delete : do nothing and return false
633 {
634 clear();
635
636 ObjectStore::Transaction t;
637 pg_log_entry_t oe;
638 oe.mark_unrollbackable();
639 pg_info_t info;
640 list<hobject_t> remove_snap;
641
642 pg_log_entry_t ne;
643 ne.mark_unrollbackable();
644 ne.version = eversion_t(1,1);
645 ne.op = pg_log_entry_t::DELETE;
646 log.add(ne);
647
648 oe.version = eversion_t(2,1);
649 oe.op = pg_log_entry_t::DELETE;
650
651 EXPECT_FALSE(is_dirty());
652 EXPECT_TRUE(remove_snap.empty());
653 EXPECT_TRUE(t.empty());
654 EXPECT_FALSE(missing.have_missing());
655 EXPECT_EQ(1U, log.log.size());
656
657 TestHandler h(remove_snap);
658 merge_old_entry(t, oe, info, &h);
659
660 EXPECT_FALSE(is_dirty());
661 EXPECT_TRUE(remove_snap.empty());
662 EXPECT_TRUE(t.empty());
663 EXPECT_FALSE(missing.have_missing());
664 EXPECT_EQ(1U, log.log.size());
665 }
666
667 // the new entry (from the logs) has a version that is lower than
668 // the old entry (from the log entry given in argument) and
669 // old is update and new is DELETE :
670 // if the object is in missing, it is removed
671 {
672 clear();
673
674 ObjectStore::Transaction t;
675 pg_log_entry_t oe;
676 oe.mark_unrollbackable();
677 pg_info_t info;
678 list<hobject_t> remove_snap;
679
680 pg_log_entry_t ne;
681 ne.mark_unrollbackable();
682 ne.version = eversion_t(1,1);
683 ne.op = pg_log_entry_t::DELETE;
684 log.add(ne);
685
686 oe.version = eversion_t(2,1);
687 oe.op = pg_log_entry_t::MODIFY;
688 missing.add_next_event(oe);
689
690 missing.flush();
691 EXPECT_FALSE(is_dirty());
692 EXPECT_TRUE(remove_snap.empty());
693 EXPECT_TRUE(t.empty());
694 EXPECT_TRUE(missing.is_missing(oe.soid));
695 EXPECT_EQ(1U, log.log.size());
696
697 TestHandler h(remove_snap);
698 merge_old_entry(t, oe, info, &h);
699
700 missing.flush();
701 EXPECT_FALSE(is_dirty());
702 EXPECT_TRUE(remove_snap.size() > 0);
703 EXPECT_TRUE(t.empty());
704 EXPECT_FALSE(missing.have_missing());
705 EXPECT_EQ(1U, log.log.size());
706 }
707
708 // there is no new entry (from the logs) and
709 // the old entry (from the log entry given in argument) is not a CLONE and
710 // the old entry prior_version is greater than the tail of the log :
711 // do nothing and return false
712 {
713 clear();
714
715 ObjectStore::Transaction t;
716 pg_log_entry_t oe;
717 oe.mark_unrollbackable();
718 pg_info_t info;
719 list<hobject_t> remove_snap;
720
721 info.log_tail = eversion_t(1,1);
722 oe.op = pg_log_entry_t::MODIFY;
723 oe.prior_version = eversion_t(2,1);
724 missing_add(oe.soid, oe.prior_version, eversion_t());
725
726 missing.flush();
727 EXPECT_FALSE(is_dirty());
728 EXPECT_TRUE(remove_snap.empty());
729 EXPECT_TRUE(t.empty());
730 EXPECT_TRUE(log.empty());
731
732 TestHandler h(remove_snap);
733 merge_old_entry(t, oe, info, &h);
734
735 missing.flush();
736 EXPECT_FALSE(is_dirty());
737 EXPECT_TRUE(remove_snap.empty());
738 EXPECT_TRUE(t.empty());
739 EXPECT_TRUE(log.empty());
740 }
741
742 // there is no new entry (from the logs) and
743 // the old entry (from the log entry given in argument) is not a CLONE and
744 // the old entry (from the log entry given in argument) is not a DELETE and
745 // the old entry prior_version is lower than the tail of the log :
c07f9fc5 746 // add the old object to the remove_snap list and
7c673cae
FG
747 // add the old object to divergent priors and
748 // add or update the prior_version of the object to missing and
749 // return false
750 {
751 clear();
752
753 ObjectStore::Transaction t;
754 pg_log_entry_t oe;
755 oe.mark_unrollbackable();
756 pg_info_t info;
757 list<hobject_t> remove_snap;
758
759 info.log_tail = eversion_t(2,1);
760 oe.soid.set_hash(1);
761 oe.op = pg_log_entry_t::MODIFY;
762 oe.prior_version = eversion_t(1,1);
763
764 EXPECT_FALSE(is_dirty());
765 EXPECT_TRUE(remove_snap.empty());
766 EXPECT_TRUE(t.empty());
767 EXPECT_FALSE(missing.have_missing());
768 EXPECT_TRUE(log.empty());
769
770 TestHandler h(remove_snap);
771 merge_old_entry(t, oe, info, &h);
772
773 EXPECT_TRUE(is_dirty());
774 EXPECT_EQ(oe.soid, remove_snap.front());
775 EXPECT_TRUE(t.empty());
776 EXPECT_TRUE(missing.is_missing(oe.soid));
777 EXPECT_TRUE(log.empty());
778 }
779
780 // there is no new entry (from the logs) and
781 // the old entry (from the log entry given in argument) is not a CLONE and
782 // the old entry (from the log entry given in argument) is a DELETE and
783 // the old entry prior_version is lower than the tail of the log :
784 // add the old object to divergent priors and
785 // add or update the prior_version of the object to missing and
786 // return false
787 {
788 clear();
789
790 ObjectStore::Transaction t;
791 pg_log_entry_t oe;
792 oe.mark_unrollbackable();
793 pg_info_t info;
794 list<hobject_t> remove_snap;
795
796 info.log_tail = eversion_t(2,1);
797 oe.soid.set_hash(1);
798 oe.op = pg_log_entry_t::DELETE;
799 oe.prior_version = eversion_t(1,1);
800
801 EXPECT_FALSE(is_dirty());
802 EXPECT_TRUE(remove_snap.empty());
803 EXPECT_TRUE(t.empty());
804 EXPECT_FALSE(missing.have_missing());
805 EXPECT_TRUE(log.empty());
806
807 TestHandler h(remove_snap);
808 merge_old_entry(t, oe, info, &h);
809
810 EXPECT_TRUE(is_dirty());
811 EXPECT_TRUE(remove_snap.empty());
812 EXPECT_TRUE(t.empty());
813 EXPECT_TRUE(missing.is_missing(oe.soid));
814 EXPECT_TRUE(log.empty());
815 }
816
817
818 // there is no new entry (from the logs) and
819 // the old entry (from the log entry given in argument) is not a CLONE and
820 // the old entry (from the log entry given in argument) is not a DELETE and
821 // the old entry prior_version is eversion_t() :
822 // add the old object to the remove_snap list and
823 // remove the prior_version of the object from missing, if any and
824 // return false
825 {
826 clear();
827
828 ObjectStore::Transaction t;
829 pg_log_entry_t oe;
830 oe.mark_unrollbackable();
831 pg_info_t info;
832 list<hobject_t> remove_snap;
833
834 info.log_tail = eversion_t(10,1);
835 oe.soid.set_hash(1);
836 oe.op = pg_log_entry_t::MODIFY;
837 oe.prior_version = eversion_t();
838
c07f9fc5 839 missing.add(oe.soid, eversion_t(1,1), eversion_t(), false);
7c673cae
FG
840
841 missing.flush();
842 EXPECT_FALSE(is_dirty());
843 EXPECT_TRUE(remove_snap.empty());
844 EXPECT_TRUE(t.empty());
845 EXPECT_TRUE(missing.is_missing(oe.soid));
846 EXPECT_TRUE(log.empty());
847
848 TestHandler h(remove_snap);
849 merge_old_entry(t, oe, info, &h);
850
851 missing.flush();
852 EXPECT_FALSE(is_dirty());
853 EXPECT_EQ(oe.soid, remove_snap.front());
854 EXPECT_TRUE(t.empty());
855 EXPECT_FALSE(missing.have_missing());
856 EXPECT_TRUE(log.empty());
857 }
858
859}
860
861TEST_F(PGLogTest, merge_log) {
862 // head and tail match, last_backfill is set:
863 // noop
864 {
865 clear();
866
867 pg_log_t olog;
868 pg_info_t oinfo;
869 pg_shard_t fromosd;
870 pg_info_t info;
871 list<hobject_t> remove_snap;
872 bool dirty_info = false;
873 bool dirty_big_info = false;
874
875 hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1, "");
876 info.last_backfill = last_backfill;
877 eversion_t stat_version(10, 1);
878 info.stats.version = stat_version;
879 log.tail = olog.tail = eversion_t(1, 1);
880 log.head = olog.head = eversion_t(2, 1);
881
882 EXPECT_FALSE(missing.have_missing());
883 EXPECT_EQ(0U, log.log.size());
884 EXPECT_EQ(stat_version, info.stats.version);
885 EXPECT_TRUE(remove_snap.empty());
886 EXPECT_EQ(last_backfill, info.last_backfill);
887 EXPECT_TRUE(info.purged_snaps.empty());
888 EXPECT_FALSE(is_dirty());
889 EXPECT_FALSE(dirty_info);
890 EXPECT_FALSE(dirty_big_info);
891
892 TestHandler h(remove_snap);
893 merge_log(oinfo, olog, fromosd, info, &h,
894 dirty_info, dirty_big_info);
895
896 EXPECT_FALSE(missing.have_missing());
897 EXPECT_EQ(0U, log.log.size());
898 EXPECT_EQ(stat_version, info.stats.version);
899 EXPECT_TRUE(remove_snap.empty());
900 EXPECT_TRUE(info.purged_snaps.empty());
901 EXPECT_FALSE(is_dirty());
902 EXPECT_FALSE(dirty_info);
903 EXPECT_FALSE(dirty_big_info);
904 }
905
906 // head and tail match, last_backfill is not set: info.stats is
907 // copied from oinfo.stats but info.stats.reported_* is guaranteed to
908 // never be replaced by a lower version
909 {
910 clear();
911
912 pg_log_t olog;
913 pg_info_t oinfo;
914 pg_shard_t fromosd;
915 pg_info_t info;
916 list<hobject_t> remove_snap;
917 bool dirty_info = false;
918 bool dirty_big_info = false;
919
920 eversion_t stat_version(10, 1);
921 oinfo.stats.version = stat_version;
922 info.stats.reported_seq = 1;
923 info.stats.reported_epoch = 10;
924 oinfo.stats.reported_seq = 1;
925 oinfo.stats.reported_epoch = 1;
926 log.tail = olog.tail = eversion_t(1, 1);
927 log.head = olog.head = eversion_t(2, 1);
c07f9fc5 928 missing.may_include_deletes = false;
7c673cae
FG
929
930 EXPECT_FALSE(missing.have_missing());
931 EXPECT_EQ(0U, log.log.size());
932 EXPECT_EQ(eversion_t(), info.stats.version);
933 EXPECT_EQ(1ull, info.stats.reported_seq);
934 EXPECT_EQ(10u, info.stats.reported_epoch);
935 EXPECT_TRUE(remove_snap.empty());
936 EXPECT_TRUE(info.last_backfill.is_max());
937 EXPECT_TRUE(info.purged_snaps.empty());
938 EXPECT_FALSE(is_dirty());
939 EXPECT_FALSE(dirty_info);
940 EXPECT_FALSE(dirty_big_info);
941
942 TestHandler h(remove_snap);
943 merge_log(oinfo, olog, fromosd, info, &h,
944 dirty_info, dirty_big_info);
945
946 EXPECT_FALSE(missing.have_missing());
947 EXPECT_EQ(0U, log.log.size());
948 EXPECT_EQ(stat_version, info.stats.version);
949 EXPECT_EQ(1ull, info.stats.reported_seq);
950 EXPECT_EQ(10u, info.stats.reported_epoch);
951 EXPECT_TRUE(remove_snap.empty());
952 EXPECT_TRUE(info.purged_snaps.empty());
953 EXPECT_FALSE(is_dirty());
954 EXPECT_FALSE(dirty_info);
955 EXPECT_FALSE(dirty_big_info);
956 }
957
958 /* Before
959 +--------------------------+
960 | log olog |
961 +--------+-------+---------+
962 | |object | |
963 |version | hash | version |
964 | | | |
965 | | x5 | (1,1) < tail
966 | | | |
967 | | | |
968 tail > (1,4) | x7 | |
969 | | | |
970 | | | |
971 head > (1,5) | x9 | (1,5) < head
972 | | | |
973 | | | |
974 +--------+-------+---------+
975
976 After
977 +-----------------
978 | log |
979 +--------+-------+
980 | |object |
981 |version | hash |
982 | | |
983 tail > (1,1) | x5 |
984 | | |
985 | | |
986 | (1,4) | x7 |
987 | | |
988 | | |
989 head > (1,5) | x9 |
990 | | |
991 | | |
992 +--------+-------+
993 */
994 {
995 clear();
996
997 pg_log_t olog;
998 pg_info_t oinfo;
999 pg_shard_t fromosd;
1000 pg_info_t info;
1001 list<hobject_t> remove_snap;
1002 bool dirty_info = false;
1003 bool dirty_big_info = false;
c07f9fc5 1004 missing.may_include_deletes = false;
7c673cae
FG
1005
1006 {
1007 pg_log_entry_t e;
1008 e.mark_unrollbackable();
1009
1010 e.version = eversion_t(1, 4);
1011 e.soid.set_hash(0x5);
1012 log.tail = e.version;
1013 log.log.push_back(e);
1014 e.version = eversion_t(1, 5);
1015 e.soid.set_hash(0x9);
1016 log.log.push_back(e);
1017 log.head = e.version;
1018 log.index();
1019
1020 info.last_update = log.head;
1021
1022 e.version = eversion_t(1, 1);
1023 e.soid.set_hash(0x5);
1024 olog.tail = e.version;
1025 olog.log.push_back(e);
1026 e.version = eversion_t(1, 5);
1027 e.soid.set_hash(0x9);
1028 olog.log.push_back(e);
1029 olog.head = e.version;
1030 }
1031
1032 hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1, "");
1033 info.last_backfill = last_backfill;
1034 eversion_t stat_version(10, 1);
1035 info.stats.version = stat_version;
1036
1037 EXPECT_FALSE(missing.have_missing());
1038 EXPECT_EQ(2U, log.log.size());
1039 EXPECT_EQ(stat_version, info.stats.version);
1040 EXPECT_TRUE(remove_snap.empty());
1041 EXPECT_EQ(last_backfill, info.last_backfill);
1042 EXPECT_TRUE(info.purged_snaps.empty());
1043 EXPECT_FALSE(is_dirty());
1044 EXPECT_FALSE(dirty_info);
1045 EXPECT_FALSE(dirty_big_info);
1046
1047 TestHandler h(remove_snap);
1048 merge_log(oinfo, olog, fromosd, info, &h,
1049 dirty_info, dirty_big_info);
1050
1051 EXPECT_FALSE(missing.have_missing());
1052 EXPECT_EQ(3U, log.log.size());
1053 EXPECT_EQ(stat_version, info.stats.version);
1054 EXPECT_TRUE(remove_snap.empty());
1055 EXPECT_TRUE(info.purged_snaps.empty());
1056 EXPECT_TRUE(is_dirty());
1057 EXPECT_TRUE(dirty_info);
1058 EXPECT_TRUE(dirty_big_info);
1059 }
1060
c07f9fc5
FG
1061 /* +--------------------------+
1062 | log olog |
1063 +--------+-------+---------+
1064 | |object | |
1065 |version | hash | version |
1066 | | | |
1067 tail > (1,1) | x5 | (1,1) < tail
1068 | | | |
1069 | | | |
1070 | (1,2) | x3 | (1,2) < lower_bound
1071 | | | |
1072 | | | |
1073 head > (1,3) | x9 | |
1074 | DELETE | | |
1075 | | | |
1076 | | x9 | (2,3) |
1077 | | | MODIFY |
1078 | | | |
1079 | | x7 | (2,4) < head
1080 | | | DELETE |
1081 +--------+-------+---------+
1082
1083 The log entry (1,3) deletes the object x9 but the olog entry (2,3) modifies
1084 it and is authoritative : the log entry (1,3) is divergent.
1085
1086 */
1087 {
1088 clear();
1089
1090 pg_log_t olog;
1091 pg_info_t oinfo;
1092 pg_shard_t fromosd;
1093 pg_info_t info;
1094 list<hobject_t> remove_snap;
1095 bool dirty_info = false;
1096 bool dirty_big_info = false;
1097
1098 hobject_t divergent_object;
1099 missing.may_include_deletes = true;
1100
1101 {
1102 pg_log_entry_t e;
1103 e.mark_unrollbackable();
1104
1105 e.version = eversion_t(1, 1);
1106 e.soid.set_hash(0x5);
1107 log.tail = e.version;
1108 log.log.push_back(e);
1109 e.version = eversion_t(1, 2);
1110 e.soid.set_hash(0x3);
1111 log.log.push_back(e);
1112 e.version = eversion_t(1,3);
1113 e.soid.set_hash(0x9);
1114 divergent_object = e.soid;
1115 e.op = pg_log_entry_t::DELETE;
1116 log.log.push_back(e);
1117 log.head = e.version;
1118 log.index();
1119
1120 info.last_update = log.head;
1121
1122 e.version = eversion_t(1, 1);
1123 e.soid.set_hash(0x5);
1124 olog.tail = e.version;
1125 olog.log.push_back(e);
1126 e.version = eversion_t(1, 2);
1127 e.soid.set_hash(0x3);
1128 olog.log.push_back(e);
1129 e.version = eversion_t(2, 3);
1130 e.soid.set_hash(0x9);
1131 e.op = pg_log_entry_t::MODIFY;
1132 olog.log.push_back(e);
1133 e.version = eversion_t(2, 4);
1134 e.soid.set_hash(0x7);
1135 e.op = pg_log_entry_t::DELETE;
1136 olog.log.push_back(e);
1137 olog.head = e.version;
1138 }
1139
1140 snapid_t purged_snap(1);
1141 {
1142 oinfo.last_update = olog.head;
1143 oinfo.purged_snaps.insert(purged_snap);
1144 }
1145
1146 EXPECT_FALSE(missing.have_missing());
1147 EXPECT_EQ(1U, log.objects.count(divergent_object));
1148 EXPECT_EQ(3U, log.log.size());
1149 EXPECT_TRUE(remove_snap.empty());
1150 EXPECT_EQ(log.head, info.last_update);
1151 EXPECT_TRUE(info.purged_snaps.empty());
1152 EXPECT_FALSE(is_dirty());
1153 EXPECT_FALSE(dirty_info);
1154 EXPECT_FALSE(dirty_big_info);
1155
1156 TestHandler h(remove_snap);
1157 merge_log(oinfo, olog, fromosd, info, &h,
1158 dirty_info, dirty_big_info);
1159
1160 /* When the divergent entry is a DELETE and the authoritative
1161 entry is a MODIFY, the object will be added to missing : it is
1162 a verifiable side effect proving the entry was identified
1163 to be divergent.
1164 */
1165 EXPECT_TRUE(missing.is_missing(divergent_object));
1166 EXPECT_EQ(1U, log.objects.count(divergent_object));
1167 EXPECT_EQ(4U, log.log.size());
1168 /* DELETE entries from olog that are appended to the hed of the
1169 log, and the divergent version of the object is removed (added
1170 to remove_snap)
1171 */
1172 EXPECT_EQ(0x9U, remove_snap.front().get_hash());
1173 EXPECT_EQ(log.head, info.last_update);
1174 EXPECT_TRUE(info.purged_snaps.contains(purged_snap));
1175 EXPECT_TRUE(is_dirty());
1176 EXPECT_TRUE(dirty_info);
1177 EXPECT_TRUE(dirty_big_info);
1178 }
1179
7c673cae
FG
1180 /* +--------------------------+
1181 | log olog |
1182 +--------+-------+---------+
1183 | |object | |
1184 |version | hash | version |
1185 | | | |
1186 tail > (1,1) | x5 | (1,1) < tail
1187 | | | |
1188 | | | |
1189 | (1,2) | x3 | (1,2) < lower_bound
1190 | | | |
1191 | | | |
1192 head > (1,3) | x9 | |
1193 | DELETE | | |
1194 | | | |
1195 | | x9 | (2,3) |
1196 | | | MODIFY |
1197 | | | |
1198 | | x7 | (2,4) < head
1199 | | | DELETE |
1200 +--------+-------+---------+
1201
1202 The log entry (1,3) deletes the object x9 but the olog entry (2,3) modifies
1203 it and is authoritative : the log entry (1,3) is divergent.
1204
1205 */
1206 {
1207 clear();
1208
1209 pg_log_t olog;
1210 pg_info_t oinfo;
1211 pg_shard_t fromosd;
1212 pg_info_t info;
1213 list<hobject_t> remove_snap;
1214 bool dirty_info = false;
1215 bool dirty_big_info = false;
1216
1217 hobject_t divergent_object;
1218
1219 {
1220 pg_log_entry_t e;
1221 e.mark_unrollbackable();
1222
1223 e.version = eversion_t(1, 1);
1224 e.soid.set_hash(0x5);
1225 log.tail = e.version;
1226 log.log.push_back(e);
1227 e.version = eversion_t(1, 2);
1228 e.soid.set_hash(0x3);
1229 log.log.push_back(e);
1230 e.version = eversion_t(1,3);
1231 e.soid.set_hash(0x9);
1232 divergent_object = e.soid;
1233 e.op = pg_log_entry_t::DELETE;
1234 log.log.push_back(e);
1235 log.head = e.version;
1236 log.index();
1237
1238 info.last_update = log.head;
1239
1240 e.version = eversion_t(1, 1);
1241 e.soid.set_hash(0x5);
1242 olog.tail = e.version;
1243 olog.log.push_back(e);
1244 e.version = eversion_t(1, 2);
1245 e.soid.set_hash(0x3);
1246 olog.log.push_back(e);
1247 e.version = eversion_t(2, 3);
1248 e.soid.set_hash(0x9);
1249 e.op = pg_log_entry_t::MODIFY;
1250 olog.log.push_back(e);
1251 e.version = eversion_t(2, 4);
1252 e.soid.set_hash(0x7);
1253 e.op = pg_log_entry_t::DELETE;
1254 olog.log.push_back(e);
1255 olog.head = e.version;
1256 }
1257
1258 snapid_t purged_snap(1);
1259 {
1260 oinfo.last_update = olog.head;
1261 oinfo.purged_snaps.insert(purged_snap);
1262 }
1263
1264 EXPECT_FALSE(missing.have_missing());
1265 EXPECT_EQ(1U, log.objects.count(divergent_object));
1266 EXPECT_EQ(3U, log.log.size());
1267 EXPECT_TRUE(remove_snap.empty());
1268 EXPECT_EQ(log.head, info.last_update);
1269 EXPECT_TRUE(info.purged_snaps.empty());
1270 EXPECT_FALSE(is_dirty());
1271 EXPECT_FALSE(dirty_info);
1272 EXPECT_FALSE(dirty_big_info);
1273
1274 TestHandler h(remove_snap);
c07f9fc5 1275 missing.may_include_deletes = false;
7c673cae
FG
1276 merge_log(oinfo, olog, fromosd, info, &h,
1277 dirty_info, dirty_big_info);
1278
1279 /* When the divergent entry is a DELETE and the authoritative
1280 entry is a MODIFY, the object will be added to missing : it is
1281 a verifiable side effect proving the entry was identified
1282 to be divergent.
1283 */
1284 EXPECT_TRUE(missing.is_missing(divergent_object));
1285 EXPECT_EQ(1U, log.objects.count(divergent_object));
1286 EXPECT_EQ(4U, log.log.size());
1287 /* DELETE entries from olog that are appended to the hed of the
c07f9fc5
FG
1288 log, and the divergent version of the object is removed (added
1289 to remove_snap). When peering handles deletes, it is the earlier
1290 version that is in the removed list.
7c673cae
FG
1291 */
1292 EXPECT_EQ(0x7U, remove_snap.front().get_hash());
1293 EXPECT_EQ(log.head, info.last_update);
1294 EXPECT_TRUE(info.purged_snaps.contains(purged_snap));
1295 EXPECT_TRUE(is_dirty());
1296 EXPECT_TRUE(dirty_info);
1297 EXPECT_TRUE(dirty_big_info);
1298 }
1299
1300 /* +--------------------------+
1301 | log olog |
1302 +--------+-------+---------+
1303 | |object | |
1304 |version | hash | version |
1305 | | | |
1306 tail > (1,1) | x5 | (1,1) < tail
1307 | | | |
1308 | | | |
1309 | (1,4) | x7 | (1,4) < head
1310 | | | |
1311 | | | |
1312 head > (1,5) | x9 | |
1313 | | | |
1314 | | | |
1315 +--------+-------+---------+
1316
1317 The head of the log entry (1,5) is divergent because it is greater than the
1318 head of olog.
1319
1320 */
1321 {
1322 clear();
1323
1324 pg_log_t olog;
1325 pg_info_t oinfo;
1326 pg_shard_t fromosd;
1327 pg_info_t info;
1328 list<hobject_t> remove_snap;
1329 bool dirty_info = false;
1330 bool dirty_big_info = false;
1331
1332 {
1333 pg_log_entry_t e;
1334 e.mark_unrollbackable();
1335
1336 e.version = eversion_t(1, 1);
1337 e.soid.set_hash(0x5);
1338 log.tail = e.version;
1339 log.log.push_back(e);
1340 e.version = eversion_t(1, 4);
1341 e.soid.set_hash(0x7);
1342 log.log.push_back(e);
1343 e.version = eversion_t(1, 5);
1344 e.soid.set_hash(0x9);
1345 log.log.push_back(e);
1346 log.head = e.version;
1347 log.index();
1348
1349 info.last_update = log.head;
1350
1351 e.version = eversion_t(1, 1);
1352 e.soid.set_hash(0x5);
1353 olog.tail = e.version;
1354 olog.log.push_back(e);
1355 e.version = eversion_t(1, 4);
1356 e.soid.set_hash(0x7);
1357 olog.log.push_back(e);
1358 olog.head = e.version;
1359 }
1360
1361 hobject_t last_backfill(object_t("oname"), string("key"), 1, 234, 1, "");
1362 info.last_backfill = last_backfill;
1363 eversion_t stat_version(10, 1);
1364 info.stats.version = stat_version;
1365
1366 EXPECT_FALSE(missing.have_missing());
1367 EXPECT_EQ(3U, log.log.size());
1368 EXPECT_EQ(stat_version, info.stats.version);
1369 EXPECT_TRUE(remove_snap.empty());
1370 EXPECT_EQ(last_backfill, info.last_backfill);
1371 EXPECT_TRUE(info.purged_snaps.empty());
1372 EXPECT_FALSE(is_dirty());
1373 EXPECT_FALSE(dirty_info);
1374 EXPECT_FALSE(dirty_big_info);
1375
1376 TestHandler h(remove_snap);
c07f9fc5 1377 missing.may_include_deletes = false;
7c673cae
FG
1378 merge_log(oinfo, olog, fromosd, info, &h,
1379 dirty_info, dirty_big_info);
1380
1381 EXPECT_FALSE(missing.have_missing());
1382 EXPECT_EQ(2U, log.log.size());
1383 EXPECT_EQ(stat_version, info.stats.version);
1384 EXPECT_EQ(0x9U, remove_snap.front().get_hash());
1385 EXPECT_TRUE(info.purged_snaps.empty());
1386 EXPECT_TRUE(is_dirty());
1387 EXPECT_TRUE(dirty_info);
1388 EXPECT_TRUE(dirty_big_info);
1389 }
1390
7c673cae
FG
1391}
1392
1393TEST_F(PGLogTest, proc_replica_log) {
1394 // empty log : no side effect
1395 {
1396 clear();
1397
1398 pg_log_t olog;
1399 pg_info_t oinfo;
1400 pg_missing_t omissing;
1401 pg_shard_t from;
1402
1403 eversion_t last_update(1, 1);
1404 log.head = olog.head = oinfo.last_update = last_update;
1405 eversion_t last_complete(1, 1);
1406 oinfo.last_complete = last_complete;
1407
1408 EXPECT_FALSE(omissing.have_missing());
1409 EXPECT_EQ(last_update, oinfo.last_update);
1410 EXPECT_EQ(last_complete, oinfo.last_complete);
1411
c07f9fc5 1412 missing.may_include_deletes = false;
7c673cae
FG
1413 proc_replica_log(oinfo, olog, omissing, from);
1414
1415 EXPECT_FALSE(omissing.have_missing());
1416 EXPECT_EQ(last_update, oinfo.last_update);
1417 EXPECT_EQ(last_update, oinfo.last_complete);
1418 }
1419
1420 /* +--------------------------+
1421 | log olog |
1422 +--------+-------+---------+
1423 | |object | |
1424 |version | hash | version |
1425 | | | |
1426 | | x3 | (1,1) < tail
1427 | | | |
1428 | | | |
1429 tail > (1,2) | x5 | |
1430 | | | |
1431 | | | |
1432 head > (1,3) | x9 | |
1433 | DELETE | | |
1434 | | | |
1435 | | x9 | (2,3) < head
1436 | | | DELETE |
1437 | | | |
1438 +--------+-------+---------+
c07f9fc5 1439
7c673cae
FG
1440 The log entry (1,3) deletes the object x9 and the olog entry
1441 (2,3) also deletes it : do nothing. The olog tail is ignored
1442 because it is before the log tail.
c07f9fc5 1443
7c673cae
FG
1444 */
1445 {
1446 clear();
1447
1448 pg_log_t olog;
1449 pg_info_t oinfo;
1450 pg_missing_t omissing;
1451 pg_shard_t from;
1452
1453 {
1454 pg_log_entry_t e;
1455 e.mark_unrollbackable();
1456
1457 e.version = eversion_t(1, 2);
1458 e.soid.set_hash(0x5);
1459 log.tail = e.version;
1460 log.log.push_back(e);
1461 e.version = eversion_t(1, 3);
1462 e.soid.set_hash(0x9);
1463 e.op = pg_log_entry_t::DELETE;
1464 log.log.push_back(e);
1465 log.head = e.version;
1466 log.index();
1467
1468 e.version = eversion_t(1, 1);
1469 e.soid.set_hash(0x3);
1470 olog.tail = e.version;
1471 olog.log.push_back(e);
1472 e.version = eversion_t(2, 3);
1473 e.soid.set_hash(0x9);
1474 e.op = pg_log_entry_t::DELETE;
1475 olog.log.push_back(e);
1476 olog.head = e.version;
1477
1478 oinfo.last_update = olog.head;
1479 oinfo.last_complete = olog.head;
1480 }
1481
1482 EXPECT_FALSE(omissing.have_missing());
1483 EXPECT_EQ(olog.head, oinfo.last_update);
1484 EXPECT_EQ(olog.head, oinfo.last_complete);
1485
c07f9fc5 1486 missing.may_include_deletes = false;
7c673cae
FG
1487 proc_replica_log(oinfo, olog, omissing, from);
1488
1489 EXPECT_FALSE(omissing.have_missing());
1490 }
1491
1492 {
1493 clear();
1494
1495 pg_log_t olog;
1496 pg_info_t oinfo;
1497 pg_missing_t omissing;
1498 pg_shard_t from;
1499
1500 hobject_t divergent_object;
1501
1502 {
1503 pg_log_entry_t e;
1504 e.mark_unrollbackable();
1505
1506 {
1507 e.soid = divergent_object;
1508 e.soid.set_hash(0x1);
1509 e.version = eversion_t(1, 1);
1510 log.tail = e.version;
1511 log.log.push_back(e);
1512
1513 e.soid = divergent_object;
1514 e.prior_version = eversion_t(1, 1);
1515 e.version = eversion_t(1, 2);
1516 log.tail = e.version;
1517 log.log.push_back(e);
1518
1519 e.soid.set_hash(0x3);
1520 e.version = eversion_t(1, 4);
1521 log.log.push_back(e);
1522
1523 e.soid.set_hash(0x7);
1524 e.version = eversion_t(1, 5);
1525 log.log.push_back(e);
1526
1527 e.soid.set_hash(0x8);
1528 e.version = eversion_t(1, 6);
1529 log.log.push_back(e);
1530
1531 e.soid.set_hash(0x9);
1532 e.op = pg_log_entry_t::DELETE;
1533 e.version = eversion_t(2, 7);
1534 log.log.push_back(e);
1535
1536 e.soid.set_hash(0xa);
1537 e.version = eversion_t(2, 8);
1538 log.head = e.version;
1539 log.log.push_back(e);
1540 }
1541 log.index();
1542
1543 {
1544 e.soid = divergent_object;
1545 e.soid.set_hash(0x1);
1546 e.version = eversion_t(1, 1);
1547 olog.tail = e.version;
1548 olog.log.push_back(e);
1549
1550 e.soid = divergent_object;
1551 e.prior_version = eversion_t(1, 1);
1552 e.version = eversion_t(1, 2);
1553 olog.log.push_back(e);
1554
1555 e.prior_version = eversion_t(0, 0);
1556 e.soid.set_hash(0x3);
1557 e.version = eversion_t(1, 4);
1558 olog.log.push_back(e);
1559
1560 e.soid.set_hash(0x7);
1561 e.version = eversion_t(1, 5);
1562 olog.log.push_back(e);
1563
1564 e.soid.set_hash(0x8);
1565 e.version = eversion_t(1, 6);
1566 olog.log.push_back(e);
1567
1568 e.soid.set_hash(0x9); // should not be added to missing, create
1569 e.op = pg_log_entry_t::MODIFY;
1570 e.version = eversion_t(1, 7);
1571 olog.log.push_back(e);
1572
1573 e.soid = divergent_object; // should be added to missing at 1,2
1574 e.op = pg_log_entry_t::MODIFY;
1575 e.version = eversion_t(1, 8);
1576 e.prior_version = eversion_t(1, 2);
1577 olog.log.push_back(e);
1578 olog.head = e.version;
1579 }
1580 oinfo.last_update = olog.head;
1581 oinfo.last_complete = olog.head;
1582 }
1583
1584 EXPECT_FALSE(omissing.have_missing());
1585 EXPECT_EQ(olog.head, oinfo.last_update);
1586 EXPECT_EQ(olog.head, oinfo.last_complete);
1587
c07f9fc5 1588 missing.may_include_deletes = false;
7c673cae
FG
1589 proc_replica_log(oinfo, olog, omissing, from);
1590
1591 EXPECT_TRUE(omissing.have_missing());
1592 EXPECT_TRUE(omissing.is_missing(divergent_object));
1593 EXPECT_EQ(eversion_t(1, 2), omissing.get_items().at(divergent_object).need);
1594 EXPECT_EQ(eversion_t(1, 6), oinfo.last_update);
1595 EXPECT_EQ(eversion_t(1, 1), oinfo.last_complete);
1596 }
1597
1598 /* +--------------------------+
1599 | olog log |
1600 +--------+-------+---------+
1601 | |object | |
1602 |version | hash | version |
1603 | | | |
1604 tail > (1,1) | x9 | (1,1) < tail
1605 | | | |
1606 | | | |
1607 | (1,2) | x3 | (1,2) |
1608 | | | |
1609 | | | |
1610 head > (1,3) | x9 | |
1611 | DELETE | | |
1612 | | | |
1613 | | x9 | (2,3) < head
1614 | | | DELETE |
1615 | | | |
1616 +--------+-------+---------+
1617
1618 The log entry (1,3) deletes the object x9 and the olog entry
1619 (2,3) also deletes it : do nothing.
1620
1621 */
1622 {
1623 clear();
1624
1625 pg_log_t olog;
1626 pg_info_t oinfo;
1627 pg_missing_t omissing;
1628 pg_shard_t from;
1629
1630 eversion_t last_update(1, 2);
1631 hobject_t divergent_object;
1632 divergent_object.set_hash(0x9);
1633
1634 {
1635 pg_log_entry_t e;
1636 e.mark_unrollbackable();
1637
1638 e.version = eversion_t(1, 1);
1639 e.soid = divergent_object;
1640 log.tail = e.version;
1641 log.log.push_back(e);
1642 e.version = last_update;
1643 e.soid.set_hash(0x3);
1644 log.log.push_back(e);
1645 e.version = eversion_t(2, 3);
1646 e.prior_version = eversion_t(1, 1);
1647 e.soid = divergent_object;
1648 e.op = pg_log_entry_t::DELETE;
1649 log.log.push_back(e);
1650 log.head = e.version;
1651 log.index();
1652
1653 e.version = eversion_t(1, 1);
1654 e.soid = divergent_object;
1655 olog.tail = e.version;
1656 olog.log.push_back(e);
1657 e.version = last_update;
1658 e.soid.set_hash(0x3);
1659 olog.log.push_back(e);
1660 e.version = eversion_t(1, 3);
1661 e.prior_version = eversion_t(1, 1);
1662 e.soid = divergent_object;
1663 e.op = pg_log_entry_t::DELETE;
1664 olog.log.push_back(e);
1665 olog.head = e.version;
1666
1667 oinfo.last_update = olog.head;
1668 oinfo.last_complete = olog.head;
1669 }
1670
1671 EXPECT_FALSE(omissing.have_missing());
1672 EXPECT_EQ(olog.head, oinfo.last_update);
1673 EXPECT_EQ(olog.head, oinfo.last_complete);
1674
c07f9fc5 1675 missing.may_include_deletes = false;
7c673cae
FG
1676 proc_replica_log(oinfo, olog, omissing, from);
1677
1678 EXPECT_TRUE(omissing.have_missing());
1679 EXPECT_TRUE(omissing.is_missing(divergent_object));
1680 EXPECT_EQ(omissing.get_items().at(divergent_object).have, eversion_t(0, 0));
1681 EXPECT_EQ(omissing.get_items().at(divergent_object).need, eversion_t(1, 1));
1682 EXPECT_EQ(last_update, oinfo.last_update);
1683 }
1684
1685 /* +--------------------------+
1686 | olog log |
1687 +--------+-------+---------+
1688 | |object | |
1689 |version | hash | version |
1690 | | | |
1691 tail > (1,1) | x9 | (1,1) < tail
1692 | | | |
1693 | | | |
1694 | (1,2) | x3 | (1,2) |
1695 | | | |
1696 | | | |
1697 head > (1,3) | x9 | |
1698 | MODIFY | | |
1699 | | | |
1700 | | x9 | (2,3) < head
1701 | | | DELETE |
1702 | | | |
1703 +--------+-------+---------+
1704
1705 The log entry (1,3) deletes the object x9 but the olog entry
1706 (2,3) modifies it : remove it from omissing.
1707
1708 */
1709 {
1710 clear();
1711
1712 pg_log_t olog;
1713 pg_info_t oinfo;
1714 pg_missing_t omissing;
1715 pg_shard_t from;
1716
1717 eversion_t last_update(1, 2);
1718 hobject_t divergent_object;
1719
1720 {
1721 pg_log_entry_t e;
1722 e.mark_unrollbackable();
1723
1724 e.version = eversion_t(1, 1);
1725 e.soid = divergent_object;
1726 log.tail = e.version;
1727 log.log.push_back(e);
1728 e.version = last_update;
1729 e.soid.set_hash(0x3);
1730 log.log.push_back(e);
1731 e.version = eversion_t(2, 3);
1732 e.prior_version = eversion_t(1, 1);
1733 e.soid = divergent_object;
1734 e.op = pg_log_entry_t::DELETE;
1735 log.log.push_back(e);
1736 log.head = e.version;
1737 log.index();
1738
1739 e.version = eversion_t(1, 1);
1740 e.soid = divergent_object;
1741 olog.tail = e.version;
1742 olog.log.push_back(e);
1743 e.version = last_update;
1744 e.soid.set_hash(0x3);
1745 olog.log.push_back(e);
1746 e.version = eversion_t(1, 3);
1747 e.prior_version = eversion_t(1, 1);
1748 e.soid = divergent_object;
1749 divergent_object = e.soid;
c07f9fc5 1750 omissing.add(divergent_object, e.version, eversion_t(), false);
7c673cae
FG
1751 e.op = pg_log_entry_t::MODIFY;
1752 olog.log.push_back(e);
1753 olog.head = e.version;
1754
1755 oinfo.last_update = olog.head;
1756 oinfo.last_complete = olog.head;
1757 }
1758
1759 EXPECT_TRUE(omissing.have_missing());
1760 EXPECT_TRUE(omissing.is_missing(divergent_object));
1761 EXPECT_EQ(eversion_t(1, 3), omissing.get_items().at(divergent_object).need);
1762 EXPECT_EQ(olog.head, oinfo.last_update);
1763 EXPECT_EQ(olog.head, oinfo.last_complete);
1764
c07f9fc5 1765 missing.may_include_deletes = false;
7c673cae
FG
1766 proc_replica_log(oinfo, olog, omissing, from);
1767
1768 EXPECT_TRUE(omissing.have_missing());
1769 EXPECT_TRUE(omissing.is_missing(divergent_object));
1770 EXPECT_EQ(omissing.get_items().at(divergent_object).have, eversion_t(0, 0));
1771 EXPECT_EQ(omissing.get_items().at(divergent_object).need, eversion_t(1, 1));
1772 EXPECT_EQ(last_update, oinfo.last_update);
1773 }
1774
1775 /* +--------------------------+
1776 | log olog |
1777 +--------+-------+---------+
1778 | |object | |
1779 |version | hash | version |
1780 | | | |
1781 tail > (1,1) | x9 | (1,1) < tail
1782 | | | |
1783 | | | |
1784 | (1,2) | x3 | (1,2) |
1785 | | | |
1786 | | | |
1787 | | x9 | (1,3) < head
1788 | | | MODIFY |
1789 | | | |
1790 head > (2,3) | x9 | |
1791 | DELETE | | |
1792 | | | |
1793 +--------+-------+---------+
1794
1795 The log entry (2,3) deletes the object x9 but the olog entry
1796 (1,3) modifies it : proc_replica_log should adjust missing to
1797 1,1 for that object until add_next_event in PG::activate processes
1798 the delete.
1799 */
1800 {
1801 clear();
1802
1803 pg_log_t olog;
1804 pg_info_t oinfo;
1805 pg_missing_t omissing;
1806 pg_shard_t from;
1807
1808 eversion_t last_update(1, 2);
1809 hobject_t divergent_object;
1810 eversion_t new_version(2, 3);
1811 eversion_t divergent_version(1, 3);
1812
1813 {
1814 pg_log_entry_t e;
1815 e.mark_unrollbackable();
1816
1817 e.version = eversion_t(1, 1);
1818 e.soid.set_hash(0x9);
1819 log.tail = e.version;
1820 log.log.push_back(e);
1821 e.version = last_update;
1822 e.soid.set_hash(0x3);
1823 log.log.push_back(e);
1824 e.version = new_version;
1825 e.prior_version = eversion_t(1, 1);
1826 e.soid.set_hash(0x9);
1827 e.op = pg_log_entry_t::DELETE;
1828 log.log.push_back(e);
1829 log.head = e.version;
1830 log.index();
1831
1832 e.op = pg_log_entry_t::MODIFY;
1833 e.version = eversion_t(1, 1);
1834 e.soid.set_hash(0x9);
1835 olog.tail = e.version;
1836 olog.log.push_back(e);
1837 e.version = last_update;
1838 e.soid.set_hash(0x3);
1839 olog.log.push_back(e);
1840 e.version = divergent_version;
1841 e.prior_version = eversion_t(1, 1);
1842 e.soid.set_hash(0x9);
1843 divergent_object = e.soid;
c07f9fc5 1844 omissing.add(divergent_object, e.version, eversion_t(), false);
7c673cae
FG
1845 e.op = pg_log_entry_t::MODIFY;
1846 olog.log.push_back(e);
1847 olog.head = e.version;
1848
1849 oinfo.last_update = olog.head;
1850 oinfo.last_complete = olog.head;
1851 }
1852
1853 EXPECT_TRUE(omissing.have_missing());
1854 EXPECT_TRUE(omissing.is_missing(divergent_object));
1855 EXPECT_EQ(divergent_version, omissing.get_items().at(divergent_object).need);
1856 EXPECT_EQ(olog.head, oinfo.last_update);
1857 EXPECT_EQ(olog.head, oinfo.last_complete);
1858
c07f9fc5 1859 missing.may_include_deletes = false;
7c673cae
FG
1860 proc_replica_log(oinfo, olog, omissing, from);
1861
1862 EXPECT_TRUE(omissing.have_missing());
1863 EXPECT_TRUE(omissing.get_items().begin()->second.need == eversion_t(1, 1));
1864 EXPECT_EQ(last_update, oinfo.last_update);
1865 EXPECT_EQ(eversion_t(0, 0), oinfo.last_complete);
1866 }
1867
1868}
1869
1870TEST_F(PGLogTest, merge_log_1) {
1871 TestCase t;
1872 t.base.push_back(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1873
1874 t.div.push_back(mk_ple_mod(mk_obj(1), mk_evt(10, 101), mk_evt(10, 100)));
1875
c07f9fc5 1876 t.final.add(mk_obj(1), mk_evt(10, 100), mk_evt(0, 0), false);
7c673cae
FG
1877
1878 t.toremove.insert(mk_obj(1));
1879
1880 t.setup();
1881 run_test_case(t);
1882}
1883
1884TEST_F(PGLogTest, merge_log_2) {
1885 TestCase t;
1886 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1887
1888 t.div.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 101), mk_evt(10, 100)));
1889 t.div.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 102), mk_evt(10, 101)));
1890
1891 t.torollback.insert(
1892 t.torollback.begin(), t.div.rbegin(), t.div.rend());
1893
1894 t.setup();
1895 run_test_case(t);
1896}
1897
1898TEST_F(PGLogTest, merge_log_3) {
1899 TestCase t;
1900 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1901
1902 t.div.push_back(mk_ple_mod(mk_obj(1), mk_evt(10, 101), mk_evt(10, 100)));
1903 t.div.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 102), mk_evt(10, 101)));
1904
c07f9fc5 1905 t.final.add(mk_obj(1), mk_evt(10, 100), mk_evt(0, 0), false);
7c673cae
FG
1906
1907 t.toremove.insert(mk_obj(1));
1908
1909 t.setup();
1910 run_test_case(t);
1911}
1912
1913TEST_F(PGLogTest, merge_log_4) {
1914 TestCase t;
1915 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1916
1917 t.div.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 101), mk_evt(10, 100)));
1918 t.div.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 102), mk_evt(10, 101)));
1919
c07f9fc5
FG
1920 t.init.add(mk_obj(1), mk_evt(10, 102), mk_evt(0, 0), false);
1921 t.final.add(mk_obj(1), mk_evt(10, 100), mk_evt(0, 0), false);
7c673cae
FG
1922
1923 t.setup();
1924 run_test_case(t);
1925}
1926
1927TEST_F(PGLogTest, merge_log_5) {
1928 TestCase t;
1929 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1930
1931 t.div.push_back(mk_ple_mod(mk_obj(1), mk_evt(10, 101), mk_evt(10, 100)));
1932 t.div.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 102), mk_evt(10, 101)));
1933
1934 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(11, 101), mk_evt(10, 100)));
1935
c07f9fc5 1936 t.final.add(mk_obj(1), mk_evt(11, 101), mk_evt(0, 0), false);
7c673cae
FG
1937
1938 t.toremove.insert(mk_obj(1));
1939
1940 t.setup();
1941 run_test_case(t);
1942}
1943
1944TEST_F(PGLogTest, merge_log_6) {
1945 TestCase t;
1946 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1947
1948 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(11, 101), mk_evt(10, 100)));
1949
c07f9fc5 1950 t.final.add(mk_obj(1), mk_evt(11, 101), mk_evt(10, 100), false);
7c673cae
FG
1951
1952 t.setup();
1953 run_test_case(t);
1954}
1955
1956TEST_F(PGLogTest, merge_log_7) {
1957 TestCase t;
1958 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1959
1960 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(11, 101), mk_evt(10, 100)));
1961
c07f9fc5
FG
1962 t.init.add(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80), false);
1963 t.final.add(mk_obj(1), mk_evt(11, 101), mk_evt(8, 80), false);
7c673cae
FG
1964
1965 t.setup();
1966 run_test_case(t);
1967}
1968
1969TEST_F(PGLogTest, merge_log_8) {
1970 TestCase t;
1971 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1972
1973 t.auth.push_back(mk_ple_dt(mk_obj(1), mk_evt(11, 101), mk_evt(10, 100)));
1974
c07f9fc5
FG
1975 t.init.add(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80), false);
1976 t.final.add(mk_obj(1), mk_evt(11, 101), mk_evt(8, 80), true);
1977
1978 t.setup();
1979 run_test_case(t);
1980}
1981
1982TEST_F(PGLogTest, merge_log_9) {
1983 TestCase t;
1984 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1985
1986 t.auth.push_back(mk_ple_dt(mk_obj(1), mk_evt(11, 101), mk_evt(10, 100)));
7c673cae 1987
c07f9fc5 1988 t.init.add(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80), false);
7c673cae 1989 t.toremove.insert(mk_obj(1));
c07f9fc5
FG
1990 t.deletes_during_peering = true;
1991
1992 t.setup();
1993 run_test_case(t);
1994}
1995
1996TEST_F(PGLogTest, merge_log_10) {
1997 TestCase t;
1998 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
1999
2000 t.auth.push_back(mk_ple_ldt(mk_obj(1), mk_evt(11, 101), mk_evt(10, 100)));
2001
2002 t.init.add(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80), false);
2003 t.final.add(mk_obj(1), mk_evt(11, 101), mk_evt(8, 80), true);
7c673cae
FG
2004
2005 t.setup();
2006 run_test_case(t);
2007}
2008
2009TEST_F(PGLogTest, merge_log_prior_version_have) {
2010 TestCase t;
2011 t.base.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 80)));
2012
2013 t.div.push_back(mk_ple_mod(mk_obj(1), mk_evt(10, 101), mk_evt(10, 100)));
2014
c07f9fc5 2015 t.init.add(mk_obj(1), mk_evt(10, 101), mk_evt(10, 100), false);
7c673cae
FG
2016
2017 t.setup();
2018 run_test_case(t);
2019}
2020
2021TEST_F(PGLogTest, merge_log_split_missing_entries_at_head) {
2022 TestCase t;
2023 t.auth.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2024 t.auth.push_back(mk_ple_mod_rb(mk_obj(1), mk_evt(15, 150), mk_evt(10, 100)));
2025
2026 t.div.push_back(mk_ple_mod(mk_obj(1), mk_evt(8, 70), mk_evt(8, 65)));
2027
2028 t.setup();
2029 t.set_div_bounds(mk_evt(9, 79), mk_evt(8, 69));
2030 t.set_auth_bounds(mk_evt(15, 160), mk_evt(9, 77));
c07f9fc5 2031 t.final.add(mk_obj(1), mk_evt(15, 150), mk_evt(8, 70), false);
7c673cae
FG
2032 run_test_case(t);
2033}
2034
2035TEST_F(PGLogTest, olog_tail_gt_log_tail_split) {
2036 TestCase t;
2037 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2038 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(15, 150), mk_evt(10, 100)));
2039 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(15, 155), mk_evt(15, 150)));
2040
2041 t.setup();
2042 t.set_div_bounds(mk_evt(15, 153), mk_evt(15, 151));
2043 t.set_auth_bounds(mk_evt(15, 156), mk_evt(10, 99));
c07f9fc5 2044 t.final.add(mk_obj(1), mk_evt(15, 155), mk_evt(15, 150), false);
7c673cae
FG
2045 run_test_case(t);
2046}
2047
2048TEST_F(PGLogTest, olog_tail_gt_log_tail_split2) {
2049 TestCase t;
2050 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2051 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(15, 150), mk_evt(10, 100)));
2052 t.auth.push_back(mk_ple_mod(mk_obj(1), mk_evt(16, 155), mk_evt(15, 150)));
2053 t.div.push_back(mk_ple_mod(mk_obj(1), mk_evt(15, 153), mk_evt(15, 150)));
2054
2055 t.setup();
2056 t.set_div_bounds(mk_evt(15, 153), mk_evt(15, 151));
2057 t.set_auth_bounds(mk_evt(16, 156), mk_evt(10, 99));
c07f9fc5 2058 t.final.add(mk_obj(1), mk_evt(16, 155), mk_evt(0, 0), false);
7c673cae
FG
2059 t.toremove.insert(mk_obj(1));
2060 run_test_case(t);
2061}
2062
2063TEST_F(PGLogTest, filter_log_1) {
2064 {
2065 clear();
2066
2067 int osd_id = 1;
2068 epoch_t epoch = 40;
224ce89b 2069 int64_t pool_id = 1;
7c673cae
FG
2070 int bits = 2;
2071 int max_osd = 4;
2072 int pg_num = max_osd << bits;
2073 int num_objects = 1000;
2074 int num_internal = 10;
2075
2076 // Set up splitting map
7c673cae
FG
2077 OSDMap *osdmap = new OSDMap;
2078 uuid_d test_uuid;
2079 test_uuid.generate_random();
224ce89b 2080 osdmap->build_simple_with_pool(g_ceph_context, epoch, test_uuid, max_osd, bits, bits);
7c673cae
FG
2081 osdmap->set_state(osd_id, CEPH_OSD_EXISTS);
2082
2083 const string hit_set_namespace("internal");
2084
2085 {
2086 pg_log_entry_t e;
2087 e.mark_unrollbackable();
2088 e.op = pg_log_entry_t::MODIFY;
2089 e.soid.pool = pool_id;
2090
2091 uuid_d uuid_name;
2092 int i;
2093 for (i = 1; i <= num_objects; ++i) {
2094 e.version = eversion_t(epoch, i);
2095 // Use this to generate random file names
2096 uuid_name.generate_random();
2097 ostringstream name;
2098 name << uuid_name;
2099 e.soid.oid.name = name.str();
2100 // First has no namespace
2101 if (i != 1) {
2102 // num_internal have the internal namspace
2103 if (i <= num_internal + 1) {
2104 e.soid.nspace = hit_set_namespace;
2105 } else { // rest have different namespaces
2106 ostringstream ns;
2107 ns << "ns" << i;
2108 e.soid.nspace = ns.str();
2109 }
2110 }
2111 log.log.push_back(e);
2112 if (i == 1)
2113 log.tail = e.version;
7c673cae
FG
2114 }
2115 log.head = e.version;
2116 log.index();
2117 }
2118
2119 spg_t pgid(pg_t(2, pool_id), shard_id_t::NO_SHARD);
2120
2121 // See if we created the right number of entries
2122 int total = log.log.size();
2123 ASSERT_EQ(total, num_objects);
2124
2125 // Some should be removed
2126 {
2127 pg_log_t filtered, reject;
2128 pg_log_t::filter_log(
2129 pgid, *osdmap, hit_set_namespace, log, filtered, reject);
2130 log = IndexedLog(filtered);
2131 }
2132 EXPECT_LE(log.log.size(), (size_t)total);
2133
2134 // If we filter a second time, there should be the same total
2135 total = log.log.size();
2136 {
2137 pg_log_t filtered, reject;
2138 pg_log_t::filter_log(
2139 pgid, *osdmap, hit_set_namespace, log, filtered, reject);
2140 log = IndexedLog(filtered);
2141 }
2142 EXPECT_EQ(log.log.size(), (size_t)total);
2143
2144 // Increase pg_num as if there would be a split
2145 int new_pg_num = pg_num * 16;
2146 OSDMap::Incremental inc(epoch + 1);
2147 inc.fsid = test_uuid;
2148 const pg_pool_t *pool = osdmap->get_pg_pool(pool_id);
2149 pg_pool_t newpool;
2150 newpool = *pool;
2151 newpool.set_pg_num(new_pg_num);
2152 newpool.set_pgp_num(new_pg_num);
2153 inc.new_pools[pool_id] = newpool;
2154 int ret = osdmap->apply_incremental(inc);
2155 ASSERT_EQ(ret, 0);
2156
2157 // We should have fewer entries after a filter
2158 {
2159 pg_log_t filtered, reject;
2160 pg_log_t::filter_log(
2161 pgid, *osdmap, hit_set_namespace, log, filtered, reject);
2162 log = IndexedLog(filtered);
2163 }
2164 EXPECT_LE(log.log.size(), (size_t)total);
2165
2166 // Make sure all internal entries are retained
2167 int count = 0;
2168 for (list<pg_log_entry_t>::iterator i = log.log.begin();
2169 i != log.log.end(); ++i) {
2170 if (i->soid.nspace == hit_set_namespace) count++;
2171 }
2172 EXPECT_EQ(count, num_internal);
2173 }
2174}
2175
2176TEST_F(PGLogTest, get_request) {
2177 clear();
2178
2179 // make sure writes, deletes, and errors are found
2180 vector<pg_log_entry_t> entries;
2181 hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
2182 entries.push_back(
2183 pg_log_entry_t(pg_log_entry_t::ERROR, oid, eversion_t(6,2), eversion_t(3,4),
2184 1, osd_reqid_t(entity_name_t::CLIENT(777), 8, 1),
2185 utime_t(0,1), -ENOENT));
2186 entries.push_back(
2187 pg_log_entry_t(pg_log_entry_t::MODIFY, oid, eversion_t(6,3), eversion_t(3,4),
2188 2, osd_reqid_t(entity_name_t::CLIENT(777), 8, 2),
2189 utime_t(1,2), 0));
2190 entries.push_back(
2191 pg_log_entry_t(pg_log_entry_t::DELETE, oid, eversion_t(7,4), eversion_t(7,4),
2192 3, osd_reqid_t(entity_name_t::CLIENT(777), 8, 3),
2193 utime_t(10,2), 0));
2194 entries.push_back(
2195 pg_log_entry_t(pg_log_entry_t::ERROR, oid, eversion_t(7,5), eversion_t(7,4),
2196 3, osd_reqid_t(entity_name_t::CLIENT(777), 8, 4),
2197 utime_t(20,1), -ENOENT));
2198
2199 for (auto &entry : entries) {
2200 log.add(entry);
2201 }
2202
2203 for (auto &entry : entries) {
2204 eversion_t replay_version;
2205 version_t user_version;
2206 int return_code = 0;
2207 bool got = log.get_request(
2208 entry.reqid, &replay_version, &user_version, &return_code);
2209 EXPECT_TRUE(got);
2210 EXPECT_EQ(entry.return_code, return_code);
2211 EXPECT_EQ(entry.version, replay_version);
2212 EXPECT_EQ(entry.user_version, user_version);
2213 }
2214}
2215
2216TEST_F(PGLogTest, ErrorNotIndexedByObject) {
2217 clear();
2218
2219 // make sure writes, deletes, and errors are found
2220 hobject_t oid(object_t("objname"), "key", 123, 456, 0, "");
2221 log.add(
2222 pg_log_entry_t(pg_log_entry_t::ERROR, oid, eversion_t(6,2), eversion_t(3,4),
2223 1, osd_reqid_t(entity_name_t::CLIENT(777), 8, 1),
2224 utime_t(0,1), -ENOENT));
2225
2226 EXPECT_FALSE(log.logged_object(oid));
2227
2228 pg_log_entry_t modify(pg_log_entry_t::MODIFY, oid, eversion_t(6,3),
2229 eversion_t(3,4), 2,
2230 osd_reqid_t(entity_name_t::CLIENT(777), 8, 2),
2231 utime_t(1,2), 0);
2232 log.add(modify);
2233
2234 EXPECT_TRUE(log.logged_object(oid));
2235 pg_log_entry_t *entry = log.objects[oid];
2236 EXPECT_EQ(modify.op, entry->op);
2237 EXPECT_EQ(modify.version, entry->version);
2238 EXPECT_EQ(modify.prior_version, entry->prior_version);
2239 EXPECT_EQ(modify.user_version, entry->user_version);
2240 EXPECT_EQ(modify.reqid, entry->reqid);
2241
2242 pg_log_entry_t del(pg_log_entry_t::DELETE, oid, eversion_t(7,4),
2243 eversion_t(7,4), 3,
2244 osd_reqid_t(entity_name_t::CLIENT(777), 8, 3),
2245 utime_t(10,2), 0);
2246 log.add(del);
2247
2248 EXPECT_TRUE(log.logged_object(oid));
2249 entry = log.objects[oid];
2250 EXPECT_EQ(del.op, entry->op);
2251 EXPECT_EQ(del.version, entry->version);
2252 EXPECT_EQ(del.prior_version, entry->prior_version);
2253 EXPECT_EQ(del.user_version, entry->user_version);
2254 EXPECT_EQ(del.reqid, entry->reqid);
2255
2256 log.add(
2257 pg_log_entry_t(pg_log_entry_t::ERROR, oid, eversion_t(7,5), eversion_t(7,4),
2258 3, osd_reqid_t(entity_name_t::CLIENT(777), 8, 4),
2259 utime_t(20,1), -ENOENT));
2260
2261 EXPECT_TRUE(log.logged_object(oid));
2262 entry = log.objects[oid];
2263 EXPECT_EQ(del.op, entry->op);
2264 EXPECT_EQ(del.version, entry->version);
2265 EXPECT_EQ(del.prior_version, entry->prior_version);
2266 EXPECT_EQ(del.user_version, entry->user_version);
2267 EXPECT_EQ(del.reqid, entry->reqid);
2268}
2269
c07f9fc5
FG
2270TEST_F(PGLogTest, split_into_preserves_may_include_deletes) {
2271 clear();
2272
2273 {
2274 rebuilt_missing_with_deletes = false;
2275 missing.may_include_deletes = true;
11fdf7f2 2276 PGLog child_log(cct);
c07f9fc5
FG
2277 pg_t child_pg;
2278 split_into(child_pg, 6, &child_log);
2279 ASSERT_TRUE(child_log.get_missing().may_include_deletes);
2280 ASSERT_TRUE(child_log.get_rebuilt_missing_with_deletes());
2281 }
2282
2283 {
2284 rebuilt_missing_with_deletes = false;
2285 missing.may_include_deletes = false;
11fdf7f2 2286 PGLog child_log(cct);
c07f9fc5
FG
2287 pg_t child_pg;
2288 split_into(child_pg, 6, &child_log);
2289 ASSERT_FALSE(child_log.get_missing().may_include_deletes);
2290 ASSERT_FALSE(child_log.get_rebuilt_missing_with_deletes());
2291 }
2292}
2293
2294class PGLogTestRebuildMissing : public PGLogTest, public StoreTestFixture {
2295public:
2296 PGLogTestRebuildMissing() : PGLogTest(), StoreTestFixture("memstore") {}
2297 void SetUp() override {
2298 StoreTestFixture::SetUp();
c07f9fc5
FG
2299 ObjectStore::Transaction t;
2300 test_coll = coll_t(spg_t(pg_t(1, 1)));
11fdf7f2 2301 ch = store->create_new_collection(test_coll);
c07f9fc5 2302 t.create_collection(test_coll, 0);
11fdf7f2 2303 store->queue_transaction(ch, std::move(t));
c07f9fc5
FG
2304 existing_oid = mk_obj(0);
2305 nonexistent_oid = mk_obj(1);
2306 ghobject_t existing_ghobj(existing_oid);
2307 object_info_t existing_info;
2308 existing_info.version = eversion_t(6, 2);
2309 bufferlist enc_oi;
11fdf7f2 2310 encode(existing_info, enc_oi, 0);
c07f9fc5
FG
2311 ObjectStore::Transaction t2;
2312 t2.touch(test_coll, ghobject_t(existing_oid));
2313 t2.setattr(test_coll, ghobject_t(existing_oid), OI_ATTR, enc_oi);
11fdf7f2 2314 ASSERT_EQ(0, store->queue_transaction(ch, std::move(t2)));
c07f9fc5
FG
2315 info.last_backfill = hobject_t::get_max();
2316 info.last_complete = eversion_t();
2317 }
2318
2319 void TearDown() override {
2320 clear();
2321 missing.may_include_deletes = false;
2322 StoreTestFixture::TearDown();
2323 }
2324
2325 pg_info_t info;
2326 coll_t test_coll;
2327 hobject_t existing_oid, nonexistent_oid;
2328
2329 void run_rebuild_missing_test(const map<hobject_t, pg_missing_item> &expected_missing_items) {
11fdf7f2 2330 rebuild_missing_set_with_deletes(store.get(), ch, info);
c07f9fc5
FG
2331 ASSERT_EQ(expected_missing_items, missing.get_items());
2332 }
2333};
2334
2335TEST_F(PGLogTestRebuildMissing, EmptyLog) {
2336 missing.add(existing_oid, mk_evt(6, 2), mk_evt(6, 3), false);
2337 missing.add(nonexistent_oid, mk_evt(7, 4), mk_evt(0, 0), false);
2338 map<hobject_t, pg_missing_item> orig_missing = missing.get_items();
2339 run_rebuild_missing_test(orig_missing);
2340}
2341
2342TEST_F(PGLogTestRebuildMissing, SameVersionMod) {
2343 missing.add(existing_oid, mk_evt(6, 2), mk_evt(6, 1), false);
2344 log.add(mk_ple_mod(existing_oid, mk_evt(6, 2), mk_evt(6, 1)));
2345 map<hobject_t, pg_missing_item> empty_missing;
2346 run_rebuild_missing_test(empty_missing);
2347}
2348
2349TEST_F(PGLogTestRebuildMissing, DelExisting) {
2350 missing.add(existing_oid, mk_evt(6, 3), mk_evt(6, 2), false);
2351 log.add(mk_ple_dt(existing_oid, mk_evt(7, 5), mk_evt(7, 4)));
2352 map<hobject_t, pg_missing_item> expected;
2353 expected[existing_oid] = pg_missing_item(mk_evt(7, 5), mk_evt(6, 2), true);
2354 run_rebuild_missing_test(expected);
2355}
2356
2357TEST_F(PGLogTestRebuildMissing, DelNonexistent) {
2358 log.add(mk_ple_dt(nonexistent_oid, mk_evt(7, 5), mk_evt(7, 4)));
2359 map<hobject_t, pg_missing_item> expected;
2360 expected[nonexistent_oid] = pg_missing_item(mk_evt(7, 5), mk_evt(0, 0), true);
2361 run_rebuild_missing_test(expected);
2362}
2363
2364TEST_F(PGLogTestRebuildMissing, MissingNotInLog) {
2365 missing.add(mk_obj(10), mk_evt(8, 12), mk_evt(8, 10), false);
2366 log.add(mk_ple_dt(nonexistent_oid, mk_evt(7, 5), mk_evt(7, 4)));
2367 map<hobject_t, pg_missing_item> expected;
2368 expected[nonexistent_oid] = pg_missing_item(mk_evt(7, 5), mk_evt(0, 0), true);
2369 expected[mk_obj(10)] = pg_missing_item(mk_evt(8, 12), mk_evt(8, 10), false);
2370 run_rebuild_missing_test(expected);
2371}
2372
2373
181888fb 2374class PGLogMergeDupsTest : protected PGLog, public StoreTestFixture {
c07f9fc5
FG
2375
2376public:
2377
181888fb 2378 PGLogMergeDupsTest() : PGLog(g_ceph_context), StoreTestFixture("memstore") { }
c07f9fc5 2379
181888fb
FG
2380 void SetUp() override {
2381 StoreTestFixture::SetUp();
181888fb
FG
2382 ObjectStore::Transaction t;
2383 test_coll = coll_t(spg_t(pg_t(1, 1)));
11fdf7f2 2384 auto ch = store->create_new_collection(test_coll);
181888fb 2385 t.create_collection(test_coll, 0);
11fdf7f2 2386 store->queue_transaction(ch, std::move(t));
181888fb 2387 }
c07f9fc5
FG
2388
2389 void TearDown() override {
181888fb 2390 test_disk_roundtrip();
c07f9fc5 2391 clear();
181888fb 2392 StoreTestFixture::TearDown();
c07f9fc5
FG
2393 }
2394
2395 static pg_log_dup_t create_dup_entry(uint a, uint b) {
2396 // make each dup_entry unique by using different client id's
2397 static uint client_id = 777;
2398 return pg_log_dup_t(eversion_t(a, b),
2399 a,
2400 osd_reqid_t(entity_name_t::CLIENT(client_id++), 8, 1),
2401 0);
2402 }
2403
2404 static std::vector<pg_log_dup_t> example_dups_1() {
2405 std::vector<pg_log_dup_t> result = {
2406 create_dup_entry(10, 11),
2407 create_dup_entry(10, 12),
2408 create_dup_entry(11, 1),
2409 create_dup_entry(12, 3),
2410 create_dup_entry(13, 99)
2411 };
2412 return result;
2413 }
2414
2415 static std::vector<pg_log_dup_t> example_dups_2() {
2416 std::vector<pg_log_dup_t> result = {
2417 create_dup_entry(12, 3),
2418 create_dup_entry(13, 99),
2419 create_dup_entry(15, 11),
2420 create_dup_entry(16, 14),
2421 create_dup_entry(16, 32)
2422 };
2423 return result;
2424 }
2425
2426 void add_dups(uint a, uint b) {
2427 log.dups.push_back(create_dup_entry(a, b));
11fdf7f2 2428 write_from_dups = std::min(write_from_dups, log.dups.back().version);
c07f9fc5
FG
2429 }
2430
2431 void add_dups(const std::vector<pg_log_dup_t>& l) {
2432 for (auto& i : l) {
2433 log.dups.push_back(i);
11fdf7f2 2434 write_from_dups = std::min(write_from_dups, log.dups.back().version);
c07f9fc5
FG
2435 }
2436 }
2437
2438 static void add_dups(IndexedLog& log, const std::vector<pg_log_dup_t>& dups) {
2439 for (auto& i : dups) {
2440 log.dups.push_back(i);
2441 }
2442 }
2443
2444 void check_order() {
2445 eversion_t prev(0, 0);
2446
2447 for (auto& i : log.dups) {
2448 EXPECT_LT(prev, i.version) << "verify versions monotonically increase";
2449 prev = i.version;
2450 }
2451 }
2452
2453 void check_index() {
2454 EXPECT_EQ(log.dups.size(), log.dup_index.size());
2455 for (auto& i : log.dups) {
2456 EXPECT_EQ(1u, log.dup_index.count(i.reqid));
2457 }
2458 }
181888fb
FG
2459
2460 void test_disk_roundtrip() {
181888fb
FG
2461 ObjectStore::Transaction t;
2462 hobject_t hoid;
2463 hoid.pool = 1;
2464 hoid.oid = "log";
2465 ghobject_t log_oid(hoid);
2466 map<string, bufferlist> km;
2467 write_log_and_missing(t, &km, test_coll, log_oid, false);
2468 if (!km.empty()) {
2469 t.omap_setkeys(test_coll, log_oid, km);
2470 }
11fdf7f2
TL
2471 auto ch = store->open_collection(test_coll);
2472 ASSERT_EQ(0, store->queue_transaction(ch, std::move(t)));
181888fb
FG
2473
2474 auto orig_dups = log.dups;
2475 clear();
2476 ostringstream err;
11fdf7f2
TL
2477 read_log_and_missing(store.get(), ch, log_oid,
2478 pg_info_t(), err, false);
181888fb
FG
2479 ASSERT_EQ(orig_dups.size(), log.dups.size());
2480 ASSERT_EQ(orig_dups, log.dups);
2481 auto dups_it = log.dups.begin();
2482 for (auto orig_dup : orig_dups) {
2483 ASSERT_EQ(orig_dup, *dups_it);
2484 ++dups_it;
2485 }
2486 }
2487
2488 coll_t test_coll;
c07f9fc5
FG
2489};
2490
2491TEST_F(PGLogMergeDupsTest, OtherEmpty) {
2492 log.tail = eversion_t(14, 5);
2493
2494 IndexedLog olog;
2495
2496 add_dups(example_dups_1());
2497 index();
2498
2499 bool changed = merge_log_dups(olog);
2500
2501 EXPECT_FALSE(changed);
2502 EXPECT_EQ(5u, log.dups.size());
2503
2504 if (5 == log.dups.size()) {
2505 EXPECT_EQ(10u, log.dups.front().version.epoch);
2506 EXPECT_EQ(11u, log.dups.front().version.version);
2507 EXPECT_EQ(13u, log.dups.back().version.epoch);
2508 EXPECT_EQ(99u, log.dups.back().version.version);
2509 }
2510
2511 check_order();
2512 check_index();
2513}
2514
2515TEST_F(PGLogMergeDupsTest, AmEmpty) {
2516 log.tail = eversion_t(14, 5);
2517 index();
2518
2519 IndexedLog olog;
2520
2521 add_dups(olog, example_dups_1());
2522
2523 bool changed = merge_log_dups(olog);
2524
2525 EXPECT_TRUE(changed);
2526 EXPECT_EQ(5u, log.dups.size());
2527
2528 if (5 == log.dups.size()) {
2529 EXPECT_EQ(10u, log.dups.front().version.epoch);
2530 EXPECT_EQ(11u, log.dups.front().version.version);
2531
2532 EXPECT_EQ(13u, log.dups.back().version.epoch);
2533 EXPECT_EQ(99u, log.dups.back().version.version);
2534 }
2535
2536 check_order();
2537 check_index();
2538}
2539
2540TEST_F(PGLogMergeDupsTest, AmEmptyOverlap) {
2541 log.tail = eversion_t(12, 3);
2542 index();
2543
2544 IndexedLog olog;
2545
2546 add_dups(olog, example_dups_1());
2547
2548 bool changed = merge_log_dups(olog);
2549
2550 EXPECT_TRUE(changed);
81eedcae 2551 EXPECT_EQ(4u, log.dups.size());
c07f9fc5 2552
81eedcae 2553 if (4 == log.dups.size()) {
c07f9fc5
FG
2554 EXPECT_EQ(10u, log.dups.front().version.epoch);
2555 EXPECT_EQ(11u, log.dups.front().version.version);
2556
81eedcae
TL
2557 EXPECT_EQ(12u, log.dups.back().version.epoch);
2558 EXPECT_EQ(3u, log.dups.back().version.version);
c07f9fc5
FG
2559 }
2560
2561 check_order();
2562 check_index();
2563}
2564
2565TEST_F(PGLogMergeDupsTest, Same) {
2566 log.tail = eversion_t(14, 1);
2567
2568 IndexedLog olog;
2569
2570 add_dups(example_dups_1());
2571 index();
2572 add_dups(olog, example_dups_1());
2573
2574 bool changed = merge_log_dups(olog);
2575
2576 EXPECT_FALSE(changed);
2577 EXPECT_EQ(5u, log.dups.size());
2578
2579 if (5 == log.dups.size()) {
2580 EXPECT_EQ(10u, log.dups.front().version.epoch);
2581 EXPECT_EQ(11u, log.dups.front().version.version);
2582
2583 EXPECT_EQ(13u, log.dups.back().version.epoch);
2584 EXPECT_EQ(99u, log.dups.back().version.version);
2585 }
2586
2587 check_order();
2588 check_index();
2589}
2590
2591
2592TEST_F(PGLogMergeDupsTest, Later) {
2593 log.tail = eversion_t(16, 14);
2594
2595 IndexedLog olog;
2596
2597 add_dups(example_dups_1());
2598 index();
2599 add_dups(olog, example_dups_2());
2600
2601 bool changed = merge_log_dups(olog);
2602
2603 EXPECT_TRUE(changed);
81eedcae 2604 EXPECT_EQ(7u, log.dups.size());
c07f9fc5 2605
81eedcae 2606 if (7 == log.dups.size()) {
c07f9fc5
FG
2607 EXPECT_EQ(10u, log.dups.front().version.epoch);
2608 EXPECT_EQ(11u, log.dups.front().version.version);
2609
81eedcae
TL
2610 EXPECT_EQ(16u, log.dups.back().version.epoch);
2611 EXPECT_EQ(14u, log.dups.back().version.version);
c07f9fc5
FG
2612 }
2613
2614 check_order();
2615 check_index();
2616}
2617
2618
2619TEST_F(PGLogMergeDupsTest, Earlier) {
2620 log.tail = eversion_t(17, 2);
2621
2622 IndexedLog olog;
2623
2624 add_dups(example_dups_2());
2625 index();
2626 add_dups(olog, example_dups_1());
2627
2628 bool changed = merge_log_dups(olog);
2629
2630 EXPECT_TRUE(changed);
2631 EXPECT_EQ(8u, log.dups.size());
2632
2633 if (6 == log.dups.size()) {
2634 EXPECT_EQ(10u, log.dups.front().version.epoch);
2635 EXPECT_EQ(11u, log.dups.front().version.version);
2636
2637 EXPECT_EQ(16u, log.dups.back().version.epoch);
2638 EXPECT_EQ(32u, log.dups.back().version.version);
2639 }
2640
2641 check_order();
2642 check_index();
2643}
2644
2645
2646TEST_F(PGLogMergeDupsTest, Superset) {
2647 log.tail = eversion_t(17, 2);
2648
2649 IndexedLog olog;
2650
2651 add_dups(example_dups_1());
2652 index();
2653
2654 olog.dups.push_back(create_dup_entry(9, 5));
2655 olog.dups.push_back(create_dup_entry(15, 11));
2656
2657 bool changed = merge_log_dups(olog);
2658
2659 EXPECT_TRUE(changed);
2660 EXPECT_EQ(7u, log.dups.size());
2661
2662 if (7 == log.dups.size()) {
2663 EXPECT_EQ(9u, log.dups.front().version.epoch);
2664 EXPECT_EQ(5u, log.dups.front().version.version);
2665
2666 EXPECT_EQ(15u, log.dups.back().version.epoch);
2667 EXPECT_EQ(11u, log.dups.back().version.version);
2668 }
2669
2670 check_order();
2671 check_index();
2672}
2673
2674
2675struct PGLogTrimTest :
2676 public ::testing::Test,
2677 public PGLogTestBase,
2678 public PGLog::IndexedLog
2679{
181888fb 2680 CephContext *cct = g_ceph_context;
c07f9fc5 2681
11fdf7f2 2682 using ::testing::Test::SetUp;
81eedcae 2683 void SetUp(unsigned dup_track) {
c07f9fc5
FG
2684 constexpr size_t size = 10;
2685
c07f9fc5
FG
2686 char dup_track_s[size];
2687
c07f9fc5
FG
2688 snprintf(dup_track_s, size, "%u", dup_track);
2689
11fdf7f2 2690 cct->_conf.set_val_or_die("osd_pg_log_dups_tracked", dup_track_s);
c07f9fc5
FG
2691 }
2692}; // struct PGLogTrimTest
2693
2694
c07f9fc5
FG
2695TEST_F(PGLogTrimTest, TestMakingCephContext)
2696{
81eedcae 2697 SetUp(5);
c07f9fc5 2698
c07f9fc5
FG
2699 EXPECT_EQ(5u, cct->_conf->osd_pg_log_dups_tracked);
2700}
2701
2702
2703TEST_F(PGLogTrimTest, TestPartialTrim)
2704{
81eedcae 2705 SetUp(20);
c07f9fc5
FG
2706 PGLog::IndexedLog log;
2707 log.head = mk_evt(24, 0);
2708 log.skip_can_rollback_to_to_head();
2709 log.head = mk_evt(9, 0);
2710
2711 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2712 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 150), mk_evt(10, 100)));
2713 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 155), mk_evt(15, 150)));
2714 log.add(mk_ple_mod(mk_obj(1), mk_evt(19, 160), mk_evt(25, 152)));
2715 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 165), mk_evt(26, 160)));
2716 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 167), mk_evt(31, 166)));
2717
2718 std::set<eversion_t> trimmed;
2719 std::set<std::string> trimmed_dups;
181888fb 2720 eversion_t write_from_dups = eversion_t::max();
c07f9fc5 2721
181888fb 2722 log.trim(cct, mk_evt(19, 157), &trimmed, &trimmed_dups, &write_from_dups);
c07f9fc5 2723
181888fb 2724 EXPECT_EQ(eversion_t(15, 150), write_from_dups);
c07f9fc5
FG
2725 EXPECT_EQ(3u, log.log.size());
2726 EXPECT_EQ(3u, trimmed.size());
2727 EXPECT_EQ(2u, log.dups.size());
2728 EXPECT_EQ(0u, trimmed_dups.size());
2729
81eedcae 2730 SetUp(15);
c07f9fc5
FG
2731
2732 std::set<eversion_t> trimmed2;
2733 std::set<std::string> trimmed_dups2;
181888fb 2734 eversion_t write_from_dups2 = eversion_t::max();
c07f9fc5 2735
181888fb
FG
2736 log.trim(cct, mk_evt(20, 164), &trimmed2, &trimmed_dups2, &write_from_dups2);
2737
2738 EXPECT_EQ(eversion_t(19, 160), write_from_dups2);
c07f9fc5
FG
2739 EXPECT_EQ(2u, log.log.size());
2740 EXPECT_EQ(1u, trimmed2.size());
2741 EXPECT_EQ(2u, log.dups.size());
2742 EXPECT_EQ(1u, trimmed_dups2.size());
2743}
2744
2745
2746TEST_F(PGLogTrimTest, TestTrimNoTrimmed) {
81eedcae 2747 SetUp(20);
c07f9fc5
FG
2748 PGLog::IndexedLog log;
2749 log.head = mk_evt(20, 0);
2750 log.skip_can_rollback_to_to_head();
2751 log.head = mk_evt(9, 0);
2752
2753 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2754 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 150), mk_evt(10, 100)));
2755 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 155), mk_evt(15, 150)));
2756 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 160), mk_evt(25, 152)));
2757 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 165), mk_evt(26, 160)));
2758 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 167), mk_evt(31, 166)));
2759
181888fb 2760 eversion_t write_from_dups = eversion_t::max();
c07f9fc5 2761
181888fb 2762 log.trim(cct, mk_evt(19, 157), nullptr, nullptr, &write_from_dups);
c07f9fc5 2763
181888fb 2764 EXPECT_EQ(eversion_t(15, 150), write_from_dups);
c07f9fc5
FG
2765 EXPECT_EQ(3u, log.log.size());
2766 EXPECT_EQ(2u, log.dups.size());
2767}
2768
2769
2770TEST_F(PGLogTrimTest, TestTrimNoDups)
2771{
81eedcae 2772 SetUp(10);
c07f9fc5
FG
2773 PGLog::IndexedLog log;
2774 log.head = mk_evt(20, 0);
2775 log.skip_can_rollback_to_to_head();
2776 log.head = mk_evt(9, 0);
2777
2778 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2779 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 150), mk_evt(10, 100)));
2780 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 155), mk_evt(15, 150)));
2781 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 160), mk_evt(25, 152)));
2782 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 165), mk_evt(26, 160)));
2783 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 167), mk_evt(31, 166)));
2784
2785 std::set<eversion_t> trimmed;
2786 std::set<std::string> trimmed_dups;
181888fb 2787 eversion_t write_from_dups = eversion_t::max();
c07f9fc5 2788
181888fb 2789 log.trim(cct, mk_evt(19, 157), &trimmed, &trimmed_dups, &write_from_dups);
c07f9fc5 2790
181888fb 2791 EXPECT_EQ(eversion_t::max(), write_from_dups);
c07f9fc5
FG
2792 EXPECT_EQ(3u, log.log.size());
2793 EXPECT_EQ(3u, trimmed.size());
2794 EXPECT_EQ(0u, log.dups.size());
2795 EXPECT_EQ(0u, trimmed_dups.size());
2796}
2797
2798TEST_F(PGLogTrimTest, TestNoTrim)
2799{
81eedcae 2800 SetUp(20);
c07f9fc5
FG
2801 PGLog::IndexedLog log;
2802 log.head = mk_evt(24, 0);
2803 log.skip_can_rollback_to_to_head();
2804 log.head = mk_evt(9, 0);
2805
2806 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2807 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 150), mk_evt(10, 100)));
2808 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 155), mk_evt(15, 150)));
2809 log.add(mk_ple_mod(mk_obj(1), mk_evt(19, 160), mk_evt(25, 152)));
2810 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 165), mk_evt(26, 160)));
2811 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 167), mk_evt(31, 166)));
2812
2813 std::set<eversion_t> trimmed;
2814 std::set<std::string> trimmed_dups;
181888fb 2815 eversion_t write_from_dups = eversion_t::max();
c07f9fc5 2816
181888fb 2817 log.trim(cct, mk_evt(9, 99), &trimmed, &trimmed_dups, &write_from_dups);
c07f9fc5 2818
181888fb 2819 EXPECT_EQ(eversion_t::max(), write_from_dups);
c07f9fc5
FG
2820 EXPECT_EQ(6u, log.log.size());
2821 EXPECT_EQ(0u, trimmed.size());
2822 EXPECT_EQ(0u, log.dups.size());
2823 EXPECT_EQ(0u, trimmed_dups.size());
2824}
2825
2826TEST_F(PGLogTrimTest, TestTrimAll)
2827{
81eedcae 2828 SetUp(20);
c07f9fc5 2829 PGLog::IndexedLog log;
a8e16298 2830 EXPECT_EQ(0u, log.dup_index.size()); // Sanity check
c07f9fc5
FG
2831 log.head = mk_evt(24, 0);
2832 log.skip_can_rollback_to_to_head();
2833 log.head = mk_evt(9, 0);
2834
2835 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70)));
2836 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 150), mk_evt(10, 100)));
2837 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 155), mk_evt(15, 150)));
2838 log.add(mk_ple_mod(mk_obj(1), mk_evt(19, 160), mk_evt(25, 152)));
2839 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 165), mk_evt(26, 160)));
2840 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 167), mk_evt(31, 166)));
2841
2842 std::set<eversion_t> trimmed;
2843 std::set<std::string> trimmed_dups;
181888fb 2844 eversion_t write_from_dups = eversion_t::max();
c07f9fc5 2845
181888fb 2846 log.trim(cct, mk_evt(22, 180), &trimmed, &trimmed_dups, &write_from_dups);
c07f9fc5 2847
181888fb 2848 EXPECT_EQ(eversion_t(15, 150), write_from_dups);
c07f9fc5
FG
2849 EXPECT_EQ(0u, log.log.size());
2850 EXPECT_EQ(6u, trimmed.size());
2851 EXPECT_EQ(5u, log.dups.size());
2852 EXPECT_EQ(0u, trimmed_dups.size());
a8e16298 2853 EXPECT_EQ(0u, log.dup_index.size()); // dup_index entry should be trimmed
c07f9fc5
FG
2854}
2855
2856
2857TEST_F(PGLogTrimTest, TestGetRequest) {
81eedcae 2858 SetUp(20);
c07f9fc5
FG
2859 PGLog::IndexedLog log;
2860 log.head = mk_evt(20, 0);
2861 log.skip_can_rollback_to_to_head();
2862 log.head = mk_evt(9, 0);
2863
2864 entity_name_t client = entity_name_t::CLIENT(777);
2865
2866 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(8, 70),
2867 osd_reqid_t(client, 8, 1)));
2868 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 150), mk_evt(10, 100),
2869 osd_reqid_t(client, 8, 2)));
2870 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 155), mk_evt(15, 150),
2871 osd_reqid_t(client, 8, 3)));
2872 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 160), mk_evt(25, 152),
2873 osd_reqid_t(client, 8, 4)));
2874 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 165), mk_evt(26, 160),
2875 osd_reqid_t(client, 8, 5)));
2876 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 167), mk_evt(31, 166),
2877 osd_reqid_t(client, 8, 6)));
2878
181888fb 2879 eversion_t write_from_dups = eversion_t::max();
c07f9fc5 2880
181888fb 2881 log.trim(cct, mk_evt(19, 157), nullptr, nullptr, &write_from_dups);
c07f9fc5 2882
181888fb 2883 EXPECT_EQ(eversion_t(15, 150), write_from_dups);
c07f9fc5
FG
2884 EXPECT_EQ(3u, log.log.size());
2885 EXPECT_EQ(2u, log.dups.size());
2886
2887 eversion_t version;
2888 version_t user_version;
2889 int return_code;
2890
2891 osd_reqid_t log_reqid = osd_reqid_t(client, 8, 5);
2892 osd_reqid_t dup_reqid = osd_reqid_t(client, 8, 3);
2893 osd_reqid_t bad_reqid = osd_reqid_t(client, 8, 1);
2894
2895 bool result;
2896
2897 result = log.get_request(log_reqid, &version, &user_version, &return_code);
2898 EXPECT_EQ(true, result);
2899 EXPECT_EQ(mk_evt(21, 165), version);
2900
2901 result = log.get_request(dup_reqid, &version, &user_version, &return_code);
2902 EXPECT_EQ(true, result);
2903 EXPECT_EQ(mk_evt(15, 155), version);
2904
2905 result = log.get_request(bad_reqid, &version, &user_version, &return_code);
2906 EXPECT_FALSE(result);
2907}
2908
d2e6a577
FG
2909TEST_F(PGLogTest, _merge_object_divergent_entries) {
2910 {
2911 // Test for issue 20843
2912 clear();
2913 hobject_t hoid(object_t(/*name*/"notify.7"),
2914 /*key*/string(""),
2915 /*snap*/7,
2916 /*hash*/77,
2917 /*pool*/5,
2918 /*nspace*/string(""));
2919 mempool::osd_pglog::list<pg_log_entry_t> orig_entries;
2920 orig_entries.push_back(mk_ple_mod(hoid, eversion_t(8336, 957), eversion_t(8336, 952)));
2921 orig_entries.push_back(mk_ple_err(hoid, eversion_t(8336, 958)));
2922 orig_entries.push_back(mk_ple_err(hoid, eversion_t(8336, 959)));
2923 orig_entries.push_back(mk_ple_mod(hoid, eversion_t(8336, 960), eversion_t(8336, 957)));
2924 log.add(mk_ple_mod(hoid, eversion_t(8973, 1075), eversion_t(8971, 1070)));
2925 missing.add(hoid,
2926 /*need*/eversion_t(8971, 1070),
2927 /*have*/eversion_t(8336, 952),
2928 false);
2929 pg_info_t oinfo;
2930 LogHandler rollbacker;
2931 _merge_object_divergent_entries(log, hoid,
2932 orig_entries, oinfo,
2933 log.get_can_rollback_to(),
81eedcae 2934 log.get_can_rollback_to(),
d2e6a577
FG
2935 missing, &rollbacker,
2936 this);
2937 // No core dump
2938 }
2939 {
2940 // skip leading error entries
2941 clear();
2942 hobject_t hoid(object_t(/*name*/"notify.7"),
2943 /*key*/string(""),
2944 /*snap*/7,
2945 /*hash*/77,
2946 /*pool*/5,
2947 /*nspace*/string(""));
2948 mempool::osd_pglog::list<pg_log_entry_t> orig_entries;
2949 orig_entries.push_back(mk_ple_err(hoid, eversion_t(8336, 956)));
2950 orig_entries.push_back(mk_ple_mod(hoid, eversion_t(8336, 957), eversion_t(8336, 952)));
2951 log.add(mk_ple_mod(hoid, eversion_t(8973, 1075), eversion_t(8971, 1070)));
2952 missing.add(hoid,
2953 /*need*/eversion_t(8971, 1070),
2954 /*have*/eversion_t(8336, 952),
2955 false);
2956 pg_info_t oinfo;
2957 LogHandler rollbacker;
2958 _merge_object_divergent_entries(log, hoid,
2959 orig_entries, oinfo,
2960 log.get_can_rollback_to(),
81eedcae 2961 log.get_can_rollback_to(),
d2e6a577
FG
2962 missing, &rollbacker,
2963 this);
2964 // No core dump
2965 }
2966}
c07f9fc5 2967
11fdf7f2
TL
2968TEST(eversion_t, get_key_name) {
2969 eversion_t a(1234, 5678);
2970 std::string a_key_name = a.get_key_name();
2971 EXPECT_EQ("0000001234.00000000000000005678", a_key_name);
2972}
2973
2974TEST(pg_log_dup_t, get_key_name) {
2975 pg_log_dup_t a(eversion_t(1234, 5678),
2976 13,
2977 osd_reqid_t(entity_name_t::CLIENT(777), 8, 999),
2978 15);
2979 std::string a_key_name = a.get_key_name();
2980 EXPECT_EQ("dup_0000001234.00000000000000005678", a_key_name);
2981}
181888fb 2982
81eedcae
TL
2983
2984// This tests trim() to make copies of
2985// 2 log entries (107, 106) and 3 additional for a total
2986// of 5 dups. Nothing from the original dups is copied.
2987TEST_F(PGLogTrimTest, TestTrimDups) {
2988 SetUp(5);
2989 PGLog::IndexedLog log;
2990 log.head = mk_evt(21, 107);
2991 log.skip_can_rollback_to_to_head();
2992 log.tail = mk_evt(9, 99);
2993 log.head = mk_evt(9, 99);
2994
2995 entity_name_t client = entity_name_t::CLIENT(777);
2996
2997 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
2998 mk_evt(9, 99), mk_evt(8, 98), osd_reqid_t(client, 8, 1))));
2999
3000 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(9, 99),
3001 osd_reqid_t(client, 8, 1)));
3002 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 101), mk_evt(10, 100),
3003 osd_reqid_t(client, 8, 2)));
3004 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 102), mk_evt(15, 101),
3005 osd_reqid_t(client, 8, 3)));
3006 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 103), mk_evt(15, 102),
3007 osd_reqid_t(client, 8, 4)));
3008 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 104), mk_evt(20, 103),
3009 osd_reqid_t(client, 8, 5)));
3010 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 105), mk_evt(21, 104),
3011 osd_reqid_t(client, 8, 6)));
3012 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 106), mk_evt(21, 105),
3013 osd_reqid_t(client, 8, 6)));
3014 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 107), mk_evt(21, 106),
3015 osd_reqid_t(client, 8, 6)));
3016
3017 eversion_t write_from_dups = eversion_t::max();
3018
3019 log.trim(cct, mk_evt(21, 105), nullptr, nullptr, &write_from_dups);
3020
3021 EXPECT_EQ(eversion_t(20, 103), write_from_dups) << log;
3022 EXPECT_EQ(2u, log.log.size()) << log;
3023 EXPECT_EQ(3u, log.dups.size()) << log;
3024}
3025
3026// This tests trim() to make copies of
3027// 4 log entries (107, 106, 105, 104) and 5 additional for a total
3028// of 9 dups. Only 1 of 2 existing dups are copied.
3029TEST_F(PGLogTrimTest, TestTrimDups2) {
3030 SetUp(9);
3031 PGLog::IndexedLog log;
3032 log.head = mk_evt(21, 107);
3033 log.skip_can_rollback_to_to_head();
3034 log.tail = mk_evt(9, 99);
3035 log.head = mk_evt(9, 99);
3036
3037 entity_name_t client = entity_name_t::CLIENT(777);
3038
3039 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3040 mk_evt(9, 98), mk_evt(8, 97), osd_reqid_t(client, 8, 1))));
3041 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3042 mk_evt(9, 99), mk_evt(8, 98), osd_reqid_t(client, 8, 1))));
3043
3044 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(9, 99),
3045 osd_reqid_t(client, 8, 1)));
3046 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 101), mk_evt(10, 100),
3047 osd_reqid_t(client, 8, 2)));
3048 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 102), mk_evt(15, 101),
3049 osd_reqid_t(client, 8, 3)));
3050 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 103), mk_evt(15, 102),
3051 osd_reqid_t(client, 8, 4)));
3052 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 104), mk_evt(20, 103),
3053 osd_reqid_t(client, 8, 5)));
3054 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 105), mk_evt(21, 104),
3055 osd_reqid_t(client, 8, 6)));
3056 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 106), mk_evt(21, 105),
3057 osd_reqid_t(client, 8, 6)));
3058 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 107), mk_evt(21, 106),
3059 osd_reqid_t(client, 8, 6)));
3060
3061 eversion_t write_from_dups = eversion_t::max();
3062
3063 log.trim(cct, mk_evt(20, 103), nullptr, nullptr, &write_from_dups);
3064
3065 EXPECT_EQ(eversion_t(10, 100), write_from_dups) << log;
3066 EXPECT_EQ(4u, log.log.size()) << log;
3067 EXPECT_EQ(5u, log.dups.size()) << log;
3068}
3069
3070// This tests copy_up_to() to make copies of
3071// 2 log entries (107, 106) and 3 additional for a total
3072// of 5 dups. Nothing from the original dups is copied.
3073TEST_F(PGLogTrimTest, TestCopyUpTo) {
3074 SetUp(5);
3075 PGLog::IndexedLog log, copy;
3076 log.tail = mk_evt(9, 99);
3077 log.head = mk_evt(9, 99);
3078
3079 entity_name_t client = entity_name_t::CLIENT(777);
3080
3081 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3082 mk_evt(9, 99), mk_evt(8, 98), osd_reqid_t(client, 8, 1))));
3083
3084 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(9, 99),
3085 osd_reqid_t(client, 8, 1)));
3086 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 101), mk_evt(10, 100),
3087 osd_reqid_t(client, 8, 2)));
3088 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 102), mk_evt(15, 101),
3089 osd_reqid_t(client, 8, 3)));
3090 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 103), mk_evt(15, 102),
3091 osd_reqid_t(client, 8, 4)));
3092 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 104), mk_evt(20, 103),
3093 osd_reqid_t(client, 8, 5)));
3094 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 105), mk_evt(21, 104),
3095 osd_reqid_t(client, 8, 6)));
3096 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 106), mk_evt(21, 105),
3097 osd_reqid_t(client, 8, 6)));
3098 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 107), mk_evt(21, 106),
3099 osd_reqid_t(client, 8, 6)));
3100
3101 copy.copy_up_to(cct, log, 2);
3102
3103 EXPECT_EQ(2u, copy.log.size()) << copy;
3104 EXPECT_EQ(copy.head, mk_evt(21, 107)) << copy;
3105 EXPECT_EQ(copy.tail, mk_evt(21, 105)) << copy;
3106 // Tracking 5 means 3 additional as dups
3107 EXPECT_EQ(3u, copy.dups.size()) << copy;
3108}
3109
3110// This tests copy_up_to() to make copies of
3111// 4 log entries (107, 106, 105, 104) and 5 additional for a total
3112// of 5 dups. Only 1 of 2 existing dups are copied.
3113TEST_F(PGLogTrimTest, TestCopyUpTo2) {
3114 SetUp(9);
3115 PGLog::IndexedLog log, copy;
3116 log.tail = mk_evt(9, 99);
3117 log.head = mk_evt(9, 99);
3118
3119 entity_name_t client = entity_name_t::CLIENT(777);
3120
3121 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3122 mk_evt(8, 98), mk_evt(8, 97), osd_reqid_t(client, 8, 1))));
3123 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3124 mk_evt(9, 99), mk_evt(8, 98), osd_reqid_t(client, 8, 1))));
3125
3126 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(9, 99),
3127 osd_reqid_t(client, 8, 1)));
3128 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 101), mk_evt(10, 100),
3129 osd_reqid_t(client, 8, 2)));
3130 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 102), mk_evt(15, 101),
3131 osd_reqid_t(client, 8, 3)));
3132 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 103), mk_evt(15, 102),
3133 osd_reqid_t(client, 8, 4)));
3134 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 104), mk_evt(20, 103),
3135 osd_reqid_t(client, 8, 5)));
3136 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 105), mk_evt(21, 104),
3137 osd_reqid_t(client, 8, 6)));
3138 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 106), mk_evt(21, 105),
3139 osd_reqid_t(client, 8, 6)));
3140 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 107), mk_evt(21, 106),
3141 osd_reqid_t(client, 8, 6)));
3142
3143 copy.copy_up_to(cct, log, 4);
3144
3145 EXPECT_EQ(4u, copy.log.size()) << copy;
3146 EXPECT_EQ(copy.head, mk_evt(21, 107)) << copy;
3147 EXPECT_EQ(copy.tail, mk_evt(20, 103)) << copy;
3148 // Tracking 5 means 3 additional as dups
3149 EXPECT_EQ(5u, copy.dups.size()) << copy;
3150}
3151
3152// This tests copy_after() by specifying a version that copies
3153// 2 log entries (107, 106) and 3 additional for a total
3154// of 5 dups. Nothing of the original dups is copied.
3155TEST_F(PGLogTrimTest, TestCopyAfter) {
3156 SetUp(5);
3157 PGLog::IndexedLog log, copy;
3158 log.tail = mk_evt(9, 99);
3159 log.head = mk_evt(9, 99);
3160
3161 entity_name_t client = entity_name_t::CLIENT(777);
3162
3163 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3164 mk_evt(9, 99), mk_evt(8, 98), osd_reqid_t(client, 8, 1))));
3165
3166 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(9, 99),
3167 osd_reqid_t(client, 8, 1)));
3168 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 101), mk_evt(10, 100),
3169 osd_reqid_t(client, 8, 2)));
3170 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 102), mk_evt(15, 101),
3171 osd_reqid_t(client, 8, 3)));
3172 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 103), mk_evt(15, 102),
3173 osd_reqid_t(client, 8, 4)));
3174 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 104), mk_evt(20, 103),
3175 osd_reqid_t(client, 8, 5)));
3176 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 105), mk_evt(21, 104),
3177 osd_reqid_t(client, 8, 6)));
3178 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 106), mk_evt(21, 105),
3179 osd_reqid_t(client, 8, 6)));
3180 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 107), mk_evt(21, 106),
3181 osd_reqid_t(client, 8, 6)));
3182
3183 copy.copy_after(cct, log, mk_evt(21, 105));
3184
3185 EXPECT_EQ(2u, copy.log.size()) << copy;
3186 EXPECT_EQ(copy.head, mk_evt(21, 107)) << copy;
3187 EXPECT_EQ(copy.tail, mk_evt(21, 105)) << copy;
3188 // Tracking 5 means 3 additional as dups
3189 EXPECT_EQ(3u, copy.dups.size()) << copy;
3190}
3191
3192// This copies everything dups and log because of the large max dups
3193// and value passed to copy_after().
3194TEST_F(PGLogTrimTest, TestCopyAfter2) {
3195 SetUp(3000);
3196 PGLog::IndexedLog log, copy;
3197 log.tail = mk_evt(9, 99);
3198 log.head = mk_evt(9, 99);
3199
3200 entity_name_t client = entity_name_t::CLIENT(777);
3201
3202 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3203 mk_evt(8, 93), mk_evt(8, 92), osd_reqid_t(client, 8, 1))));
3204 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3205 mk_evt(8, 94), mk_evt(8, 93), osd_reqid_t(client, 8, 1))));
3206 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3207 mk_evt(8, 95), mk_evt(8, 94), osd_reqid_t(client, 8, 1))));
3208 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3209 mk_evt(8, 96), mk_evt(8, 95), osd_reqid_t(client, 8, 1))));
3210 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3211 mk_evt(8, 97), mk_evt(8, 96), osd_reqid_t(client, 8, 1))));
3212 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3213 mk_evt(8, 98), mk_evt(8, 97), osd_reqid_t(client, 8, 1))));
3214 log.dups.push_back(pg_log_dup_t(mk_ple_mod(mk_obj(1),
3215 mk_evt(9, 99), mk_evt(8, 98), osd_reqid_t(client, 8, 1))));
3216
3217 log.add(mk_ple_mod(mk_obj(1), mk_evt(10, 100), mk_evt(9, 99),
3218 osd_reqid_t(client, 8, 1)));
3219 log.add(mk_ple_dt(mk_obj(2), mk_evt(15, 101), mk_evt(10, 100),
3220 osd_reqid_t(client, 8, 2)));
3221 log.add(mk_ple_mod_rb(mk_obj(3), mk_evt(15, 102), mk_evt(15, 101),
3222 osd_reqid_t(client, 8, 3)));
3223 log.add(mk_ple_mod(mk_obj(1), mk_evt(20, 103), mk_evt(15, 102),
3224 osd_reqid_t(client, 8, 4)));
3225 log.add(mk_ple_mod(mk_obj(4), mk_evt(21, 104), mk_evt(20, 103),
3226 osd_reqid_t(client, 8, 5)));
3227 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 105), mk_evt(21, 104),
3228 osd_reqid_t(client, 8, 6)));
3229 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 106), mk_evt(21, 105),
3230 osd_reqid_t(client, 8, 6)));
3231 log.add(mk_ple_dt_rb(mk_obj(5), mk_evt(21, 107), mk_evt(21, 106),
3232 osd_reqid_t(client, 8, 6)));
3233
3234 copy.copy_after(cct, log, mk_evt(9, 99));
3235
3236 EXPECT_EQ(8u, copy.log.size()) << copy;
3237 EXPECT_EQ(copy.head, mk_evt(21, 107)) << copy;
3238 EXPECT_EQ(copy.tail, mk_evt(9, 99)) << copy;
3239 // Tracking 3000 is larger than all entries, so all dups copied
3240 EXPECT_EQ(7u, copy.dups.size()) << copy;
3241}
3242
7c673cae
FG
3243// Local Variables:
3244// compile-command: "cd ../.. ; make unittest_pglog ; ./unittest_pglog --log-to-stderr=true --debug-osd=20 # --gtest_filter=*.* "
3245// End: