deno.land / std@0.173.0 / archive / untar_test.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.import { assert, assertEquals, assertExists } from "../testing/asserts.ts";import { resolve } from "../path/mod.ts";import { Tar, type TarMeta } from "./tar.ts";import { TarEntry, type TarHeader, Untar } from "./untar.ts";import { Buffer } from "../io/buffer.ts";import { copy } from "../streams/copy.ts";import { readAll } from "../streams/read_all.ts";import { filePath, testdataDir } from "./_test_common.ts";
interface TestEntry { name: string; content?: Uint8Array; filePath?: string;}
async function createTar(entries: TestEntry[]): Promise<Tar> { const tar = new Tar(); // put data on memory for (const file of entries) { let options;
if (file.content) { options = { reader: new Buffer(file.content), contentSize: file.content.byteLength, }; } else { options = { filePath: file.filePath }; }
await tar.append(file.name, options); }
return tar;}
Deno.test("untarAsyncIterator", async function () { const entries: TestEntry[] = [ { name: "output.txt", content: new TextEncoder().encode("hello tar world!"), }, { name: "dir/tar.ts", filePath, }, ];
const tar = await createTar(entries);
// read data from a tar archive const untar = new Untar(tar.getReader());
let lastEntry; for await (const entry of untar) { const expected = entries.shift(); assert(expected);
let content = expected.content; if (expected.filePath) { content = await Deno.readFile(expected.filePath); } assertEquals(content, await readAll(entry)); assertEquals(expected.name, entry.fileName);
if (lastEntry) assert(lastEntry.consumed); lastEntry = entry; } assert(lastEntry); assert(lastEntry.consumed); assertEquals(entries.length, 0);});
Deno.test("untarAsyncIteratorWithoutReadingBody", async function (): Promise< void> { const entries: TestEntry[] = [ { name: "output.txt", content: new TextEncoder().encode("hello tar world!"), }, { name: "dir/tar.ts", filePath, }, ];
const tar = await createTar(entries);
// read data from a tar archive const untar = new Untar(tar.getReader());
for await (const entry of untar) { const expected = entries.shift(); assert(expected); assertEquals(expected.name, entry.fileName); }
assertEquals(entries.length, 0);});
Deno.test( "untarAsyncIteratorWithoutReadingBodyFromFileReader", async function () { const entries: TestEntry[] = [ { name: "output.txt", content: new TextEncoder().encode("hello tar world!"), }, { name: "dir/tar.ts", filePath, }, ];
const outputFile = resolve(testdataDir, "test.tar");
const tar = await createTar(entries); const file = await Deno.open(outputFile, { create: true, write: true }); await copy(tar.getReader(), file); file.close();
const reader = await Deno.open(outputFile, { read: true }); // read data from a tar archive const untar = new Untar(reader);
for await (const entry of untar) { const expected = entries.shift(); assert(expected); assertEquals(expected.name, entry.fileName); }
reader.close(); await Deno.remove(outputFile); assertEquals(entries.length, 0); },);
Deno.test("untarAsyncIteratorFromFileReader", async function () { const entries: TestEntry[] = [ { name: "output.txt", content: new TextEncoder().encode("hello tar world!"), }, { name: "dir/tar.ts", filePath, }, ];
const outputFile = resolve(testdataDir, "test.tar");
const tar = await createTar(entries); const file = await Deno.open(outputFile, { create: true, write: true }); await copy(tar.getReader(), file); file.close();
const reader = await Deno.open(outputFile, { read: true }); // read data from a tar archive const untar = new Untar(reader);
for await (const entry of untar) { const expected = entries.shift(); assert(expected);
let content = expected.content; if (expected.filePath) { content = await Deno.readFile(expected.filePath); }
assertEquals(content, await readAll(entry)); assertEquals(expected.name, entry.fileName); }
reader.close(); await Deno.remove(outputFile); assertEquals(entries.length, 0);});
Deno.test( "untarAsyncIteratorReadingLessThanRecordSize", async function () { // record size is 512 const bufSizes = [1, 53, 256, 511];
for (const bufSize of bufSizes) { const entries: TestEntry[] = [ { name: "output.txt", content: new TextEncoder().encode("hello tar world!".repeat(100)), }, // Need to test at least two files, to make sure the first entry doesn't over-read // Causing the next to fail with: checksum error { name: "deni.txt", content: new TextEncoder().encode("deno!".repeat(250)), }, ];
const tar = await createTar(entries);
// read data from a tar archive const untar = new Untar(tar.getReader());
for await (const entry of untar) { const expected = entries.shift(); assert(expected); assertEquals(expected.name, entry.fileName);
const writer = new Buffer(); while (true) { const buf = new Uint8Array(bufSize); const n = await entry.read(buf); if (n === null) break;
await writer.write(buf.subarray(0, n)); } assertEquals(writer.bytes(), expected!.content); }
assertEquals(entries.length, 0); } },);
Deno.test("untarLinuxGeneratedTar", async function () { const filePath = resolve(testdataDir, "deno.tar"); const file = await Deno.open(filePath, { read: true });
type ExpectedEntry = TarMeta & { content?: Uint8Array };
const expectedEntries: ExpectedEntry[] = [ { fileName: "archive/", fileSize: 0, fileMode: 509, mtime: 1591800767, uid: 1001, gid: 1001, owner: "deno", group: "deno", type: "directory", }, { fileName: "archive/deno/", fileSize: 0, fileMode: 509, mtime: 1591799635, uid: 1001, gid: 1001, owner: "deno", group: "deno", type: "directory", }, { fileName: "archive/deno/land/", fileSize: 0, fileMode: 509, mtime: 1591799660, uid: 1001, gid: 1001, owner: "deno", group: "deno", type: "directory", }, { fileName: "archive/deno/land/land.txt", fileMode: 436, fileSize: 5, mtime: 1591799660, uid: 1001, gid: 1001, owner: "deno", group: "deno", type: "file", content: new TextEncoder().encode("land\n"), }, { fileName: "archive/file.txt", fileMode: 436, fileSize: 5, mtime: 1591799626, uid: 1001, gid: 1001, owner: "deno", group: "deno", type: "file", content: new TextEncoder().encode("file\n"), }, { fileName: "archive/deno.txt", fileMode: 436, fileSize: 5, mtime: 1591799642, uid: 1001, gid: 1001, owner: "deno", group: "deno", type: "file", content: new TextEncoder().encode("deno\n"), }, ];
const untar = new Untar(file);
for await (const entry of untar) { const expected = expectedEntries.shift(); assert(expected); const content = expected.content; delete expected.content;
assertEquals({ ...entry }, expected);
if (content) { assertEquals(content, await readAll(entry)); } }
file.close();});
Deno.test({ name: "test TarEntry", // only: true, fn() { // test TarEntry class assertExists(TarEntry); // Test TarEntry type const bufSizes = [1, 53, 256, 511]; const header: TarHeader = { test: new Uint8Array(bufSizes), }; const content = new TextEncoder().encode("hello tar world!"); const reader = new Buffer(content); const tarMeta = { fileName: "archive/", fileSize: 0, fileMode: 509, mtime: 1591800767, uid: 1001, gid: 1001, owner: "deno", group: "deno", type: "directory", }; const tarEntry: TarEntry = new TarEntry(tarMeta, header, reader); assertExists(tarEntry); },});
Version Info