138 lines
4.5 KiB
TypeScript
138 lines
4.5 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
|
|
import { ServiceManager } from '../ts/manager.service/classes.servicemanager.js';
|
|
|
|
const createDeleteable = (labelArg: string, callsArg: string[]) => ({
|
|
id: labelArg,
|
|
delete: async () => callsArg.push(`delete:${labelArg}`),
|
|
});
|
|
|
|
const createManager = (optionsArg: {
|
|
calls: string[];
|
|
failBackups?: boolean;
|
|
}) => {
|
|
const calls = optionsArg.calls;
|
|
const service = {
|
|
id: 'service-1',
|
|
data: {
|
|
name: 'ghost',
|
|
imageId: 'image-1',
|
|
appTemplateId: 'ghost',
|
|
secretBundleId: 'bundle-1',
|
|
registryTarget: { repository: 'workloads/ghost-service-1' },
|
|
domains: [{ name: 'ghost.example.com' }],
|
|
},
|
|
removeDnsEntries: async () => calls.push('delete:dns'),
|
|
delete: async () => calls.push('delete:service'),
|
|
};
|
|
const manager = Object.create(ServiceManager.prototype) as any;
|
|
manager.CService = {
|
|
getInstance: async () => service,
|
|
};
|
|
manager.cloudlyRef = {
|
|
appStoreManager: {
|
|
clearOperationsForService: (serviceIdArg: string) => calls.push(`clear-upgrades:${serviceIdArg}`),
|
|
},
|
|
deploymentManager: {
|
|
CDeployment: {
|
|
getInstances: async () => [createDeleteable('deployment-1', calls)],
|
|
},
|
|
},
|
|
platformManager: {
|
|
CPlatformBinding: {
|
|
getInstances: async (queryArg: { serviceId: string }) => queryArg.serviceId === 'service-1'
|
|
? [createDeleteable('platform-binding-1', calls)]
|
|
: [],
|
|
},
|
|
},
|
|
backupManager: {
|
|
deleteBackupsForService: async (serviceIdArg: string) => {
|
|
calls.push(`delete-backups:${serviceIdArg}`);
|
|
if (optionsArg.failBackups) {
|
|
throw new Error('backup cleanup failed');
|
|
}
|
|
},
|
|
},
|
|
registryManager: {
|
|
deleteServiceRepository: async () => calls.push('delete:registry-repository'),
|
|
},
|
|
secretManager: {
|
|
CSecretBundle: {
|
|
getInstance: async () => ({
|
|
id: 'bundle-1',
|
|
data: {
|
|
serviceId: 'service-1',
|
|
includedSecretGroupIds: ['group-1'],
|
|
},
|
|
delete: async () => calls.push('delete:secret-bundle'),
|
|
}),
|
|
getInstances: async () => [],
|
|
},
|
|
CSecretGroup: {
|
|
getInstance: async () => createDeleteable('secret-group-1', calls),
|
|
},
|
|
},
|
|
imageManager: {
|
|
deleteImageIfUnreferenced: async (imageIdArg: string, serviceIdArg: string) => {
|
|
calls.push(`delete-image:${imageIdArg}:${serviceIdArg}`);
|
|
return true;
|
|
},
|
|
},
|
|
settingsManager: {
|
|
getSettings: async () => ({
|
|
dcrouterGatewayUrl: 'https://dcrouter.example.com',
|
|
dcrouterGatewayApiToken: 'token',
|
|
dcrouterWorkHosterId: 'cloudly-main',
|
|
}),
|
|
},
|
|
clusterManager: {
|
|
getAllClusters: async () => [],
|
|
},
|
|
coreflowManager: {
|
|
pushClusterConfigToConnectedCoreflows: async () => calls.push('push:coreflow'),
|
|
},
|
|
};
|
|
manager.fireDcRouterRequest = async (_url: string, methodArg: string, payloadArg: any) => {
|
|
calls.push(`${methodArg}:${payloadArg.ownership.hostname}:${payloadArg.ownership.workHosterId}`);
|
|
return { success: true, action: 'deleted' };
|
|
};
|
|
return { manager, service };
|
|
};
|
|
|
|
tap.test('should delete Cloudly service-owned resources before deleting the service row', async () => {
|
|
const calls: string[] = [];
|
|
const { manager } = createManager({ calls });
|
|
|
|
await manager.deleteServiceById('service-1');
|
|
|
|
expect(calls).toContain('syncWorkAppRoute:ghost.example.com:cloudly-main');
|
|
expect(calls).toContain('clear-upgrades:service-1');
|
|
expect(calls).toContain('delete:deployment-1');
|
|
expect(calls).toContain('delete:dns');
|
|
expect(calls).toContain('delete:platform-binding-1');
|
|
expect(calls).toContain('delete-backups:service-1');
|
|
expect(calls).toContain('delete:registry-repository');
|
|
expect(calls).toContain('delete:secret-bundle');
|
|
expect(calls).toContain('delete:secret-group-1');
|
|
expect(calls).toContain('delete-image:image-1:service-1');
|
|
expect(calls.at(-2)).toEqual('delete:service');
|
|
expect(calls.at(-1)).toEqual('push:coreflow');
|
|
});
|
|
|
|
tap.test('should keep Cloudly service row when required cleanup fails', async () => {
|
|
const calls: string[] = [];
|
|
const { manager } = createManager({ calls, failBackups: true });
|
|
|
|
let errorMessage = '';
|
|
try {
|
|
await manager.deleteServiceById('service-1');
|
|
} catch (error) {
|
|
errorMessage = (error as Error).message;
|
|
}
|
|
expect(errorMessage).toEqual('backup cleanup failed');
|
|
expect(calls).not.toContain('delete:service');
|
|
expect(calls).not.toContain('push:coreflow');
|
|
});
|
|
|
|
export default tap.start();
|