UNPKG

@backstage/backend-test-utils

Version:

Test helpers library for Backstage backends

173 lines (167 loc) • 5.48 kB
'use strict'; var Keyv = require('keyv'); var isDockerDisabledForTests = require('../util/isDockerDisabledForTests.cjs.js'); var memcache = require('./memcache.cjs.js'); var redis = require('./redis.cjs.js'); var types = require('./types.cjs.js'); var valkey = require('./valkey.cjs.js'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } var Keyv__default = /*#__PURE__*/_interopDefaultCompat(Keyv); class TestCaches { instanceById; supportedIds; static defaultIds; /** * Creates an empty `TestCaches` instance, and sets up Jest to clean up all of * its acquired resources after all tests finish. * * You typically want to create just a single instance like this at the top of * your test file or `describe` block, and then call `init` many times on that * instance inside the individual tests. Spinning up a "physical" cache * instance takes a considerable amount of time, slowing down tests. But * wiping the contents of an instance using `init` is very fast. */ static create(options) { const ids = options?.ids; const disableDocker = options?.disableDocker ?? isDockerDisabledForTests.isDockerDisabledForTests(); let testCacheIds; if (ids) { testCacheIds = ids; } else if (TestCaches.defaultIds) { testCacheIds = TestCaches.defaultIds; } else { testCacheIds = Object.keys(types.allCaches); } const supportedIds = testCacheIds.filter((id) => { const properties = types.allCaches[id]; if (!properties) { return false; } if (properties.connectionStringEnvironmentVariableName && process.env[properties.connectionStringEnvironmentVariableName]) { return true; } if (!properties.dockerImageName) { return true; } if (disableDocker) { return false; } return true; }); const caches = new TestCaches(supportedIds); if (supportedIds.length > 0) { afterAll(async () => { await caches.shutdown(); }); } return caches; } static setDefaults(options) { TestCaches.defaultIds = options.ids; } constructor(supportedIds) { this.instanceById = /* @__PURE__ */ new Map(); this.supportedIds = supportedIds; } supports(id) { return this.supportedIds.includes(id); } eachSupportedId() { return this.supportedIds.map((id) => [id]); } /** * Returns a fresh, empty cache for the given driver. * * @param id - The ID of the cache to use, e.g. 'REDIS_7' * @returns Cache connection properties */ async init(id) { const properties = types.allCaches[id]; if (!properties) { const candidates = Object.keys(types.allCaches).join(", "); throw new Error( `Unknown test cache ${id}, possible values are ${candidates}` ); } if (!this.supportedIds.includes(id)) { const candidates = this.supportedIds.join(", "); throw new Error( `Unsupported test cache ${id} for this environment, possible values are ${candidates}` ); } let instance = this.instanceById.get(id); if (!instance) { instance = await this.initAny(properties); this.instanceById.set(id, instance); } await instance.keyv.clear(); return { store: instance.store, connection: instance.connection, keyv: instance.keyv }; } async initAny(properties) { switch (properties.store) { case "memcache": return this.initMemcached(properties); case "redis": return this.initRedis(properties); case "valkey": return this.initValkey(properties); case "memory": return { store: "memory", connection: "memory", keyv: new Keyv__default.default(), stop: async () => { } }; default: throw new Error(`Unknown cache store '${properties.store}'`); } } async initMemcached(properties) { const envVarName = properties.connectionStringEnvironmentVariableName; if (envVarName) { const connectionString = process.env[envVarName]; if (connectionString) { return memcache.connectToExternalMemcache(connectionString); } } return await memcache.startMemcachedContainer(properties.dockerImageName); } async initRedis(properties) { const envVarName = properties.connectionStringEnvironmentVariableName; if (envVarName) { const connectionString = process.env[envVarName]; if (connectionString) { return redis.connectToExternalRedis(connectionString); } } return await redis.startRedisContainer(properties.dockerImageName); } async initValkey(properties) { const envVarName = properties.connectionStringEnvironmentVariableName; if (envVarName) { const connectionString = process.env[envVarName]; if (connectionString) { return valkey.connectToExternalValkey(connectionString); } } return await valkey.startValkeyContainer(properties.dockerImageName); } async shutdown() { const instances = [...this.instanceById.values()]; this.instanceById.clear(); await Promise.all( instances.map( ({ stop }) => stop().catch((error) => { console.warn(`TestCaches: Failed to stop container`, { error }); }) ) ); } } exports.TestCaches = TestCaches; //# sourceMappingURL=TestCaches.cjs.js.map