@backstage/backend-test-utils
Version:
Test helpers library for Backstage backends
173 lines (167 loc) • 5.48 kB
JavaScript
;
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