commit be4d8469cb3e7046051fd069d9d060e0a97aa291
Author: Christos Stavrakakis <cstavr@grnet.gr>
Date:   Mon Jul 15 19:36:09 2013 +0300

    cyclades: Add tests for network reconciliation

diff --git a/snf-cyclades-app/synnefo/logic/tests/reconciliation.py b/snf-cyclades-app/synnefo/logic/tests/reconciliation.py
index 6c401a2..7287708 100644
--- a/snf-cyclades-app/synnefo/logic/tests/reconciliation.py
+++ b/snf-cyclades-app/synnefo/logic/tests/reconciliation.py
@@ -30,7 +30,7 @@
 import logging
 from django.test import TestCase
 
-from synnefo.db.models import VirtualMachine
+from synnefo.db.models import VirtualMachine, Network, BackendNetwork
 from synnefo.db import models_factory as mfactory
 from synnefo.logic import reconciliation
 from datetime import timedelta
@@ -41,7 +41,7 @@ from synnefo import settings
 
 
 @patch("synnefo.logic.rapi_pool.GanetiRapiClient")
-class ReconciliationTest(TestCase):
+class ServerReconciliationTest(TestCase):
     @patch("synnefo.logic.rapi_pool.GanetiRapiClient")
     def setUp(self, mrapi):
         self.backend = mfactory.BackendFactory()
@@ -239,3 +239,117 @@ class ReconciliationTest(TestCase):
         self.assertEqual(nic.network, network2)
         self.assertEqual(nic.ipv4, "192.168.2.1")
         self.assertEqual(nic.mac, "aa:00:bb:cc:dd:ee")
+
+
+@patch("synnefo.logic.rapi_pool.GanetiRapiClient")
+class NetworkReconciliationTest(TestCase):
+    def setUp(self):
+        self.backend = mfactory.BackendFactory()
+        log = logging.getLogger()
+        self.reconciler = reconciliation.NetworkReconciler(
+            logger=log,
+            fix=True)
+
+    def test_parted_network(self, mrapi):
+        net1 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False)
+        mrapi().GetNetworks.return_value = []
+        # Test nothing if Ganeti returns nothing
+        self.assertEqual(net1.backend_networks.count(), 0)
+        self.reconciler.reconcile_networks()
+        self.assertEqual(net1.backend_networks.count(), 0)
+
+        # Test creation if exists in Ganeti
+        self.assertEqual(net1.backend_networks.count(), 0)
+        mrapi().GetNetworks.return_value = [{"name": net1.backend_id,
+                                             "group_list": ["default"],
+                                             "network": net1.subnet,
+                                             "map": "....",
+                                             "external_reservations": ""}]
+        self.reconciler.reconcile_networks()
+        self.assertTrue(net1.backend_networks
+                            .filter(backend=self.backend).exists())
+        # ..but not if it is destroying
+        net1.backend_networks.all().delete()
+        net1.action = "DESTROY"
+        net1.save()
+        self.reconciler.reconcile_networks()
+        self.assertFalse(net1.backend_networks
+                             .filter(backend=self.backend).exists())
+        # or network is public!
+        net1.action = "CREATE"
+        net1.public = True
+        net1.save()
+        self.reconciler.reconcile_networks()
+        self.assertFalse(net1.backend_networks
+                             .filter(backend=self.backend).exists())
+        # Test creation if network is a floating IP pool
+        net2 = mfactory.NetworkFactory(subnet="192.168.0.0/30",
+                                       floating_ip_pool=True)
+        mrapi().GetNetworks.return_value = []
+        self.assertEqual(net2.backend_networks.count(), 0)
+        self.reconciler.reconcile_networks()
+        self.assertTrue(net2.backend_networks
+                            .filter(backend=self.backend).exists())
+
+    def test_stale_network(self, mrapi):
+        # Test that stale network will be deleted from DB, if network action is
+        # destroy
+        net1 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False,
+                                       flavor="IP_LESS_ROUTED",
+                                       action="DESTROY", deleted=False)
+        bn1 = mfactory.BackendNetworkFactory(network=net1,
+                                             backend=self.backend,
+                                             operstate="ACTIVE")
+        mrapi().GetNetworks.return_value = []
+        self.assertFalse(net1.deleted)
+        with mocked_quotaholder():
+            self.reconciler.reconcile_networks()
+        bn1 = BackendNetwork.objects.get(id=bn1.id)
+        net1 = Network.objects.get(id=net1.id)
+        self.assertEqual(bn1.operstate, "DELETED")
+        self.assertTrue(net1.deleted)
+        # But not if action is not DESTROY
+        net2 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False,
+                                       action="CREATE")
+        mfactory.BackendNetworkFactory(network=net2, backend=self.backend)
+        self.assertFalse(net2.deleted)
+        self.reconciler.reconcile_networks()
+        self.assertFalse(net2.deleted)
+
+    def test_missing_network(self, mrapi):
+        net2 = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False,
+                                       action="CREATE")
+        mfactory.BackendNetworkFactory(network=net2, backend=self.backend)
+        mrapi().GetNetworks.return_value = []
+        self.reconciler.reconcile_networks()
+        self.assertEqual(len(mrapi().CreateNetwork.mock_calls), 1)
+
+    #def test_hanging_networks(self, mrapi):
+    #    pass
+
+    def test_unsynced_networks(self, mrapi):
+        net = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False,
+                                      state="PENDING",
+                                      action="CREATE", deleted=False)
+        bn = mfactory.BackendNetworkFactory(network=net, backend=self.backend,
+                                            operstate="PENDING")
+        mrapi().GetNetworks.return_value = [{"name": net.backend_id,
+                                             "group_list": [],
+                                             "network": net.subnet,
+                                             "map": "....",
+                                             "external_reservations": ""}]
+        self.assertEqual(bn.operstate, "PENDING")
+        self.reconciler.reconcile_networks()
+        bn = BackendNetwork.objects.get(id=bn.id)
+        self.assertEqual(bn.operstate, "ACTIVE")
+
+    def test_orphan_networks(self, mrapi):
+        net = mfactory.NetworkFactory(subnet="192.168.0.0/30", public=False,
+                                      action="CREATE", deleted=True)
+        mrapi().GetNetworks.return_value = [{"name": net.backend_id,
+                                             "group_list": [],
+                                             "network": net.subnet,
+                                             "map": "....",
+                                             "external_reservations": ""}]
+        self.reconciler.reconcile_networks()
+        mrapi().DeleteNetwork.assert_called_once_with(net.backend_id, [])
