Coverage for osm_pla/test/test_mznModelGenerator.py: 98%
134 statements
« prev ^ index » next coverage.py v6.4.1, created at 2024-06-30 08:29 +0000
« prev ^ index » next coverage.py v6.4.1, created at 2024-06-30 08:29 +0000
1# 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
23from jinja2 import Template
25from osm_pla.placement.mznplacement import MznModelGenerator
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}
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}
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}
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}
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}
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}
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];
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
195var Vims: VNF1;
196var Vims: VNF2;
197var Vims: VNF3;
198var Vims: VNF4;
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;
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];
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];
219var int: total_cost = used_transport_cost + used_vim_cost;
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];
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
260var Vims: VNFone;
261var Vims: VNFtwo;
262var Vims: VNFthree;
263var Vims: VNFfour;
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;
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];
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];
284var int: total_cost = used_transport_cost + used_vim_cost;
286solve minimize total_cost;
287"""
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];
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
326var Vims: VNFone;
327var Vims: VNFtwo;
328var Vims: VNFthree;
329var Vims: VNFfour;
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
335var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+
336trp_link_price_list[VNFtwo, VNFthree]+
337trp_link_price_list[VNFthree, VNFfour];
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];
344var int: total_cost = used_transport_cost + used_vim_cost;
346solve minimize total_cost;
347"""
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];
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
386var Vims: VNF1;
387Vims: VNF2 = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87;
388var Vims: VNF3;
389Vims: VNF4 = vimcccccccc_ed84_4e49_b5df_a9d117bd731f;
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;
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];
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];
410var int: total_cost = used_transport_cost + used_vim_cost;
412solve minimize total_cost;
413"""
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];
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
452var Vims: VNFone;
453Vims: VNFtwo = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87;
454var Vims: VNFthree;
455Vims: VNFfour = vimcccccccc_ed84_4e49_b5df_a9d117bd731f;
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;
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];
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];
476var int: total_cost = used_transport_cost + used_vim_cost;
478solve minimize total_cost;
479"""
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];
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
516var Vims: VNFone;
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
521var int: used_transport_cost =0;
523var int: used_vim_cost =vim_price_list_one[VNFone];
525var int: total_cost = used_transport_cost + used_vim_cost;
527solve minimize total_cost;
528"""
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)
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):
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)
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):
569 """
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")
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)
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"
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)
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'
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)
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'
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 = ""
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"
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")