Write each backed-up original once and skip the precache (closes #106)
check / check (push) Successful in 49s
check / check (push) Successful in 49s
An original fetched for a backup is now written by the download writer straight into the backup's originals/, and the content cache records it there instead of keeping its own copy. One the cache already held is still copied. `quak backup` opens its library with the thumbnail and originals precache off, as the one-shot commands do. Model: opus-5-5
This commit was merged in pull request #124.
This commit is contained in:
+29
-1
@@ -562,11 +562,39 @@ describe("lib.backup", () => {
|
||||
lib.close();
|
||||
});
|
||||
|
||||
it("fsyncs a copied original before the rename and its directory after", async () => {
|
||||
it("fetches each original once and writes it only into the backup", async () => {
|
||||
// A backup of a 500 GB account must write 500 GB, not a copy in the
|
||||
// cache as well: an original fetched for the backup goes straight
|
||||
// into its originals/, and the cache records it there.
|
||||
const source = stubSource();
|
||||
const lib = await openLibrary(source);
|
||||
const outDir = join(root, "backup");
|
||||
|
||||
const result = await lib.backup({ downloadDirectory: outDir });
|
||||
|
||||
expect(result.downloaded).toBe(3);
|
||||
expect(source.originalCalls).toBe(3);
|
||||
expect(readdirSync(join(root, "cache", "originals"))).toEqual([]);
|
||||
const stored = readdirSync(join(outDir, "originals")).filter(
|
||||
(name) => !name.endsWith(".json"),
|
||||
);
|
||||
expect(stored.sort()).toEqual(["100.jpg", "101.jpg", "200.png"]);
|
||||
// The cache counts the backup's copy as present: reading the
|
||||
// original afterwards fetches nothing and answers with that copy.
|
||||
const read = await lib.photos.byID({ fileID: 100 })!.original();
|
||||
expect(read.path).toBe(join(outDir, "originals", "100.jpg"));
|
||||
expect(source.originalCalls).toBe(3);
|
||||
await lib.close();
|
||||
});
|
||||
|
||||
it("fsyncs an original copied from the cache before the rename and its directory after", async () => {
|
||||
const lib = await openLibrary(stubSource());
|
||||
const outDir = join(root, "backup");
|
||||
const originals = join(outDir, "originals");
|
||||
const dest = join(originals, "100.jpg");
|
||||
// Only an original already in the cache is copied into the backup;
|
||||
// one fetched for the backup is written there by the download writer.
|
||||
await lib.photos.byID({ fileID: 100 })!.original();
|
||||
fsEvents.length = 0;
|
||||
|
||||
await lib.backup({ downloadDirectory: outDir });
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import {
|
||||
existsSync,
|
||||
mkdtempSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
statSync,
|
||||
@@ -427,6 +428,16 @@ describe("backup", () => {
|
||||
expect(stdout.text).toBe("");
|
||||
});
|
||||
|
||||
// The backup opens its library with the precache off: it fetches the
|
||||
// originals it needs into the backup, and must not also fetch every
|
||||
// thumbnail in the account, or keep originals, in the per-user cache.
|
||||
it("leaves nothing in the cache's originals and thumbnails", async () => {
|
||||
const dir = join(root, "backup");
|
||||
expect(await backupCommand(context(), dir, {})).toBe(0);
|
||||
expect(readdirSync(join(root, "cache", "thumbnails"))).toEqual([]);
|
||||
expect(readdirSync(join(root, "cache", "originals"))).toEqual([]);
|
||||
});
|
||||
|
||||
it("exits 1 and lists the file when one download fails", async () => {
|
||||
const ctx = context(fakeClient({ failID: 101 }));
|
||||
expect(await backupCommand(ctx, join(root, "backup"), {})).toBe(1);
|
||||
|
||||
Reference in New Issue
Block a user