@docker-harpoon/core 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/promise.d.ts +1 -1
- package/dist/api/promise.d.ts.map +1 -1
- package/dist/api/promise.js +28 -18
- package/dist/bindings/index.d.ts +2 -2
- package/dist/bindings/index.d.ts.map +1 -1
- package/dist/bindings/index.js +1 -1
- package/dist/bindings/types.d.ts.map +1 -1
- package/dist/bindings/types.js +1 -3
- package/dist/build-strategies/types.d.ts.map +1 -1
- package/dist/config-patchers/index.d.ts.map +1 -1
- package/dist/config-patchers/types.d.ts.map +1 -1
- package/dist/dockerfile-transformers/core.d.ts.map +1 -1
- package/dist/dockerfile-transformers/core.js +2 -5
- package/dist/dockerfile-transformers/index.d.ts.map +1 -1
- package/dist/dockerfile-transformers/types.d.ts.map +1 -1
- package/dist/errors.d.ts +6 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -3
- package/dist/helpers/database.d.ts.map +1 -1
- package/dist/helpers/database.js +1 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/resources/container.d.ts +7 -2
- package/dist/resources/container.d.ts.map +1 -1
- package/dist/resources/container.js +222 -31
- package/dist/resources/image.d.ts.map +1 -1
- package/dist/resources/image.js +14 -35
- package/dist/resources/network.d.ts.map +1 -1
- package/dist/resources/network.js +23 -9
- package/dist/resources/schemas.d.ts +177 -18
- package/dist/resources/schemas.d.ts.map +1 -1
- package/dist/resources/schemas.js +1 -1
- package/dist/services/CircuitBreaker.d.ts +83 -0
- package/dist/services/CircuitBreaker.d.ts.map +1 -0
- package/dist/services/CircuitBreaker.js +164 -0
- package/dist/services/ContainerPool.d.ts +82 -0
- package/dist/services/ContainerPool.d.ts.map +1 -0
- package/dist/services/ContainerPool.js +186 -0
- package/dist/services/DockerBatcher.d.ts +74 -0
- package/dist/services/DockerBatcher.d.ts.map +1 -0
- package/dist/services/DockerBatcher.js +107 -0
- package/dist/services/DockerClient.d.ts +125 -0
- package/dist/services/DockerClient.d.ts.map +1 -0
- package/dist/services/DockerClient.js +220 -0
- package/dist/services/DockerErrors.d.ts +145 -0
- package/dist/services/DockerErrors.d.ts.map +1 -0
- package/dist/services/DockerErrors.js +224 -0
- package/dist/services/DockerRateLimiter.d.ts +80 -0
- package/dist/services/DockerRateLimiter.d.ts.map +1 -0
- package/dist/services/DockerRateLimiter.js +93 -0
- package/dist/services/EventBus.d.ts +126 -0
- package/dist/services/EventBus.d.ts.map +1 -0
- package/dist/services/EventBus.js +111 -0
- package/dist/services/Harpoon.d.ts +151 -0
- package/dist/services/Harpoon.d.ts.map +1 -0
- package/dist/services/Harpoon.js +148 -0
- package/dist/services/HarpoonConfig.d.ts +60 -0
- package/dist/services/HarpoonConfig.d.ts.map +1 -0
- package/dist/services/HarpoonConfig.js +67 -0
- package/dist/services/HarpoonLogger.d.ts +36 -0
- package/dist/services/HarpoonLogger.d.ts.map +1 -0
- package/dist/services/HarpoonLogger.js +94 -0
- package/dist/services/ReadinessCoordinator.d.ts +128 -0
- package/dist/services/ReadinessCoordinator.d.ts.map +1 -0
- package/dist/services/ReadinessCoordinator.js +170 -0
- package/dist/services/ResourceTracker.d.ts +74 -0
- package/dist/services/ResourceTracker.d.ts.map +1 -0
- package/dist/services/ResourceTracker.js +145 -0
- package/dist/services/index.d.ts +29 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +47 -0
- package/dist/testing/helpers.d.ts +114 -0
- package/dist/testing/helpers.d.ts.map +1 -0
- package/dist/testing/helpers.js +140 -0
- package/dist/testing/index.d.ts +29 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +47 -0
- package/dist/testing/mocks.d.ts +66 -0
- package/dist/testing/mocks.d.ts.map +1 -0
- package/dist/testing/mocks.js +224 -0
- package/dist/utils/process.d.ts +24 -0
- package/dist/utils/process.d.ts.map +1 -0
- package/dist/utils/process.js +49 -0
- package/package.json +12 -8
- package/dist/__tests__/bindings.test.d.ts +0 -10
- package/dist/__tests__/bindings.test.d.ts.map +0 -1
- package/dist/__tests__/bindings.test.js +0 -128
- package/dist/__tests__/container.test.d.ts +0 -12
- package/dist/__tests__/container.test.d.ts.map +0 -1
- package/dist/__tests__/container.test.js +0 -136
- package/dist/__tests__/database.test.d.ts +0 -10
- package/dist/__tests__/database.test.d.ts.map +0 -1
- package/dist/__tests__/database.test.js +0 -78
- package/dist/__tests__/docker-infra.template.d.ts +0 -2
- package/dist/__tests__/docker-infra.template.d.ts.map +0 -1
- package/dist/__tests__/docker-infra.template.js +0 -174
- package/dist/__tests__/network.test.d.ts +0 -10
- package/dist/__tests__/network.test.d.ts.map +0 -1
- package/dist/__tests__/network.test.js +0 -44
- package/dist/__tests__/test-setup.d.ts +0 -9
- package/dist/__tests__/test-setup.d.ts.map +0 -1
- package/dist/__tests__/test-setup.js +0 -20
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Database Helper Integration Tests
|
|
3
|
-
*
|
|
4
|
-
* Dogfoods the database helper to verify:
|
|
5
|
-
* - Connection string generation
|
|
6
|
-
* - Port mapping
|
|
7
|
-
* - Database-specific defaults
|
|
8
|
-
*/
|
|
9
|
-
import { describe, test, expect, afterEach, setDefaultTimeout } from 'bun:test';
|
|
10
|
-
import { Network, database, destroyAll } from '../index';
|
|
11
|
-
setDefaultTimeout(60_000);
|
|
12
|
-
describe('database', () => {
|
|
13
|
-
afterEach(async () => {
|
|
14
|
-
await destroyAll();
|
|
15
|
-
});
|
|
16
|
-
test('creates a postgres database with connection string', async () => {
|
|
17
|
-
const db = await database('test-postgres', {
|
|
18
|
-
image: 'postgres:16-alpine',
|
|
19
|
-
env: {
|
|
20
|
-
POSTGRES_PASSWORD: 'testpass',
|
|
21
|
-
POSTGRES_DB: 'testdb',
|
|
22
|
-
},
|
|
23
|
-
hostPort: 15432,
|
|
24
|
-
});
|
|
25
|
-
expect(db.id).toBeDefined();
|
|
26
|
-
expect(db.name).toBe('test-postgres');
|
|
27
|
-
expect(db.port).toBe(5432);
|
|
28
|
-
expect(db.hostPort).toBe(15432);
|
|
29
|
-
expect(db.connectionString).toBe('postgresql://postgres:testpass@localhost:15432/testdb');
|
|
30
|
-
await db.destroy();
|
|
31
|
-
});
|
|
32
|
-
test('creates a redis database with connection string', async () => {
|
|
33
|
-
const db = await database('test-redis', {
|
|
34
|
-
image: 'redis:7-alpine',
|
|
35
|
-
hostPort: 16379,
|
|
36
|
-
});
|
|
37
|
-
expect(db.port).toBe(6379);
|
|
38
|
-
expect(db.hostPort).toBe(16379);
|
|
39
|
-
expect(db.connectionString).toBe('redis://localhost:16379');
|
|
40
|
-
await db.destroy();
|
|
41
|
-
});
|
|
42
|
-
test('creates a redis database with password', async () => {
|
|
43
|
-
const db = await database('test-redis-auth', {
|
|
44
|
-
image: 'redis:7-alpine',
|
|
45
|
-
hostPort: 16380,
|
|
46
|
-
env: {
|
|
47
|
-
REDIS_PASSWORD: 'secret',
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
expect(db.connectionString).toBe('redis://:secret@localhost:16380');
|
|
51
|
-
await db.destroy();
|
|
52
|
-
});
|
|
53
|
-
test('attaches database to network', async () => {
|
|
54
|
-
const network = await Network('test-db-net');
|
|
55
|
-
const db = await database('test-db-networked', {
|
|
56
|
-
image: 'redis:7-alpine',
|
|
57
|
-
networks: [network],
|
|
58
|
-
hostPort: 16381,
|
|
59
|
-
});
|
|
60
|
-
const ip = await db.getIp('test-db-net');
|
|
61
|
-
expect(ip).toBeDefined();
|
|
62
|
-
expect(ip).not.toBe('');
|
|
63
|
-
await db.destroy();
|
|
64
|
-
await network.destroy();
|
|
65
|
-
});
|
|
66
|
-
test('database inherits container methods', async () => {
|
|
67
|
-
const db = await database('test-db-methods', {
|
|
68
|
-
image: 'redis:7-alpine',
|
|
69
|
-
hostPort: 16382,
|
|
70
|
-
});
|
|
71
|
-
await db.waitForLog('Ready to accept connections', 10000);
|
|
72
|
-
const result = await db.exec(['redis-cli', 'PING']);
|
|
73
|
-
expect(result.stdout.trim()).toBe('PONG');
|
|
74
|
-
const stats = await db.stats();
|
|
75
|
-
expect(stats.cpu).toBeDefined();
|
|
76
|
-
await db.destroy();
|
|
77
|
-
});
|
|
78
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docker-infra.template.d.ts","sourceRoot":"","sources":["../../src/__tests__/docker-infra.template.ts"],"names":[],"mappings":""}
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Docker Infrastructure Test Template
|
|
3
|
-
*
|
|
4
|
-
* Copy and customize this file to test your project's Dockerfile and entrypoint.
|
|
5
|
-
* Replace {{PROJECT_NAME}} and {{PROJECT_IMAGE}} with your values.
|
|
6
|
-
*
|
|
7
|
-
* This template demonstrates Harpoon's complete API for testing Docker infrastructure:
|
|
8
|
-
* - Image building with buildArgs
|
|
9
|
-
* - Container creation with volumes, capabilities, and user overrides
|
|
10
|
-
* - Log waiting and streaming
|
|
11
|
-
* - Command execution inside containers
|
|
12
|
-
* - Network isolation testing
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```bash
|
|
16
|
-
* # Copy and customize for your project
|
|
17
|
-
* cp docker-infra.template.ts my-project.test.ts
|
|
18
|
-
* # Edit PROJECT config and tests
|
|
19
|
-
* bun test my-project.test.ts
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
import { describe, test, expect, beforeAll, afterEach, setDefaultTimeout } from 'bun:test';
|
|
23
|
-
import { Image, Container, Network, destroyAll } from '@docker-harpoon/core';
|
|
24
|
-
// ============ PROJECT CONFIGURATION ============
|
|
25
|
-
// Customize these values for your project
|
|
26
|
-
const PROJECT = {
|
|
27
|
-
name: '{{PROJECT_NAME}}',
|
|
28
|
-
image: '{{PROJECT_IMAGE}}:latest',
|
|
29
|
-
context: './',
|
|
30
|
-
dockerfile: 'Dockerfile',
|
|
31
|
-
port: 3000,
|
|
32
|
-
healthPath: '/api/status',
|
|
33
|
-
};
|
|
34
|
-
// Set a generous timeout for Docker operations
|
|
35
|
-
setDefaultTimeout(120_000);
|
|
36
|
-
describe(`${PROJECT.name} Docker Infrastructure`, () => {
|
|
37
|
-
beforeAll(async () => {
|
|
38
|
-
// Build the project image
|
|
39
|
-
await Image(PROJECT.image, {
|
|
40
|
-
context: PROJECT.context,
|
|
41
|
-
dockerfile: PROJECT.dockerfile,
|
|
42
|
-
buildArgs: { SEED_DATABASE: 'true' },
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
afterEach(async () => {
|
|
46
|
-
await destroyAll();
|
|
47
|
-
});
|
|
48
|
-
// ============ HEALTH CHECK TEST ============
|
|
49
|
-
test('health check responds 200', async () => {
|
|
50
|
-
const container = await Container('test-health', {
|
|
51
|
-
image: PROJECT.image,
|
|
52
|
-
env: { PORT: String(PROJECT.port) },
|
|
53
|
-
ports: [{ internal: PROJECT.port, external: 13000 }],
|
|
54
|
-
});
|
|
55
|
-
await container.waitForLog(/listening|started|ready/i, 30000);
|
|
56
|
-
const res = await fetch(`http://localhost:13000${PROJECT.healthPath}`);
|
|
57
|
-
expect(res.status).toBe(200);
|
|
58
|
-
});
|
|
59
|
-
// ============ VOLUME MOUNT TEST ============
|
|
60
|
-
test('db snapshot copy-on-boot pattern', async () => {
|
|
61
|
-
const container = await Container('test-snapshot', {
|
|
62
|
-
image: PROJECT.image,
|
|
63
|
-
env: {
|
|
64
|
-
DB_SOURCE: '/data/snapshot/app.db',
|
|
65
|
-
DB_PATH: '/app/data/test.db',
|
|
66
|
-
},
|
|
67
|
-
volumes: [
|
|
68
|
-
{ hostPath: '/tmp/test-snapshot.db', containerPath: '/data/snapshot/app.db', readonly: true },
|
|
69
|
-
],
|
|
70
|
-
});
|
|
71
|
-
await container.waitForLog(/snapshot copied|database ready/i, 30000);
|
|
72
|
-
});
|
|
73
|
-
// ============ FILE SYSTEM TEST ============
|
|
74
|
-
test('file upload directory setup', async () => {
|
|
75
|
-
const container = await Container('test-uploads', {
|
|
76
|
-
image: PROJECT.image,
|
|
77
|
-
env: { FILE_UPLOAD_PATH: '/app/custom-uploads' },
|
|
78
|
-
});
|
|
79
|
-
await container.waitForLog(/upload directory|ensuring/i, 10000);
|
|
80
|
-
const result = await container.exec(['ls', '-la', '/app/custom-uploads']);
|
|
81
|
-
expect(result.exitCode).toBe(0);
|
|
82
|
-
expect(result.stdout).toContain('drwx'); // Directory exists with permissions
|
|
83
|
-
});
|
|
84
|
-
// ============ NETWORK ISOLATION TEST ============
|
|
85
|
-
test('network isolation with iptables', async () => {
|
|
86
|
-
const network = await Network('isolated-net');
|
|
87
|
-
const container = await Container('test-isolation', {
|
|
88
|
-
image: PROJECT.image,
|
|
89
|
-
networks: [network],
|
|
90
|
-
env: { ENABLE_NETWORK_ISOLATION: 'true' },
|
|
91
|
-
capAdd: ['NET_ADMIN'],
|
|
92
|
-
});
|
|
93
|
-
await container.waitForLog(/network isolation configured|iptables/i, 15000);
|
|
94
|
-
});
|
|
95
|
-
// ============ PRIVILEGE DROPPING TEST ============
|
|
96
|
-
test('privilege dropping', async () => {
|
|
97
|
-
const container = await Container('test-privileges', {
|
|
98
|
-
image: PROJECT.image,
|
|
99
|
-
});
|
|
100
|
-
await container.waitForLog(/dropping privileges|started/i, 15000);
|
|
101
|
-
const result = await container.exec(['whoami']);
|
|
102
|
-
expect(result.exitCode).toBe(0);
|
|
103
|
-
expect(result.stdout.trim()).not.toBe('root');
|
|
104
|
-
});
|
|
105
|
-
// ============ ENVIRONMENT VARIABLE TEST ============
|
|
106
|
-
test('environment variable propagation', async () => {
|
|
107
|
-
const container = await Container('test-env', {
|
|
108
|
-
image: PROJECT.image,
|
|
109
|
-
env: {
|
|
110
|
-
PORT: '8080',
|
|
111
|
-
LOG_LEVEL: 'debug',
|
|
112
|
-
CUSTOM_VAR: 'test-value',
|
|
113
|
-
},
|
|
114
|
-
ports: [{ internal: 8080, external: 18080 }],
|
|
115
|
-
});
|
|
116
|
-
await container.waitForLog(/listening|started/i, 30000);
|
|
117
|
-
// Verify env vars are set
|
|
118
|
-
const envResult = await container.exec(['printenv']);
|
|
119
|
-
expect(envResult.stdout).toContain('PORT=8080');
|
|
120
|
-
expect(envResult.stdout).toContain('LOG_LEVEL=debug');
|
|
121
|
-
expect(envResult.stdout).toContain('CUSTOM_VAR=test-value');
|
|
122
|
-
});
|
|
123
|
-
// ============ USER OVERRIDE TEST ============
|
|
124
|
-
test('user override', async () => {
|
|
125
|
-
const container = await Container('test-user', {
|
|
126
|
-
image: PROJECT.image,
|
|
127
|
-
user: '1000:1000',
|
|
128
|
-
});
|
|
129
|
-
await container.waitForLog(/started|ready/i, 15000);
|
|
130
|
-
const result = await container.exec(['id']);
|
|
131
|
-
expect(result.exitCode).toBe(0);
|
|
132
|
-
expect(result.stdout).toContain('uid=1000');
|
|
133
|
-
expect(result.stdout).toContain('gid=1000');
|
|
134
|
-
});
|
|
135
|
-
// ============ CAPABILITIES TEST ============
|
|
136
|
-
test('dropped capabilities', async () => {
|
|
137
|
-
const container = await Container('test-caps', {
|
|
138
|
-
image: PROJECT.image,
|
|
139
|
-
capDrop: ['ALL'],
|
|
140
|
-
capAdd: ['NET_BIND_SERVICE'],
|
|
141
|
-
});
|
|
142
|
-
await container.waitForLog(/started|ready/i, 15000);
|
|
143
|
-
// Container should be running with minimal capabilities
|
|
144
|
-
const result = await container.exec(['cat', '/proc/1/status']);
|
|
145
|
-
expect(result.exitCode).toBe(0);
|
|
146
|
-
// CapEff should show limited capabilities
|
|
147
|
-
expect(result.stdout).toContain('CapEff');
|
|
148
|
-
});
|
|
149
|
-
// ============ GRACEFUL SHUTDOWN TEST ============
|
|
150
|
-
test('graceful shutdown', async () => {
|
|
151
|
-
const container = await Container('test-shutdown', {
|
|
152
|
-
image: PROJECT.image,
|
|
153
|
-
env: { PORT: String(PROJECT.port) },
|
|
154
|
-
});
|
|
155
|
-
await container.waitForLog(/listening|started|ready/i, 30000);
|
|
156
|
-
const metadata = await container.stop('SIGTERM', 10000);
|
|
157
|
-
expect(metadata.graceful).toBe(true);
|
|
158
|
-
expect(metadata.signal).toBe('SIGTERM');
|
|
159
|
-
});
|
|
160
|
-
// ============ RESOURCE STATS TEST ============
|
|
161
|
-
test('container stats', async () => {
|
|
162
|
-
const container = await Container('test-stats', {
|
|
163
|
-
image: PROJECT.image,
|
|
164
|
-
env: { PORT: String(PROJECT.port) },
|
|
165
|
-
});
|
|
166
|
-
await container.waitForLog(/listening|started|ready/i, 30000);
|
|
167
|
-
const stats = await container.stats();
|
|
168
|
-
expect(stats.cpu).toBeDefined();
|
|
169
|
-
expect(stats.cpu.percent).toBeGreaterThanOrEqual(0);
|
|
170
|
-
expect(stats.memory).toBeDefined();
|
|
171
|
-
expect(stats.memory.usage).toBeGreaterThan(0);
|
|
172
|
-
expect(stats.network).toBeDefined();
|
|
173
|
-
});
|
|
174
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"network.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/network.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Network Resource Integration Tests
|
|
3
|
-
*
|
|
4
|
-
* Dogfoods the Network resource to verify:
|
|
5
|
-
* - Creation and destruction
|
|
6
|
-
* - Property access (id, name)
|
|
7
|
-
* - Duplicate network handling
|
|
8
|
-
*/
|
|
9
|
-
import { describe, test, expect, afterEach, setDefaultTimeout } from 'bun:test';
|
|
10
|
-
import { Network, destroyAll } from '../index';
|
|
11
|
-
setDefaultTimeout(30_000);
|
|
12
|
-
describe('Network', () => {
|
|
13
|
-
afterEach(async () => {
|
|
14
|
-
await destroyAll();
|
|
15
|
-
});
|
|
16
|
-
test('creates a network and returns resource with id and name', async () => {
|
|
17
|
-
const network = await Network('test-network-basic');
|
|
18
|
-
expect(network.id).toBeDefined();
|
|
19
|
-
expect(network.id.length).toBeGreaterThan(0);
|
|
20
|
-
expect(network.name).toBe('test-network-basic');
|
|
21
|
-
await network.destroy();
|
|
22
|
-
});
|
|
23
|
-
test('allows custom driver configuration', async () => {
|
|
24
|
-
const network = await Network('test-network-custom', {
|
|
25
|
-
driver: 'bridge',
|
|
26
|
-
});
|
|
27
|
-
expect(network.name).toBe('test-network-custom');
|
|
28
|
-
expect(network.id).toBeDefined();
|
|
29
|
-
await network.destroy();
|
|
30
|
-
});
|
|
31
|
-
test('handles creating network with same name (replaces existing)', async () => {
|
|
32
|
-
const network1 = await Network('test-network-duplicate');
|
|
33
|
-
const id1 = network1.id;
|
|
34
|
-
const network2 = await Network('test-network-duplicate');
|
|
35
|
-
const id2 = network2.id;
|
|
36
|
-
expect(id2).not.toBe(id1);
|
|
37
|
-
await network2.destroy();
|
|
38
|
-
});
|
|
39
|
-
test('destroy is idempotent', async () => {
|
|
40
|
-
const network = await Network('test-network-idempotent');
|
|
41
|
-
await network.destroy();
|
|
42
|
-
expect(network.destroy()).resolves.toBeUndefined();
|
|
43
|
-
});
|
|
44
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared test setup for integration tests.
|
|
3
|
-
*
|
|
4
|
-
* Builds a minimal test image that can be used across all tests,
|
|
5
|
-
* ensuring tests are self-contained and don't rely on external images.
|
|
6
|
-
*/
|
|
7
|
-
export declare const TEST_IMAGE = "harpoon-test:latest";
|
|
8
|
-
export declare function buildTestImage(): Promise<void>;
|
|
9
|
-
//# sourceMappingURL=test-setup.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,eAAO,MAAM,UAAU,wBAAwB,CAAC;AAIhD,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAWpD"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared test setup for integration tests.
|
|
3
|
-
*
|
|
4
|
-
* Builds a minimal test image that can be used across all tests,
|
|
5
|
-
* ensuring tests are self-contained and don't rely on external images.
|
|
6
|
-
*/
|
|
7
|
-
import { Image } from '../index';
|
|
8
|
-
import { join } from 'path';
|
|
9
|
-
export const TEST_IMAGE = 'harpoon-test:latest';
|
|
10
|
-
let imageBuilt = false;
|
|
11
|
-
export async function buildTestImage() {
|
|
12
|
-
if (imageBuilt) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
await Image(TEST_IMAGE, {
|
|
16
|
-
context: join(__dirname, 'fixtures'),
|
|
17
|
-
dockerfile: 'Dockerfile',
|
|
18
|
-
});
|
|
19
|
-
imageBuilt = true;
|
|
20
|
-
}
|