Moving DHCP event handling in model policy, update the subscriber only when needed

Change-Id: I77ec7c05d802a5902d96a8216b932d7a703af4e9
diff --git a/xos/synchronizer/model_policies/model_policy_att_workflow_driver_serviceinstance.py b/xos/synchronizer/model_policies/model_policy_att_workflow_driver_serviceinstance.py
index 8513d41..32d0eaa 100644
--- a/xos/synchronizer/model_policies/model_policy_att_workflow_driver_serviceinstance.py
+++ b/xos/synchronizer/model_policies/model_policy_att_workflow_driver_serviceinstance.py
@@ -46,7 +46,7 @@
             self.validate_onu_state(si)
         else:
             # just clean the status
-            si.status_message = ""
+            si.status_message = "ONU has been disabled"
 
         # handling the subscriber status
         subscriber = self.get_subscriber(si.serial_number)
@@ -101,12 +101,18 @@
             subscriber.status = "auth-failed"
             si.status_message += " - Authentication denied"
 
-        if cur_status == subscriber.status:
+        # NOTE we save the subscriber only if:
+        # - the status has changed
+        # - we get a DHCPACK event
+        if cur_status != subscriber.status or si.dhcp_state == "DHCPACK":
+            self.logger.debug("MODEL_POLICY: updating subscriber", onu_device=subscriber.onu_device, authentication_state=si.authentication_state, subscriber_status=subscriber.status)
+            if si.ip_address and si.mac_address:
+                subscriber.ip_address = si.ip_address
+                subscriber.mac_address = si.mac_address
+            subscriber.save(always_update_timestamp=True)
+        else:
             self.logger.debug("MODEL_POLICY: subscriber status has not changed", onu_device=subscriber.onu_device,
                               authentication_state=si.authentication_state, subscriber_status=subscriber.status)
-        else:
-            self.logger.debug("MODEL_POLICY: updating subscriber", onu_device=subscriber.onu_device, authentication_state=si.authentication_state, subscriber_status=subscriber.status)
-            subscriber.save(always_update_timestamp=True)
 
     def handle_delete(self, si):
         pass
diff --git a/xos/synchronizer/model_policies/test_model_policy_att_workflow_driver_serviceinstance.py b/xos/synchronizer/model_policies/test_model_policy_att_workflow_driver_serviceinstance.py
index 8e15202..afa4183 100644
--- a/xos/synchronizer/model_policies/test_model_policy_att_workflow_driver_serviceinstance.py
+++ b/xos/synchronizer/model_policies/test_model_policy_att_workflow_driver_serviceinstance.py
@@ -240,6 +240,22 @@
             self.policy.update_subscriber(sub, self.si)
             sub_save.assert_not_called()
 
+    def test_update_subscriber_dhcp(self):
+        sub = RCORDSubscriber(
+            onu_device="BRCM1234"
+        )
+
+        self.si.dhcp_state = "DHCPACK"
+        self.si.ip_address = "1234"
+        self.si.mac_address = "4321"
+
+        with patch.object(sub, "save") as sub_save:
+            self.policy.update_subscriber(sub, self.si)
+            sub_save.assert_called()
+            self.assertEqual(sub.mac_address, self.si.mac_address)
+            self.assertEqual(sub.ip_address, self.si.ip_address)
+
+
 
     def test_handle_update_subscriber(self):
         self.si.onu_state = "DISABLED"
@@ -249,7 +265,6 @@
         )
 
         with patch.object(self.policy, "get_subscriber") as get_subscriber, \
-            patch.object(self.policy, "update_onu") as update_onu, \
             patch.object(self.policy, "update_subscriber") as update_subscriber:
 
             get_subscriber.return_value = None