backend-app-api: add module initialization test + fix

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-08-11 14:00:31 +02:00
parent ed90ce7f2c
commit 8ade35b780
2 changed files with 81 additions and 3 deletions
@@ -20,10 +20,15 @@ import {
coreServices,
createBackendPlugin,
createBackendModule,
createExtensionPoint,
} from '@backstage/backend-plugin-api';
import { BackendInitializer } from './BackendInitializer';
import { ServiceRegistry } from './ServiceRegistry';
import { rootLifecycleServiceFactory } from '../services/implementations';
import {
lifecycleServiceFactory,
loggerServiceFactory,
rootLifecycleServiceFactory,
} from '../services/implementations';
const rootRef = createServiceRef<{ x: number }>({
id: '1',
@@ -44,6 +49,17 @@ class MockLogger {
}
}
const baseFactories = [
lifecycleServiceFactory(),
rootLifecycleServiceFactory(),
createServiceFactory({
service: coreServices.rootLogger,
deps: {},
factory: () => new MockLogger(),
})(),
loggerServiceFactory(),
];
describe('BackendInitializer', () => {
it('should initialize root scoped services', async () => {
const rootFactory = jest.fn();
@@ -75,6 +91,65 @@ describe('BackendInitializer', () => {
expect(pluginFactory).not.toHaveBeenCalled();
});
it('should initialize modules with extension points', async () => {
expect.assertions(3);
const extensionPoint = createExtensionPoint<{ values: string[] }>({
id: 'a',
});
const init = new BackendInitializer(new ServiceRegistry(baseFactories));
init.add(
createBackendModule({
pluginId: 'test',
moduleId: 'modA',
register(reg) {
reg.registerInit({
deps: { extension: extensionPoint },
async init({ extension }) {
expect(extension.values).toEqual(['b']);
extension.values.push('a');
},
});
},
})(),
);
init.add(
createBackendModule({
pluginId: 'test',
moduleId: 'modB',
register(reg) {
const values = ['b'];
reg.registerExtensionPoint(extensionPoint, { values });
reg.registerInit({
deps: {},
async init() {
expect(values).toEqual(['b', 'a', 'c']);
},
});
},
})(),
);
init.add(
createBackendModule({
pluginId: 'test',
moduleId: 'modC',
register(reg) {
reg.registerInit({
deps: { extension: extensionPoint },
async init({ extension }) {
expect(extension.values).toEqual(['b', 'a']);
extension.values.push('c');
},
});
},
})(),
);
await init.start();
});
it('should forward errors when plugins fail to start', async () => {
const init = new BackendInitializer(new ServiceRegistry([]));
init.add(
@@ -216,8 +216,11 @@ export class BackendInitializer {
const tree = DependencyTree.fromIterable(
Array.from(modules).map(([id, { provides, consumes }]) => ({
id,
provides: Array.from(provides).map(p => p.id),
consumes: Array.from(consumes).map(c => c.id),
// Relationships are reversed at this point since we're only interested in the extension points.
// If a modules provides extension point A we want it to be initialized AFTER all modules
// that depend on extension point A, so that they can provide their extensions.
consumes: Array.from(provides).map(p => p.id),
produces: Array.from(consumes).map(c => c.id),
})),
);
const circular = tree.detectCircularDependency();