Skip to content

Commit 2c1a5ca

Browse files
authored
Merge pull request #37873 from mantidproject/ewm6894-fix-ConfigService-remove
Expose `ConfigService::configureLogging()` to API, fix handling of removed properties not also in file
2 parents c431818 + 8d357f1 commit 2c1a5ca

File tree

7 files changed

+83
-5
lines changed

7 files changed

+83
-5
lines changed

Framework/Kernel/inc/MantidKernel/ConfigService.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ class MANTID_KERNEL_DLL ConfigServiceImpl final {
206206
/// Sets the log level priority for all log channels
207207
void setLogLevel(int logLevel, bool quiet = false);
208208
/// Sets the log level priority for all log channels
209-
void setLogLevel(std::string logLevel, bool quiet = false);
209+
void setLogLevel(std::string const &logLevel, bool quiet = false);
210+
// return the string name for the log level
211+
std::string getLogLevel();
210212

211213
/// Look for an instrument
212214
const InstrumentInfo &getInstrument(const std::string &instrumentName = "") const;

Framework/Kernel/src/ConfigService.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,11 +721,16 @@ void ConfigServiceImpl::saveConfig(const std::string &filename) const {
721721
} // End while-loop
722722

723723
// Any remaining keys within the changed key store weren't present in the
724-
// current user properties so append them
724+
// current user properties so append them IF they exist
725725
if (!m_changed_keys.empty()) {
726726
updated_file += "\n";
727727
auto key_end = m_changed_keys.end();
728728
for (auto key_itr = m_changed_keys.begin(); key_itr != key_end;) {
729+
// if the key does not have a property, skip it
730+
if (!hasProperty(*key_itr)) {
731+
++key_itr;
732+
continue;
733+
}
729734
updated_file += *key_itr + "=";
730735
std::string value = getString(*key_itr, false);
731736
Poco::replaceInPlace(value, "\\", "\\\\"); // replace single \ with double
@@ -1916,7 +1921,7 @@ void ConfigServiceImpl::setLogLevel(int logLevel, bool quiet) {
19161921
}
19171922
}
19181923

1919-
void ConfigServiceImpl::setLogLevel(std::string logLevel, bool quiet) {
1924+
void ConfigServiceImpl::setLogLevel(std::string const &logLevel, bool quiet) {
19201925
Mantid::Kernel::Logger::setLevelForAll(logLevel);
19211926
// update the internal value to keep strings in sync
19221927
m_pConf->setString(LOG_LEVEL_KEY, g_log.getLevelName());
@@ -1926,6 +1931,8 @@ void ConfigServiceImpl::setLogLevel(std::string logLevel, bool quiet) {
19261931
}
19271932
}
19281933

1934+
std::string ConfigServiceImpl::getLogLevel() { return g_log.getLevelName(); }
1935+
19291936
/// \cond TEMPLATE
19301937
template DLLExport boost::optional<double> ConfigServiceImpl::getValue(const std::string &);
19311938
template DLLExport boost::optional<std::string> ConfigServiceImpl::getValue(const std::string &);

Framework/Kernel/test/ConfigServiceTest.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ class ConfigServiceTest : public CxxTest::TestSuite {
110110
TS_ASSERT_THROWS_NOTHING(ConfigService::Instance().setLogLevel(4));
111111
}
112112

113+
void testLogLevelSetGet() {
114+
Logger log1("testLogLevelGetSet");
115+
116+
for (std::string x : Logger::PriorityNames) {
117+
TS_ASSERT_THROWS_NOTHING(ConfigService::Instance().setLogLevel(x));
118+
TS_ASSERT_EQUALS(log1.getLevelName(), x);
119+
TS_ASSERT_EQUALS(ConfigService::Instance().getLogLevel(), x);
120+
}
121+
122+
// return back to previous values
123+
TS_ASSERT_THROWS_NOTHING(ConfigService::Instance().setLogLevel(4));
124+
}
125+
113126
void testDefaultFacility() {
114127
TS_ASSERT_THROWS_NOTHING(ConfigService::Instance().getFacility());
115128
//
@@ -410,6 +423,50 @@ class ConfigServiceTest : public CxxTest::TestSuite {
410423
}
411424
}
412425

426+
void testRemoveNotPopulated() {
427+
/* If a property was not originally set in the properties file,
428+
* but is later removed, it will still appear in a list or properties
429+
* to update. This test ensures the removed properties are not present.
430+
*/
431+
432+
// Backup current user settings
433+
ConfigServiceImpl &settings = ConfigService::Instance();
434+
const std::string userFileBackup = settings.getUserFilename() + ".unittest";
435+
try {
436+
Poco::File userFile(settings.getUserFilename());
437+
userFile.moveTo(userFileBackup);
438+
} catch (Poco::Exception &) {
439+
}
440+
441+
// pick a property that is not in the config file
442+
std::string garbage("garbage.truck");
443+
std::string keeps("garbage.keep"); // control property
444+
TS_ASSERT(!settings.hasProperty(garbage));
445+
TS_ASSERT(!settings.hasProperty(keeps));
446+
447+
// add the property to the config
448+
settings.setString(garbage, "yes");
449+
settings.setString(keeps, "yes");
450+
TS_ASSERT(settings.hasProperty(garbage));
451+
TS_ASSERT(settings.hasProperty(keeps));
452+
453+
// now remove the property and save.
454+
// ensure the removed property is not inside the config file
455+
settings.remove(garbage);
456+
settings.saveConfig(settings.getUserFilename());
457+
const std::string contents = readFile(settings.getUserFilename());
458+
TS_ASSERT(!contents.empty());
459+
TS_ASSERT(contents.find(garbage) == std::string::npos);
460+
TS_ASSERT(contents.find(keeps) != std::string::npos);
461+
462+
// restore the old file
463+
try {
464+
Poco::File backup(userFileBackup);
465+
backup.moveTo(settings.getUserFilename());
466+
} catch (Poco::Exception &) {
467+
}
468+
}
469+
413470
void testSaveConfigWithPropertyRemoved() {
414471
const std::string filename("user.settings.testSaveConfigWithPropertyRemoved");
415472
Poco::File prop_file(filename);

Framework/PythonInterface/mantid/kernel/src/Exports/ConfigService.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ void export_ConfigService() {
104104
"definitions")
105105
.def("getFacilityNames", &ConfigServiceImpl::getFacilityNames, arg("self"), "Returns the default facility")
106106
.def("getFacilities", &ConfigServiceImpl::getFacilities, arg("self"), "Returns the default facility")
107+
.def("configureLogging", &ConfigServiceImpl::configureLogging, arg("self"),
108+
"Configure and start the logging framework")
107109
.def("remove", &ConfigServiceImpl::remove, (arg("self"), arg("rootName")), "Remove the indicated key.")
108110
.def("getFacility", (const FacilityInfo &(ConfigServiceImpl::*)() const) & ConfigServiceImpl::getFacility,
109111
arg("self"), return_value_policy<reference_existing_object>(), "Returns the default facility")
@@ -144,10 +146,12 @@ void export_ConfigService() {
144146
.def("saveConfig", &ConfigServiceImpl::saveConfig, (arg("self"), arg("filename")),
145147
"Saves the keys that have changed from their default to the given "
146148
"filename")
149+
.def("getLogLevel", &ConfigServiceImpl::getLogLevel, arg("self"),
150+
"Return the string value for the log representation")
147151
.def("setLogLevel", (void (ConfigServiceImpl::*)(int, bool)) & ConfigServiceImpl::setLogLevel,
148152
(arg("self"), arg("logLevel"), arg("quiet") = false),
149153
"Sets the log level priority for all the log channels, logLevel 1 = Fatal, 6 = information, 7 = Debug")
150-
.def("setLogLevel", (void (ConfigServiceImpl::*)(std::string, bool)) & ConfigServiceImpl::setLogLevel,
154+
.def("setLogLevel", (void (ConfigServiceImpl::*)(std::string const &, bool)) & ConfigServiceImpl::setLogLevel,
151155
(arg("self"), arg("logLevel"), arg("quiet") = false),
152156
"Sets the log level priority for all the log channels. Allowed values are fatal, critical, error, warning, "
153157
"notice, information, debug, and trace.")

Framework/PythonInterface/test/python/mantid/kernel/ConfigServiceTest.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ def test_setting_log_channel_levels(self):
133133
testhelpers.assertRaisesNothing(self, config.setLogLevel, 4, True)
134134
testhelpers.assertRaisesNothing(self, config.setLogLevel, "warning", True)
135135

136+
def test_log_level_get_set(self):
137+
logLevels = ["fatal", "error", "warning", "information", "debug"]
138+
for x in logLevels:
139+
config.setLogLevel(x)
140+
self.assertEqual(config.getLogLevel(), x)
141+
136142
def test_properties_documented(self):
137143
# location of the rst file relative to this file this will break if either moves
138144
doc_filename = os.path.split(__file__)[0]

buildconfig/CMake/CppCheck_Suppressions.txt.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ returnByReference:${CMAKE_SOURCE_DIR}/Framework/Kernel/inc/MantidKernel/ConfigSe
9191
returnByReference:${CMAKE_SOURCE_DIR}/Framework/Kernel/inc/MantidKernel/ConfigService.h:197
9292
virtualCallInConstructor:${CMAKE_SOURCE_DIR}/Framework/Kernel/inc/MantidKernel/ThreadScheduler.h:174
9393
virtualCallInConstructor:${CMAKE_SOURCE_DIR}/Framework/Kernel/inc/MantidKernel/ThreadScheduler.h:278
94-
passedByValue:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/ConfigService.cpp:1919
9594
constParameterPointer:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/TopicInfo.cpp:38
9695
returnStdMoveLocal:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/FilteredTimeSeriesProperty.cpp:408
9796
constVariablePointer:${CMAKE_SOURCE_DIR}/Framework/Kernel/src/PropertyManagerProperty.cpp:149
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- expose :class:`ConfigService::configureLogging() <mantid.kernel.ConfigServiceImpl.configureLogging>` to python API
2+
- expose :class:`ConfigService::getLogLevel() <mantid.kernel.ConfigServiceImpl.getLogLevel>` to python API
3+
- fix handling of removed propertyies in :class:`ConfigService::saveConfig() <mantid.kernel.ConfigServiceImpl.saveConfig>`

0 commit comments

Comments
 (0)