1 import { ComponentFixture, TestBed } from '@angular/core/testing';
2 import { Mock } from 'ts-mockery';
5 Capability, ComponentInstance, CompositionCiLinkBase, CompositionCiNodeBase, CompositionCiNodeCp,
6 CompositionCiNodeVf, CompositionCiNodeVl,
7 Requirement, RequirementsGroup
8 } from '../../../../../models';
9 import { MatchCapabilitiesRequirementsUtils } from './match-capability-requierment-utils';
11 describe('match capability requirements utils service ', () => {
13 const bindableReq = Mock.of<Requirement>({
14 capability : 'tosca.capabilities.network.Bindable',
15 name: 'virtualBinding',
16 relationship: 'tosca.relationships.network.BindsTo',
17 uniqueId: 'eef99154-8039-4227-ba68-62a32e6b0d98.virtualBinding',
22 const virtualLinkReq = Mock.of<Requirement>({
23 capability: 'tosca.capabilities.network.Linkable',
25 relationship: 'tosca.relationships.network.LinksTo',
26 uniqueId: 'eef99154-8039-4227-ba68-62a32e6b0d98.virtualLink',
31 const storeAttachmentReq = Mock.of<Requirement>({
32 capability: 'tosca.capabilities.Attachment',
33 name: 'local_storage',
34 relationship: 'tosca.relationships.AttachesTo',
35 uniqueId: 'eef99154-8039-4227-ba68-62a32e6b0d98.local_storage',
36 node: 'tosca.nodes.BlockStorage',
41 const vlAttachmentReq = Mock.of<Requirement>({
42 capability: 'tosca.capabilities.Attachment',
43 name: 'local_storage',
44 relationship: 'tosca.relationships.AttachesTo',
45 uniqueId: 'eef99154-8039-4227-ba68-62a32e6b0d98.local_storage',
46 node: 'tosca.nodes.BlockStorage',
51 const extVirtualLinkReq = Mock.of<Requirement>({
52 capability: 'tosca.capabilities.network.Linkable',
53 name: 'external_virtualLink',
54 relationship: 'tosca.relationships.network.LinksTo',
55 uniqueId: 'eef99154-8039-4227-ba68-62a32e6b0d98.external_virtualLink'
58 const dependencyReq = Mock.of<Requirement>({
59 capability: 'tosca.capabilities.Node',
61 relationship: 'tosca.relationships.DependsOn',
62 uniqueId: 'eef99154-8039-4227-ba68-62a32e6b0d98.dependency'
65 const featureCap = Mock.of<Capability>({
66 type: 'tosca.capabilities.Node',
68 uniqueId: 'capability.ddf1301e-866b-4fa3-bc4f-edbd81e532cd.feature',
69 maxOccurrences: 'UNBOUNDED',
73 const internalConnPointCap = Mock.of<Capability>({
74 type: 'tosca.capabilities.Node',
75 name: 'internal_connectionPoint',
76 capabilitySources : ['org.openecomp.resource.cp.extCP'],
77 uniqueId: 'capability.ddf1301e-866b-4fa3-bc4f-edbd81e532cd.internal_connectionPoint',
78 maxOccurrences: 'UNBOUNDED',
82 const blockStoreAttachmentCap = Mock.of<Capability>({
83 type: 'tosca.capabilities.Attachment',
85 capabilitySources: ['tosca.nodes.BlockStorage'],
86 uniqueId: 'capability.ddf1301e-866b-4fa3-bc4f-edbd81e532cd.attachment',
87 maxOccurrences: 'UNBOUNDED',
91 const bindingCap = Mock.of<Capability>({
92 type: 'tosca.capabilities.network.Bindable',
94 capabilitySources: ['tosca.nodes.Compute'],
95 uniqueId: 'capability.ddf1301e-866b-4fa3-bc4f-edbd81e532cd.binding',
96 maxOccurrences: 'UNBOUNDED',
100 const linkableCap = Mock.of<Capability>({
101 type: 'tosca.capabilities.network.Linkable',
102 capabilitySources: ['org.openecomp.resource.vl.extVL'],
103 uniqueId: 'capability.ddf1301e-866b-4fa3-bc4f-edbd81e532cd.virtual_linkable',
104 maxOccurrences: 'UNBOUNDED',
108 const nodeCompute = Mock.of<CompositionCiNodeVf>({
110 componentInstance: Mock.of<ComponentInstance>({
111 componentName: 'Compute',
112 uniqueId : 'compute0',
113 requirements: Mock.of<RequirementsGroup>({
114 'tosca.capabilities.Node' : [ dependencyReq ],
115 'tosca.capabilities.Attachment' : [ storeAttachmentReq ]
117 capabilities: Mock.of<CapabilitiesGroup>({
118 'tosca.capabilities.network.Bindable' : [ bindingCap ],
119 'tosca.capabilities.Node' : [ featureCap ]
124 const nodeBlockStorage = Mock.of<CompositionCiNodeVf>({
125 name: 'BlockStorage 0',
126 componentInstance: Mock.of<ComponentInstance>({
127 componentName: 'BlockStorage',
128 uniqueId : 'blockstorage0',
129 requirements: Mock.of<RequirementsGroup>({
130 'tosca.capabilities.Node' : [ dependencyReq ]
132 capabilities: Mock.of<CapabilitiesGroup>({
133 'tosca.capabilities.Attachment' : [ blockStoreAttachmentCap ],
134 'tosca.capabilities.Node' : [ featureCap ]
139 const nodeVl = Mock.of<CompositionCiNodeVl>({
141 componentInstance: Mock.of<ComponentInstance>({
142 componentName: 'BlockStorage',
144 requirements: Mock.of<RequirementsGroup>({
145 'tosca.capabilities.Node' : [ dependencyReq ]
147 capabilities: Mock.of<CapabilitiesGroup>({
148 'tosca.capabilities.network.Linkable' : [ linkableCap ],
149 'tosca.capabilities.Node' : [ featureCap ]
154 const nodeCp = Mock.of<CompositionCiNodeCp>({
156 componentInstance: Mock.of<ComponentInstance>({
157 componentName: 'ExtCP',
159 requirements: Mock.of<RequirementsGroup>({
160 'tosca.capabilities.network.Linkable' : [ virtualLinkReq ],
161 'tosca.capabilities.network.Bindable' : [ bindableReq ]
163 capabilities: Mock.of<CapabilitiesGroup>({
164 'tosca.capabilities.Node' : [ featureCap ]
169 let service: MatchCapabilitiesRequirementsUtils;
172 TestBed.configureTestingModule({
174 providers: [MatchCapabilitiesRequirementsUtils]
177 service = TestBed.get(MatchCapabilitiesRequirementsUtils);
180 it('match capability requirements utils should be defined', () => {
181 console.log(JSON.stringify(service));
182 expect(service).toBeDefined();
185 describe('isMatch function ', () => {
187 it('capability type not equal to requirement capability, match is false', () => {
188 const requirement = Mock.of<Requirement>({capability: 'tosca.capabilities.network.Linkable11'});
189 const capability = Mock.of<Capability>({type: 'tosca.capabilities.network.Linkable'});
190 expect(service.isMatch(requirement, capability)).toBeFalsy();
193 it('capability type equal to requirement capability and requirement node not exist, match is true', () => {
194 const requirement = Mock.of<Requirement>({capability: 'tosca.capabilities.network.Linkable'});
195 const capability = Mock.of<Capability>({type: 'tosca.capabilities.network.Linkable'});
196 expect(service.isMatch(requirement, capability)).toBeTruthy();
199 it('is match - capability type equal to requirement capability and requirement node exist and includes in capability sources, match is true', () => {
200 const requirement = Mock.of<Requirement>({capability: 'tosca.capabilities.network.Linkable', node: 'node1'});
201 const capability = Mock.of<Capability>({
202 type: 'tosca.capabilities.network.Linkable',
203 capabilitySources: ['node1', 'node2', 'node3']
205 expect(service.isMatch(requirement, capability)).toBeTruthy();
208 it('no match - capability type equal to requirement capability and requirement node but not includes in capability sources, match is false', () => {
209 const requirement = Mock.of<Requirement>({capability: 'tosca.capabilities.network.Linkable', node: 'node4'});
210 const capability = Mock.of<Capability>({
211 type: 'tosca.capabilities.network.Linkable',
212 capabilitySources: ['node1', 'node2', 'node3']
214 expect(service.isMatch(requirement, capability)).toBeFalsy();
218 describe('hasUnfulfilledRequirementContainingMatch function ', () => {
220 it('node have no componentInstance, return false', () => {
221 const node = Mock.of<CompositionCiNodeVf>({componentInstance: undefined});
222 expect(service.hasUnfulfilledRequirementContainingMatch(node, [], {}, [])).toBeFalsy();
225 it('node have componentInstance data but no unfulfilled requirements, return false', () => {
226 const node = Mock.of<CompositionCiNodeVf>({componentInstance: Mock.of<ComponentInstance>()});
227 jest.spyOn(service, 'getUnfulfilledRequirements').mockReturnValue([]);
228 expect(service.hasUnfulfilledRequirementContainingMatch(node, [], {}, [])).toBeFalsy();
231 it('node have componentInstance data and unfulfilled requirements but no match found, return false', () => {
232 const node = Mock.of<CompositionCiNodeVf>({componentInstance: Mock.of<ComponentInstance>()});
233 jest.spyOn(service, 'getUnfulfilledRequirements').mockReturnValue([Mock.of<Requirement>(), Mock.of<Requirement>()]);
234 jest.spyOn(service, 'containsMatch').mockReturnValue(false);
235 expect(service.hasUnfulfilledRequirementContainingMatch(node, [], {}, [])).toBeFalsy();
238 it('node have componentInstance data with unfulfilled requirements and match found, return true', () => {
239 const node = Mock.of<CompositionCiNodeVf>({componentInstance: Mock.of<ComponentInstance>()});
240 jest.spyOn(service, 'getUnfulfilledRequirements').mockReturnValue([Mock.of<Requirement>(), Mock.of<Requirement>()]);
241 jest.spyOn(service, 'containsMatch').mockReturnValue(true);
242 expect(service.hasUnfulfilledRequirementContainingMatch(node, [], {}, [])).toBeTruthy();
246 describe('getMatches function ', () => {
255 it('node have no unfulfilled requirements, return empty match array', () => {
256 jest.spyOn(service, 'getUnfulfilledRequirements').mockReturnValue([]);
257 expect(service.getMatches({}, {}, [], fromId, toId, true)).toHaveLength(0);
260 it('node have unfulfilled requirements but no capabilities, return empty match array', () => {
261 jest.spyOn(service, 'getUnfulfilledRequirements').mockReturnValue([Mock.of<Requirement>(), Mock.of<Requirement>()]);
262 expect(service.getMatches({}, {}, [], fromId, toId, true)).toHaveLength(0);
265 it('node have unfulfilled requirements and capabilities but no match found, return empty match array', () => {
266 jest.spyOn(service, 'getUnfulfilledRequirements').mockReturnValue([Mock.of<Requirement>(), Mock.of<Requirement>()]);
267 jest.spyOn(service, 'isMatch').mockReturnValue(false);
268 expect(service.getMatches({}, {}, [], fromId, toId, true)).toHaveLength(0);
271 it('node have 2 unfulfilled requirements and 2 capabilities and match found, return 4 matches', () => {
272 jest.spyOn(service, 'getUnfulfilledRequirements').mockReturnValue([Mock.of<Requirement>(), Mock.of<Requirement>()]);
273 const capabilities = {aaa: Mock.of<Capability>(), bbb: Mock.of<Capability>()};
274 jest.spyOn(service, 'isMatch').mockReturnValue(true);
275 expect(service.getMatches({}, capabilities, [], fromId, toId, true)).toHaveLength(4);
279 describe('Find matching nodes ===>', () => {
281 it('should find matching nodes with component instance', () => {
282 const nodes = [ nodeBlockStorage, nodeCompute, nodeVl ];
283 let matchingNodes: any;
285 // Compute can connect to Block Store
286 matchingNodes = service.findMatchingNodesToComponentInstance(nodeCompute.componentInstance, nodes, []);
287 expect(matchingNodes).toHaveLength(1);
288 expect(matchingNodes).toContain(nodeBlockStorage);
290 // Block Storage can connect to Compute
291 matchingNodes = service.findMatchingNodesToComponentInstance(nodeBlockStorage.componentInstance, nodes, []);
292 expect(matchingNodes).toHaveLength(1);
293 expect(matchingNodes).toContain(nodeCompute);
296 matchingNodes = service.findMatchingNodesToComponentInstance(nodeVl.componentInstance, nodes, []);
297 expect(matchingNodes).toHaveLength(0);
299 // CP should be able to connect to VL and Compute
300 matchingNodes = service.findMatchingNodesToComponentInstance(nodeCp.componentInstance, nodes, []);
301 expect(matchingNodes).toHaveLength(2);
302 expect(matchingNodes).toContain(nodeCompute);
303 expect(matchingNodes).toContain(nodeVl);
306 it('try with empty list of nodes', () => {
308 let matchingNodes: any;
310 // Compute can connect to Block Store
311 matchingNodes = service.findMatchingNodesToComponentInstance(nodeCompute.componentInstance, nodes, []);
312 expect(matchingNodes).toHaveLength(0);
315 it('should detect fulfilled connection with compute node', () => {
316 const nodes = [ nodeBlockStorage, nodeCompute, nodeVl ];
317 let matchingNodes: any;
324 requirementOwnerId: 'extcp0',
325 requirement: 'virtualBinding',
327 type: 'tosca.relationships.network.BindsTo'
335 const links = [link];
336 // CP should be able to connect to VL only since it already has a link with compute
337 matchingNodes = service.findMatchingNodesToComponentInstance(nodeCp.componentInstance, nodes, links as CompositionCiLinkBase[]);
338 expect(matchingNodes).toHaveLength(1);
339 expect(matchingNodes).toContain(nodeVl);