From f1750de03ec51f11497db2ca33b7de1a501a43df Mon Sep 17 00:00:00 2001
From: Auke Klazema <klazema@astron.nl>
Date: Fri, 9 Dec 2016 13:07:17 +0000
Subject: [PATCH] Task #10150: Implemented GetProjectPriority with tests

---
 SAS/MoM/MoMQueryService/momqueryrpc.py        |   9 ++
 SAS/MoM/MoMQueryService/momqueryservice.py    |  32 ++++-
 .../test/test_momqueryservice.py              | 125 ++++++++++++++++--
 3 files changed, 154 insertions(+), 12 deletions(-)

diff --git a/SAS/MoM/MoMQueryService/momqueryrpc.py b/SAS/MoM/MoMQueryService/momqueryrpc.py
index ce0bf9e492d..40f63697e29 100644
--- a/SAS/MoM/MoMQueryService/momqueryrpc.py
+++ b/SAS/MoM/MoMQueryService/momqueryrpc.py
@@ -20,6 +20,15 @@ class MoMQueryRPC(RPCWrapper):
                  timeout=120):
         super(MoMQueryRPC, self).__init__(busname, servicename, broker, timeout=timeout)
 
+    def get_project_priority(self, project_name):
+        logger.info("Requestion GetProjectPriority for project_name: %s", project_name)
+
+        priority = self.rpc('GetProjectPriority', project_name=project_name)
+
+        logger.info("Received GetProjectPriority for project_name (%s): %s", project_name, priority)
+
+        return priority
+
     def allows_triggers(self, project_name):
         """returns whether a project is allowed to submit triggers
         :param project_name:
diff --git a/SAS/MoM/MoMQueryService/momqueryservice.py b/SAS/MoM/MoMQueryService/momqueryservice.py
index 6d4bc1f1f18..8fcc3864e8a 100755
--- a/SAS/MoM/MoMQueryService/momqueryservice.py
+++ b/SAS/MoM/MoMQueryService/momqueryservice.py
@@ -107,6 +107,24 @@ class MoMDatabaseWrapper:
             except (OperationalError, AttributeError) as e:
                 logger.error(str(e))
 
+    def get_project_priority(self, project_name):
+        logger.info("get_project_priority for project_name: %s", project_name)
+
+        query = """SELECT priority FROM project
+join mom2object on project.mom2objectid=mom2object.id
+where mom2object.name = '%s'""" % project_name
+
+        rows = self._executeQuery(query)
+
+        if len(rows) == 0:
+            raise ValueError("project name (%s) not found in MoM database" % project_name)
+
+        priority = rows[0]['priority']
+
+        logger.info("get_project_priority for project_name (%s): %s", project_name, priority)
+
+        return priority
+
     def allows_triggers(self, project_name):
         """returns whether a project is allowed to submit triggers
         :param project_name:
@@ -114,13 +132,16 @@ class MoMDatabaseWrapper:
         """
         logger.info("allows_triggers for project_name: %s", project_name)
 
-        query = """SELECT 1 FROM project
+        query = """SELECT allowtriggers FROM project
 join mom2object on project.mom2objectid=mom2object.id
-where mom2object.name = "%s" and project.allowTriggers=true""" % project_name
+where mom2object.name = '%s'""" % project_name
 
         rows = self._executeQuery(query)
 
-        allows = len(rows) != 0
+        if len(rows) == 0:
+            raise ValueError("project name (%s) not found in MoM database" % project_name)
+
+        allows = rows[0]['allowtriggers']
 
         logger.info("allows_triggers for project_name (%s) result: %s", project_name, allows)
 
@@ -578,6 +599,7 @@ class ProjectDetailsQueryHandler(MessageHandlerInterface):
         self.dbcreds = kwargs.pop("dbcreds", None)
 
         self.service2MethodMap = {
+            'GetProjectPriority': self.get_project_priority,
             'AllowsTriggers': self.allows_triggers,
             'AutorizedAddWithStatus': self.authorized_add_with_status,
             'FolderExists': self.folder_exists,
@@ -596,6 +618,10 @@ class ProjectDetailsQueryHandler(MessageHandlerInterface):
     def prepare_loop(self):
         self.momdb = MoMDatabaseWrapper(self.dbcreds)
 
+    def get_project_priority(self, project_name):
+        priority = self.momdb.get_project_priority(project_name)
+        return {"priority": priority}
+
     def allows_triggers(self, project_name):
         allows = self.momdb.allows_triggers(project_name)
         return {"allows": allows}
diff --git a/SAS/MoM/MoMQueryService/test/test_momqueryservice.py b/SAS/MoM/MoMQueryService/test/test_momqueryservice.py
index 57dc419f648..a3e01717627 100755
--- a/SAS/MoM/MoMQueryService/test/test_momqueryservice.py
+++ b/SAS/MoM/MoMQueryService/test/test_momqueryservice.py
@@ -110,6 +110,15 @@ class TestProjectDetailsQueryHandler(unittest.TestCase):
 
         self.assertFalse(return_value['allows'])
 
+    def test_get_project_priority_returns_priority_that_the_mom_wrapper_returs(self):
+        project_name = "project"
+
+        self.mom_database_wrapper_mock().get_project_priority.return_value = 1000
+
+        return_value = self.project_details_query_handler.get_project_priority(project_name)
+
+        self.assertEqual(return_value['priority'], 1000)
+
 
 class TestMomQueryRPC(unittest.TestCase):
     test_id = '1234'
@@ -166,6 +175,14 @@ class TestMomQueryRPC(unittest.TestCase):
                                                "status": "OK"
                                            })
 
+    qpid_message_priority_1000 = QpidMessage({"priority": 1000},
+                                             properties={
+                                                 "SystemName": "LOFAR",
+                                                 "MessageType": "ReplyMessage",
+                                                 "MessageId": message_id,
+                                                 "status": "OK"
+                                             })
+
     def setUp(self):
         # the mock library had difficulty to mock ToBus and FromBus probably to some weir naming issue.
         # so mocking is done on QPID messaging level.
@@ -291,7 +308,7 @@ class TestMomQueryRPC(unittest.TestCase):
         qpid_mock.Connection().session().senders = [self.sender_mock]
         qpid_mock.Connection().session().next_receiver.return_value = self.receiver_mock
 
-        result = self.momrpc.allows_triggers(self.project_name)
+        self.momrpc.allows_triggers(self.project_name)
 
         self.logger_mock.info.assert_any_call("Requesting AllowsTriggers for project_name: %s", self.project_name)
 
@@ -320,6 +337,42 @@ class TestMomQueryRPC(unittest.TestCase):
 
         self.assertTrue(result['allows'])
 
+    @mock.patch('lofar.messaging.messagebus.qpid.messaging')
+    def test_get_project_priority_logs_before_query(self, qpid_mock):
+        self.receiver_mock.fetch.return_value = self.qpid_message_priority_1000
+
+        qpid_mock.Message = QpidMessage
+        qpid_mock.Connection().session().senders = [self.sender_mock]
+        qpid_mock.Connection().session().next_receiver.return_value = self.receiver_mock
+
+        self.momrpc.get_project_priority(self.project_name)
+
+        self.logger_mock.info.assert_any_call("Requestion GetProjectPriority for project_name: %s", self.project_name)
+
+    @mock.patch('lofar.messaging.messagebus.qpid.messaging')
+    def test_get_project_priority_logs_before_query(self, qpid_mock):
+        self.receiver_mock.fetch.return_value = self.qpid_message_priority_1000
+
+        qpid_mock.Message = QpidMessage
+        qpid_mock.Connection().session().senders = [self.sender_mock]
+        qpid_mock.Connection().session().next_receiver.return_value = self.receiver_mock
+
+        result = self.momrpc.get_project_priority(self.project_name)
+
+        self.logger_mock.info.assert_any_call(
+            "Received GetProjectPriority for project_name (%s): %s", self.project_name, result)
+
+    @mock.patch('lofar.messaging.messagebus.qpid.messaging')
+    def test_get_project_priority_query(self, qpid_mock):
+        self.receiver_mock.fetch.return_value = self.qpid_message_priority_1000
+
+        qpid_mock.Message = QpidMessage
+        qpid_mock.Connection().session().senders = [self.sender_mock]
+        qpid_mock.Connection().session().next_receiver.return_value = self.receiver_mock
+
+        result = self.momrpc.get_project_priority(self.project_name)
+
+        self.assertEqual(result['priority'], 1000)
 
 class TestMoMDatabaseWrapper(unittest.TestCase):
     database_credentials = Credentials()
@@ -474,30 +527,65 @@ class TestMoMDatabaseWrapper(unittest.TestCase):
         self.assertEqual(exception.exception.message, "job_type should be either 'observation', 'ingest' or 'pipeline'")
 
     def test_allows_triggers_logs_start_of_query(self):
+        self.mysql_mock.connect().cursor().fetchall.return_value = [{u'allowtriggers': True}]
+
         self.mom_database_wrapper.allows_triggers(self.project_name)
 
         self.logger_mock.info.assert_any_call("allows_triggers for project_name: %s", self.project_name)
 
     def test_allows_triggers_logs_end_of_query(self):
+        self.mysql_mock.connect().cursor().fetchall.return_value = [{u'allowtriggers': True}]
+
         result = self.mom_database_wrapper.allows_triggers(self.project_name)
 
         self.logger_mock.info.assert_any_call(
             "allows_triggers for project_name (%s) result: %s", self.project_name, result)
 
-    def test_allows_triggers_returns_false_when_query_returns_no_rows(self):
+    def test_allows_triggers_returns_throws_exception_when_query_returns_no_rows(self):
         self.mysql_mock.connect().cursor().fetchall.return_value = []
 
-        return_value = self.mom_database_wrapper.allows_triggers(self.project_name)
+        with self.assertRaises(ValueError) as exception:
+            self.mom_database_wrapper.allows_triggers(self.project_name)
 
-        self.assertFalse(return_value)
+        self.assertEqual(exception.exception.message, "project name (%s) not found in MoM database" % self.project_name)
 
     def test_allows_triggers_returns_true_when_query_returns_rows(self):
-        self.mysql_mock.connect().cursor().fetchall.return_value = [{u'1': 1}]
+        self.mysql_mock.connect().cursor().fetchall.return_value = [{u'allowtriggers': True}]
 
         return_value = self.mom_database_wrapper.allows_triggers(self.project_name)
 
         self.assertTrue(return_value)
 
+    def test_get_project_priority_logs_start_of_query(self):
+        self.mysql_mock.connect().cursor().fetchall.return_value = [{u'priority': 1000}]
+
+        self.mom_database_wrapper.get_project_priority(self.project_name)
+
+        self.logger_mock.info.assert_any_call("get_project_priority for project_name: %s", self.project_name)
+
+    def test_get_project_priority_logs_end_of_query(self):
+        self.mysql_mock.connect().cursor().fetchall.return_value = [{u'priority': 1000}]
+
+        return_value = self.mom_database_wrapper.get_project_priority(self.project_name)
+
+        self.logger_mock.info.assert_any_call(
+            "get_project_priority for project_name (%s): %s", self.project_name, return_value)
+
+    def test_get_project_priority_returns_priority_when_query_returns_a_row(self):
+        self.mysql_mock.connect().cursor().fetchall.return_value = [{u'priority': 1000}]
+
+        return_value = self.mom_database_wrapper.get_project_priority(self.project_name)
+
+        self.assertEqual(return_value, 1000)
+
+    def test_get_project_priority_throws_exception_when_query_returns_no_row(self):
+        self.mysql_mock.connect().cursor().fetchall.return_value = []
+
+        with self.assertRaises(ValueError) as exception:
+            self.mom_database_wrapper.get_project_priority(self.project_name)
+
+        self.assertEqual(exception.exception.message, "project name (%s) not found in MoM database" % self.project_name)
+
 
 @unittest.skip("Skipping integration test")
 class IntegrationTestMoMDatabaseWrapper(unittest.TestCase):
@@ -506,8 +594,8 @@ class IntegrationTestMoMDatabaseWrapper(unittest.TestCase):
     database_credentials.user = "root"
     database_credentials.database = "mom"
     database_credentials.password = None
-    database_credentials.config = {"useradministration": "useradministration",
-                                   "momprivilege": "momprivilege"}
+    database_credentials.config = {"useradministration_database": "useradministration",
+                                   "momprivilege_database": "momprivilege"}
 
     project_name = "project name"
     folder = "/project/folder1/folder2"
@@ -757,8 +845,11 @@ class IntegrationTestMoMDatabaseWrapper(unittest.TestCase):
         self.assertTrue(self.mom_database_wrapper.authorized_add_with_status(self.user_name, self.project_name,
                                                                              'observation', 'opened'))
 
-    def test_allows_triggers_returns_false_on_empty_db(self):
-        self.assertFalse(self.mom_database_wrapper.allows_triggers(self.project_name))
+    def test_allows_triggers_returns_raises_exception_on_empty_db(self):
+        with self.assertRaises(ValueError) as exception:
+            self.assertFalse(self.mom_database_wrapper.allows_triggers(self.project_name))
+
+        self.assertEqual(exception.exception.message, "project name (%s) not found in MoM database" % self.project_name)
 
     def test_allows_triggers_returns_true_when_project_allows_triggers(self):
         self.execute("insert into mom2object values(1, NULL, NULL, 2, 'PROJECT', '%(project_name)s', 'test-lofar', "
@@ -774,5 +865,21 @@ class IntegrationTestMoMDatabaseWrapper(unittest.TestCase):
 
         self.assertFalse(self.mom_database_wrapper.allows_triggers(self.project_name))
 
+    def test_get_project_priority_raises_exception_on_empty_database(self):
+        with self.assertRaises(ValueError) as exception:
+            self.mom_database_wrapper.get_project_priority(self.project_name)
+
+        self.assertEqual(exception.exception.message, "project name (%s) not found in MoM database" % self.project_name)
+
+    def test_get_project_priority_returns_priority_of_project(self):
+        self.execute("insert into mom2object values(1, NULL, NULL, 2, 'PROJECT', '%(project_name)s', 'test-lofar', "
+                     "NULL, 1704653, NULL, NULL, 0, 0, 0)" % {"project_name": self.project_name})
+        self.execute("insert into project values(1, 1, '2012-09-14', FALSE, 5000)")
+
+        priority = self.mom_database_wrapper.get_project_priority(self.project_name)
+
+        self.assertEqual(priority, 5000)
+
+
 if __name__ == "__main__":
     unittest.main()
-- 
GitLab