balena-cli/tests/utils/tarDirectory.spec.ts
myarmolinsky 7d13946c3e Bump balena-lint to 7.2.1
Change-type: patch
2023-10-30 07:45:51 -04:00

136 lines
4.2 KiB
TypeScript

/**
* @license
* Copyright 2020 Balena Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect } from 'chai';
import * as path from 'path';
import * as tar from 'tar-stream';
import { tarDirectory } from '../../build/utils/compose_ts';
import { setupDockerignoreTestData } from '../projects';
const repoPath = path.normalize(path.join(__dirname, '..', '..'));
const projectsPath = path.join(repoPath, 'tests', 'test-data', 'projects');
interface TarFiles {
[name: string]: {
fileSize?: number;
type?: string | null;
};
}
describe('compare new and old tarDirectory implementations', function () {
const extraContent = 'extra';
const extraEntry: tar.Headers = {
name: 'extra.txt',
size: extraContent.length,
type: 'file',
};
const preFinalizeCallback = (pack: tar.Pack) => {
pack.entry(extraEntry, extraContent);
};
this.beforeAll(async () => {
await setupDockerignoreTestData();
});
this.afterAll(async () => {
await setupDockerignoreTestData({ cleanup: true });
});
// NOTE: if this test or other tests involving symbolic links fail on Windows
// (with a mismatched fileSize 13 vs 5 for 'symlink-a.txt'), ensure that the
// `core.symlinks` property is set to `true` in the `.git/config` file. Ref:
// https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresymlinks
it('should produce the expected file list', async function () {
const dockerignoreProjDir = path.join(
projectsPath,
'no-docker-compose',
'dockerignore1',
);
const expectedFiles = {
'.balena/balena.yml': { fileSize: 12, type: 'file' },
'.dockerignore': { fileSize: 438, type: 'file' },
'.gitignore': { fileSize: 20, type: 'file' },
'.git/foo.txt': { fileSize: 4, type: 'file' },
'a.txt': { fileSize: 1, type: 'file' },
'c.txt': { fileSize: 1, type: 'file' },
Dockerfile: { fileSize: 13, type: 'file' },
'extra.txt': { fileSize: 5, type: 'file' },
'src/.balena/balena.yml': { fileSize: 16, type: 'file' },
'src/.gitignore': { fileSize: 10, type: 'file' },
'src/src-a.txt': { fileSize: 5, type: 'file' },
'src/src-c.txt': { fileSize: 5, type: 'file' },
'vendor/.git/vendor-git-contents': { fileSize: 20, type: 'file' },
};
const tarPack = await tarDirectory(dockerignoreProjDir, {
preFinalizeCallback,
});
const fileList = await getTarPackFiles(tarPack);
expect(fileList).to.deep.equal(expectedFiles);
});
it('should produce the expected file list (symbolic links)', async function () {
const projectPath = path.join(
projectsPath,
'no-docker-compose',
'dockerignore2',
);
const expectedFiles = {
'.dockerignore': { fileSize: 33, type: 'file' },
'b.txt': { fileSize: 1, type: 'file' },
Dockerfile: { fileSize: 13, type: 'file' },
'lib/.dockerignore': { fileSize: 10, type: 'file' },
'lib/src-b.txt': { fileSize: 5, type: 'file' },
'src/src-b.txt': { fileSize: 5, type: 'file' },
'symlink-a.txt': { fileSize: 5, type: 'file' },
};
const tarPack = await tarDirectory(projectPath, {});
const fileList = await getTarPackFiles(tarPack);
expect(fileList).to.deep.equal(expectedFiles);
});
});
async function getTarPackFiles(
pack: import('stream').Readable,
): Promise<TarFiles> {
const { drainStream } = await import('tar-utils');
const fileList: TarFiles = {};
const extract = tar.extract();
return await new Promise((resolve, reject) => {
extract
.on('error', reject)
.on('entry', async function (header, stream, next) {
expect(fileList).to.not.have.property(header.name);
fileList[header.name] = {
fileSize: header.size,
type: header.type,
};
await drainStream(stream);
next();
})
.on('finish', function () {
resolve(fileList);
});
pack.pipe(extract);
});
}