blob: ed571f4a52b4dd17c6272746407cf758147c60f6 [file] [log] [blame]
magnussonl2b0e2d72020-02-04 10:52:46 +01001# Copyright 2020 ArctosLabs Scandinavia AB
2#
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
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
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
12# implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15import datetime
16import logging
17# import unittest
18from unittest import TestCase
19# import random
20# from operator import itemgetter
21import re
22
23from jinja2 import Template
24
25from osm_pla.placement.mznplacement import MznModelGenerator
26
27test_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],
34 [0, 0, 0, 0, 0]],
35 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
36 [0, 0, 0, 0, 0]],
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]],
38 'ns_desc': [
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()}
47}
48
49test_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],
56 [0, 0, 0, 0, 0]],
57 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
58 [0, 0, 0, 0, 0]],
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]],
60 'ns_desc': [
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()}
69}
70
71test_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],
78 [0, 0, 0, 0, 0]],
79 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
80 [0, 0, 0, 0, 0]],
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]],
82 'ns_desc': [
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()}
91}
92
93test_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],
100 [0, 0, 0, 0, 0]],
101 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
102 [0, 0, 0, 0, 0]],
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]],
104 'ns_desc': [
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()}
115}
116
117test_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],
124 [0, 0, 0, 0, 0]],
125 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
126 [0, 0, 0, 0, 0]],
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]],
128 'ns_desc': [
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()}
139}
140
141test_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],
148 [0, 0, 0, 0, 0]],
149 'trp_link_jitter': [[0, 5, 10, 15, 20], [0, 0, 10, 15, 20], [0, 0, 0, 15, 20], [0, 0, 0, 0, 20],
150 [0, 0, 0, 0, 0]],
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]],
152 'ns_desc': [
153 {'vnf_id': 'one', 'vnf_price_per_vim': [50, 51, 52, 53, 54]}],
154 'vld_desc': [],
155 'generator_data': {'file': __file__, 'time': datetime.datetime.now()}
156}
157
158expected_model_fragment = """
159%This is the NETWORK RESOURCE MODEL
160enum Vims = {
161vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
162vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
163vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
164vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
165vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
166array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
167|0,0,100,150,200,
168|0,0,0,150,200,
169|0,0,0,0,200,
170|0,0,0,0,0,
171|]; % Transport link latency between data centers
172array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
173|0,0,10,15,20,
174|0,0,0,15,20,
175|0,0,0,0,20,
176|0,0,0,0,0,
177|]; % Transport link jitter between data centers
178array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
179|0,0,6,6,7,
180|0,0,0,6,7,
181|0,0,0,0,7,
182|0,0,0,0,0,
183|]; % Transport link price list
184array[Vims] of int: vim_price_list_1 = [50,51,52,53,54];
185array[Vims] of int: vim_price_list_2 = [20,21,22,23,24];
186array[Vims] of int: vim_price_list_3 = [70,71,72,73,74];
187array[Vims] of int: vim_price_list_4 = [40,41,42,43,44];
188
189
190% This is the NETWORK BASIC LOAD MODEL (CONSUMED)
191% NOTE. This is not applicable in OSM Release 7
192
193% This is the SERVICE CONSUMPTION MODEL
194% These are the variables, i.e. which DC to select for each VNF
195var Vims: VNF1;
196var Vims: VNF2;
197var Vims: VNF3;
198var Vims: VNF4;
199
200
201% These are the set of rules for selecting DCs to VNFs
202constraint trp_link_latency[VNF1, VNF2] <= 150;
203constraint trp_link_latency[VNF2, VNF3] <= 140;
204constraint trp_link_latency[VNF3, VNF4] <= 130;
205constraint trp_link_jitter[VNF1, VNF2] <= 30;
206constraint trp_link_jitter[VNF2, VNF3] <= 30;
207constraint trp_link_jitter[VNF3, VNF4] <= 30;
208
209% Calculate the cost for VNFs and cost for transport link and total cost
210var int: used_transport_cost =trp_link_price_list[VNF1, VNF2]+
211trp_link_price_list[VNF2, VNF3]+
212trp_link_price_list[VNF3, VNF4];
213
214var int: used_vim_cost =vim_price_list_1[VNF1]+
215vim_price_list_2[VNF2]+
216vim_price_list_3[VNF3]+
217vim_price_list_4[VNF4];
218
219var int: total_cost = used_transport_cost + used_vim_cost;
220
221solve minimize total_cost;
222"""
223expected_model_fragment_str = """
224%This is the NETWORK RESOURCE MODEL
225enum Vims = {
226vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
227vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
228vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
229vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
230vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
231array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
232|0,0,100,150,200,
233|0,0,0,150,200,
234|0,0,0,0,200,
235|0,0,0,0,0,
236|]; % Transport link latency between data centers
237array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
238|0,0,10,15,20,
239|0,0,0,15,20,
240|0,0,0,0,20,
241|0,0,0,0,0,
242|]; % Transport link jitter between data centers
243array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
244|0,0,6,6,7,
245|0,0,0,6,7,
246|0,0,0,0,7,
247|0,0,0,0,0,
248|]; % Transport link price list
249array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
250array[Vims] of int: vim_price_list_two = [20,21,22,23,24];
251array[Vims] of int: vim_price_list_three = [70,71,72,73,74];
252array[Vims] of int: vim_price_list_four = [40,41,42,43,44];
253
254
255% This is the NETWORK BASIC LOAD MODEL (CONSUMED)
256% NOTE. This is not applicable in OSM Release 7
257
258% This is the SERVICE CONSUMPTION MODEL
259% These are the variables, i.e. which DC to select for each VNF
260var Vims: VNFone;
261var Vims: VNFtwo;
262var Vims: VNFthree;
263var Vims: VNFfour;
264
265
266% These are the set of rules for selecting DCs to VNFs
267constraint trp_link_latency[VNFone, VNFtwo] <= 150;
268constraint trp_link_latency[VNFtwo, VNFthree] <= 140;
269constraint trp_link_latency[VNFthree, VNFfour] <= 130;
270constraint trp_link_jitter[VNFone, VNFtwo] <= 30;
271constraint trp_link_jitter[VNFtwo, VNFthree] <= 30;
272constraint trp_link_jitter[VNFthree, VNFfour] <= 30;
273
274% Calculate the cost for VNFs and cost for transport link and total cost
275var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+
276trp_link_price_list[VNFtwo, VNFthree]+
277trp_link_price_list[VNFthree, VNFfour];
278
279var int: used_vim_cost =vim_price_list_one[VNFone]+
280vim_price_list_two[VNFtwo]+
281vim_price_list_three[VNFthree]+
282vim_price_list_four[VNFfour];
283
284var int: total_cost = used_transport_cost + used_vim_cost;
285
286solve minimize total_cost;
287"""
288
289expected_model_fragment_str_no_vld_constraints = """
290%This is the NETWORK RESOURCE MODEL
291enum Vims = {
292vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
293vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
294vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
295vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
296vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
297array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
298|0,0,100,150,200,
299|0,0,0,150,200,
300|0,0,0,0,200,
301|0,0,0,0,0,
302|]; % Transport link latency between data centers
303array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
304|0,0,10,15,20,
305|0,0,0,15,20,
306|0,0,0,0,20,
307|0,0,0,0,0,
308|]; % Transport link jitter between data centers
309array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
310|0,0,6,6,7,
311|0,0,0,6,7,
312|0,0,0,0,7,
313|0,0,0,0,0,
314|]; % Transport link price list
315array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
316array[Vims] of int: vim_price_list_two = [20,21,22,23,24];
317array[Vims] of int: vim_price_list_three = [70,71,72,73,74];
318array[Vims] of int: vim_price_list_four = [40,41,42,43,44];
319
320
321% This is the NETWORK BASIC LOAD MODEL (CONSUMED)
322% NOTE. This is not applicable in OSM Release 7
323
324% This is the SERVICE CONSUMPTION MODEL
325% These are the variables, i.e. which DC to select for each VNF
326var Vims: VNFone;
327var Vims: VNFtwo;
328var Vims: VNFthree;
329var Vims: VNFfour;
330
331
332% These are the set of rules for selecting DCs to VNFs
333
334% Calculate the cost for VNFs and cost for transport link and total cost
335var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+
336trp_link_price_list[VNFtwo, VNFthree]+
337trp_link_price_list[VNFthree, VNFfour];
338
339var int: used_vim_cost =vim_price_list_one[VNFone]+
340vim_price_list_two[VNFtwo]+
341vim_price_list_three[VNFthree]+
342vim_price_list_four[VNFfour];
343
344var int: total_cost = used_transport_cost + used_vim_cost;
345
346solve minimize total_cost;
347"""
348
349expected_model_fragment_w_pinning = """
350%This is the NETWORK RESOURCE MODEL
351enum Vims = {
352vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
353vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
354vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
355vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
356vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
357array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
358|0,0,100,150,200,
359|0,0,0,150,200,
360|0,0,0,0,200,
361|0,0,0,0,0,
362|]; % Transport link latency between data centers
363array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
364|0,0,10,15,20,
365|0,0,0,15,20,
366|0,0,0,0,20,
367|0,0,0,0,0,
368|]; % Transport link jitter between data centers
369array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
370|0,0,6,6,7,
371|0,0,0,6,7,
372|0,0,0,0,7,
373|0,0,0,0,0,
374|]; % Transport link price list
375array[Vims] of int: vim_price_list_1 = [50,51,52,53,54];
376array[Vims] of int: vim_price_list_2 = [20,21,22,23,24];
377array[Vims] of int: vim_price_list_3 = [70,71,72,73,74];
378array[Vims] of int: vim_price_list_4 = [40,41,42,43,44];
379
380
381% This is the NETWORK BASIC LOAD MODEL (CONSUMED)
382% NOTE. This is not applicable in OSM Release 7
383
384% This is the SERVICE CONSUMPTION MODEL
385% These are the variables, i.e. which DC to select for each VNF
386var Vims: VNF1;
387Vims: VNF2 = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87;
388var Vims: VNF3;
389Vims: VNF4 = vimcccccccc_ed84_4e49_b5df_a9d117bd731f;
390
391
392% These are the set of rules for selecting DCs to VNFs
393constraint trp_link_latency[VNF1, VNF2] <= 150;
394constraint trp_link_latency[VNF2, VNF3] <= 140;
395constraint trp_link_latency[VNF3, VNF4] <= 130;
396constraint trp_link_jitter[VNF1, VNF2] <= 30;
397constraint trp_link_jitter[VNF2, VNF3] <= 30;
398constraint trp_link_jitter[VNF3, VNF4] <= 30;
399
400% Calculate the cost for VNFs and cost for transport link and total cost
401var int: used_transport_cost =trp_link_price_list[VNF1, VNF2]+
402trp_link_price_list[VNF2, VNF3]+
403trp_link_price_list[VNF3, VNF4];
404
405var int: used_vim_cost =vim_price_list_1[VNF1]+
406vim_price_list_2[VNF2]+
407vim_price_list_3[VNF3]+
408vim_price_list_4[VNF4];
409
410var int: total_cost = used_transport_cost + used_vim_cost;
411
412solve minimize total_cost;
413"""
414
415expected_model_fragment_w_pinning_str = """
416%This is the NETWORK RESOURCE MODEL
417enum Vims = {
418vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
419vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
420vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
421vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
422vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
423array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
424|0,0,100,150,200,
425|0,0,0,150,200,
426|0,0,0,0,200,
427|0,0,0,0,0,
428|]; % Transport link latency between data centers
429array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
430|0,0,10,15,20,
431|0,0,0,15,20,
432|0,0,0,0,20,
433|0,0,0,0,0,
434|]; % Transport link jitter between data centers
435array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
436|0,0,6,6,7,
437|0,0,0,6,7,
438|0,0,0,0,7,
439|0,0,0,0,0,
440|]; % Transport link price list
441array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
442array[Vims] of int: vim_price_list_two = [20,21,22,23,24];
443array[Vims] of int: vim_price_list_three = [70,71,72,73,74];
444array[Vims] of int: vim_price_list_four = [40,41,42,43,44];
445
446
447% This is the NETWORK BASIC LOAD MODEL (CONSUMED)
448% NOTE. This is not applicable in OSM Release 7
449
450% This is the SERVICE CONSUMPTION MODEL
451% These are the variables, i.e. which DC to select for each VNF
452var Vims: VNFone;
453Vims: VNFtwo = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87;
454var Vims: VNFthree;
455Vims: VNFfour = vimcccccccc_ed84_4e49_b5df_a9d117bd731f;
456
457
458% These are the set of rules for selecting DCs to VNFs
459constraint trp_link_latency[VNFone, VNFtwo] <= 150;
460constraint trp_link_latency[VNFtwo, VNFthree] <= 140;
461constraint trp_link_latency[VNFthree, VNFfour] <= 130;
462constraint trp_link_jitter[VNFone, VNFtwo] <= 30;
463constraint trp_link_jitter[VNFtwo, VNFthree] <= 30;
464constraint trp_link_jitter[VNFthree, VNFfour] <= 30;
465
466% Calculate the cost for VNFs and cost for transport link and total cost
467var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+
468trp_link_price_list[VNFtwo, VNFthree]+
469trp_link_price_list[VNFthree, VNFfour];
470
471var int: used_vim_cost =vim_price_list_one[VNFone]+
472vim_price_list_two[VNFtwo]+
473vim_price_list_three[VNFthree]+
474vim_price_list_four[VNFfour];
475
476var int: total_cost = used_transport_cost + used_vim_cost;
477
478solve minimize total_cost;
479"""
480
481expected_model_fragment_str_no_vld = """
482%This is the NETWORK RESOURCE MODEL
483enum Vims = {
484vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87,
485vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87,
486vimcccccccc_ed84_4e49_b5df_a9d117bd731f,
487vimdddddddd_ed84_4e49_b5df_a9d117bd731f,
488vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts
489array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200,
490|0,0,100,150,200,
491|0,0,0,150,200,
492|0,0,0,0,200,
493|0,0,0,0,0,
494|]; % Transport link latency between data centers
495array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20,
496|0,0,10,15,20,
497|0,0,0,15,20,
498|0,0,0,0,20,
499|0,0,0,0,0,
500|]; % Transport link jitter between data centers
501array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7,
502|0,0,6,6,7,
503|0,0,0,6,7,
504|0,0,0,0,7,
505|0,0,0,0,0,
506|]; % Transport link price list
507array[Vims] of int: vim_price_list_one = [50,51,52,53,54];
508
509
510% This is the NETWORK BASIC LOAD MODEL (CONSUMED)
511% NOTE. This is not applicable in OSM Release 7
512
513% This is the SERVICE CONSUMPTION MODEL
514% These are the variables, i.e. which DC to select for each VNF
515
516var Vims: VNFone;
517
518% These are the set of rules for selecting DCs to VNFs
519
520% Calculate the cost for VNFs and cost for transport link and total cost
521var int: used_transport_cost =0;
522
523var int: used_vim_cost =vim_price_list_one[VNFone];
524
525var int: total_cost = used_transport_cost + used_vim_cost;
526
527solve minimize total_cost;
528"""
529
530
531class 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)
535
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")
539
540 def test_create_model_no_vld_constraints(self):
541 """
542 instantiate w/o constraints in nsd or order params has a valid model
543 :return:
544 """
545 mg = MznModelGenerator(logging.getLogger(__name__))
546 mzn_model = mg.create_model(test_ns_placement_data_str_no_vld_constraints)
547
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")
551
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)
555
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")
559
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)
563
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")
567
568 def test__load_jinja_template(self):
569 """
570
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))
573 """
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")
577
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)
582
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 _")
589
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)
593
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")
600
601 def test_link_latency(self):
602 mg = MznModelGenerator(logging.getLogger(__name__))
603 mzn_model = mg.create_model(test_ns_placement_data_str)
604
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")
611
612 def test_link_jitter(self):
613 mg = MznModelGenerator(logging.getLogger(__name__))
614 mzn_model = mg.create_model(test_ns_placement_data_str)
615
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'
620
621 res = re.findall(expected, mzn_model)
622
623 self.assertEqual(1, len(res), "trp_link_jitter values is not correct")
624
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)
628
629 expected = ""
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"
634
635 res = re.findall(expected, mzn_model)
636 self.assertEqual(1, len(res), "mzn_model contains pinning")
637
638 def test_pinning(self):
639 mg = MznModelGenerator(logging.getLogger(__name__))
640 mzn_model = mg.create_model(test_ns_placement_data_str)
641
642 expected = ""
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'
646 else:
647 expected += 'var Vims: VNF' + pin_list.get('vnf_id') + ';\n'
648
649 res = re.findall(expected, mzn_model)
650 self.assertEqual(1, len(res), "mzn_model has no pinning")
651
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)
655
656 expected = ""
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'
660 else:
661 expected += 'var Vims: VNF' + pin_list.get('vnf_id') + ';\n'
662
663 res = re.findall(expected, mzn_model)
664 self.assertEqual(1, len(res), "mzn_model contains pinning")
665
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)
669
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
676
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")
682
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)
686
687 expected_latency = ""
688 expected_jitter = ""
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"
695
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"
698
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")