test_cablepaths.py 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806
  1. from django.test import TestCase
  2. from circuits.models import *
  3. from dcim.choices import LinkStatusChoices
  4. from dcim.models import *
  5. from dcim.svg import CableTraceSVG
  6. from dcim.utils import object_to_path_node
  7. class CablePathTestCase(TestCase):
  8. """
  9. Test NetBox's ability to trace and retrace CablePaths in response to data model changes. Tests are numbered
  10. as follows:
  11. 1XX: Test direct connections between different endpoint types
  12. 2XX: Test different cable topologies
  13. 3XX: Test responses to changes in existing objects
  14. """
  15. @classmethod
  16. def setUpTestData(cls):
  17. # Create a single device that will hold all components
  18. cls.site = Site.objects.create(name='Site', slug='site')
  19. manufacturer = Manufacturer.objects.create(name='Generic', slug='generic')
  20. device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Test Device')
  21. device_role = DeviceRole.objects.create(name='Device Role', slug='device-role')
  22. cls.device = Device.objects.create(site=cls.site, device_type=device_type, device_role=device_role, name='Test Device')
  23. cls.powerpanel = PowerPanel.objects.create(site=cls.site, name='Power Panel')
  24. provider = Provider.objects.create(name='Provider', slug='provider')
  25. circuit_type = CircuitType.objects.create(name='Circuit Type', slug='circuit-type')
  26. cls.circuit = Circuit.objects.create(provider=provider, type=circuit_type, cid='Circuit 1')
  27. def assertPathExists(self, nodes, **kwargs):
  28. """
  29. Assert that a CablePath from origin to destination with a specific intermediate path exists.
  30. :param nodes: Iterable of steps, with each step being either a single node or a list of nodes
  31. :param is_active: Boolean indicating whether the end-to-end path is complete and active (optional)
  32. :return: The matching CablePath (if any)
  33. """
  34. path = []
  35. for step in nodes:
  36. if type(step) in (list, tuple):
  37. path.append([object_to_path_node(node) for node in step])
  38. else:
  39. path.append([object_to_path_node(step)])
  40. cablepath = CablePath.objects.filter(path=path, **kwargs).first()
  41. self.assertIsNotNone(cablepath, msg='CablePath not found')
  42. return cablepath
  43. def assertPathIsSet(self, origin, cablepath, msg=None):
  44. """
  45. Assert that a specific CablePath instance is set as the path on the origin.
  46. :param origin: The originating path endpoint
  47. :param cablepath: The CablePath instance originating from this endpoint
  48. :param msg: Custom failure message (optional)
  49. """
  50. if msg is None:
  51. msg = f"Path #{cablepath.pk} not set on originating endpoint {origin}"
  52. self.assertEqual(origin._path_id, cablepath.pk, msg=msg)
  53. def assertPathIsNotSet(self, origin, msg=None):
  54. """
  55. Assert that a specific CablePath instance is set as the path on the origin.
  56. :param origin: The originating path endpoint
  57. :param msg: Custom failure message (optional)
  58. """
  59. if msg is None:
  60. msg = f"Path #{origin._path_id} set as origin on {origin}; should be None!"
  61. self.assertIsNone(origin._path_id, msg=msg)
  62. def test_101_interface_to_interface(self):
  63. """
  64. [IF1] --C1-- [IF2]
  65. """
  66. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  67. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  68. # Create cable 1
  69. cable1 = Cable(
  70. a_terminations=[interface1],
  71. b_terminations=[interface2]
  72. )
  73. cable1.save()
  74. path1 = self.assertPathExists(
  75. (interface1, cable1, interface2),
  76. is_complete=True,
  77. is_active=True
  78. )
  79. path2 = self.assertPathExists(
  80. (interface2, cable1, interface1),
  81. is_complete=True,
  82. is_active=True
  83. )
  84. self.assertEqual(CablePath.objects.count(), 2)
  85. interface1.refresh_from_db()
  86. interface2.refresh_from_db()
  87. self.assertPathIsSet(interface1, path1)
  88. self.assertPathIsSet(interface2, path2)
  89. # Test SVG generation
  90. CableTraceSVG(interface1).render()
  91. # Delete cable 1
  92. cable1.delete()
  93. # Check that all CablePaths have been deleted
  94. self.assertEqual(CablePath.objects.count(), 0)
  95. def test_102_consoleport_to_consoleserverport(self):
  96. """
  97. [CP1] --C1-- [CSP1]
  98. """
  99. consoleport1 = ConsolePort.objects.create(device=self.device, name='Console Port 1')
  100. consoleserverport1 = ConsoleServerPort.objects.create(device=self.device, name='Console Server Port 1')
  101. # Create cable 1
  102. cable1 = Cable(
  103. a_terminations=[consoleport1],
  104. b_terminations=[consoleserverport1]
  105. )
  106. cable1.save()
  107. path1 = self.assertPathExists(
  108. (consoleport1, cable1, consoleserverport1),
  109. is_complete=True,
  110. is_active=True
  111. )
  112. path2 = self.assertPathExists(
  113. (consoleserverport1, cable1, consoleport1),
  114. is_complete=True,
  115. is_active=True
  116. )
  117. self.assertEqual(CablePath.objects.count(), 2)
  118. consoleport1.refresh_from_db()
  119. consoleserverport1.refresh_from_db()
  120. self.assertPathIsSet(consoleport1, path1)
  121. self.assertPathIsSet(consoleserverport1, path2)
  122. # Test SVG generation
  123. CableTraceSVG(consoleport1).render()
  124. # Delete cable 1
  125. cable1.delete()
  126. # Check that all CablePaths have been deleted
  127. self.assertEqual(CablePath.objects.count(), 0)
  128. def test_103_powerport_to_poweroutlet(self):
  129. """
  130. [PP1] --C1-- [PO1]
  131. """
  132. powerport1 = PowerPort.objects.create(device=self.device, name='Power Port 1')
  133. poweroutlet1 = PowerOutlet.objects.create(device=self.device, name='Power Outlet 1')
  134. # Create cable 1
  135. cable1 = Cable(
  136. a_terminations=[powerport1],
  137. b_terminations=[poweroutlet1]
  138. )
  139. cable1.save()
  140. path1 = self.assertPathExists(
  141. (powerport1, cable1, poweroutlet1),
  142. is_complete=True,
  143. is_active=True
  144. )
  145. path2 = self.assertPathExists(
  146. (poweroutlet1, cable1, powerport1),
  147. is_complete=True,
  148. is_active=True
  149. )
  150. self.assertEqual(CablePath.objects.count(), 2)
  151. powerport1.refresh_from_db()
  152. poweroutlet1.refresh_from_db()
  153. self.assertPathIsSet(powerport1, path1)
  154. self.assertPathIsSet(poweroutlet1, path2)
  155. # Test SVG generation
  156. CableTraceSVG(powerport1).render()
  157. # Delete cable 1
  158. cable1.delete()
  159. # Check that all CablePaths have been deleted
  160. self.assertEqual(CablePath.objects.count(), 0)
  161. def test_104_powerport_to_powerfeed(self):
  162. """
  163. [PP1] --C1-- [PF1]
  164. """
  165. powerport1 = PowerPort.objects.create(device=self.device, name='Power Port 1')
  166. powerfeed1 = PowerFeed.objects.create(power_panel=self.powerpanel, name='Power Feed 1')
  167. # Create cable 1
  168. cable1 = Cable(
  169. a_terminations=[powerport1],
  170. b_terminations=[powerfeed1]
  171. )
  172. cable1.save()
  173. path1 = self.assertPathExists(
  174. (powerport1, cable1, powerfeed1),
  175. is_complete=True,
  176. is_active=True
  177. )
  178. path2 = self.assertPathExists(
  179. (powerfeed1, cable1, powerport1),
  180. is_complete=True,
  181. is_active=True
  182. )
  183. self.assertEqual(CablePath.objects.count(), 2)
  184. powerport1.refresh_from_db()
  185. powerfeed1.refresh_from_db()
  186. self.assertPathIsSet(powerport1, path1)
  187. self.assertPathIsSet(powerfeed1, path2)
  188. # Test SVG generation
  189. CableTraceSVG(powerport1).render()
  190. # Delete cable 1
  191. cable1.delete()
  192. # Check that all CablePaths have been deleted
  193. self.assertEqual(CablePath.objects.count(), 0)
  194. def test_120_single_interface_to_multi_interface(self):
  195. """
  196. [IF1] --C1-- [IF2]
  197. [IF3]
  198. """
  199. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  200. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  201. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  202. # Create cable 1
  203. cable1 = Cable(
  204. a_terminations=[interface1],
  205. b_terminations=[interface2, interface3]
  206. )
  207. cable1.save()
  208. path1 = self.assertPathExists(
  209. (interface1, cable1, (interface2, interface3)),
  210. is_complete=True,
  211. is_active=True
  212. )
  213. path2 = self.assertPathExists(
  214. ((interface2, interface3), cable1, interface1),
  215. is_complete=True,
  216. is_active=True
  217. )
  218. self.assertEqual(CablePath.objects.count(), 2)
  219. interface1.refresh_from_db()
  220. interface2.refresh_from_db()
  221. interface3.refresh_from_db()
  222. self.assertPathIsSet(interface1, path1)
  223. self.assertPathIsSet(interface2, path2)
  224. self.assertPathIsSet(interface3, path2)
  225. # Test SVG generation
  226. CableTraceSVG(interface1).render()
  227. # Delete cable 1
  228. cable1.delete()
  229. # Check that all CablePaths have been deleted
  230. self.assertEqual(CablePath.objects.count(), 0)
  231. interface1.refresh_from_db()
  232. interface2.refresh_from_db()
  233. interface3.refresh_from_db()
  234. self.assertPathIsNotSet(interface1)
  235. self.assertPathIsNotSet(interface2)
  236. self.assertPathIsNotSet(interface3)
  237. def test_121_multi_interface_to_multi_interface(self):
  238. """
  239. [IF1] --C1-- [IF3]
  240. [IF2] [IF4]
  241. """
  242. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  243. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  244. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  245. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  246. # Create cable 1
  247. cable1 = Cable(
  248. a_terminations=[interface1, interface2],
  249. b_terminations=[interface3, interface4]
  250. )
  251. cable1.save()
  252. path1 = self.assertPathExists(
  253. ((interface1, interface2), cable1, (interface3, interface4)),
  254. is_complete=True,
  255. is_active=True
  256. )
  257. path2 = self.assertPathExists(
  258. ((interface3, interface4), cable1, (interface1, interface2)),
  259. is_complete=True,
  260. is_active=True
  261. )
  262. self.assertEqual(CablePath.objects.count(), 2)
  263. interface1.refresh_from_db()
  264. interface2.refresh_from_db()
  265. interface3.refresh_from_db()
  266. interface4.refresh_from_db()
  267. self.assertPathIsSet(interface1, path1)
  268. self.assertPathIsSet(interface2, path1)
  269. self.assertPathIsSet(interface3, path2)
  270. self.assertPathIsSet(interface4, path2)
  271. # Test SVG generation
  272. CableTraceSVG(interface1).render()
  273. # Delete cable 1
  274. cable1.delete()
  275. # Check that all CablePaths have been deleted
  276. self.assertEqual(CablePath.objects.count(), 0)
  277. interface1.refresh_from_db()
  278. interface2.refresh_from_db()
  279. interface3.refresh_from_db()
  280. interface4.refresh_from_db()
  281. self.assertPathIsNotSet(interface1)
  282. self.assertPathIsNotSet(interface2)
  283. self.assertPathIsNotSet(interface3)
  284. self.assertPathIsNotSet(interface4)
  285. def test_201_single_path_via_pass_through(self):
  286. """
  287. [IF1] --C1-- [FP1] [RP1] --C2-- [IF2]
  288. """
  289. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  290. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  291. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=1)
  292. frontport1 = FrontPort.objects.create(
  293. device=self.device, name='Front Port 1', rear_port=rearport1, rear_port_position=1
  294. )
  295. # Create cable 1
  296. cable1 = Cable(
  297. a_terminations=[interface1],
  298. b_terminations=[frontport1]
  299. )
  300. cable1.save()
  301. self.assertPathExists(
  302. (interface1, cable1, frontport1, rearport1),
  303. is_complete=False
  304. )
  305. self.assertEqual(CablePath.objects.count(), 1)
  306. # Create cable 2
  307. cable2 = Cable(
  308. a_terminations=[rearport1],
  309. b_terminations=[interface2]
  310. )
  311. cable2.save()
  312. self.assertPathExists(
  313. (interface1, cable1, frontport1, rearport1, cable2, interface2),
  314. is_complete=True,
  315. is_active=True
  316. )
  317. self.assertPathExists(
  318. (interface2, cable2, rearport1, frontport1, cable1, interface1),
  319. is_complete=True,
  320. is_active=True
  321. )
  322. self.assertEqual(CablePath.objects.count(), 2)
  323. # Delete cable 2
  324. cable2.delete()
  325. path1 = self.assertPathExists(
  326. (interface1, cable1, frontport1, rearport1),
  327. is_complete=False
  328. )
  329. self.assertEqual(CablePath.objects.count(), 1)
  330. interface1.refresh_from_db()
  331. interface2.refresh_from_db()
  332. self.assertPathIsSet(interface1, path1)
  333. self.assertPathIsNotSet(interface2)
  334. def test_202_single_path_via_pass_through_with_breakouts(self):
  335. """
  336. [IF1] --C1-- [FP1] [RP1] --C2-- [IF3]
  337. [IF2] [IF4]
  338. """
  339. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  340. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  341. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  342. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  343. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=1)
  344. frontport1 = FrontPort.objects.create(
  345. device=self.device, name='Front Port 1', rear_port=rearport1, rear_port_position=1
  346. )
  347. # Create cable 1
  348. cable1 = Cable(
  349. a_terminations=[interface1, interface2],
  350. b_terminations=[frontport1]
  351. )
  352. cable1.save()
  353. self.assertPathExists(
  354. ([interface1, interface2], cable1, frontport1, rearport1),
  355. is_complete=False
  356. )
  357. self.assertEqual(CablePath.objects.count(), 1)
  358. # Create cable 2
  359. cable2 = Cable(
  360. a_terminations=[rearport1],
  361. b_terminations=[interface3, interface4]
  362. )
  363. cable2.save()
  364. self.assertPathExists(
  365. ([interface1, interface2], cable1, frontport1, rearport1, cable2, [interface3, interface4]),
  366. is_complete=True,
  367. is_active=True
  368. )
  369. self.assertPathExists(
  370. ([interface3, interface4], cable2, rearport1, frontport1, cable1, [interface1, interface2]),
  371. is_complete=True,
  372. is_active=True
  373. )
  374. self.assertEqual(CablePath.objects.count(), 2)
  375. # Delete cable 2
  376. cable2.delete()
  377. path1 = self.assertPathExists(
  378. ([interface1, interface2], cable1, frontport1, rearport1),
  379. is_complete=False
  380. )
  381. self.assertEqual(CablePath.objects.count(), 1)
  382. interface1.refresh_from_db()
  383. interface2.refresh_from_db()
  384. self.assertPathIsSet(interface1, path1)
  385. self.assertPathIsSet(interface2, path1)
  386. self.assertPathIsNotSet(interface3)
  387. self.assertPathIsNotSet(interface4)
  388. def test_203_multiple_paths_via_pass_through(self):
  389. """
  390. [IF1] --C1-- [FP1:1] [RP1] --C3-- [RP2] [FP2:1] --C4-- [IF3]
  391. [IF2] --C2-- [FP1:2] [FP2:2] --C5-- [IF4]
  392. """
  393. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  394. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  395. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  396. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  397. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  398. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=4)
  399. frontport1_1 = FrontPort.objects.create(
  400. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  401. )
  402. frontport1_2 = FrontPort.objects.create(
  403. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  404. )
  405. frontport2_1 = FrontPort.objects.create(
  406. device=self.device, name='Front Port 2:1', rear_port=rearport2, rear_port_position=1
  407. )
  408. frontport2_2 = FrontPort.objects.create(
  409. device=self.device, name='Front Port 2:2', rear_port=rearport2, rear_port_position=2
  410. )
  411. # Create cables 1-2
  412. cable1 = Cable(
  413. a_terminations=[interface1],
  414. b_terminations=[frontport1_1]
  415. )
  416. cable1.save()
  417. cable2 = Cable(
  418. a_terminations=[interface2],
  419. b_terminations=[frontport1_2]
  420. )
  421. cable2.save()
  422. self.assertPathExists(
  423. (interface1, cable1, frontport1_1, rearport1),
  424. is_complete=False
  425. )
  426. self.assertPathExists(
  427. (interface2, cable2, frontport1_2, rearport1),
  428. is_complete=False
  429. )
  430. self.assertEqual(CablePath.objects.count(), 2)
  431. # Create cable 3
  432. cable3 = Cable(
  433. a_terminations=[rearport1],
  434. b_terminations=[rearport2]
  435. )
  436. cable3.save()
  437. self.assertPathExists(
  438. (interface1, cable1, frontport1_1, rearport1, cable3, rearport2, frontport2_1),
  439. is_complete=False
  440. )
  441. self.assertPathExists(
  442. (interface2, cable2, frontport1_2, rearport1, cable3, rearport2, frontport2_2),
  443. is_complete=False
  444. )
  445. self.assertEqual(CablePath.objects.count(), 2)
  446. # Create cables 4-5
  447. cable4 = Cable(
  448. a_terminations=[frontport2_1],
  449. b_terminations=[interface3]
  450. )
  451. cable4.save()
  452. cable5 = Cable(
  453. a_terminations=[frontport2_2],
  454. b_terminations=[interface4]
  455. )
  456. cable5.save()
  457. path1 = self.assertPathExists(
  458. (interface1, cable1, frontport1_1, rearport1, cable3, rearport2, frontport2_1, cable4, interface3),
  459. is_complete=True,
  460. is_active=True
  461. )
  462. path2 = self.assertPathExists(
  463. (interface2, cable2, frontport1_2, rearport1, cable3, rearport2, frontport2_2, cable5, interface4),
  464. is_complete=True,
  465. is_active=True
  466. )
  467. path3 = self.assertPathExists(
  468. (interface3, cable4, frontport2_1, rearport2, cable3, rearport1, frontport1_1, cable1, interface1),
  469. is_complete=True,
  470. is_active=True
  471. )
  472. path4 = self.assertPathExists(
  473. (interface4, cable5, frontport2_2, rearport2, cable3, rearport1, frontport1_2, cable2, interface2),
  474. is_complete=True,
  475. is_active=True
  476. )
  477. self.assertEqual(CablePath.objects.count(), 4)
  478. # Delete cable 3
  479. cable3.delete()
  480. # Check for four partial paths; one from each interface
  481. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 4)
  482. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 0)
  483. interface1.refresh_from_db()
  484. interface2.refresh_from_db()
  485. interface3.refresh_from_db()
  486. interface4.refresh_from_db()
  487. self.assertPathIsSet(interface1, path1)
  488. self.assertPathIsSet(interface2, path2)
  489. self.assertPathIsSet(interface3, path3)
  490. self.assertPathIsSet(interface4, path4)
  491. def test_204_multiple_paths_via_pass_through_with_breakouts(self):
  492. """
  493. [IF1] --C1-- [FP1:1] [RP1] --C3-- [RP2] [FP2:1] --C4-- [IF4]
  494. [IF2] [IF5]
  495. [IF3] --C2-- [FP1:2] [FP2:2] --C5-- [IF6]
  496. [IF4] [IF7]
  497. """
  498. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  499. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  500. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  501. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  502. interface5 = Interface.objects.create(device=self.device, name='Interface 5')
  503. interface6 = Interface.objects.create(device=self.device, name='Interface 6')
  504. interface7 = Interface.objects.create(device=self.device, name='Interface 7')
  505. interface8 = Interface.objects.create(device=self.device, name='Interface 8')
  506. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  507. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=4)
  508. frontport1_1 = FrontPort.objects.create(
  509. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  510. )
  511. frontport1_2 = FrontPort.objects.create(
  512. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  513. )
  514. frontport2_1 = FrontPort.objects.create(
  515. device=self.device, name='Front Port 2:1', rear_port=rearport2, rear_port_position=1
  516. )
  517. frontport2_2 = FrontPort.objects.create(
  518. device=self.device, name='Front Port 2:2', rear_port=rearport2, rear_port_position=2
  519. )
  520. # Create cables 1-2
  521. cable1 = Cable(
  522. a_terminations=[interface1, interface2],
  523. b_terminations=[frontport1_1]
  524. )
  525. cable1.save()
  526. cable2 = Cable(
  527. a_terminations=[interface3, interface4],
  528. b_terminations=[frontport1_2]
  529. )
  530. cable2.save()
  531. self.assertPathExists(
  532. ([interface1, interface2], cable1, frontport1_1, rearport1),
  533. is_complete=False
  534. )
  535. self.assertPathExists(
  536. ([interface3, interface4], cable2, frontport1_2, rearport1),
  537. is_complete=False
  538. )
  539. self.assertEqual(CablePath.objects.count(), 2)
  540. # Create cable 3
  541. cable3 = Cable(
  542. a_terminations=[rearport1],
  543. b_terminations=[rearport2]
  544. )
  545. cable3.save()
  546. self.assertPathExists(
  547. ([interface1, interface2], cable1, frontport1_1, rearport1, cable3, rearport2, frontport2_1),
  548. is_complete=False
  549. )
  550. self.assertPathExists(
  551. ([interface3, interface4], cable2, frontport1_2, rearport1, cable3, rearport2, frontport2_2),
  552. is_complete=False
  553. )
  554. self.assertEqual(CablePath.objects.count(), 2)
  555. # Create cables 4-5
  556. cable4 = Cable(
  557. a_terminations=[frontport2_1],
  558. b_terminations=[interface5, interface6]
  559. )
  560. cable4.save()
  561. cable5 = Cable(
  562. a_terminations=[frontport2_2],
  563. b_terminations=[interface7, interface8]
  564. )
  565. cable5.save()
  566. path1 = self.assertPathExists(
  567. ([interface1, interface2], cable1, frontport1_1, rearport1, cable3, rearport2, frontport2_1, cable4, [interface5, interface6]),
  568. is_complete=True,
  569. is_active=True
  570. )
  571. path2 = self.assertPathExists(
  572. ([interface3, interface4], cable2, frontport1_2, rearport1, cable3, rearport2, frontport2_2, cable5, [interface7, interface8]),
  573. is_complete=True,
  574. is_active=True
  575. )
  576. path3 = self.assertPathExists(
  577. ([interface5, interface6], cable4, frontport2_1, rearport2, cable3, rearport1, frontport1_1, cable1, [interface1, interface2]),
  578. is_complete=True,
  579. is_active=True
  580. )
  581. path4 = self.assertPathExists(
  582. ([interface7, interface8], cable5, frontport2_2, rearport2, cable3, rearport1, frontport1_2, cable2, [interface3, interface4]),
  583. is_complete=True,
  584. is_active=True
  585. )
  586. self.assertEqual(CablePath.objects.count(), 4)
  587. # Delete cable 3
  588. cable3.delete()
  589. # Check for four partial paths; one from each interface
  590. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 4)
  591. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 0)
  592. interface1.refresh_from_db()
  593. interface2.refresh_from_db()
  594. interface3.refresh_from_db()
  595. interface4.refresh_from_db()
  596. interface5.refresh_from_db()
  597. interface6.refresh_from_db()
  598. interface7.refresh_from_db()
  599. interface8.refresh_from_db()
  600. self.assertPathIsSet(interface1, path1)
  601. self.assertPathIsSet(interface2, path1)
  602. self.assertPathIsSet(interface3, path2)
  603. self.assertPathIsSet(interface4, path2)
  604. self.assertPathIsSet(interface5, path3)
  605. self.assertPathIsSet(interface6, path3)
  606. self.assertPathIsSet(interface7, path4)
  607. self.assertPathIsSet(interface8, path4)
  608. def test_205_multiple_paths_via_nested_pass_throughs(self):
  609. """
  610. [IF1] --C1-- [FP1:1] [RP1] --C3-- [FP2] [RP2] --C4-- [RP3] [FP3] --C5-- [RP4] [FP4:1] --C6-- [IF3]
  611. [IF2] --C2-- [FP1:2] [FP4:2] --C7-- [IF4]
  612. """
  613. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  614. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  615. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  616. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  617. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  618. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=1)
  619. rearport3 = RearPort.objects.create(device=self.device, name='Rear Port 3', positions=1)
  620. rearport4 = RearPort.objects.create(device=self.device, name='Rear Port 4', positions=4)
  621. frontport1_1 = FrontPort.objects.create(
  622. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  623. )
  624. frontport1_2 = FrontPort.objects.create(
  625. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  626. )
  627. frontport2 = FrontPort.objects.create(
  628. device=self.device, name='Front Port 2', rear_port=rearport2, rear_port_position=1
  629. )
  630. frontport3 = FrontPort.objects.create(
  631. device=self.device, name='Front Port 3', rear_port=rearport3, rear_port_position=1
  632. )
  633. frontport4_1 = FrontPort.objects.create(
  634. device=self.device, name='Front Port 4:1', rear_port=rearport4, rear_port_position=1
  635. )
  636. frontport4_2 = FrontPort.objects.create(
  637. device=self.device, name='Front Port 4:2', rear_port=rearport4, rear_port_position=2
  638. )
  639. # Create cables 1-2, 6-7
  640. cable1 = Cable(
  641. a_terminations=[interface1],
  642. b_terminations=[frontport1_1]
  643. )
  644. cable1.save()
  645. cable2 = Cable(
  646. a_terminations=[interface2],
  647. b_terminations=[frontport1_2]
  648. )
  649. cable2.save()
  650. cable6 = Cable(
  651. a_terminations=[interface3],
  652. b_terminations=[frontport4_1]
  653. )
  654. cable6.save()
  655. cable7 = Cable(
  656. a_terminations=[interface4],
  657. b_terminations=[frontport4_2]
  658. )
  659. cable7.save()
  660. self.assertEqual(CablePath.objects.count(), 4) # Four partial paths; one from each interface
  661. # Create cables 3 and 5
  662. cable3 = Cable(
  663. a_terminations=[rearport1],
  664. b_terminations=[frontport2]
  665. )
  666. cable3.save()
  667. cable5 = Cable(
  668. a_terminations=[rearport4],
  669. b_terminations=[frontport3]
  670. )
  671. cable5.save()
  672. self.assertEqual(CablePath.objects.count(), 4) # Four (longer) partial paths; one from each interface
  673. # Create cable 4
  674. cable4 = Cable(
  675. a_terminations=[rearport2],
  676. b_terminations=[rearport3]
  677. )
  678. cable4.save()
  679. self.assertPathExists(
  680. (
  681. interface1, cable1, frontport1_1, rearport1, cable3, frontport2, rearport2, cable4, rearport3,
  682. frontport3, cable5, rearport4, frontport4_1, cable6, interface3,
  683. ),
  684. is_complete=True,
  685. is_active=True
  686. )
  687. self.assertPathExists(
  688. (
  689. interface2, cable2, frontport1_2, rearport1, cable3, frontport2, rearport2, cable4, rearport3,
  690. frontport3, cable5, rearport4, frontport4_2, cable7, interface4,
  691. ),
  692. is_complete=True,
  693. is_active=True
  694. )
  695. self.assertPathExists(
  696. (
  697. interface3, cable6, frontport4_1, rearport4, cable5, frontport3, rearport3, cable4, rearport2,
  698. frontport2, cable3, rearport1, frontport1_1, cable1, interface1,
  699. ),
  700. is_complete=True,
  701. is_active=True
  702. )
  703. self.assertPathExists(
  704. (
  705. interface4, cable7, frontport4_2, rearport4, cable5, frontport3, rearport3, cable4, rearport2,
  706. frontport2, cable3, rearport1, frontport1_2, cable2, interface2,
  707. ),
  708. is_complete=True,
  709. is_active=True
  710. )
  711. self.assertEqual(CablePath.objects.count(), 4)
  712. # Delete cable 3
  713. cable3.delete()
  714. # Check for four partial paths; one from each interface
  715. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 4)
  716. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 0)
  717. def test_206_multiple_paths_via_multiple_pass_throughs(self):
  718. """
  719. [IF1] --C1-- [FP1:1] [RP1] --C3-- [RP2] [FP2:1] --C4-- [FP3:1] [RP3] --C6-- [RP4] [FP4:1] --C7-- [IF3]
  720. [IF2] --C2-- [FP1:2] [FP2:1] --C5-- [FP3:1] [FP4:2] --C8-- [IF4]
  721. """
  722. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  723. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  724. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  725. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  726. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  727. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=4)
  728. rearport3 = RearPort.objects.create(device=self.device, name='Rear Port 3', positions=4)
  729. rearport4 = RearPort.objects.create(device=self.device, name='Rear Port 4', positions=4)
  730. frontport1_1 = FrontPort.objects.create(
  731. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  732. )
  733. frontport1_2 = FrontPort.objects.create(
  734. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  735. )
  736. frontport2_1 = FrontPort.objects.create(
  737. device=self.device, name='Front Port 2:1', rear_port=rearport2, rear_port_position=1
  738. )
  739. frontport2_2 = FrontPort.objects.create(
  740. device=self.device, name='Front Port 2:2', rear_port=rearport2, rear_port_position=2
  741. )
  742. frontport3_1 = FrontPort.objects.create(
  743. device=self.device, name='Front Port 3:1', rear_port=rearport3, rear_port_position=1
  744. )
  745. frontport3_2 = FrontPort.objects.create(
  746. device=self.device, name='Front Port 3:2', rear_port=rearport3, rear_port_position=2
  747. )
  748. frontport4_1 = FrontPort.objects.create(
  749. device=self.device, name='Front Port 4:1', rear_port=rearport4, rear_port_position=1
  750. )
  751. frontport4_2 = FrontPort.objects.create(
  752. device=self.device, name='Front Port 4:2', rear_port=rearport4, rear_port_position=2
  753. )
  754. # Create cables 1-3, 6-8
  755. cable1 = Cable(
  756. a_terminations=[interface1],
  757. b_terminations=[frontport1_1]
  758. )
  759. cable1.save()
  760. cable2 = Cable(
  761. a_terminations=[interface2],
  762. b_terminations=[frontport1_2]
  763. )
  764. cable2.save()
  765. cable3 = Cable(
  766. a_terminations=[rearport1],
  767. b_terminations=[rearport2]
  768. )
  769. cable3.save()
  770. cable6 = Cable(
  771. a_terminations=[rearport3],
  772. b_terminations=[rearport4]
  773. )
  774. cable6.save()
  775. cable7 = Cable(
  776. a_terminations=[interface3],
  777. b_terminations=[frontport4_1]
  778. )
  779. cable7.save()
  780. cable8 = Cable(
  781. a_terminations=[interface4],
  782. b_terminations=[frontport4_2]
  783. )
  784. cable8.save()
  785. self.assertEqual(CablePath.objects.count(), 4) # Four partial paths; one from each interface
  786. # Create cables 4 and 5
  787. cable4 = Cable(
  788. a_terminations=[frontport2_1],
  789. b_terminations=[frontport3_1]
  790. )
  791. cable4.save()
  792. cable5 = Cable(
  793. a_terminations=[frontport2_2],
  794. b_terminations=[frontport3_2]
  795. )
  796. cable5.save()
  797. self.assertPathExists(
  798. (
  799. interface1, cable1, frontport1_1, rearport1, cable3, rearport2, frontport2_1,
  800. cable4, frontport3_1, rearport3, cable6, rearport4, frontport4_1,
  801. cable7, interface3,
  802. ),
  803. is_complete=True,
  804. is_active=True
  805. )
  806. self.assertPathExists(
  807. (
  808. interface2, cable2, frontport1_2, rearport1, cable3, rearport2, frontport2_2,
  809. cable5, frontport3_2, rearport3, cable6, rearport4, frontport4_2,
  810. cable8, interface4,
  811. ),
  812. is_complete=True,
  813. is_active=True
  814. )
  815. self.assertPathExists(
  816. (
  817. interface3, cable7, frontport4_1, rearport4, cable6, rearport3, frontport3_1,
  818. cable4, frontport2_1, rearport2, cable3, rearport1, frontport1_1,
  819. cable1, interface1,
  820. ),
  821. is_complete=True,
  822. is_active=True
  823. )
  824. self.assertPathExists(
  825. (
  826. interface4, cable8, frontport4_2, rearport4, cable6, rearport3, frontport3_2,
  827. cable5, frontport2_2, rearport2, cable3, rearport1, frontport1_2,
  828. cable2, interface2,
  829. ),
  830. is_complete=True,
  831. is_active=True
  832. )
  833. self.assertEqual(CablePath.objects.count(), 4)
  834. # Delete cable 5
  835. cable5.delete()
  836. # Check for two complete paths (IF1 <--> IF2) and two partial (IF3 <--> IF4)
  837. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 2)
  838. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 2)
  839. def test_207_multiple_paths_via_patched_pass_throughs(self):
  840. """
  841. [IF1] --C1-- [FP1:1] [RP1] --C3-- [FP2] [RP2] --C4-- [RP3] [FP3:1] --C5-- [IF3]
  842. [IF2] --C2-- [FP1:2] [FP3:2] --C6-- [IF4]
  843. """
  844. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  845. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  846. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  847. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  848. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  849. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 5', positions=1)
  850. rearport3 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=4)
  851. frontport1_1 = FrontPort.objects.create(
  852. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  853. )
  854. frontport1_2 = FrontPort.objects.create(
  855. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  856. )
  857. frontport2 = FrontPort.objects.create(
  858. device=self.device, name='Front Port 5', rear_port=rearport2, rear_port_position=1
  859. )
  860. frontport3_1 = FrontPort.objects.create(
  861. device=self.device, name='Front Port 2:1', rear_port=rearport3, rear_port_position=1
  862. )
  863. frontport3_2 = FrontPort.objects.create(
  864. device=self.device, name='Front Port 2:2', rear_port=rearport3, rear_port_position=2
  865. )
  866. # Create cables 1-2, 5-6
  867. cable1 = Cable(
  868. a_terminations=[interface1],
  869. b_terminations=[frontport1_1]
  870. )
  871. cable1.save()
  872. cable2 = Cable(
  873. a_terminations=[interface2],
  874. b_terminations=[frontport1_2]
  875. )
  876. cable2.save()
  877. cable5 = Cable(
  878. a_terminations=[interface3],
  879. b_terminations=[frontport3_1]
  880. )
  881. cable5.save()
  882. cable6 = Cable(
  883. a_terminations=[interface4],
  884. b_terminations=[frontport3_2]
  885. )
  886. cable6.save()
  887. self.assertEqual(CablePath.objects.count(), 4) # Four partial paths; one from each interface
  888. # Create cables 3-4
  889. cable3 = Cable(
  890. a_terminations=[rearport1],
  891. b_terminations=[frontport2]
  892. )
  893. cable3.save()
  894. cable4 = Cable(
  895. a_terminations=[rearport2],
  896. b_terminations=[rearport3]
  897. )
  898. cable4.save()
  899. self.assertPathExists(
  900. (
  901. interface1, cable1, frontport1_1, rearport1, cable3, frontport2, rearport2,
  902. cable4, rearport3, frontport3_1, cable5, interface3,
  903. ),
  904. is_complete=True,
  905. is_active=True
  906. )
  907. self.assertPathExists(
  908. (
  909. interface2, cable2, frontport1_2, rearport1, cable3, frontport2, rearport2,
  910. cable4, rearport3, frontport3_2, cable6, interface4,
  911. ),
  912. is_complete=True,
  913. is_active=True
  914. )
  915. self.assertPathExists(
  916. (
  917. interface3, cable5, frontport3_1, rearport3, cable4, rearport2, frontport2,
  918. cable3, rearport1, frontport1_1, cable1, interface1,
  919. ),
  920. is_complete=True,
  921. is_active=True
  922. )
  923. self.assertPathExists(
  924. (
  925. interface4, cable6, frontport3_2, rearport3, cable4, rearport2, frontport2,
  926. cable3, rearport1, frontport1_2, cable2, interface2,
  927. ),
  928. is_complete=True,
  929. is_active=True
  930. )
  931. self.assertEqual(CablePath.objects.count(), 4)
  932. # Delete cable 3
  933. cable3.delete()
  934. # Check for four partial paths; one from each interface
  935. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 4)
  936. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 0)
  937. def test_208_unidirectional_split_paths(self):
  938. """
  939. [IF1] --C1-- [RP1] [FP1:1] --C2-- [IF2]
  940. [FP1:2] --C3-- [IF3]
  941. """
  942. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  943. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  944. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  945. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  946. frontport1_1 = FrontPort.objects.create(
  947. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  948. )
  949. frontport1_2 = FrontPort.objects.create(
  950. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  951. )
  952. # Create cables 1
  953. cable1 = Cable(
  954. a_terminations=[interface1],
  955. b_terminations=[rearport1]
  956. )
  957. cable1.save()
  958. self.assertPathExists(
  959. (interface1, cable1, rearport1),
  960. is_complete=False,
  961. is_split=True
  962. )
  963. self.assertEqual(CablePath.objects.count(), 1)
  964. # Create cables 2-3
  965. cable2 = Cable(
  966. a_terminations=[interface2],
  967. b_terminations=[frontport1_1]
  968. )
  969. cable2.save()
  970. cable3 = Cable(
  971. a_terminations=[interface3],
  972. b_terminations=[frontport1_2]
  973. )
  974. cable3.save()
  975. self.assertPathExists(
  976. (interface2, cable2, frontport1_1, rearport1, cable1, interface1),
  977. is_complete=True,
  978. is_active=True
  979. )
  980. self.assertPathExists(
  981. (interface3, cable3, frontport1_2, rearport1, cable1, interface1),
  982. is_complete=True,
  983. is_active=True
  984. )
  985. self.assertEqual(CablePath.objects.count(), 3)
  986. # Delete cable 1
  987. cable1.delete()
  988. # Check that the partial path was deleted and the two complete paths are now partial
  989. self.assertPathExists(
  990. (interface2, cable2, frontport1_1, rearport1),
  991. is_complete=False
  992. )
  993. self.assertPathExists(
  994. (interface3, cable3, frontport1_2, rearport1),
  995. is_complete=False
  996. )
  997. self.assertEqual(CablePath.objects.count(), 2)
  998. def test_209_rearport_without_frontport(self):
  999. """
  1000. [IF1] --C1-- [FP1] [RP1] --C2-- [RP2]
  1001. """
  1002. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1003. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=1)
  1004. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=1)
  1005. frontport1 = FrontPort.objects.create(
  1006. device=self.device, name='Front Port 1', rear_port=rearport1, rear_port_position=1
  1007. )
  1008. # Create cables
  1009. cable1 = Cable(
  1010. a_terminations=[interface1],
  1011. b_terminations=[frontport1]
  1012. )
  1013. cable1.save()
  1014. cable2 = Cable(
  1015. a_terminations=[rearport1],
  1016. b_terminations=[rearport2]
  1017. )
  1018. cable2.save()
  1019. self.assertPathExists(
  1020. (interface1, cable1, frontport1, rearport1, cable2, rearport2),
  1021. is_complete=False
  1022. )
  1023. self.assertEqual(CablePath.objects.count(), 1)
  1024. def test_210_interface_to_circuittermination(self):
  1025. """
  1026. [IF1] --C1-- [CT1]
  1027. """
  1028. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1029. circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='A')
  1030. # Create cable 1
  1031. cable1 = Cable(
  1032. a_terminations=[interface1],
  1033. b_terminations=[circuittermination1]
  1034. )
  1035. cable1.save()
  1036. # Check for incomplete path
  1037. self.assertPathExists(
  1038. (interface1, cable1, circuittermination1),
  1039. is_complete=False
  1040. )
  1041. self.assertEqual(CablePath.objects.count(), 1)
  1042. # Delete cable 1
  1043. cable1.delete()
  1044. self.assertEqual(CablePath.objects.count(), 0)
  1045. interface1.refresh_from_db()
  1046. self.assertPathIsNotSet(interface1)
  1047. def test_211_interface_to_interface_via_circuit(self):
  1048. """
  1049. [IF1] --C1-- [CT1] [CT2] --C2-- [IF2]
  1050. """
  1051. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1052. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1053. circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='A')
  1054. # Create cable 1
  1055. cable1 = Cable(
  1056. a_terminations=[interface1],
  1057. b_terminations=[circuittermination1]
  1058. )
  1059. cable1.save()
  1060. # Check for partial path from interface1
  1061. self.assertPathExists(
  1062. (interface1, cable1, circuittermination1),
  1063. is_complete=False
  1064. )
  1065. # Create CT2
  1066. circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='Z')
  1067. # Check for partial path to site
  1068. self.assertPathExists(
  1069. (interface1, cable1, circuittermination1, circuittermination2, self.site),
  1070. is_active=True
  1071. )
  1072. # Create cable 2
  1073. cable2 = Cable(
  1074. a_terminations=[circuittermination2],
  1075. b_terminations=[interface2]
  1076. )
  1077. cable2.save()
  1078. # Check for complete path in each direction
  1079. self.assertPathExists(
  1080. (interface1, cable1, circuittermination1, circuittermination2, cable2, interface2),
  1081. is_complete=True,
  1082. is_active=True
  1083. )
  1084. self.assertPathExists(
  1085. (interface2, cable2, circuittermination2, circuittermination1, cable1, interface1),
  1086. is_complete=True,
  1087. is_active=True
  1088. )
  1089. self.assertEqual(CablePath.objects.count(), 2)
  1090. # Delete cable 2
  1091. cable2.delete()
  1092. path1 = self.assertPathExists(
  1093. (interface1, cable1, circuittermination1, circuittermination2, self.site),
  1094. is_active=True
  1095. )
  1096. self.assertEqual(CablePath.objects.count(), 1)
  1097. interface1.refresh_from_db()
  1098. interface2.refresh_from_db()
  1099. self.assertPathIsSet(interface1, path1)
  1100. self.assertPathIsNotSet(interface2)
  1101. def test_212_interface_to_interface_via_circuit_with_breakouts(self):
  1102. """
  1103. [IF1] --C1-- [CT1] [CT2] --C2-- [IF3]
  1104. [IF2] [IF4]
  1105. """
  1106. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1107. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1108. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  1109. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  1110. circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='A')
  1111. # Create cable 1
  1112. cable1 = Cable(
  1113. a_terminations=[interface1, interface2],
  1114. b_terminations=[circuittermination1]
  1115. )
  1116. cable1.save()
  1117. # Check for partial path from interface1
  1118. self.assertPathExists(
  1119. ([interface1, interface2], cable1, circuittermination1),
  1120. is_complete=False
  1121. )
  1122. # Create CT2
  1123. circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='Z')
  1124. # Check for partial path to site
  1125. self.assertPathExists(
  1126. ([interface1, interface2], cable1, circuittermination1, circuittermination2, self.site),
  1127. is_active=True
  1128. )
  1129. # Create cable 2
  1130. cable2 = Cable(
  1131. a_terminations=[circuittermination2],
  1132. b_terminations=[interface3, interface4]
  1133. )
  1134. cable2.save()
  1135. # Check for complete path in each direction
  1136. self.assertPathExists(
  1137. ([interface1, interface2], cable1, circuittermination1, circuittermination2, cable2, [interface3, interface4]),
  1138. is_complete=True,
  1139. is_active=True
  1140. )
  1141. self.assertPathExists(
  1142. ([interface3, interface4], cable2, circuittermination2, circuittermination1, cable1, [interface1, interface2]),
  1143. is_complete=True,
  1144. is_active=True
  1145. )
  1146. self.assertEqual(CablePath.objects.count(), 2)
  1147. # Delete cable 2
  1148. cable2.delete()
  1149. path1 = self.assertPathExists(
  1150. ([interface1, interface2], cable1, circuittermination1, circuittermination2, self.site),
  1151. is_active=True
  1152. )
  1153. self.assertEqual(CablePath.objects.count(), 1)
  1154. interface1.refresh_from_db()
  1155. interface2.refresh_from_db()
  1156. interface3.refresh_from_db()
  1157. interface4.refresh_from_db()
  1158. self.assertPathIsSet(interface1, path1)
  1159. self.assertPathIsSet(interface2, path1)
  1160. self.assertPathIsNotSet(interface3)
  1161. self.assertPathIsNotSet(interface4)
  1162. def test_213_interface_to_site_via_circuit(self):
  1163. """
  1164. [IF1] --C1-- [CT1] [CT2] --> [Site2]
  1165. """
  1166. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1167. site2 = Site.objects.create(name='Site 2', slug='site-2')
  1168. circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='A')
  1169. circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, site=site2, term_side='Z')
  1170. # Create cable 1
  1171. cable1 = Cable(
  1172. a_terminations=[interface1],
  1173. b_terminations=[circuittermination1]
  1174. )
  1175. cable1.save()
  1176. self.assertPathExists(
  1177. (interface1, cable1, circuittermination1, circuittermination2, site2),
  1178. is_active=True
  1179. )
  1180. self.assertEqual(CablePath.objects.count(), 1)
  1181. # Delete cable 1
  1182. cable1.delete()
  1183. self.assertEqual(CablePath.objects.count(), 0)
  1184. interface1.refresh_from_db()
  1185. self.assertPathIsNotSet(interface1)
  1186. def test_214_interface_to_providernetwork_via_circuit(self):
  1187. """
  1188. [IF1] --C1-- [CT1] [CT2] --> [PN1]
  1189. """
  1190. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1191. providernetwork = ProviderNetwork.objects.create(name='Provider Network 1', provider=self.circuit.provider)
  1192. circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='A')
  1193. circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, provider_network=providernetwork, term_side='Z')
  1194. # Create cable 1
  1195. cable1 = Cable(
  1196. a_terminations=[interface1],
  1197. b_terminations=[circuittermination1]
  1198. )
  1199. cable1.save()
  1200. self.assertPathExists(
  1201. (interface1, cable1, circuittermination1, circuittermination2, providernetwork),
  1202. is_active=True
  1203. )
  1204. self.assertEqual(CablePath.objects.count(), 1)
  1205. self.assertTrue(CablePath.objects.first().is_complete)
  1206. # Delete cable 1
  1207. cable1.delete()
  1208. self.assertEqual(CablePath.objects.count(), 0)
  1209. interface1.refresh_from_db()
  1210. self.assertPathIsNotSet(interface1)
  1211. def test_215_multiple_paths_via_circuit(self):
  1212. """
  1213. [IF1] --C1-- [FP1:1] [RP1] --C3-- [CT1] [CT2] --C4-- [RP2] [FP2:1] --C5-- [IF3]
  1214. [IF2] --C2-- [FP1:2] [FP2:2] --C6-- [IF4]
  1215. """
  1216. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1217. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1218. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  1219. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  1220. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  1221. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=4)
  1222. frontport1_1 = FrontPort.objects.create(
  1223. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  1224. )
  1225. frontport1_2 = FrontPort.objects.create(
  1226. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  1227. )
  1228. frontport2_1 = FrontPort.objects.create(
  1229. device=self.device, name='Front Port 2:1', rear_port=rearport2, rear_port_position=1
  1230. )
  1231. frontport2_2 = FrontPort.objects.create(
  1232. device=self.device, name='Front Port 2:2', rear_port=rearport2, rear_port_position=2
  1233. )
  1234. circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='A')
  1235. circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='Z')
  1236. # Create cables
  1237. cable1 = Cable(
  1238. a_terminations=[interface1],
  1239. b_terminations=[frontport1_1]
  1240. )
  1241. cable1.save()
  1242. cable2 = Cable(
  1243. a_terminations=[interface2],
  1244. b_terminations=[frontport1_2]
  1245. )
  1246. cable2.save()
  1247. cable3 = Cable(
  1248. a_terminations=[rearport1],
  1249. b_terminations=[circuittermination1]
  1250. )
  1251. cable3.save()
  1252. cable4 = Cable(
  1253. a_terminations=[rearport2],
  1254. b_terminations=[circuittermination2]
  1255. )
  1256. cable4.save()
  1257. cable5 = Cable(
  1258. a_terminations=[interface3],
  1259. b_terminations=[frontport2_1]
  1260. )
  1261. cable5.save()
  1262. cable6 = Cable(
  1263. a_terminations=[interface4],
  1264. b_terminations=[frontport2_2]
  1265. )
  1266. cable6.save()
  1267. self.assertPathExists(
  1268. (
  1269. interface1, cable1, frontport1_1, rearport1, cable3, circuittermination1, circuittermination2,
  1270. cable4, rearport2, frontport2_1, cable5, interface3,
  1271. ),
  1272. is_complete=True,
  1273. is_active=True
  1274. )
  1275. self.assertPathExists(
  1276. (
  1277. interface2, cable2, frontport1_2, rearport1, cable3, circuittermination1, circuittermination2,
  1278. cable4, rearport2, frontport2_2, cable6, interface4,
  1279. ),
  1280. is_complete=True,
  1281. is_active=True
  1282. )
  1283. self.assertPathExists(
  1284. (
  1285. interface3, cable5, frontport2_1, rearport2, cable4, circuittermination2, circuittermination1,
  1286. cable3, rearport1, frontport1_1, cable1, interface1,
  1287. ),
  1288. is_complete=True,
  1289. is_active=True
  1290. )
  1291. self.assertPathExists(
  1292. (
  1293. interface4, cable6, frontport2_2, rearport2, cable4, circuittermination2, circuittermination1,
  1294. cable3, rearport1, frontport1_2, cable2, interface2,
  1295. ),
  1296. is_complete=True,
  1297. is_active=True
  1298. )
  1299. self.assertEqual(CablePath.objects.count(), 4)
  1300. # Delete cables 3-4
  1301. cable3.delete()
  1302. cable4.delete()
  1303. # Check for four partial paths; one from each interface
  1304. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 4)
  1305. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 0)
  1306. def test_216_interface_to_interface_via_multiple_circuits(self):
  1307. """
  1308. [IF1] --C1-- [CT1] [CT2] --C2-- [CT3] [CT4] --C3-- [IF2]
  1309. """
  1310. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1311. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1312. circuit2 = Circuit.objects.create(provider=self.circuit.provider, type=self.circuit.type, cid='Circuit 2')
  1313. circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='A')
  1314. circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, site=self.site, term_side='Z')
  1315. circuittermination3 = CircuitTermination.objects.create(circuit=circuit2, site=self.site, term_side='A')
  1316. circuittermination4 = CircuitTermination.objects.create(circuit=circuit2, site=self.site, term_side='Z')
  1317. # Create cables
  1318. cable1 = Cable(
  1319. a_terminations=[interface1],
  1320. b_terminations=[circuittermination1]
  1321. )
  1322. cable1.save()
  1323. cable2 = Cable(
  1324. a_terminations=[circuittermination2],
  1325. b_terminations=[circuittermination3]
  1326. )
  1327. cable2.save()
  1328. cable3 = Cable(
  1329. a_terminations=[circuittermination4],
  1330. b_terminations=[interface2]
  1331. )
  1332. cable3.save()
  1333. # Check for paths
  1334. self.assertPathExists(
  1335. (
  1336. interface1, cable1, circuittermination1, circuittermination2, cable2, circuittermination3,
  1337. circuittermination4, cable3, interface2,
  1338. ),
  1339. is_complete=True,
  1340. is_active=True
  1341. )
  1342. self.assertPathExists(
  1343. (
  1344. interface2, cable3, circuittermination4, circuittermination3, cable2, circuittermination2,
  1345. circuittermination1, cable1, interface1,
  1346. ),
  1347. is_complete=True,
  1348. is_active=True
  1349. )
  1350. self.assertEqual(CablePath.objects.count(), 2)
  1351. # Delete cable 2
  1352. cable2.delete()
  1353. path1 = self.assertPathExists(
  1354. (interface1, cable1, circuittermination1, circuittermination2, self.site),
  1355. is_active=True
  1356. )
  1357. path2 = self.assertPathExists(
  1358. (interface2, cable3, circuittermination4, circuittermination3, self.site),
  1359. is_active=True
  1360. )
  1361. self.assertEqual(CablePath.objects.count(), 2)
  1362. interface1.refresh_from_db()
  1363. interface2.refresh_from_db()
  1364. self.assertPathIsSet(interface1, path1)
  1365. self.assertPathIsSet(interface2, path2)
  1366. def test_217_interface_to_interface_via_rear_ports(self):
  1367. """
  1368. [IF1] --C1-- [FP1] [RP1] --C2-- [RP3] [FP3] --C3-- [IF2]
  1369. [FP2] [RP2] [RP4] [FP4]
  1370. """
  1371. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1372. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1373. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=1)
  1374. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=1)
  1375. rearport3 = RearPort.objects.create(device=self.device, name='Rear Port 3', positions=1)
  1376. rearport4 = RearPort.objects.create(device=self.device, name='Rear Port 4', positions=1)
  1377. frontport1 = FrontPort.objects.create(
  1378. device=self.device, name='Front Port 1', rear_port=rearport1, rear_port_position=1
  1379. )
  1380. frontport2 = FrontPort.objects.create(
  1381. device=self.device, name='Front Port 2', rear_port=rearport2, rear_port_position=1
  1382. )
  1383. frontport3 = FrontPort.objects.create(
  1384. device=self.device, name='Front Port 3', rear_port=rearport3, rear_port_position=1
  1385. )
  1386. frontport4 = FrontPort.objects.create(
  1387. device=self.device, name='Front Port 4', rear_port=rearport4, rear_port_position=1
  1388. )
  1389. # Create cables 1-2
  1390. cable1 = Cable(
  1391. a_terminations=[interface1],
  1392. b_terminations=[frontport1, frontport2]
  1393. )
  1394. cable1.save()
  1395. cable3 = Cable(
  1396. a_terminations=[interface2],
  1397. b_terminations=[frontport3, frontport4]
  1398. )
  1399. cable3.save()
  1400. self.assertPathExists(
  1401. (interface1, cable1, (frontport1, frontport2), (rearport1, rearport2)),
  1402. is_complete=False
  1403. )
  1404. self.assertPathExists(
  1405. (interface2, cable3, (frontport3, frontport4), (rearport3, rearport4)),
  1406. is_complete=False
  1407. )
  1408. self.assertEqual(CablePath.objects.count(), 2)
  1409. # Create cable 2
  1410. cable2 = Cable(
  1411. a_terminations=[rearport1, rearport2],
  1412. b_terminations=[rearport3, rearport4]
  1413. )
  1414. cable2.save()
  1415. path1 = self.assertPathExists(
  1416. (
  1417. interface1, cable1, (frontport1, frontport2), (rearport1, rearport2), cable2,
  1418. (rearport3, rearport4), (frontport3, frontport4), cable3, interface2
  1419. ),
  1420. is_complete=True
  1421. )
  1422. path2 = self.assertPathExists(
  1423. (
  1424. interface2, cable3, (frontport3, frontport4), (rearport3, rearport4), cable2,
  1425. (rearport1, rearport2), (frontport1, frontport2), cable1, interface1
  1426. ),
  1427. is_complete=True
  1428. )
  1429. self.assertEqual(CablePath.objects.count(), 2)
  1430. # Delete cable 2
  1431. cable2.delete()
  1432. # Check for two partial paths; one from each interface
  1433. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 2)
  1434. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 0)
  1435. interface1.refresh_from_db()
  1436. interface2.refresh_from_db()
  1437. self.assertPathIsSet(interface1, path1)
  1438. self.assertPathIsSet(interface2, path2)
  1439. def test_218_interfaces_to_interfaces_via_multiposition_rear_ports(self):
  1440. """
  1441. [IF1] --C1-- [FP1:1] [RP1] --C3-- [RP2] [FP2:1] --C4-- [IF3]
  1442. [FP1:2] [FP2:2]
  1443. [IF2] --C2-- [FP1:3] [FP2:3] --C5-- [IF4]
  1444. [FP1:4] [FP2:4]
  1445. """
  1446. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1447. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1448. interface3 = Interface.objects.create(device=self.device, name='Interface 3')
  1449. interface4 = Interface.objects.create(device=self.device, name='Interface 4')
  1450. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=4)
  1451. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=4)
  1452. frontport1_1 = FrontPort.objects.create(
  1453. device=self.device, name='Front Port 1:1', rear_port=rearport1, rear_port_position=1
  1454. )
  1455. frontport1_2 = FrontPort.objects.create(
  1456. device=self.device, name='Front Port 1:2', rear_port=rearport1, rear_port_position=2
  1457. )
  1458. frontport1_3 = FrontPort.objects.create(
  1459. device=self.device, name='Front Port 1:3', rear_port=rearport1, rear_port_position=3
  1460. )
  1461. frontport1_4 = FrontPort.objects.create(
  1462. device=self.device, name='Front Port 1:4', rear_port=rearport1, rear_port_position=4
  1463. )
  1464. frontport2_1 = FrontPort.objects.create(
  1465. device=self.device, name='Front Port 2:1', rear_port=rearport2, rear_port_position=1
  1466. )
  1467. frontport2_2 = FrontPort.objects.create(
  1468. device=self.device, name='Front Port 2:2', rear_port=rearport2, rear_port_position=2
  1469. )
  1470. frontport2_3 = FrontPort.objects.create(
  1471. device=self.device, name='Front Port 2:3', rear_port=rearport2, rear_port_position=3
  1472. )
  1473. frontport2_4 = FrontPort.objects.create(
  1474. device=self.device, name='Front Port 2:4', rear_port=rearport2, rear_port_position=4
  1475. )
  1476. # Create cables 1-2
  1477. cable1 = Cable(
  1478. a_terminations=[interface1],
  1479. b_terminations=[frontport1_1, frontport1_2]
  1480. )
  1481. cable1.save()
  1482. cable2 = Cable(
  1483. a_terminations=[interface2],
  1484. b_terminations=[frontport1_3, frontport1_4]
  1485. )
  1486. cable2.save()
  1487. self.assertPathExists(
  1488. (interface1, cable1, (frontport1_1, frontport1_2), rearport1),
  1489. is_complete=False
  1490. )
  1491. self.assertPathExists(
  1492. (interface2, cable2, (frontport1_3, frontport1_4), rearport1),
  1493. is_complete=False
  1494. )
  1495. self.assertEqual(CablePath.objects.count(), 2)
  1496. # Create cable 3
  1497. cable3 = Cable(
  1498. a_terminations=[rearport1],
  1499. b_terminations=[rearport2]
  1500. )
  1501. cable3.save()
  1502. self.assertPathExists(
  1503. (interface1, cable1, (frontport1_1, frontport1_2), rearport1, cable3, rearport2, (frontport2_1, frontport2_2)),
  1504. is_complete=False
  1505. )
  1506. self.assertPathExists(
  1507. (interface2, cable2, (frontport1_3, frontport1_4), rearport1, cable3, rearport2, (frontport2_3, frontport2_4)),
  1508. is_complete=False
  1509. )
  1510. self.assertEqual(CablePath.objects.count(), 2)
  1511. # Create cables 4-5
  1512. cable4 = Cable(
  1513. a_terminations=[frontport2_1, frontport2_2],
  1514. b_terminations=[interface3]
  1515. )
  1516. cable4.save()
  1517. cable5 = Cable(
  1518. a_terminations=[frontport2_3, frontport2_4],
  1519. b_terminations=[interface4]
  1520. )
  1521. cable5.save()
  1522. path1 = self.assertPathExists(
  1523. (interface1, cable1, (frontport1_1, frontport1_2), rearport1, cable3, rearport2, (frontport2_1, frontport2_2), cable4, interface3),
  1524. is_complete=True,
  1525. is_active=True
  1526. )
  1527. path2 = self.assertPathExists(
  1528. (interface2, cable2, (frontport1_3, frontport1_4), rearport1, cable3, rearport2, (frontport2_3, frontport2_4), cable5, interface4),
  1529. is_complete=True,
  1530. is_active=True
  1531. )
  1532. path3 = self.assertPathExists(
  1533. (interface3, cable4, (frontport2_1, frontport2_2), rearport2, cable3, rearport1, (frontport1_1, frontport1_2), cable1, interface1),
  1534. is_complete=True,
  1535. is_active=True
  1536. )
  1537. path4 = self.assertPathExists(
  1538. (interface4, cable5, (frontport2_3, frontport2_4), rearport2, cable3, rearport1, (frontport1_3, frontport1_4), cable2, interface2),
  1539. is_complete=True,
  1540. is_active=True
  1541. )
  1542. self.assertEqual(CablePath.objects.count(), 4)
  1543. # Delete cable 3
  1544. cable3.delete()
  1545. # Check for four partial paths; one from each interface
  1546. self.assertEqual(CablePath.objects.filter(is_complete=False).count(), 4)
  1547. self.assertEqual(CablePath.objects.filter(is_complete=True).count(), 0)
  1548. interface1.refresh_from_db()
  1549. interface2.refresh_from_db()
  1550. interface3.refresh_from_db()
  1551. interface4.refresh_from_db()
  1552. self.assertPathIsSet(interface1, path1)
  1553. self.assertPathIsSet(interface2, path2)
  1554. self.assertPathIsSet(interface3, path3)
  1555. self.assertPathIsSet(interface4, path4)
  1556. def test_301_create_path_via_existing_cable(self):
  1557. """
  1558. [IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- [IF2]
  1559. """
  1560. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1561. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1562. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=1)
  1563. rearport2 = RearPort.objects.create(device=self.device, name='Rear Port 2', positions=1)
  1564. frontport1 = FrontPort.objects.create(
  1565. device=self.device, name='Front Port 1', rear_port=rearport1, rear_port_position=1
  1566. )
  1567. frontport2 = FrontPort.objects.create(
  1568. device=self.device, name='Front Port 2', rear_port=rearport2, rear_port_position=1
  1569. )
  1570. # Create cable 2
  1571. cable2 = Cable(
  1572. a_terminations=[rearport1],
  1573. b_terminations=[rearport2]
  1574. )
  1575. cable2.save()
  1576. self.assertEqual(CablePath.objects.count(), 0)
  1577. # Create cable1
  1578. cable1 = Cable(
  1579. a_terminations=[interface1],
  1580. b_terminations=[frontport1]
  1581. )
  1582. cable1.save()
  1583. self.assertPathExists(
  1584. (interface1, cable1, frontport1, rearport1, cable2, rearport2, frontport2),
  1585. is_complete=False
  1586. )
  1587. self.assertEqual(CablePath.objects.count(), 1)
  1588. # Create cable 3
  1589. cable3 = Cable(
  1590. a_terminations=[frontport2],
  1591. b_terminations=[interface2]
  1592. )
  1593. cable3.save()
  1594. self.assertPathExists(
  1595. (interface1, cable1, frontport1, rearport1, cable2, rearport2, frontport2, cable3, interface2),
  1596. is_complete=True,
  1597. is_active=True
  1598. )
  1599. self.assertPathExists(
  1600. (interface2, cable3, frontport2, rearport2, cable2, rearport1, frontport1, cable1, interface1),
  1601. is_complete=True,
  1602. is_active=True
  1603. )
  1604. self.assertEqual(CablePath.objects.count(), 2)
  1605. def test_302_update_path_on_cable_status_change(self):
  1606. """
  1607. [IF1] --C1-- [FP1] [RP1] --C2-- [IF2]
  1608. """
  1609. interface1 = Interface.objects.create(device=self.device, name='Interface 1')
  1610. interface2 = Interface.objects.create(device=self.device, name='Interface 2')
  1611. rearport1 = RearPort.objects.create(device=self.device, name='Rear Port 1', positions=1)
  1612. frontport1 = FrontPort.objects.create(
  1613. device=self.device, name='Front Port 1', rear_port=rearport1, rear_port_position=1
  1614. )
  1615. # Create cables 1 and 2
  1616. cable1 = Cable(
  1617. a_terminations=[interface1],
  1618. b_terminations=[frontport1]
  1619. )
  1620. cable1.save()
  1621. cable2 = Cable(
  1622. a_terminations=[rearport1],
  1623. b_terminations=[interface2]
  1624. )
  1625. cable2.save()
  1626. self.assertEqual(CablePath.objects.filter(is_active=True).count(), 2)
  1627. self.assertEqual(CablePath.objects.count(), 2)
  1628. # Change cable 2's status to "planned"
  1629. cable2 = Cable.objects.get(pk=cable2.pk) # Rebuild object to ditch A/B terminations set earlier
  1630. cable2.status = LinkStatusChoices.STATUS_PLANNED
  1631. cable2.save()
  1632. self.assertPathExists(
  1633. (interface1, cable1, frontport1, rearport1, cable2, interface2),
  1634. is_complete=True,
  1635. is_active=False
  1636. )
  1637. self.assertPathExists(
  1638. (interface2, cable2, rearport1, frontport1, cable1, interface1),
  1639. is_complete=True,
  1640. is_active=False
  1641. )
  1642. self.assertEqual(CablePath.objects.count(), 2)
  1643. # Change cable 2's status to "connected"
  1644. cable2 = Cable.objects.get(pk=cable2.pk)
  1645. cable2.status = LinkStatusChoices.STATUS_CONNECTED
  1646. cable2.save()
  1647. self.assertPathExists(
  1648. (interface1, cable1, frontport1, rearport1, cable2, interface2),
  1649. is_complete=True,
  1650. is_active=True
  1651. )
  1652. self.assertPathExists(
  1653. (interface2, cable2, rearport1, frontport1, cable1, interface1),
  1654. is_complete=True,
  1655. is_active=True
  1656. )
  1657. self.assertEqual(CablePath.objects.count(), 2)