backend-app-api: add module initialization test + fix
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user