Giuseppe Lavagetto has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/234008

Change subject: Add unit tests for FileConfigurationObserver
......................................................................

Add unit tests for FileConfigurationObserver

Change-Id: I526d573716ba668c9b8b7eb585daab6d9402c64e
---
M pybal/config.py
M pybal/pybal.py
M pybal/test/fixtures.py
M pybal/test/test_config.py
4 files changed, 90 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/operations/debs/pybal 
refs/changes/08/234008/1

diff --git a/pybal/config.py b/pybal/config.py
index 7e3a43b..3172cf6 100644
--- a/pybal/config.py
+++ b/pybal/config.py
@@ -69,7 +69,6 @@
         self.lastFileStat = None
         self.lastConfig = None
         self.reloadTask = task.LoopingCall(self.reloadConfig)
-        self.startObserving()
 
     def startObserving(self):
         """Start (or re-start) watching the configuration file for changes."""
@@ -95,7 +94,8 @@
                     continue
                 server = ast.literal_eval(line)
                 host = server.pop('host')
-                config[host] = server
+                config[host] = {'enabled': server['enabled'],
+                                'weight': server['weight']}
             except (KeyError, SyntaxError, TypeError, ValueError) as ex:
                 # We catch exceptions here (rather than simply allow them to
                 # bubble up to FileConfigurationObserver.logError) because we
diff --git a/pybal/pybal.py b/pybal/pybal.py
old mode 100644
new mode 100755
index 0ae9df6..f39816c
--- a/pybal/pybal.py
+++ b/pybal/pybal.py
@@ -278,6 +278,7 @@
         self.serverConfigUrl = configUrl
         self.serverInitDeferredList = defer.Deferred()
         self.configObserver = config.ConfigurationObserver.fromUrl(self, 
configUrl)
+        self.configObserver.startObserving()
 
     def __str__(self):
         return "[%s]" % self.lvsservice.name
diff --git a/pybal/test/fixtures.py b/pybal/test/fixtures.py
index 1fe18e2..ab480f8 100644
--- a/pybal/test/fixtures.py
+++ b/pybal/test/fixtures.py
@@ -47,6 +47,9 @@
         self.up = False
         self.reason = reason
 
+    def onConfigUpdate(self, config):
+        self.config = config
+
 
 class StubLVSService(object):
     """Test stub for `pybal.ipvs.LVSService`."""
diff --git a/pybal/test/test_config.py b/pybal/test/test_config.py
index 5fd9db1..2e77801 100644
--- a/pybal/test/test_config.py
+++ b/pybal/test/test_config.py
@@ -6,12 +6,13 @@
   This module contains tests for `pybal.config`.
 
 """
-import unittest
+import mock
 import tempfile
 import os
 
 import pybal
 import pybal.config
+
 
 from .fixtures import PyBalTestCase
 
@@ -32,3 +33,85 @@
             pybal.config.ConfigurationObserver.fromUrl(None, 'dummy://'),
             DummyConfigurationObserver
         )
+
+
+class FileConfigurationObserverTestCase(PyBalTestCase):
+    """Test case for `pybal.config.FileConfigurationObserver`."""
+
+    def setUp(self):
+        super(FileConfigurationObserverTestCase, self).setUp()
+        self.observer = self.getObserver()
+
+    def getObserver(self, filename='file:///something/here'):
+        return pybal.config.FileConfigurationObserver(
+            self.coordinator, filename)
+
+    def testInit(self):
+        """Test `FileConfigurationObserver.__init__`"""
+        self.assertEquals(self.observer.filePath, '/something/here')
+        self.assertEquals(self.observer.reloadIntervalSeconds, 1)
+
+    @mock.patch('os.stat')
+    def testReloadConfig(self, mock_stat):
+        """Test `FileConfigurationObserver.reloadConfig`"""
+        self.observer.lastFileStat = 'WMF'
+        mock_stat.return_value = 'WMF'
+        self.observer.parseConfig = mock.MagicMock(return_value="some_config")
+        # No stat changes mean no config parsing
+        self.observer.reloadConfig()
+        mock_stat.assert_called_with('/something/here')
+        self.observer.parseConfig.assert_not_called()
+        # Stat change means we open the file and parse the configuration
+        mock_stat.reset_mock()
+        mock_stat.return_value = 'WMF!'
+        m = mock.mock_open(read_data="123")
+        with mock.patch('__builtin__.open', m, True) as mock_open:
+            self.observer.reloadConfig()
+        mock_stat.assert_called_with('/something/here')
+        mock_open.assert_called_with('/something/here', 'rt')
+        self.observer.parseConfig.assert_called_with('123')
+        self.assertEquals(self.observer.lastConfig, 'some_config')
+        self.assertEquals(self.observer.coordinator.config, 'some_config')
+
+    def testParseConfig(self):
+        """Test `FileConfigurationObserver.parseConfig`"""
+        self.observer.parseLegacyConfig = 
mock.MagicMock(return_value='legacy_config')
+        self.observer.parseJsonConfig = 
mock.MagicMock(return_value='json_config')
+        self.assertEquals(self.observer.parseConfig("I am legacy"), 
'legacy_config')
+        self.observer.parseLegacyConfig.assert_called_with("I am legacy")
+        self.observer.configUrl += '.json'
+        self.assertEquals(self.observer.parseConfig("I am json"), 
'json_config')
+        self.observer.parseJsonConfig.assert_called_with("I am json")
+
+    def testParseJsonConfig(self):
+        """Test `FileConfigurationObserver.parseJsonConfig`"""
+        json_config = """
+        {
+          "mw1200": { "enabled": true, "weight": 10 },
+          "mw1201": {"enabled": false, "weight": 1 }
+        }
+        """
+        expected_config = {'mw1200': {'enabled': True, 'weight': 10},
+                           'mw1201': {'enabled': False, 'weight': 1}}
+        self.assertEquals(self.observer.parseJsonConfig(json_config),
+                          expected_config)
+        invalid_config = "{[]"
+        self.assertRaises(Exception, self.observer.parseJsonConfig,
+                          invalid_config)
+
+    def testParseLegacyConfig(self):
+        """Test `FileConfigurationObserver.parseLegacyConfig`"""
+        legacy_config = """
+{'host': 'mw1200', 'weight': 10, 'enabled': True }
+{'host': 'mw1201', 'weight': 1, 'enabled': False }
+        """
+        expected_config = {'mw1200': {'enabled': True, 'weight': 10},
+                           'mw1201': {'enabled': False, 'weight': 1}}
+        self.assertEquals(self.observer.parseLegacyConfig(legacy_config),
+                          expected_config)
+        invalid_config="""
+{'host': 'something'}
+        """
+        # Needed for nose to pass... it doesn't really get raised
+        self.assertEquals(self.observer.parseLegacyConfig(invalid_config), {})
+        self.flushLoggedErrors(KeyError)

-- 
To view, visit https://gerrit.wikimedia.org/r/234008
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I526d573716ba668c9b8b7eb585daab6d9402c64e
Gerrit-PatchSet: 1
Gerrit-Project: operations/debs/pybal
Gerrit-Branch: master
Gerrit-Owner: Giuseppe Lavagetto <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to