Merge "Fix race condition in reload_on_sighup functional"
diff --git a/common/config.py b/common/config.py
index f8ae075..3aee48f 100644
--- a/common/config.py
+++ b/common/config.py
@@ -130,6 +130,11 @@
default=30,
help="Timeout in seconds to wait for adding or removing child"
"process after receiving of sighup signal"),
+ cfg.IntOpt('sighup_config_edit_retries',
+ default=10,
+ help='Count of retries to edit config file during sighup. If '
+ 'another worker already edit config file, file can be '
+ 'busy, so need to wait and try edit file again.'),
cfg.StrOpt('heat-config-notify-script',
default=('heat-config-notify'),
help="Path to the script heat-config-notify"),
diff --git a/functional/test_reload_on_sighup.py b/functional/test_reload_on_sighup.py
index cba5386..b014f49 100644
--- a/functional/test_reload_on_sighup.py
+++ b/functional/test_reload_on_sighup.py
@@ -28,8 +28,27 @@
def _set_config_value(self, service, key, value):
config = configparser.ConfigParser()
- config.read(self.config_file)
- config.set(service, key, value)
+
+ # NOTE(prazumovsky): If there are several workers, there can be
+ # situation, when one thread opens self.config_file for writing
+ # (so config_file erases with opening), in that moment other thread
+ # intercepts to this file and try to set config option value, i.e.
+ # write to file, which is already erased by first thread, so,
+ # NoSectionError raised. So, should wait until first thread writes to
+ # config_file.
+ retries_count = self.conf.sighup_config_edit_retries
+ while True:
+ config.read(self.config_file)
+ try:
+ config.set(service, key, value)
+ except configparser.NoSectionError:
+ if retries_count <= 0:
+ raise
+ retries_count -= 1
+ eventlet.sleep(1)
+ else:
+ break
+
with open(self.config_file, 'wb') as f:
config.write(f)