Merge "Re-enable the ceilometer alarm test"
diff --git a/functional/test_reload_on_sighup.py b/functional/test_reload_on_sighup.py
new file mode 100644
index 0000000..f987882
--- /dev/null
+++ b/functional/test_reload_on_sighup.py
@@ -0,0 +1,98 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import eventlet
+
+from oslo_concurrency import processutils
+from six.moves import configparser
+
+from heat_integrationtests.common import test
+
+
+class ReloadOnSighupTest(test.HeatIntegrationTest):
+
+    def setUp(self):
+        self.config_file = "/etc/heat/heat.conf"
+        super(ReloadOnSighupTest, self).setUp()
+
+    def _set_config_value(self, service, key, value):
+        config = configparser.ConfigParser()
+        config.read(self.config_file)
+        config.set(service, key, value)
+        with open(self.config_file, 'wb') as f:
+            config.write(f)
+
+    def _get_config_value(self, service, key):
+        config = configparser.ConfigParser()
+        config.read(self.config_file)
+        val = config.get(service, key)
+        return val
+
+    def _get_heat_api_pids(self, service):
+        # get the pids of all heat-api processes
+        if service == "heat_api":
+            process = "heat-api|grep -Ev 'grep|cloudwatch|cfn'"
+        else:
+            process = "%s|grep -Ev 'grep'" % service.replace('_', '-')
+        cmd = "ps -ef|grep %s|awk '{print $2}'" % process
+        out, err = processutils.execute(cmd, shell=True)
+        self.assertIsNotNone(out, "heat-api service not running. %s" % err)
+        pids = filter(None, out.split('\n'))
+
+        # get the parent pids of all heat-api processes
+        cmd = "ps -ef|grep %s|awk '{print $3}'" % process
+        out, _ = processutils.execute(cmd, shell=True)
+        parent_pids = filter(None, out.split('\n'))
+
+        heat_api_parent = list(set(pids) & set(parent_pids))[0]
+        heat_api_children = list(set(pids) - set(parent_pids))
+
+        return heat_api_parent, heat_api_children
+
+    def _change_config(self, service, old_workers, new_workers):
+        pre_reload_parent, pre_reload_children = self._get_heat_api_pids(
+            service)
+        self.assertEqual(old_workers, len(pre_reload_children))
+
+        # change the config values
+        self._set_config_value(service, 'workers', new_workers)
+        cmd = "kill -HUP %s" % pre_reload_parent
+        processutils.execute(cmd, shell=True)
+        # wait till heat-api reloads
+        eventlet.sleep(2)
+
+        post_reload_parent, post_reload_children = self._get_heat_api_pids(
+            service)
+        self.assertEqual(pre_reload_parent, post_reload_parent)
+        self.assertEqual(new_workers, len(post_reload_children))
+        # test if all child processes are newly created
+        self.assertEqual(set(post_reload_children) & set(pre_reload_children),
+                         set())
+
+    def _reload(self, service):
+        old_workers = int(self._get_config_value(service, 'workers'))
+        new_workers = old_workers + 1
+        self.addCleanup(self._set_config_value, service, 'workers',
+                        old_workers)
+
+        self._change_config(service, old_workers, new_workers)
+        # revert all the changes made
+        self._change_config(service, new_workers, old_workers)
+
+    def test_api_reload_on_sighup(self):
+        self._reload('heat_api')
+
+    def test_api_cfn_reload_on_sighup(self):
+        self._reload('heat_api_cfn')
+
+    def test_api_cloudwatch_on_sighup(self):
+        self._reload('heat_api_cloudwatch')