Pin a restore point and keep a note on it
Both live in the catalog on the location, so a new server sees them; the database holds a local copy for the lists. The retention policy leaves a pinned restore point alone and does not count it. Available on the restore page and as occ backup:pin and backup:note.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\NgBackup\Tests\Unit\Repository;
|
||||
|
||||
use OCA\NgBackup\Backend\LocalBackend;
|
||||
use OCA\NgBackup\Crypto\KeyRing;
|
||||
use OCA\NgBackup\Repository\Repository;
|
||||
use OCA\NgBackup\Tests\Unit\TempDirTrait;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/** A pin and a note on a snapshot live in the catalog on the location, so a new server sees them too. */
|
||||
class SnapshotMarksTest extends TestCase {
|
||||
use TempDirTrait;
|
||||
|
||||
private LocalBackend $backend;
|
||||
private KeyRing $keys;
|
||||
private string $snapshot;
|
||||
|
||||
protected function setUp(): void {
|
||||
$this->backend = new LocalBackend($this->tempDir());
|
||||
$this->keys = KeyRing::generate();
|
||||
$src = $this->tempDir();
|
||||
file_put_contents("$src/a", 'x');
|
||||
$this->snapshot = Repository::initWithKey($this->backend, $this->keys, $this->keys->wrap('pw'))->backupDirectory($src)['snapshot'];
|
||||
}
|
||||
|
||||
private function repo(): Repository {
|
||||
return Repository::openWithKey($this->backend, $this->keys);
|
||||
}
|
||||
|
||||
public function testTheyAreThereAfterOpeningAgain(): void {
|
||||
$this->repo()->setPinned($this->snapshot, true);
|
||||
$this->repo()->setSnapshotNote($this->snapshot, 'before the upgrade');
|
||||
$this->assertSame([$this->snapshot], $this->repo()->pinnedSnapshots());
|
||||
$this->assertSame([$this->snapshot => 'before the upgrade'], $this->repo()->snapshotNotes());
|
||||
}
|
||||
|
||||
public function testTheyCanBeTakenOffAgain(): void {
|
||||
$this->repo()->setPinned($this->snapshot, true);
|
||||
$this->repo()->setSnapshotNote($this->snapshot, 'x');
|
||||
$this->repo()->setPinned($this->snapshot, false);
|
||||
$this->repo()->setSnapshotNote($this->snapshot, '');
|
||||
$this->assertSame([], $this->repo()->pinnedSnapshots());
|
||||
$this->assertSame([], $this->repo()->snapshotNotes());
|
||||
}
|
||||
|
||||
public function testNoChangeWritesNoCatalog(): void {
|
||||
$repo = $this->repo();
|
||||
$repo->setPinned($this->snapshot, true);
|
||||
$generation = $repo->catalogGeneration();
|
||||
$repo->setPinned($this->snapshot, true);
|
||||
$repo->setSnapshotNote($this->snapshot, '');
|
||||
$this->assertSame($generation, $repo->catalogGeneration());
|
||||
}
|
||||
|
||||
public function testASnapshotThatIsNotThereIsRefused(): void {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$this->repo()->setPinned('0123456789abcdef0123456789abcdef', true);
|
||||
}
|
||||
|
||||
public function testATrashedSnapshotLosesItsPinAndKeepsItsNote(): void {
|
||||
$repo = $this->repo();
|
||||
$repo->setPinned($this->snapshot, true);
|
||||
$repo->setSnapshotNote($this->snapshot, 'kept');
|
||||
$repo->forget($this->snapshot);
|
||||
$this->assertSame([], $this->repo()->pinnedSnapshots());
|
||||
$this->assertSame([$this->snapshot => 'kept'], $this->repo()->snapshotNotes());
|
||||
|
||||
$repo = $this->repo();
|
||||
$repo->untrash($this->snapshot);
|
||||
$this->assertSame([], $this->repo()->pinnedSnapshots(), 'back in the list, as a normal one');
|
||||
$this->assertSame([$this->snapshot => 'kept'], $this->repo()->snapshotNotes());
|
||||
}
|
||||
|
||||
public function testThePurgeTakesTheNoteAlong(): void {
|
||||
$repo = $this->repo();
|
||||
$repo->setSnapshotNote($this->snapshot, 'kept');
|
||||
$repo->forget($this->snapshot);
|
||||
$repo->purgeTrash(0);
|
||||
$this->assertSame([], $this->repo()->snapshotNotes());
|
||||
}
|
||||
|
||||
public function testACatalogFromBeforeThisVersionReadsAsNone(): void {
|
||||
$this->assertSame([], $this->repo()->pinnedSnapshots());
|
||||
$this->assertSame([], $this->repo()->snapshotNotes());
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,17 @@ class RetentionPolicyTest extends TestCase {
|
||||
$this->assertCount(3, $months);
|
||||
}
|
||||
|
||||
public function testAPinnedSnapshotStaysAndDoesNotCount(): void {
|
||||
$policy = new RetentionPolicy(1, 0, 0, 0);
|
||||
$snaps = ['old' => 100, 'pinned' => 300, 'new' => 200];
|
||||
$this->assertSame(['pinned'], array_keys($policy->keep($snaps)), 'without the pin it would take the place of "last"');
|
||||
$keep = $policy->keepWithPinned($snaps, ['pinned', 'gone-already']);
|
||||
$this->assertSame(['pinned'], $keep['pinned']);
|
||||
$this->assertSame(['last'], $keep['new'], 'the newest one that is not pinned');
|
||||
$this->assertArrayNotHasKey('old', $keep);
|
||||
$this->assertArrayNotHasKey('gone-already', $keep);
|
||||
}
|
||||
|
||||
public function testKeepsEverythingWhenFewSnapshots(): void {
|
||||
$keep = (new RetentionPolicy())->keep(['a' => 100, 'b' => 200]);
|
||||
$this->assertSame(['a', 'b'], array_values(array_intersect(['a', 'b'], array_keys($keep))));
|
||||
|
||||
@@ -120,6 +120,17 @@ ok "database dump and restore"
|
||||
|
||||
# Retention, trash and catalog.
|
||||
occ backup:retention --last=1 --daily=0 --weekly=0 --monthly=0 >/dev/null
|
||||
# A pinned restore point stays, and a note can change afterwards.
|
||||
FIRST=$(occ backup:list ci | awk -F'|' '!f && / first /{gsub(/ /,"",$3); print $3; f=1}')
|
||||
occ backup:pin ci "$FIRST" >/dev/null || fail "pin"
|
||||
occ backup:note ci "$FIRST" "a note made later" >/dev/null || fail "note"
|
||||
occ backup:list ci | grep " first " | grep " yes " | grep "a note made later" >/dev/null || fail "pin and note not listed"
|
||||
occ backup:prune ci --dry-run | grep "would forget 1 " >/dev/null || fail "a pinned snapshot would be removed"
|
||||
occ backup:pin ci "$FIRST" --unpin >/dev/null || fail "unpin"
|
||||
occ backup:prune ci --dry-run | grep "would forget 2 " >/dev/null || fail "an unpinned snapshot would stay"
|
||||
occ backup:note ci "$FIRST" >/dev/null || fail "remove note"
|
||||
occ backup:list ci | grep -q "a note made later" && fail "note not removed"
|
||||
ok "pin and note on a restore point"
|
||||
occ backup:prune ci | grep "forgot 2" >/dev/null || fail "prune" # first and second; "page" (above) is the last
|
||||
occ backup:trash ci | grep " first " >/dev/null || fail "trash"
|
||||
TID=$(occ backup:trash ci | awk -F'|' '!f && / first /{gsub(/ /,"",$3); print $3; f=1}')
|
||||
|
||||
Reference in New Issue
Block a user