1 # Copyright 2020 ArctosLabs Scandinavia AB
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
18 from unittest
import TestCase
20 # from operator import itemgetter
23 from jinja2
import Template
25 from osm_pla
.placement
.mznplacement
import MznModelGenerator
27 test_ns_placement_data_str
= {
28 'vim_accounts': ['vim' + vim_account
.replace('-', '_') for vim_account
in ['aaaaaaaa-38f5-438d-b8ee-3f93b3531f87',
29 'bbbbbbbb-38f5-438d-b8ee-3f93b3531f87',
30 'cccccccc-ed84-4e49-b5df-a9d117bd731f',
31 'dddddddd-ed84-4e49-b5df-a9d117bd731f',
32 'eeeeeeee-38f5-438d-b8ee-3f93b3531f87']],
33 'trp_link_latency': [[0, 50, 100, 150, 200], [0, 0, 100, 150, 200], [0, 0, 0, 150, 200], [0, 0, 0, 0, 200],
35 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
37 'trp_link_price_list': [[0, 5, 6, 6, 7], [0, 0, 6, 6, 7], [0, 0, 0, 6, 7], [0, 0, 0, 0, 7], [0, 0, 0, 0, 0]],
39 {'vnf_id': 'one', 'vnf_price_per_vim': [50, 51, 52, 53, 54]},
40 {'vnf_id': 'two', 'vnf_price_per_vim': [20, 21, 22, 23, 24]},
41 {'vnf_id': 'three', 'vnf_price_per_vim': [70, 71, 72, 73, 74]},
42 {'vnf_id': 'four', 'vnf_price_per_vim': [40, 41, 42, 43, 44]}],
43 'vld_desc': [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
44 {'cp_refs': ['two', 'three'], 'latency': 140, 'jitter': 30},
45 {'cp_refs': ['three', 'four'], 'latency': 130, 'jitter': 30}],
46 'generator_data': {'file': __file__
, 'time': datetime
.datetime
.now()}
49 test_ns_placement_data_str_no_vld_constraints
= {
50 'vim_accounts': ['vim' + vim_account
.replace('-', '_') for vim_account
in ['aaaaaaaa-38f5-438d-b8ee-3f93b3531f87',
51 'bbbbbbbb-38f5-438d-b8ee-3f93b3531f87',
52 'cccccccc-ed84-4e49-b5df-a9d117bd731f',
53 'dddddddd-ed84-4e49-b5df-a9d117bd731f',
54 'eeeeeeee-38f5-438d-b8ee-3f93b3531f87']],
55 'trp_link_latency': [[0, 50, 100, 150, 200], [0, 0, 100, 150, 200], [0, 0, 0, 150, 200], [0, 0, 0, 0, 200],
57 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
59 'trp_link_price_list': [[0, 5, 6, 6, 7], [0, 0, 6, 6, 7], [0, 0, 0, 6, 7], [0, 0, 0, 0, 7], [0, 0, 0, 0, 0]],
61 {'vnf_id': 'one', 'vnf_price_per_vim': [50, 51, 52, 53, 54]},
62 {'vnf_id': 'two', 'vnf_price_per_vim': [20, 21, 22, 23, 24]},
63 {'vnf_id': 'three', 'vnf_price_per_vim': [70, 71, 72, 73, 74]},
64 {'vnf_id': 'four', 'vnf_price_per_vim': [40, 41, 42, 43, 44]}],
65 'vld_desc': [{'cp_refs': ['one', 'two']},
66 {'cp_refs': ['two', 'three']},
67 {'cp_refs': ['three', 'four']}],
68 'generator_data': {'file': __file__
, 'time': datetime
.datetime
.now()}
71 test_ns_placement_data
= {
72 'vim_accounts': ['vim' + vim_account
.replace('-', '_') for vim_account
in ['aaaaaaaa-38f5-438d-b8ee-3f93b3531f87',
73 'bbbbbbbb-38f5-438d-b8ee-3f93b3531f87',
74 'cccccccc-ed84-4e49-b5df-a9d117bd731f',
75 'dddddddd-ed84-4e49-b5df-a9d117bd731f',
76 'eeeeeeee-38f5-438d-b8ee-3f93b3531f87']],
77 'trp_link_latency': [[0, 50, 100, 150, 200], [0, 0, 100, 150, 200], [0, 0, 0, 150, 200], [0, 0, 0, 0, 200],
79 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
81 'trp_link_price_list': [[0, 5, 6, 6, 7], [0, 0, 6, 6, 7], [0, 0, 0, 6, 7], [0, 0, 0, 0, 7], [0, 0, 0, 0, 0]],
83 {'vnf_id': '1', 'vnf_price_per_vim': [50, 51, 52, 53, 54]},
84 {'vnf_id': '2', 'vnf_price_per_vim': [20, 21, 22, 23, 24]},
85 {'vnf_id': '3', 'vnf_price_per_vim': [70, 71, 72, 73, 74]},
86 {'vnf_id': '4', 'vnf_price_per_vim': [40, 41, 42, 43, 44]}],
87 'vld_desc': [{'cp_refs': ['1', '2'], 'latency': 150, 'jitter': 30},
88 {'cp_refs': ['2', '3'], 'latency': 140, 'jitter': 30},
89 {'cp_refs': ['3', '4'], 'latency': 130, 'jitter': 30}],
90 'generator_data': {'file': __file__
, 'time': datetime
.datetime
.now()}
93 test_ns_placement_data_w_pinning
= {
94 'vim_accounts': ['vim' + vim_account
.replace('-', '_') for vim_account
in ['aaaaaaaa-38f5-438d-b8ee-3f93b3531f87',
95 'bbbbbbbb-38f5-438d-b8ee-3f93b3531f87',
96 'cccccccc-ed84-4e49-b5df-a9d117bd731f',
97 'dddddddd-ed84-4e49-b5df-a9d117bd731f',
98 'eeeeeeee-38f5-438d-b8ee-3f93b3531f87']],
99 'trp_link_latency': [[0, 50, 100, 150, 200], [0, 0, 100, 150, 200], [0, 0, 0, 150, 200], [0, 0, 0, 0, 200],
101 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
103 'trp_link_price_list': [[0, 5, 6, 6, 7], [0, 0, 6, 6, 7], [0, 0, 0, 6, 7], [0, 0, 0, 0, 7], [0, 0, 0, 0, 0]],
105 {'vnf_id': '1', 'vnf_price_per_vim': [50, 51, 52, 53, 54]},
106 {'vnf_id': '2', 'vnf_price_per_vim': [20, 21, 22, 23, 24],
107 'vim_account': 'vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87'},
108 {'vnf_id': '3', 'vnf_price_per_vim': [70, 71, 72, 73, 74]},
109 {'vnf_id': '4', 'vnf_price_per_vim': [40, 41, 42, 43, 44],
110 'vim_account': 'vimcccccccc_ed84_4e49_b5df_a9d117bd731f'}],
111 'vld_desc': [{'cp_refs': ['1', '2'], 'latency': 150, 'jitter': 30},
112 {'cp_refs': ['2', '3'], 'latency': 140, 'jitter': 30},
113 {'cp_refs': ['3', '4'], 'latency': 130, 'jitter': 30}],
114 'generator_data': {'file': __file__
, 'time': datetime
.datetime
.now()}
117 test_ns_placement_data_w_pinning_str
= {
118 'vim_accounts': ['vim' + vim_account
.replace('-', '_') for vim_account
in ['aaaaaaaa-38f5-438d-b8ee-3f93b3531f87',
119 'bbbbbbbb-38f5-438d-b8ee-3f93b3531f87',
120 'cccccccc-ed84-4e49-b5df-a9d117bd731f',
121 'dddddddd-ed84-4e49-b5df-a9d117bd731f',
122 'eeeeeeee-38f5-438d-b8ee-3f93b3531f87']],
123 'trp_link_latency': [[0, 50, 100, 150, 200], [0, 0, 100, 150, 200], [0, 0, 0, 150, 200], [0, 0, 0, 0, 200],
125 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
127 'trp_link_price_list': [[0, 5, 6, 6, 7], [0, 0, 6, 6, 7], [0, 0, 0, 6, 7], [0, 0, 0, 0, 7], [0, 0, 0, 0, 0]],
129 {'vnf_id': 'one', 'vnf_price_per_vim': [50, 51, 52, 53, 54]},
130 {'vnf_id': 'two', 'vnf_price_per_vim': [20, 21, 22, 23, 24],
131 'vim_account': 'vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87'},
132 {'vnf_id': 'three', 'vnf_price_per_vim': [70, 71, 72, 73, 74]},
133 {'vnf_id': 'four', 'vnf_price_per_vim': [40, 41, 42, 43, 44],
134 'vim_account': 'vimcccccccc_ed84_4e49_b5df_a9d117bd731f'}],
135 'vld_desc': [{'cp_refs': ['one', 'two'], 'latency': 150, 'jitter': 30},
136 {'cp_refs': ['two', 'three'], 'latency': 140, 'jitter': 30},
137 {'cp_refs': ['three', 'four'], 'latency': 130, 'jitter': 30}],
138 'generator_data': {'file': __file__
, 'time': datetime
.datetime
.now()}
141 test_ns_placement_data_str_no_vld
= {
142 'vim_accounts': ['vim' + vim_account
.replace('-', '_') for vim_account
in ['aaaaaaaa-38f5-438d-b8ee-3f93b3531f87',
143 'bbbbbbbb-38f5-438d-b8ee-3f93b3531f87',
144 'cccccccc-ed84-4e49-b5df-a9d117bd731f',
145 'dddddddd-ed84-4e49-b5df-a9d117bd731f',
146 'eeeeeeee-38f5-438d-b8ee-3f93b3531f87']],
147 'trp_link_latency': [[0, 50, 100, 150, 200], [0, 0, 100, 150, 200], [0, 0, 0, 150, 200], [0, 0, 0, 0, 200],
149 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
151 'trp_link_price_list': [[0, 5, 6, 6, 7], [0, 0, 6, 6, 7], [0, 0, 0, 6, 7], [0, 0, 0, 0, 7], [0, 0, 0, 0, 0]],
153 {'vnf_id': 'one', 'vnf_price_per_vim': [50, 51, 52, 53, 54]}],
155 'generator_data': {'file': __file__
, 'time': datetime
.datetime
.now()}
158 expected_model_fragment
= """
159 %This is the NETWORK RESOURCE MODEL
161 vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
162 vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
163 vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
164 vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
165 vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
166 array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
171 |]; % Transport link latency between data centers
172 array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
177 |]; % Transport link jitter between data centers
178 array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
183 |]; % Transport link price list
184 array[Vims] of int: vim_price_list_1 = [50,51,52,53,54];
185 array[Vims] of int: vim_price_list_2 = [20,21,22,23,24];
186 array[Vims] of int: vim_price_list_3 = [70,71,72,73,74];
187 array[Vims] of int: vim_price_list_4 = [40,41,42,43,44];
190 % This is the NETWORK BASIC LOAD MODEL (CONSUMED)
191 % NOTE. This is not applicable in OSM Release 7
193 % This is the SERVICE CONSUMPTION MODEL
194 % These are the variables, i.e. which DC to select for each VNF
201 % These are the set of rules for selecting DCs to VNFs
202 constraint trp_link_latency[VNF1, VNF2] <= 150;
203 constraint trp_link_latency[VNF2, VNF3] <= 140;
204 constraint trp_link_latency[VNF3, VNF4] <= 130;
205 constraint trp_link_jitter[VNF1, VNF2] <= 30;
206 constraint trp_link_jitter[VNF2, VNF3] <= 30;
207 constraint trp_link_jitter[VNF3, VNF4] <= 30;
209 % Calculate the cost for VNFs and cost for transport link and total cost
210 var int: used_transport_cost =trp_link_price_list[VNF1, VNF2]+
211 trp_link_price_list[VNF2, VNF3]+
212 trp_link_price_list[VNF3, VNF4];
214 var int: used_vim_cost =vim_price_list_1[VNF1]+
215 vim_price_list_2[VNF2]+
216 vim_price_list_3[VNF3]+
217 vim_price_list_4[VNF4];
219 var int: total_cost = used_transport_cost + used_vim_cost;
221 solve minimize total_cost;
223 expected_model_fragment_str
= """
224 %This is the NETWORK RESOURCE MODEL
226 vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
227 vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
228 vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
229 vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
230 vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
231 array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
236 |]; % Transport link latency between data centers
237 array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
242 |]; % Transport link jitter between data centers
243 array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
248 |]; % Transport link price list
249 array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
250 array[Vims] of int: vim_price_list_two = [20,21,22,23,24];
251 array[Vims] of int: vim_price_list_three = [70,71,72,73,74];
252 array[Vims] of int: vim_price_list_four = [40,41,42,43,44];
255 % This is the NETWORK BASIC LOAD MODEL (CONSUMED)
256 % NOTE. This is not applicable in OSM Release 7
258 % This is the SERVICE CONSUMPTION MODEL
259 % These are the variables, i.e. which DC to select for each VNF
266 % These are the set of rules for selecting DCs to VNFs
267 constraint trp_link_latency[VNFone, VNFtwo] <= 150;
268 constraint trp_link_latency[VNFtwo, VNFthree] <= 140;
269 constraint trp_link_latency[VNFthree, VNFfour] <= 130;
270 constraint trp_link_jitter[VNFone, VNFtwo] <= 30;
271 constraint trp_link_jitter[VNFtwo, VNFthree] <= 30;
272 constraint trp_link_jitter[VNFthree, VNFfour] <= 30;
274 % Calculate the cost for VNFs and cost for transport link and total cost
275 var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+
276 trp_link_price_list[VNFtwo, VNFthree]+
277 trp_link_price_list[VNFthree, VNFfour];
279 var int: used_vim_cost =vim_price_list_one[VNFone]+
280 vim_price_list_two[VNFtwo]+
281 vim_price_list_three[VNFthree]+
282 vim_price_list_four[VNFfour];
284 var int: total_cost = used_transport_cost + used_vim_cost;
286 solve minimize total_cost;
289 expected_model_fragment_str_no_vld_constraints
= """
290 %This is the NETWORK RESOURCE MODEL
292 vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
293 vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
294 vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
295 vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
296 vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
297 array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
302 |]; % Transport link latency between data centers
303 array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
308 |]; % Transport link jitter between data centers
309 array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
314 |]; % Transport link price list
315 array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
316 array[Vims] of int: vim_price_list_two = [20,21,22,23,24];
317 array[Vims] of int: vim_price_list_three = [70,71,72,73,74];
318 array[Vims] of int: vim_price_list_four = [40,41,42,43,44];
321 % This is the NETWORK BASIC LOAD MODEL (CONSUMED)
322 % NOTE. This is not applicable in OSM Release 7
324 % This is the SERVICE CONSUMPTION MODEL
325 % These are the variables, i.e. which DC to select for each VNF
332 % These are the set of rules for selecting DCs to VNFs
334 % Calculate the cost for VNFs and cost for transport link and total cost
335 var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+
336 trp_link_price_list[VNFtwo, VNFthree]+
337 trp_link_price_list[VNFthree, VNFfour];
339 var int: used_vim_cost =vim_price_list_one[VNFone]+
340 vim_price_list_two[VNFtwo]+
341 vim_price_list_three[VNFthree]+
342 vim_price_list_four[VNFfour];
344 var int: total_cost = used_transport_cost + used_vim_cost;
346 solve minimize total_cost;
349 expected_model_fragment_w_pinning
= """
350 %This is the NETWORK RESOURCE MODEL
352 vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
353 vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
354 vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
355 vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
356 vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
357 array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
362 |]; % Transport link latency between data centers
363 array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
368 |]; % Transport link jitter between data centers
369 array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
374 |]; % Transport link price list
375 array[Vims] of int: vim_price_list_1 = [50,51,52,53,54];
376 array[Vims] of int: vim_price_list_2 = [20,21,22,23,24];
377 array[Vims] of int: vim_price_list_3 = [70,71,72,73,74];
378 array[Vims] of int: vim_price_list_4 = [40,41,42,43,44];
381 % This is the NETWORK BASIC LOAD MODEL (CONSUMED)
382 % NOTE. This is not applicable in OSM Release 7
384 % This is the SERVICE CONSUMPTION MODEL
385 % These are the variables, i.e. which DC to select for each VNF
387 Vims: VNF2 = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87;
389 Vims: VNF4 = vimcccccccc_ed84_4e49_b5df_a9d117bd731f;
392 % These are the set of rules for selecting DCs to VNFs
393 constraint trp_link_latency[VNF1, VNF2] <= 150;
394 constraint trp_link_latency[VNF2, VNF3] <= 140;
395 constraint trp_link_latency[VNF3, VNF4] <= 130;
396 constraint trp_link_jitter[VNF1, VNF2] <= 30;
397 constraint trp_link_jitter[VNF2, VNF3] <= 30;
398 constraint trp_link_jitter[VNF3, VNF4] <= 30;
400 % Calculate the cost for VNFs and cost for transport link and total cost
401 var int: used_transport_cost =trp_link_price_list[VNF1, VNF2]+
402 trp_link_price_list[VNF2, VNF3]+
403 trp_link_price_list[VNF3, VNF4];
405 var int: used_vim_cost =vim_price_list_1[VNF1]+
406 vim_price_list_2[VNF2]+
407 vim_price_list_3[VNF3]+
408 vim_price_list_4[VNF4];
410 var int: total_cost = used_transport_cost + used_vim_cost;
412 solve minimize total_cost;
415 expected_model_fragment_w_pinning_str
= """
416 %This is the NETWORK RESOURCE MODEL
418 vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
419 vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
420 vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
421 vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
422 vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
423 array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
428 |]; % Transport link latency between data centers
429 array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
434 |]; % Transport link jitter between data centers
435 array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
440 |]; % Transport link price list
441 array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
442 array[Vims] of int: vim_price_list_two = [20,21,22,23,24];
443 array[Vims] of int: vim_price_list_three = [70,71,72,73,74];
444 array[Vims] of int: vim_price_list_four = [40,41,42,43,44];
447 % This is the NETWORK BASIC LOAD MODEL (CONSUMED)
448 % NOTE. This is not applicable in OSM Release 7
450 % This is the SERVICE CONSUMPTION MODEL
451 % These are the variables, i.e. which DC to select for each VNF
453 Vims: VNFtwo = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87;
455 Vims: VNFfour = vimcccccccc_ed84_4e49_b5df_a9d117bd731f;
458 % These are the set of rules for selecting DCs to VNFs
459 constraint trp_link_latency[VNFone, VNFtwo] <= 150;
460 constraint trp_link_latency[VNFtwo, VNFthree] <= 140;
461 constraint trp_link_latency[VNFthree, VNFfour] <= 130;
462 constraint trp_link_jitter[VNFone, VNFtwo] <= 30;
463 constraint trp_link_jitter[VNFtwo, VNFthree] <= 30;
464 constraint trp_link_jitter[VNFthree, VNFfour] <= 30;
466 % Calculate the cost for VNFs and cost for transport link and total cost
467 var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+
468 trp_link_price_list[VNFtwo, VNFthree]+
469 trp_link_price_list[VNFthree, VNFfour];
471 var int: used_vim_cost =vim_price_list_one[VNFone]+
472 vim_price_list_two[VNFtwo]+
473 vim_price_list_three[VNFthree]+
474 vim_price_list_four[VNFfour];
476 var int: total_cost = used_transport_cost + used_vim_cost;
478 solve minimize total_cost;
481 expected_model_fragment_str_no_vld
= """
482 %This is the NETWORK RESOURCE MODEL
484 vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
485 vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
486 vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
487 vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
488 vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
489 array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
494 |]; % Transport link latency between data centers
495 array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
500 |]; % Transport link jitter between data centers
501 array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
506 |]; % Transport link price list
507 array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
510 % This is the NETWORK BASIC LOAD MODEL (CONSUMED)
511 % NOTE. This is not applicable in OSM Release 7
513 % This is the SERVICE CONSUMPTION MODEL
514 % These are the variables, i.e. which DC to select for each VNF
518 % These are the set of rules for selecting DCs to VNFs
520 % Calculate the cost for VNFs and cost for transport link and total cost
521 var int: used_transport_cost =0;
523 var int: used_vim_cost =vim_price_list_one[VNFone];
525 var int: total_cost = used_transport_cost + used_vim_cost;
527 solve minimize total_cost;
531 class TestMznModelGenerator(TestCase
):
532 def test_create_model(self
):
533 mg
= MznModelGenerator(logging
.getLogger(__name__
))
534 mzn_model
= mg
.create_model(test_ns_placement_data_str
)
536 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines
537 self
.assertTrue(expected_model_fragment_str
.replace('\n', '') in
538 mzn_model
.replace('\n', ''), "faulty model generated")
540 def test_create_model_no_vld_constraints(self
):
542 instantiate w/o constraints in nsd or order params has a valid model
545 mg
= MznModelGenerator(logging
.getLogger(__name__
))
546 mzn_model
= mg
.create_model(test_ns_placement_data_str_no_vld_constraints
)
548 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines
549 self
.assertTrue(expected_model_fragment_str_no_vld_constraints
.replace('\n', '') in
550 mzn_model
.replace('\n', ''), "faulty model generated")
552 def test_create_model_w_pinning(self
):
553 mg
= MznModelGenerator(logging
.getLogger(__name__
))
554 mzn_model
= mg
.create_model(test_ns_placement_data_w_pinning_str
)
556 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines
557 self
.assertTrue(expected_model_fragment_w_pinning_str
.replace('\n', '') in
558 mzn_model
.replace('\n', ''), "faulty model generated")
560 def test_create_model_no_vld(self
):
561 mg
= MznModelGenerator(logging
.getLogger(__name__
))
562 mzn_model
= mg
.create_model(test_ns_placement_data_str_no_vld
)
564 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines
565 self
.assertTrue(expected_model_fragment_str_no_vld
.replace('\n', '') in
566 mzn_model
.replace('\n', ''), "faulty model generated")
568 def test__load_jinja_template(self
):
571 add other test to check exception if template not loaded (e.g. invalid template name,
572 perhaps also valid name but invalid content (in case jinja2 detects such things))
574 mg
= MznModelGenerator(logging
.getLogger(__name__
))
575 template
= mg
._load
_jinja
_template
() # Note we use the default template
576 self
.assertTrue(isinstance(template
, Template
), "failed to load jinja2 template")
578 def test_vim_account_replace(self
):
579 mg
= MznModelGenerator(logging
.getLogger(__name__
))
580 nspd
= test_ns_placement_data_str
581 mzn_model
= mg
.create_model(nspd
)
583 expected
= '%This is the NETWORK RESOURCE MODEL' + '\n' + 'enum Vims = {' + '\n'
584 for val
in test_ns_placement_data_str
['vim_accounts']:
585 expected
= expected
+ val
.replace('-', '_') + ',\n'
586 expected
= expected
[:-2] + '}; % The vim-accounts'
587 res
= re
.findall(expected
, mzn_model
)
588 self
.assertEqual(1, len(res
), "vim accounts didnt replace from - to _")
590 def test_trp_link_price_list(self
):
591 mg
= MznModelGenerator(logging
.getLogger(__name__
))
592 mzn_model
= mg
.create_model(test_ns_placement_data_str
)
594 expected
= 'array\\[Vims, Vims\\] of int: trp_link_price_list = \\['
595 for price_list
in test_ns_placement_data_str
['trp_link_price_list']:
596 expected
= expected
+ '\\|' + (str(price_list
)[1:-1]).replace(" ", "") + ',\n'
597 expected
= expected
+ '\\|\\]; % Transport link price list'
598 res
= re
.findall(expected
, mzn_model
)
599 self
.assertEqual(1, len(res
), "price list is not correct")
601 def test_link_latency(self
):
602 mg
= MznModelGenerator(logging
.getLogger(__name__
))
603 mzn_model
= mg
.create_model(test_ns_placement_data_str
)
605 expected
= 'array\\[Vims, Vims\\] of int: trp_link_latency = \\['
606 for link_latency
in test_ns_placement_data_str
['trp_link_latency']:
607 expected
= expected
+ '\\|' + (str(link_latency
)[1:-1]).replace(" ", "") + ',\n'
608 expected
= expected
+ '\\|\\]; % Transport link latency between data centers'
609 res
= re
.findall(expected
, mzn_model
)
610 self
.assertEqual(1, len(res
), "trp_link_latency values is not correct")
612 def test_link_jitter(self
):
613 mg
= MznModelGenerator(logging
.getLogger(__name__
))
614 mzn_model
= mg
.create_model(test_ns_placement_data_str
)
616 expected
= 'array\\[Vims, Vims\\] of int: trp_link_jitter = \\['
617 for link_jitter
in test_ns_placement_data_str
['trp_link_jitter']:
618 expected
= expected
+ '\\|' + (str(link_jitter
)[1:-1]).replace(" ", "") + ',\n'
619 expected
= expected
+ '\\|\\]; % Transport link jitter between data centers'
621 res
= re
.findall(expected
, mzn_model
)
623 self
.assertEqual(1, len(res
), "trp_link_jitter values is not correct")
625 def test_price_per_vim(self
):
626 mg
= MznModelGenerator(logging
.getLogger(__name__
))
627 mzn_model
= mg
.create_model(test_ns_placement_data_w_pinning_str
)
630 for price_list
in test_ns_placement_data_w_pinning_str
['ns_desc']:
631 expected
+= 'array\\[Vims\\] of int: vim_price_list_' + price_list
.get('vnf_id') + " = "
632 temp
= str(price_list
.get('vnf_price_per_vim'))[1:-1].replace(" ", "")
633 expected
+= "\\[" + temp
+ "\\];\n"
635 res
= re
.findall(expected
, mzn_model
)
636 self
.assertEqual(1, len(res
), "mzn_model contains pinning")
638 def test_pinning(self
):
639 mg
= MznModelGenerator(logging
.getLogger(__name__
))
640 mzn_model
= mg
.create_model(test_ns_placement_data_str
)
643 for pin_list
in test_ns_placement_data_str
['ns_desc']:
644 if pin_list
.get('vim_account'):
645 expected
+= 'Vims: VNF' + pin_list
.get('vnf_id') + ' = ' + pin_list
.get('vim_account') + ';\n'
647 expected
+= 'var Vims: VNF' + pin_list
.get('vnf_id') + ';\n'
649 res
= re
.findall(expected
, mzn_model
)
650 self
.assertEqual(1, len(res
), "mzn_model has no pinning")
652 def test__without_pinning(self
):
653 mg
= MznModelGenerator(logging
.getLogger(__name__
))
654 mzn_model
= mg
.create_model(test_ns_placement_data_w_pinning_str
)
657 for pin_list
in test_ns_placement_data_w_pinning_str
['ns_desc']:
658 if pin_list
.get('vim_account'):
659 expected
+= 'Vims: VNF' + pin_list
.get('vnf_id') + ' = ' + pin_list
.get('vim_account') + ';\n'
661 expected
+= 'var Vims: VNF' + pin_list
.get('vnf_id') + ';\n'
663 res
= re
.findall(expected
, mzn_model
)
664 self
.assertEqual(1, len(res
), "mzn_model contains pinning")
666 def test__without_constraints_for_jitter_and_latency(self
):
667 mg
= MznModelGenerator(logging
.getLogger(__name__
))
668 mzn_model
= mg
.create_model(test_ns_placement_data_str_no_vld_constraints
)
670 expected_latency
= "constraint trp_link_latency"
671 expected_jitter
= "constraint trp_link_jitter"
672 latency_or_jitter_was_found
= 0
673 for l_o_j
in test_ns_placement_data_str_no_vld_constraints
['vld_desc']:
674 if l_o_j
.get('latency') or l_o_j
.get('jitter'):
675 latency_or_jitter_was_found
= 1
677 res_latency
= re
.findall(expected_latency
, mzn_model
)
678 res_jitter
= re
.findall(expected_jitter
, mzn_model
)
679 self
.assertEqual(0, latency_or_jitter_was_found
, "Jitter or latency was found in the test input")
680 self
.assertEqual(0, len(res_latency
), "constraint trp_link_latency was found in mzn_model")
681 self
.assertEqual(0, len(res_jitter
), "constraint trp_link_latency was found in mzn_model")
683 def test__constraints_for_jitter_and_latency(self
):
684 mg
= MznModelGenerator(logging
.getLogger(__name__
))
685 mzn_model
= mg
.create_model(test_ns_placement_data_str
)
687 expected_latency
= ""
689 latency_or_jitter_was_found
= 0
690 for l_o_j
in test_ns_placement_data_str
['vld_desc']:
691 if not (l_o_j
.get('latency') or l_o_j
.get('jitter')):
692 latency_or_jitter_was_found
= 1
693 expected_latency
+= "constraint trp_link_latency" + "\\[VNF" + l_o_j
.get('cp_refs')[0] + ", VNF" + \
694 l_o_j
.get('cp_refs')[1] + "\\] \\<= " + str(l_o_j
.get('latency')) + ";\n\n"
696 expected_jitter
+= "constraint trp_link_jitter" + "\\[VNF" + l_o_j
.get('cp_refs')[0] + ", VNF" + \
697 l_o_j
.get('cp_refs')[1] + "\\] \\<= " + str(l_o_j
.get('jitter')) + ";\n\n"
699 res
= re
.findall(expected_latency
+ expected_jitter
, mzn_model
)
700 self
.assertEqual(0, latency_or_jitter_was_found
, "Jitter or latency was not found in the test input")
701 self
.assertEqual(1, len(res
), "faulty model generated")