Files
dockhand-upstream/tests/container-image-divergence.test.ts
T

122 lines
4.1 KiB
TypeScript

/**
* Unit tests for detectImageEnvDivergence and detectImageLabelDivergence.
*
* Both helpers report keys whose container value differs from the
* image's CURRENT value. Keys present on only one side are NOT
* reported — those are user-only or image-only, neither of which is
* a divergence between sides we can act on.
*/
import { describe, test, expect } from 'bun:test';
import {
detectImageEnvDivergence,
detectImageLabelDivergence
} from '../src/lib/server/container-image-divergence';
describe('detectImageEnvDivergence', () => {
test('returns [] when arrays match', () => {
expect(detectImageEnvDivergence(['A=1', 'B=2'], ['A=1', 'B=2'])).toEqual([]);
});
test('returns [] for empty inputs', () => {
expect(detectImageEnvDivergence([], [])).toEqual([]);
expect(detectImageEnvDivergence(['A=1'], [])).toEqual([]);
expect(detectImageEnvDivergence([], ['A=1'])).toEqual([]);
});
test('returns differing keys', () => {
const result = detectImageEnvDivergence(
['PORT=80', 'NGINX_VERSION=1.27.3', 'PATH=/usr/bin'],
['PORT=8080', 'NGINX_VERSION=1.27.4', 'PATH=/usr/bin']
);
expect(result.sort()).toEqual(['NGINX_VERSION', 'PORT']);
});
test('does NOT report keys present in only one side', () => {
// USER_ONLY appears only in the container — user-set, not divergence
// IMAGE_ONLY appears only in the image — image-added, not divergence
const result = detectImageEnvDivergence(
['USER_ONLY=foo', 'PATH=/usr/bin'],
['IMAGE_ONLY=bar', 'PATH=/usr/bin']
);
expect(result).toEqual([]);
});
test('handles values containing =', () => {
const result = detectImageEnvDivergence(
['CONFIG=a=b=c', 'OTHER=ok'],
['CONFIG=x=y=z', 'OTHER=ok']
);
expect(result).toEqual(['CONFIG']);
});
test('handles empty values', () => {
expect(detectImageEnvDivergence(['EMPTY='], ['EMPTY=set'])).toEqual(['EMPTY']);
expect(detectImageEnvDivergence(['EMPTY='], ['EMPTY='])).toEqual([]);
});
test('handles entries with no = (treated as empty value)', () => {
// Bare "KEY" entries are valid in Docker env arrays — treat as KEY=""
expect(detectImageEnvDivergence(['BARE'], ['BARE='])).toEqual([]);
expect(detectImageEnvDivergence(['BARE'], ['BARE=value'])).toEqual(['BARE']);
});
test('reporter scenarios from #1135 and #1061', () => {
// #1135: user overrode image's ASPNETCORE_HTTP_PORTS=8080 to 80
expect(
detectImageEnvDivergence(['ASPNETCORE_HTTP_PORTS=80'], ['ASPNETCORE_HTTP_PORTS=8080'])
).toEqual(['ASPNETCORE_HTTP_PORTS']);
// #1061: container was created when image had APP_VERSION=0.32.0;
// image now has 0.36.0
expect(
detectImageEnvDivergence(['APP_VERSION=0.32.0'], ['APP_VERSION=0.36.0'])
).toEqual(['APP_VERSION']);
});
});
describe('detectImageLabelDivergence', () => {
test('returns [] when objects match', () => {
expect(detectImageLabelDivergence({ a: '1', b: '2' }, { a: '1', b: '2' })).toEqual([]);
});
test('returns [] for nullish inputs', () => {
expect(detectImageLabelDivergence(null, null)).toEqual([]);
expect(detectImageLabelDivergence(undefined, undefined)).toEqual([]);
expect(detectImageLabelDivergence({}, {})).toEqual([]);
});
test('returns differing keys', () => {
const result = detectImageLabelDivergence(
{ 'com.example.policy': 'strict', shared: 'same' },
{ 'com.example.policy': 'permissive', shared: 'same' }
);
expect(result).toEqual(['com.example.policy']);
});
test('does NOT report keys present in only one side', () => {
const result = detectImageLabelDivergence(
{ 'user.only': 'foo' },
{ 'image.only': 'bar' }
);
expect(result).toEqual([]);
});
test('dockhand.update opt-out: user="false" vs image="true"', () => {
// The exact regression we worried about: user disables auto-update
// via label; image bakes the opposite default.
expect(
detectImageLabelDivergence({ 'dockhand.update': 'false' }, { 'dockhand.update': 'true' })
).toEqual(['dockhand.update']);
});
test('handles empty values', () => {
expect(
detectImageLabelDivergence({ EMPTY: '' }, { EMPTY: 'set' })
).toEqual(['EMPTY']);
expect(
detectImageLabelDivergence({ EMPTY: '' }, { EMPTY: '' })
).toEqual([]);
});
});