Coverage for osm_pla/test/test_mznModelGenerator.py: 98%

134 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2024-06-22 10:12 +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 

18# import unittest 

19from unittest import TestCase 

20 

21# import random 

22# from operator import itemgetter 

23import re 

24 

25from jinja2 import Template 

26 

27from osm_pla.placement.mznplacement import MznModelGenerator 

28 

29test_ns_placement_data_str = { 

30 "vim_accounts": [ 

31 "vim" + vim_account.replace("-", "_") 

32 for vim_account in [ 

33 "aaaaaaaa-38f5-438d-b8ee-3f93b3531f87", 

34 "bbbbbbbb-38f5-438d-b8ee-3f93b3531f87", 

35 "cccccccc-ed84-4e49-b5df-a9d117bd731f", 

36 "dddddddd-ed84-4e49-b5df-a9d117bd731f", 

37 "eeeeeeee-38f5-438d-b8ee-3f93b3531f87", 

38 ] 

39 ], 

40 "trp_link_latency": [ 

41 [0, 50, 100, 150, 200], 

42 [0, 0, 100, 150, 200], 

43 [0, 0, 0, 150, 200], 

44 [0, 0, 0, 0, 200], 

45 [0, 0, 0, 0, 0], 

46 ], 

47 "trp_link_jitter": [ 

48 [0, 5, 10, 15, 20], 

49 [0, 0, 10, 15, 20], 

50 [0, 0, 0, 15, 20], 

51 [0, 0, 0, 0, 20], 

52 [0, 0, 0, 0, 0], 

53 ], 

54 "trp_link_price_list": [ 

55 [0, 5, 6, 6, 7], 

56 [0, 0, 6, 6, 7], 

57 [0, 0, 0, 6, 7], 

58 [0, 0, 0, 0, 7], 

59 [0, 0, 0, 0, 0], 

60 ], 

61 "ns_desc": [ 

62 {"vnf_id": "one", "vnf_price_per_vim": [50, 51, 52, 53, 54]}, 

63 {"vnf_id": "two", "vnf_price_per_vim": [20, 21, 22, 23, 24]}, 

64 {"vnf_id": "three", "vnf_price_per_vim": [70, 71, 72, 73, 74]}, 

65 {"vnf_id": "four", "vnf_price_per_vim": [40, 41, 42, 43, 44]}, 

66 ], 

67 "vld_desc": [ 

68 {"cp_refs": ["one", "two"], "latency": 150, "jitter": 30}, 

69 {"cp_refs": ["two", "three"], "latency": 140, "jitter": 30}, 

70 {"cp_refs": ["three", "four"], "latency": 130, "jitter": 30}, 

71 ], 

72 "generator_data": {"file": __file__, "time": datetime.datetime.now()}, 

73} 

74 

75test_ns_placement_data_str_no_vld_constraints = { 

76 "vim_accounts": [ 

77 "vim" + vim_account.replace("-", "_") 

78 for vim_account in [ 

79 "aaaaaaaa-38f5-438d-b8ee-3f93b3531f87", 

80 "bbbbbbbb-38f5-438d-b8ee-3f93b3531f87", 

81 "cccccccc-ed84-4e49-b5df-a9d117bd731f", 

82 "dddddddd-ed84-4e49-b5df-a9d117bd731f", 

83 "eeeeeeee-38f5-438d-b8ee-3f93b3531f87", 

84 ] 

85 ], 

86 "trp_link_latency": [ 

87 [0, 50, 100, 150, 200], 

88 [0, 0, 100, 150, 200], 

89 [0, 0, 0, 150, 200], 

90 [0, 0, 0, 0, 200], 

91 [0, 0, 0, 0, 0], 

92 ], 

93 "trp_link_jitter": [ 

94 [0, 5, 10, 15, 20], 

95 [0, 0, 10, 15, 20], 

96 [0, 0, 0, 15, 20], 

97 [0, 0, 0, 0, 20], 

98 [0, 0, 0, 0, 0], 

99 ], 

100 "trp_link_price_list": [ 

101 [0, 5, 6, 6, 7], 

102 [0, 0, 6, 6, 7], 

103 [0, 0, 0, 6, 7], 

104 [0, 0, 0, 0, 7], 

105 [0, 0, 0, 0, 0], 

106 ], 

107 "ns_desc": [ 

108 {"vnf_id": "one", "vnf_price_per_vim": [50, 51, 52, 53, 54]}, 

109 {"vnf_id": "two", "vnf_price_per_vim": [20, 21, 22, 23, 24]}, 

110 {"vnf_id": "three", "vnf_price_per_vim": [70, 71, 72, 73, 74]}, 

111 {"vnf_id": "four", "vnf_price_per_vim": [40, 41, 42, 43, 44]}, 

112 ], 

113 "vld_desc": [ 

114 {"cp_refs": ["one", "two"]}, 

115 {"cp_refs": ["two", "three"]}, 

116 {"cp_refs": ["three", "four"]}, 

117 ], 

118 "generator_data": {"file": __file__, "time": datetime.datetime.now()}, 

119} 

120 

121test_ns_placement_data = { 

122 "vim_accounts": [ 

123 "vim" + vim_account.replace("-", "_") 

124 for vim_account in [ 

125 "aaaaaaaa-38f5-438d-b8ee-3f93b3531f87", 

126 "bbbbbbbb-38f5-438d-b8ee-3f93b3531f87", 

127 "cccccccc-ed84-4e49-b5df-a9d117bd731f", 

128 "dddddddd-ed84-4e49-b5df-a9d117bd731f", 

129 "eeeeeeee-38f5-438d-b8ee-3f93b3531f87", 

130 ] 

131 ], 

132 "trp_link_latency": [ 

133 [0, 50, 100, 150, 200], 

134 [0, 0, 100, 150, 200], 

135 [0, 0, 0, 150, 200], 

136 [0, 0, 0, 0, 200], 

137 [0, 0, 0, 0, 0], 

138 ], 

139 "trp_link_jitter": [ 

140 [0, 5, 10, 15, 20], 

141 [0, 0, 10, 15, 20], 

142 [0, 0, 0, 15, 20], 

143 [0, 0, 0, 0, 20], 

144 [0, 0, 0, 0, 0], 

145 ], 

146 "trp_link_price_list": [ 

147 [0, 5, 6, 6, 7], 

148 [0, 0, 6, 6, 7], 

149 [0, 0, 0, 6, 7], 

150 [0, 0, 0, 0, 7], 

151 [0, 0, 0, 0, 0], 

152 ], 

153 "ns_desc": [ 

154 {"vnf_id": "1", "vnf_price_per_vim": [50, 51, 52, 53, 54]}, 

155 {"vnf_id": "2", "vnf_price_per_vim": [20, 21, 22, 23, 24]}, 

156 {"vnf_id": "3", "vnf_price_per_vim": [70, 71, 72, 73, 74]}, 

157 {"vnf_id": "4", "vnf_price_per_vim": [40, 41, 42, 43, 44]}, 

158 ], 

159 "vld_desc": [ 

160 {"cp_refs": ["1", "2"], "latency": 150, "jitter": 30}, 

161 {"cp_refs": ["2", "3"], "latency": 140, "jitter": 30}, 

162 {"cp_refs": ["3", "4"], "latency": 130, "jitter": 30}, 

163 ], 

164 "generator_data": {"file": __file__, "time": datetime.datetime.now()}, 

165} 

166 

167test_ns_placement_data_w_pinning = { 

168 "vim_accounts": [ 

169 "vim" + vim_account.replace("-", "_") 

170 for vim_account in [ 

171 "aaaaaaaa-38f5-438d-b8ee-3f93b3531f87", 

172 "bbbbbbbb-38f5-438d-b8ee-3f93b3531f87", 

173 "cccccccc-ed84-4e49-b5df-a9d117bd731f", 

174 "dddddddd-ed84-4e49-b5df-a9d117bd731f", 

175 "eeeeeeee-38f5-438d-b8ee-3f93b3531f87", 

176 ] 

177 ], 

178 "trp_link_latency": [ 

179 [0, 50, 100, 150, 200], 

180 [0, 0, 100, 150, 200], 

181 [0, 0, 0, 150, 200], 

182 [0, 0, 0, 0, 200], 

183 [0, 0, 0, 0, 0], 

184 ], 

185 "trp_link_jitter": [ 

186 [0, 5, 10, 15, 20], 

187 [0, 0, 10, 15, 20], 

188 [0, 0, 0, 15, 20], 

189 [0, 0, 0, 0, 20], 

190 [0, 0, 0, 0, 0], 

191 ], 

192 "trp_link_price_list": [ 

193 [0, 5, 6, 6, 7], 

194 [0, 0, 6, 6, 7], 

195 [0, 0, 0, 6, 7], 

196 [0, 0, 0, 0, 7], 

197 [0, 0, 0, 0, 0], 

198 ], 

199 "ns_desc": [ 

200 {"vnf_id": "1", "vnf_price_per_vim": [50, 51, 52, 53, 54]}, 

201 { 

202 "vnf_id": "2", 

203 "vnf_price_per_vim": [20, 21, 22, 23, 24], 

204 "vim_account": "vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87", 

205 }, 

206 {"vnf_id": "3", "vnf_price_per_vim": [70, 71, 72, 73, 74]}, 

207 { 

208 "vnf_id": "4", 

209 "vnf_price_per_vim": [40, 41, 42, 43, 44], 

210 "vim_account": "vimcccccccc_ed84_4e49_b5df_a9d117bd731f", 

211 }, 

212 ], 

213 "vld_desc": [ 

214 {"cp_refs": ["1", "2"], "latency": 150, "jitter": 30}, 

215 {"cp_refs": ["2", "3"], "latency": 140, "jitter": 30}, 

216 {"cp_refs": ["3", "4"], "latency": 130, "jitter": 30}, 

217 ], 

218 "generator_data": {"file": __file__, "time": datetime.datetime.now()}, 

219} 

220 

221test_ns_placement_data_w_pinning_str = { 

222 "vim_accounts": [ 

223 "vim" + vim_account.replace("-", "_") 

224 for vim_account in [ 

225 "aaaaaaaa-38f5-438d-b8ee-3f93b3531f87", 

226 "bbbbbbbb-38f5-438d-b8ee-3f93b3531f87", 

227 "cccccccc-ed84-4e49-b5df-a9d117bd731f", 

228 "dddddddd-ed84-4e49-b5df-a9d117bd731f", 

229 "eeeeeeee-38f5-438d-b8ee-3f93b3531f87", 

230 ] 

231 ], 

232 "trp_link_latency": [ 

233 [0, 50, 100, 150, 200], 

234 [0, 0, 100, 150, 200], 

235 [0, 0, 0, 150, 200], 

236 [0, 0, 0, 0, 200], 

237 [0, 0, 0, 0, 0], 

238 ], 

239 "trp_link_jitter": [ 

240 [0, 5, 10, 15, 20], 

241 [0, 0, 10, 15, 20], 

242 [0, 0, 0, 15, 20], 

243 [0, 0, 0, 0, 20], 

244 [0, 0, 0, 0, 0], 

245 ], 

246 "trp_link_price_list": [ 

247 [0, 5, 6, 6, 7], 

248 [0, 0, 6, 6, 7], 

249 [0, 0, 0, 6, 7], 

250 [0, 0, 0, 0, 7], 

251 [0, 0, 0, 0, 0], 

252 ], 

253 "ns_desc": [ 

254 {"vnf_id": "one", "vnf_price_per_vim": [50, 51, 52, 53, 54]}, 

255 { 

256 "vnf_id": "two", 

257 "vnf_price_per_vim": [20, 21, 22, 23, 24], 

258 "vim_account": "vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87", 

259 }, 

260 {"vnf_id": "three", "vnf_price_per_vim": [70, 71, 72, 73, 74]}, 

261 { 

262 "vnf_id": "four", 

263 "vnf_price_per_vim": [40, 41, 42, 43, 44], 

264 "vim_account": "vimcccccccc_ed84_4e49_b5df_a9d117bd731f", 

265 }, 

266 ], 

267 "vld_desc": [ 

268 {"cp_refs": ["one", "two"], "latency": 150, "jitter": 30}, 

269 {"cp_refs": ["two", "three"], "latency": 140, "jitter": 30}, 

270 {"cp_refs": ["three", "four"], "latency": 130, "jitter": 30}, 

271 ], 

272 "generator_data": {"file": __file__, "time": datetime.datetime.now()}, 

273} 

274 

275test_ns_placement_data_str_no_vld = { 

276 "vim_accounts": [ 

277 "vim" + vim_account.replace("-", "_") 

278 for vim_account in [ 

279 "aaaaaaaa-38f5-438d-b8ee-3f93b3531f87", 

280 "bbbbbbbb-38f5-438d-b8ee-3f93b3531f87", 

281 "cccccccc-ed84-4e49-b5df-a9d117bd731f", 

282 "dddddddd-ed84-4e49-b5df-a9d117bd731f", 

283 "eeeeeeee-38f5-438d-b8ee-3f93b3531f87", 

284 ] 

285 ], 

286 "trp_link_latency": [ 

287 [0, 50, 100, 150, 200], 

288 [0, 0, 100, 150, 200], 

289 [0, 0, 0, 150, 200], 

290 [0, 0, 0, 0, 200], 

291 [0, 0, 0, 0, 0], 

292 ], 

293 "trp_link_jitter": [ 

294 [0, 5, 10, 15, 20], 

295 [0, 0, 10, 15, 20], 

296 [0, 0, 0, 15, 20], 

297 [0, 0, 0, 0, 20], 

298 [0, 0, 0, 0, 0], 

299 ], 

300 "trp_link_price_list": [ 

301 [0, 5, 6, 6, 7], 

302 [0, 0, 6, 6, 7], 

303 [0, 0, 0, 6, 7], 

304 [0, 0, 0, 0, 7], 

305 [0, 0, 0, 0, 0], 

306 ], 

307 "ns_desc": [{"vnf_id": "one", "vnf_price_per_vim": [50, 51, 52, 53, 54]}], 

308 "vld_desc": [], 

309 "generator_data": {"file": __file__, "time": datetime.datetime.now()}, 

310} 

311 

312expected_model_fragment = """ 

313%This is the NETWORK RESOURCE MODEL 

314enum Vims = { 

315vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87, 

316vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87, 

317vimcccccccc_ed84_4e49_b5df_a9d117bd731f, 

318vimdddddddd_ed84_4e49_b5df_a9d117bd731f, 

319vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts 

320array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200, 

321|0,0,100,150,200, 

322|0,0,0,150,200, 

323|0,0,0,0,200, 

324|0,0,0,0,0, 

325|]; % Transport link latency between data centers 

326array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20, 

327|0,0,10,15,20, 

328|0,0,0,15,20, 

329|0,0,0,0,20, 

330|0,0,0,0,0, 

331|]; % Transport link jitter between data centers 

332array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7, 

333|0,0,6,6,7, 

334|0,0,0,6,7, 

335|0,0,0,0,7, 

336|0,0,0,0,0, 

337|]; % Transport link price list 

338array[Vims] of int: vim_price_list_1 = [50,51,52,53,54]; 

339array[Vims] of int: vim_price_list_2 = [20,21,22,23,24]; 

340array[Vims] of int: vim_price_list_3 = [70,71,72,73,74]; 

341array[Vims] of int: vim_price_list_4 = [40,41,42,43,44]; 

342 

343 

344% This is the NETWORK BASIC LOAD MODEL (CONSUMED) 

345% NOTE. This is not applicable in OSM Release 7 

346 

347% This is the SERVICE CONSUMPTION MODEL 

348% These are the variables, i.e. which DC to select for each VNF 

349var Vims: VNF1; 

350var Vims: VNF2; 

351var Vims: VNF3; 

352var Vims: VNF4; 

353 

354 

355% These are the set of rules for selecting DCs to VNFs 

356constraint trp_link_latency[VNF1, VNF2] <= 150; 

357constraint trp_link_latency[VNF2, VNF3] <= 140; 

358constraint trp_link_latency[VNF3, VNF4] <= 130; 

359constraint trp_link_jitter[VNF1, VNF2] <= 30; 

360constraint trp_link_jitter[VNF2, VNF3] <= 30; 

361constraint trp_link_jitter[VNF3, VNF4] <= 30; 

362 

363% Calculate the cost for VNFs and cost for transport link and total cost 

364var int: used_transport_cost =trp_link_price_list[VNF1, VNF2]+ 

365trp_link_price_list[VNF2, VNF3]+ 

366trp_link_price_list[VNF3, VNF4]; 

367 

368var int: used_vim_cost =vim_price_list_1[VNF1]+ 

369vim_price_list_2[VNF2]+ 

370vim_price_list_3[VNF3]+ 

371vim_price_list_4[VNF4]; 

372 

373var int: total_cost = used_transport_cost + used_vim_cost; 

374 

375solve minimize total_cost; 

376""" 

377expected_model_fragment_str = """ 

378%This is the NETWORK RESOURCE MODEL 

379enum Vims = { 

380vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87, 

381vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87, 

382vimcccccccc_ed84_4e49_b5df_a9d117bd731f, 

383vimdddddddd_ed84_4e49_b5df_a9d117bd731f, 

384vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts 

385array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200, 

386|0,0,100,150,200, 

387|0,0,0,150,200, 

388|0,0,0,0,200, 

389|0,0,0,0,0, 

390|]; % Transport link latency between data centers 

391array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20, 

392|0,0,10,15,20, 

393|0,0,0,15,20, 

394|0,0,0,0,20, 

395|0,0,0,0,0, 

396|]; % Transport link jitter between data centers 

397array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7, 

398|0,0,6,6,7, 

399|0,0,0,6,7, 

400|0,0,0,0,7, 

401|0,0,0,0,0, 

402|]; % Transport link price list 

403array[Vims] of int: vim_price_list_one = [50,51,52,53,54]; 

404array[Vims] of int: vim_price_list_two = [20,21,22,23,24]; 

405array[Vims] of int: vim_price_list_three = [70,71,72,73,74]; 

406array[Vims] of int: vim_price_list_four = [40,41,42,43,44]; 

407 

408 

409% This is the NETWORK BASIC LOAD MODEL (CONSUMED) 

410% NOTE. This is not applicable in OSM Release 7 

411 

412% This is the SERVICE CONSUMPTION MODEL 

413% These are the variables, i.e. which DC to select for each VNF 

414var Vims: VNFone; 

415var Vims: VNFtwo; 

416var Vims: VNFthree; 

417var Vims: VNFfour; 

418 

419 

420% These are the set of rules for selecting DCs to VNFs 

421constraint trp_link_latency[VNFone, VNFtwo] <= 150; 

422constraint trp_link_latency[VNFtwo, VNFthree] <= 140; 

423constraint trp_link_latency[VNFthree, VNFfour] <= 130; 

424constraint trp_link_jitter[VNFone, VNFtwo] <= 30; 

425constraint trp_link_jitter[VNFtwo, VNFthree] <= 30; 

426constraint trp_link_jitter[VNFthree, VNFfour] <= 30; 

427 

428% Calculate the cost for VNFs and cost for transport link and total cost 

429var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+ 

430trp_link_price_list[VNFtwo, VNFthree]+ 

431trp_link_price_list[VNFthree, VNFfour]; 

432 

433var int: used_vim_cost =vim_price_list_one[VNFone]+ 

434vim_price_list_two[VNFtwo]+ 

435vim_price_list_three[VNFthree]+ 

436vim_price_list_four[VNFfour]; 

437 

438var int: total_cost = used_transport_cost + used_vim_cost; 

439 

440solve minimize total_cost; 

441""" 

442 

443expected_model_fragment_str_no_vld_constraints = """ 

444%This is the NETWORK RESOURCE MODEL 

445enum Vims = { 

446vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87, 

447vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87, 

448vimcccccccc_ed84_4e49_b5df_a9d117bd731f, 

449vimdddddddd_ed84_4e49_b5df_a9d117bd731f, 

450vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts 

451array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200, 

452|0,0,100,150,200, 

453|0,0,0,150,200, 

454|0,0,0,0,200, 

455|0,0,0,0,0, 

456|]; % Transport link latency between data centers 

457array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20, 

458|0,0,10,15,20, 

459|0,0,0,15,20, 

460|0,0,0,0,20, 

461|0,0,0,0,0, 

462|]; % Transport link jitter between data centers 

463array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7, 

464|0,0,6,6,7, 

465|0,0,0,6,7, 

466|0,0,0,0,7, 

467|0,0,0,0,0, 

468|]; % Transport link price list 

469array[Vims] of int: vim_price_list_one = [50,51,52,53,54]; 

470array[Vims] of int: vim_price_list_two = [20,21,22,23,24]; 

471array[Vims] of int: vim_price_list_three = [70,71,72,73,74]; 

472array[Vims] of int: vim_price_list_four = [40,41,42,43,44]; 

473 

474 

475% This is the NETWORK BASIC LOAD MODEL (CONSUMED) 

476% NOTE. This is not applicable in OSM Release 7 

477 

478% This is the SERVICE CONSUMPTION MODEL 

479% These are the variables, i.e. which DC to select for each VNF 

480var Vims: VNFone; 

481var Vims: VNFtwo; 

482var Vims: VNFthree; 

483var Vims: VNFfour; 

484 

485 

486% These are the set of rules for selecting DCs to VNFs 

487 

488% Calculate the cost for VNFs and cost for transport link and total cost 

489var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+ 

490trp_link_price_list[VNFtwo, VNFthree]+ 

491trp_link_price_list[VNFthree, VNFfour]; 

492 

493var int: used_vim_cost =vim_price_list_one[VNFone]+ 

494vim_price_list_two[VNFtwo]+ 

495vim_price_list_three[VNFthree]+ 

496vim_price_list_four[VNFfour]; 

497 

498var int: total_cost = used_transport_cost + used_vim_cost; 

499 

500solve minimize total_cost; 

501""" 

502 

503expected_model_fragment_w_pinning = """ 

504%This is the NETWORK RESOURCE MODEL 

505enum Vims = { 

506vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87, 

507vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87, 

508vimcccccccc_ed84_4e49_b5df_a9d117bd731f, 

509vimdddddddd_ed84_4e49_b5df_a9d117bd731f, 

510vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts 

511array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200, 

512|0,0,100,150,200, 

513|0,0,0,150,200, 

514|0,0,0,0,200, 

515|0,0,0,0,0, 

516|]; % Transport link latency between data centers 

517array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20, 

518|0,0,10,15,20, 

519|0,0,0,15,20, 

520|0,0,0,0,20, 

521|0,0,0,0,0, 

522|]; % Transport link jitter between data centers 

523array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7, 

524|0,0,6,6,7, 

525|0,0,0,6,7, 

526|0,0,0,0,7, 

527|0,0,0,0,0, 

528|]; % Transport link price list 

529array[Vims] of int: vim_price_list_1 = [50,51,52,53,54]; 

530array[Vims] of int: vim_price_list_2 = [20,21,22,23,24]; 

531array[Vims] of int: vim_price_list_3 = [70,71,72,73,74]; 

532array[Vims] of int: vim_price_list_4 = [40,41,42,43,44]; 

533 

534 

535% This is the NETWORK BASIC LOAD MODEL (CONSUMED) 

536% NOTE. This is not applicable in OSM Release 7 

537 

538% This is the SERVICE CONSUMPTION MODEL 

539% These are the variables, i.e. which DC to select for each VNF 

540var Vims: VNF1; 

541Vims: VNF2 = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87; 

542var Vims: VNF3; 

543Vims: VNF4 = vimcccccccc_ed84_4e49_b5df_a9d117bd731f; 

544 

545 

546% These are the set of rules for selecting DCs to VNFs 

547constraint trp_link_latency[VNF1, VNF2] <= 150; 

548constraint trp_link_latency[VNF2, VNF3] <= 140; 

549constraint trp_link_latency[VNF3, VNF4] <= 130; 

550constraint trp_link_jitter[VNF1, VNF2] <= 30; 

551constraint trp_link_jitter[VNF2, VNF3] <= 30; 

552constraint trp_link_jitter[VNF3, VNF4] <= 30; 

553 

554% Calculate the cost for VNFs and cost for transport link and total cost 

555var int: used_transport_cost =trp_link_price_list[VNF1, VNF2]+ 

556trp_link_price_list[VNF2, VNF3]+ 

557trp_link_price_list[VNF3, VNF4]; 

558 

559var int: used_vim_cost =vim_price_list_1[VNF1]+ 

560vim_price_list_2[VNF2]+ 

561vim_price_list_3[VNF3]+ 

562vim_price_list_4[VNF4]; 

563 

564var int: total_cost = used_transport_cost + used_vim_cost; 

565 

566solve minimize total_cost; 

567""" 

568 

569expected_model_fragment_w_pinning_str = """ 

570%This is the NETWORK RESOURCE MODEL 

571enum Vims = { 

572vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87, 

573vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87, 

574vimcccccccc_ed84_4e49_b5df_a9d117bd731f, 

575vimdddddddd_ed84_4e49_b5df_a9d117bd731f, 

576vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts 

577array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200, 

578|0,0,100,150,200, 

579|0,0,0,150,200, 

580|0,0,0,0,200, 

581|0,0,0,0,0, 

582|]; % Transport link latency between data centers 

583array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20, 

584|0,0,10,15,20, 

585|0,0,0,15,20, 

586|0,0,0,0,20, 

587|0,0,0,0,0, 

588|]; % Transport link jitter between data centers 

589array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7, 

590|0,0,6,6,7, 

591|0,0,0,6,7, 

592|0,0,0,0,7, 

593|0,0,0,0,0, 

594|]; % Transport link price list 

595array[Vims] of int: vim_price_list_one = [50,51,52,53,54]; 

596array[Vims] of int: vim_price_list_two = [20,21,22,23,24]; 

597array[Vims] of int: vim_price_list_three = [70,71,72,73,74]; 

598array[Vims] of int: vim_price_list_four = [40,41,42,43,44]; 

599 

600 

601% This is the NETWORK BASIC LOAD MODEL (CONSUMED) 

602% NOTE. This is not applicable in OSM Release 7 

603 

604% This is the SERVICE CONSUMPTION MODEL 

605% These are the variables, i.e. which DC to select for each VNF 

606var Vims: VNFone; 

607Vims: VNFtwo = vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87; 

608var Vims: VNFthree; 

609Vims: VNFfour = vimcccccccc_ed84_4e49_b5df_a9d117bd731f; 

610 

611 

612% These are the set of rules for selecting DCs to VNFs 

613constraint trp_link_latency[VNFone, VNFtwo] <= 150; 

614constraint trp_link_latency[VNFtwo, VNFthree] <= 140; 

615constraint trp_link_latency[VNFthree, VNFfour] <= 130; 

616constraint trp_link_jitter[VNFone, VNFtwo] <= 30; 

617constraint trp_link_jitter[VNFtwo, VNFthree] <= 30; 

618constraint trp_link_jitter[VNFthree, VNFfour] <= 30; 

619 

620% Calculate the cost for VNFs and cost for transport link and total cost 

621var int: used_transport_cost =trp_link_price_list[VNFone, VNFtwo]+ 

622trp_link_price_list[VNFtwo, VNFthree]+ 

623trp_link_price_list[VNFthree, VNFfour]; 

624 

625var int: used_vim_cost =vim_price_list_one[VNFone]+ 

626vim_price_list_two[VNFtwo]+ 

627vim_price_list_three[VNFthree]+ 

628vim_price_list_four[VNFfour]; 

629 

630var int: total_cost = used_transport_cost + used_vim_cost; 

631 

632solve minimize total_cost; 

633""" 

634 

635expected_model_fragment_str_no_vld = """ 

636%This is the NETWORK RESOURCE MODEL 

637enum Vims = { 

638vimaaaaaaaa_38f5_438d_b8ee_3f93b3531f87, 

639vimbbbbbbbb_38f5_438d_b8ee_3f93b3531f87, 

640vimcccccccc_ed84_4e49_b5df_a9d117bd731f, 

641vimdddddddd_ed84_4e49_b5df_a9d117bd731f, 

642vimeeeeeeee_38f5_438d_b8ee_3f93b3531f87}; % The vim-accounts 

643array[Vims, Vims] of int: trp_link_latency = [|0,50,100,150,200, 

644|0,0,100,150,200, 

645|0,0,0,150,200, 

646|0,0,0,0,200, 

647|0,0,0,0,0, 

648|]; % Transport link latency between data centers 

649array[Vims, Vims] of int: trp_link_jitter = [|0,5,10,15,20, 

650|0,0,10,15,20, 

651|0,0,0,15,20, 

652|0,0,0,0,20, 

653|0,0,0,0,0, 

654|]; % Transport link jitter between data centers 

655array[Vims, Vims] of int: trp_link_price_list = [|0,5,6,6,7, 

656|0,0,6,6,7, 

657|0,0,0,6,7, 

658|0,0,0,0,7, 

659|0,0,0,0,0, 

660|]; % Transport link price list 

661array[Vims] of int: vim_price_list_one = [50,51,52,53,54]; 

662 

663 

664% This is the NETWORK BASIC LOAD MODEL (CONSUMED) 

665% NOTE. This is not applicable in OSM Release 7 

666 

667% This is the SERVICE CONSUMPTION MODEL 

668% These are the variables, i.e. which DC to select for each VNF 

669 

670var Vims: VNFone; 

671 

672% These are the set of rules for selecting DCs to VNFs 

673 

674% Calculate the cost for VNFs and cost for transport link and total cost 

675var int: used_transport_cost =0; 

676 

677var int: used_vim_cost =vim_price_list_one[VNFone]; 

678 

679var int: total_cost = used_transport_cost + used_vim_cost; 

680 

681solve minimize total_cost; 

682""" 

683 

684 

685class TestMznModelGenerator(TestCase): 

686 def test_create_model(self): 

687 mg = MznModelGenerator(logging.getLogger(__name__)) 

688 mzn_model = mg.create_model(test_ns_placement_data_str) 

689 

690 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines 

691 self.assertTrue( 

692 expected_model_fragment_str.replace("\n", "") 

693 in mzn_model.replace("\n", ""), 

694 "faulty model generated", 

695 ) 

696 

697 def test_create_model_no_vld_constraints(self): 

698 """ 

699 instantiate w/o constraints in nsd or order params has a valid model 

700 :return: 

701 """ 

702 mg = MznModelGenerator(logging.getLogger(__name__)) 

703 mzn_model = mg.create_model(test_ns_placement_data_str_no_vld_constraints) 

704 

705 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines 

706 self.assertTrue( 

707 expected_model_fragment_str_no_vld_constraints.replace("\n", "") 

708 in mzn_model.replace("\n", ""), 

709 "faulty model generated", 

710 ) 

711 

712 def test_create_model_w_pinning(self): 

713 mg = MznModelGenerator(logging.getLogger(__name__)) 

714 mzn_model = mg.create_model(test_ns_placement_data_w_pinning_str) 

715 

716 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines 

717 self.assertTrue( 

718 expected_model_fragment_w_pinning_str.replace("\n", "") 

719 in mzn_model.replace("\n", ""), 

720 "faulty model generated", 

721 ) 

722 

723 def test_create_model_no_vld(self): 

724 mg = MznModelGenerator(logging.getLogger(__name__)) 

725 mzn_model = mg.create_model(test_ns_placement_data_str_no_vld) 

726 

727 # so asserting exact content is difficult due to the datetime.now(), therefore we ignore the first lines 

728 self.assertTrue( 

729 expected_model_fragment_str_no_vld.replace("\n", "") 

730 in mzn_model.replace("\n", ""), 

731 "faulty model generated", 

732 ) 

733 

734 def test__load_jinja_template(self): 

735 """ 

736 

737 add other test to check exception if template not loaded (e.g. invalid template name, 

738 perhaps also valid name but invalid content (in case jinja2 detects such things)) 

739 """ 

740 mg = MznModelGenerator(logging.getLogger(__name__)) 

741 template = mg._load_jinja_template() # Note we use the default template 

742 self.assertTrue( 

743 isinstance(template, Template), "failed to load jinja2 template" 

744 ) 

745 

746 def test_vim_account_replace(self): 

747 mg = MznModelGenerator(logging.getLogger(__name__)) 

748 nspd = test_ns_placement_data_str 

749 mzn_model = mg.create_model(nspd) 

750 

751 expected = ( 

752 "%This is the NETWORK RESOURCE MODEL" + "\n" + "enum Vims = {" + "\n" 

753 ) 

754 for val in test_ns_placement_data_str["vim_accounts"]: 

755 expected = expected + val.replace("-", "_") + ",\n" 

756 expected = expected[:-2] + "}; % The vim-accounts" 

757 res = re.findall(expected, mzn_model) 

758 self.assertEqual(1, len(res), "vim accounts didnt replace from - to _") 

759 

760 def test_trp_link_price_list(self): 

761 mg = MznModelGenerator(logging.getLogger(__name__)) 

762 mzn_model = mg.create_model(test_ns_placement_data_str) 

763 

764 expected = "array\\[Vims, Vims\\] of int: trp_link_price_list = \\[" 

765 for price_list in test_ns_placement_data_str["trp_link_price_list"]: 

766 expected = ( 

767 expected + "\\|" + (str(price_list)[1:-1]).replace(" ", "") + ",\n" 

768 ) 

769 expected = expected + "\\|\\]; % Transport link price list" 

770 res = re.findall(expected, mzn_model) 

771 self.assertEqual(1, len(res), "price list is not correct") 

772 

773 def test_link_latency(self): 

774 mg = MznModelGenerator(logging.getLogger(__name__)) 

775 mzn_model = mg.create_model(test_ns_placement_data_str) 

776 

777 expected = "array\\[Vims, Vims\\] of int: trp_link_latency = \\[" 

778 for link_latency in test_ns_placement_data_str["trp_link_latency"]: 

779 expected = ( 

780 expected + "\\|" + (str(link_latency)[1:-1]).replace(" ", "") + ",\n" 

781 ) 

782 expected = expected + "\\|\\]; % Transport link latency between data centers" 

783 res = re.findall(expected, mzn_model) 

784 self.assertEqual(1, len(res), "trp_link_latency values is not correct") 

785 

786 def test_link_jitter(self): 

787 mg = MznModelGenerator(logging.getLogger(__name__)) 

788 mzn_model = mg.create_model(test_ns_placement_data_str) 

789 

790 expected = "array\\[Vims, Vims\\] of int: trp_link_jitter = \\[" 

791 for link_jitter in test_ns_placement_data_str["trp_link_jitter"]: 

792 expected = ( 

793 expected + "\\|" + (str(link_jitter)[1:-1]).replace(" ", "") + ",\n" 

794 ) 

795 expected = expected + "\\|\\]; % Transport link jitter between data centers" 

796 

797 res = re.findall(expected, mzn_model) 

798 

799 self.assertEqual(1, len(res), "trp_link_jitter values is not correct") 

800 

801 def test_price_per_vim(self): 

802 mg = MznModelGenerator(logging.getLogger(__name__)) 

803 mzn_model = mg.create_model(test_ns_placement_data_w_pinning_str) 

804 

805 expected = "" 

806 for price_list in test_ns_placement_data_w_pinning_str["ns_desc"]: 

807 expected += ( 

808 "array\\[Vims\\] of int: vim_price_list_" 

809 + price_list.get("vnf_id") 

810 + " = " 

811 ) 

812 temp = str(price_list.get("vnf_price_per_vim"))[1:-1].replace(" ", "") 

813 expected += "\\[" + temp + "\\];\n" 

814 

815 res = re.findall(expected, mzn_model) 

816 self.assertEqual(1, len(res), "mzn_model contains pinning") 

817 

818 def test_pinning(self): 

819 mg = MznModelGenerator(logging.getLogger(__name__)) 

820 mzn_model = mg.create_model(test_ns_placement_data_str) 

821 

822 expected = "" 

823 for pin_list in test_ns_placement_data_str["ns_desc"]: 

824 if pin_list.get("vim_account"): 

825 expected += ( 

826 "Vims: VNF" 

827 + pin_list.get("vnf_id") 

828 + " = " 

829 + pin_list.get("vim_account") 

830 + ";\n" 

831 ) 

832 else: 

833 expected += "var Vims: VNF" + pin_list.get("vnf_id") + ";\n" 

834 

835 res = re.findall(expected, mzn_model) 

836 self.assertEqual(1, len(res), "mzn_model has no pinning") 

837 

838 def test__without_pinning(self): 

839 mg = MznModelGenerator(logging.getLogger(__name__)) 

840 mzn_model = mg.create_model(test_ns_placement_data_w_pinning_str) 

841 

842 expected = "" 

843 for pin_list in test_ns_placement_data_w_pinning_str["ns_desc"]: 

844 if pin_list.get("vim_account"): 

845 expected += ( 

846 "Vims: VNF" 

847 + pin_list.get("vnf_id") 

848 + " = " 

849 + pin_list.get("vim_account") 

850 + ";\n" 

851 ) 

852 else: 

853 expected += "var Vims: VNF" + pin_list.get("vnf_id") + ";\n" 

854 

855 res = re.findall(expected, mzn_model) 

856 self.assertEqual(1, len(res), "mzn_model contains pinning") 

857 

858 def test__without_constraints_for_jitter_and_latency(self): 

859 mg = MznModelGenerator(logging.getLogger(__name__)) 

860 mzn_model = mg.create_model(test_ns_placement_data_str_no_vld_constraints) 

861 

862 expected_latency = "constraint trp_link_latency" 

863 expected_jitter = "constraint trp_link_jitter" 

864 latency_or_jitter_was_found = 0 

865 for l_o_j in test_ns_placement_data_str_no_vld_constraints["vld_desc"]: 

866 if l_o_j.get("latency") or l_o_j.get("jitter"): 

867 latency_or_jitter_was_found = 1 

868 

869 res_latency = re.findall(expected_latency, mzn_model) 

870 res_jitter = re.findall(expected_jitter, mzn_model) 

871 self.assertEqual( 

872 0, 

873 latency_or_jitter_was_found, 

874 "Jitter or latency was found in the test input", 

875 ) 

876 self.assertEqual( 

877 0, len(res_latency), "constraint trp_link_latency was found in mzn_model" 

878 ) 

879 self.assertEqual( 

880 0, len(res_jitter), "constraint trp_link_latency was found in mzn_model" 

881 ) 

882 

883 def test__constraints_for_jitter_and_latency(self): 

884 mg = MznModelGenerator(logging.getLogger(__name__)) 

885 mzn_model = mg.create_model(test_ns_placement_data_str) 

886 

887 expected_latency = "" 

888 expected_jitter = "" 

889 latency_or_jitter_was_found = 0 

890 for l_o_j in test_ns_placement_data_str["vld_desc"]: 

891 if not (l_o_j.get("latency") or l_o_j.get("jitter")): 

892 latency_or_jitter_was_found = 1 

893 expected_latency += ( 

894 "constraint trp_link_latency" 

895 + "\\[VNF" 

896 + l_o_j.get("cp_refs")[0] 

897 + ", VNF" 

898 + l_o_j.get("cp_refs")[1] 

899 + "\\] \\<= " 

900 + str(l_o_j.get("latency")) 

901 + ";\n\n" 

902 ) 

903 

904 expected_jitter += ( 

905 "constraint trp_link_jitter" 

906 + "\\[VNF" 

907 + l_o_j.get("cp_refs")[0] 

908 + ", VNF" 

909 + l_o_j.get("cp_refs")[1] 

910 + "\\] \\<= " 

911 + str(l_o_j.get("jitter")) 

912 + ";\n\n" 

913 ) 

914 

915 res = re.findall(expected_latency + expected_jitter, mzn_model) 

916 self.assertEqual( 

917 0, 

918 latency_or_jitter_was_found, 

919 "Jitter or latency was not found in the test input", 

920 ) 

921 self.assertEqual(1, len(res), "faulty model generated")