balena-supervisor/test/39-compose-images.spec.ts
Christina Wang 4a2ac557ef
Remove mz, mkdirp, body-parser dependencies
'mz' can be safely replaced with fs.promises
and util.promisify for faster native methods.
'mkdirp' after Node v8 uses native fs.mkdir, thus
is redundant. 'body-parser' is deprecated and
contained within express v4.x.

Closes: #1567
Change-type: patch
Signed-off-by: Christina Wang <christina@balena.io>
2021-04-28 07:20:15 +09:00

134 lines
4.8 KiB
TypeScript

import * as _ from 'lodash';
import { docker } from '../src/lib/docker-utils';
import { expect } from 'chai';
import * as Images from '../src/compose/images';
import * as mockedDockerode from './lib/mocked-dockerode';
import * as mockedDatabase from './lib/mocked-database';
import * as db from '../src/db';
import * as sampleImageData from './data/compose-image-data.json';
describe('compose/images', () => {
before(() => {
mockedDatabase.create();
});
after(() => {
try {
mockedDatabase.restore();
} catch (e) {
/* noop */
}
});
afterEach(() => {
// Clear Dockerode actions recorded for each test
mockedDockerode.resetHistory();
});
it('Removes a legacy Image', async () => {
const images = sampleImageData['legacy-image'].dockerode;
const IMAGE_TO_REMOVE = sampleImageData['legacy-image'].remove;
const IMAGES_FROM_DB = sampleImageData['legacy-image'].database;
// Stub the database to return images we want
mockedDatabase.setImages(IMAGES_FROM_DB).stub();
// Perform the test with our specially crafted data
await mockedDockerode.testWithData({ images }, async () => {
// Check that our legacy image exists
await expect(docker.getImage(IMAGE_TO_REMOVE.name).inspect()).to
.eventually.not.be.undefined;
await expect(
db.models('image').select().where(IMAGE_TO_REMOVE),
).to.eventually.have.lengthOf(1);
// Check that docker has this Image
await expect(docker.getImage(IMAGE_TO_REMOVE.name).inspect()).to
.eventually.not.be.undefined;
// Now remove this image...
await Images.remove(IMAGE_TO_REMOVE);
// Check if it still exists!
await expect(docker.getImage(IMAGE_TO_REMOVE.name).inspect()).to
.eventually.be.undefined;
await expect(db.models('image').select().where(IMAGE_TO_REMOVE)).to
.eventually.be.empty;
// Check that docker remove was called once
const removeSteps = _(mockedDockerode.actions)
.pickBy({ name: 'remove' })
.map()
.value();
expect(removeSteps).to.have.lengthOf(1);
});
});
it('Removes a single Image', async () => {
const images = sampleImageData['single-image'].dockerode;
const IMAGE_TO_REMOVE = sampleImageData['single-image'].remove;
const IMAGES_FROM_DB = sampleImageData['single-image'].database;
// Stub the database to return images we want
mockedDatabase.setImages(IMAGES_FROM_DB).stub();
// Perform the test with our specially crafted data
await mockedDockerode.testWithData({ images }, async () => {
// Check that a single image is returned when given entire object
expect(
db.models('image').select().where(IMAGE_TO_REMOVE),
).to.eventually.have.lengthOf(1);
// Check that only one image with this dockerImageId exists in the db
expect(
db
.models('image')
.where({ dockerImageId: IMAGE_TO_REMOVE.dockerImageId })
.select(),
).to.eventually.have.lengthOf(1);
// Now remove this image...
await Images.remove(IMAGE_TO_REMOVE);
// Check that docker does not have this image
await expect(docker.getImage(IMAGE_TO_REMOVE.name).inspect()).to
.eventually.be.empty;
// Check that the database longer has this image
await expect(db.models('image').select().where(IMAGE_TO_REMOVE)).to
.eventually.be.empty;
// Check that docker remove was called once
const removeSteps = _(mockedDockerode.actions)
.pickBy({ name: 'remove' })
.map()
.value();
expect(removeSteps).to.have.lengthOf(1);
});
});
it('Removes an Image with digests', async () => {
const images = sampleImageData['image-with-digests'].dockerode;
const IMAGE_TO_REMOVE = sampleImageData['image-with-digests'].remove;
const IMAGES_FROM_DB = sampleImageData['image-with-digests'].database;
// Stub the database to return images we want
mockedDatabase.setImages(IMAGES_FROM_DB).stub();
// Perform the test with our specially crafted data
await mockedDockerode.testWithData({ images }, async () => {
// Check that a single image is returned when given entire object
expect(
db.models('image').select().where(IMAGE_TO_REMOVE),
).to.eventually.have.lengthOf(1);
// Check that multiple images with the same dockerImageId are returned
expect(
db
.models('image')
.where({ dockerImageId: IMAGE_TO_REMOVE.dockerImageId })
.select(),
).to.eventually.have.lengthOf(2);
// Now remove these image...
await Images.remove(IMAGE_TO_REMOVE);
// Check that docker does not have this image
await expect(docker.getImage(IMAGE_TO_REMOVE.name).inspect()).to
.eventually.be.empty;
// Check that the database no longer has this image
await expect(db.models('image').select().where(IMAGE_TO_REMOVE)).to
.eventually.be.empty;
// Check that docker remove was called twice
const removeSteps = _(mockedDockerode.actions)
.pickBy({ name: 'remove' })
.map()
.value();
expect(removeSteps).to.have.lengthOf(2);
});
});
});