Fix focus, defaultId, foregroundId logic 67/34467/3
authorPiotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
Tue, 27 Jan 2015 15:13:03 +0000 (16:13 +0100)
committerPiotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
Wed, 28 Jan 2015 09:58:28 +0000 (10:58 +0100)
[Bug/Feature]   Buggy focus logic. DefaultId, foregroundId does not work
                after implementing dynamic zone adding and removing.
[Cause]         N/A
[Solution]      Update focus after remove, pause and stop zone.
                DefaultId moved to dynamic config. ForegroundId removed
                from config.
[Verification]  Build, run tests, run daemon and check focus after
                adding, pausing, removing zones, switching zones.

Change-Id: I325e501242b747802da07b103ccba4c20891138e

17 files changed:
common/config.hpp
server/configs/daemon.conf.in
server/host-dbus-definitions.hpp
server/zones-manager-config.hpp
server/zones-manager.cpp
server/zones-manager.hpp
tests/unit_tests/client/configs/ut-client/test-dbus-daemon.conf.in
tests/unit_tests/server/configs/CMakeLists.txt
tests/unit_tests/server/configs/ut-server/buggy-daemon.conf.in
tests/unit_tests/server/configs/ut-server/test-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/buggy-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in [deleted file]
tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in [deleted file]
tests/unit_tests/server/configs/ut-zones-manager/empty-dbus-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/test-daemon.conf.in
tests/unit_tests/server/configs/ut-zones-manager/test-dbus-daemon.conf.in
tests/unit_tests/server/ut-zones-manager.cpp

index 0721de4..753430e 100644 (file)
@@ -55,6 +55,7 @@
 #define final
 #define override
 #define thread_local __thread  // use GCC extension instead of C++11
+#define steady_clock monotonic_clock
 #endif // GCC_VERSION < 40700
 
 #endif // GCC_VERSION
index b7d9c87..ea2d457 100644 (file)
@@ -6,7 +6,6 @@
     "zoneTemplatePath" : "/etc/vasum/templates/template.conf",
     "zoneNewConfigPrefix" : "/var/lib/vasum",
     "runMountPointPrefix" : "/var/run/zones",
-    "foregroundId" : "",
     "defaultId" : "",
     "lxcTemplatePrefix" : "/etc/vasum/lxc-templates",
     "inputConfig" : {"enabled" : true,
index e17261c..ff13843 100644 (file)
@@ -36,7 +36,7 @@ const std::string BUS_NAME                  = "org.tizen.vasum.host";
 const std::string OBJECT_PATH               = "/org/tizen/vasum/host";
 const std::string INTERFACE                 = "org.tizen.vasum.host.manager";
 
-const std::string ERROR_ZONE_STOPPED        = "org.tizen.vasum.host.Error.ZonesStopped";
+const std::string ERROR_ZONE_NOT_RUNNING    = "org.tizen.vasum.host.Error.ZonesNotRunning";
 
 const std::string METHOD_GET_ZONE_DBUSES    = "GetZoneDbuses";
 const std::string METHOD_GET_ZONE_ID_LIST   = "GetZoneIds";
index ab55762..19da74a 100644 (file)
@@ -44,16 +44,6 @@ struct ZonesManagerConfig {
     std::string dbPath;
 
     /**
-     * An ID of a currently focused/foreground zone.
-     */
-    std::string foregroundId;
-
-    /**
-     * An ID of default zone.
-     */
-    std::string defaultId;
-
-    /**
      * A path where the zones mount points reside.
      */
     std::string zonesPath;
@@ -97,8 +87,6 @@ struct ZonesManagerConfig {
     CONFIG_REGISTER
     (
         dbPath,
-        foregroundId,
-        defaultId,
         zonesPath,
         zoneImagePath,
         zoneTemplatePath,
@@ -118,9 +106,15 @@ struct ZonesManagerDynamicConfig {
      */
     std::vector<std::string> zoneConfigs;
 
+    /**
+     * An ID of default zone.
+     */
+    std::string defaultId;
+
     CONFIG_REGISTER
     (
-        zoneConfigs
+        zoneConfigs,
+        defaultId
     )
 };
 
index 99e87ee..fa6ec80 100644 (file)
@@ -156,12 +156,7 @@ ZonesManager::ZonesManager(const std::string& configPath)
         createZone(utils::createFilePath(mConfig.zoneNewConfigPrefix, zoneConfig));
     }
 
-    // check if default zone exists, throw ZoneOperationException if not found
-    if (!mConfig.defaultId.empty() && mZones.find(mConfig.defaultId) == mZones.end()) {
-        LOGE("Provided default zone ID " << mConfig.defaultId << " is invalid.");
-        throw ZoneOperationException("Provided default zone ID " + mConfig.defaultId +
-                                          " is invalid.");
-    }
+    updateDefaultId();
 
     LOGD("ZonesManager object instantiated");
 
@@ -198,6 +193,29 @@ void ZonesManager::saveDynamicConfig()
     config::saveToKVStore(mConfig.dbPath, mDynamicConfig, DB_PREFIX);
 }
 
+void ZonesManager::updateDefaultId()
+{
+    // TODO add an api to change defaultId
+    if (mZones.empty() && mDynamicConfig.defaultId.empty()) {
+        LOGT("Keep empty defaultId");
+        return;
+    }
+    if (mZones.find(mDynamicConfig.defaultId) != mZones.end()) {
+        LOGT("Keep " << mDynamicConfig.defaultId << " as defaultId");
+        return;
+    }
+
+    // update
+    if (mZones.empty()) {
+        mDynamicConfig.defaultId.clear();
+        LOGD("DefaultId cleared");
+    } else {
+        mDynamicConfig.defaultId = mZones.begin()->first;
+        LOGD("DefaultId changed to " << mDynamicConfig.defaultId);
+    }
+    saveDynamicConfig();
+}
+
 void ZonesManager::createZone(const std::string& zoneConfigPath)
 {
     LOGT("Creating Zone " << zoneConfigPath);
@@ -251,7 +269,6 @@ void ZonesManager::destroyZone(const std::string& zoneId)
         throw ZoneOperationException("No such zone");
     }
 
-    // TODO give back the focus
     it->second->setDestroyOnExit();
     mZones.erase(it);
 
@@ -264,14 +281,34 @@ void ZonesManager::destroyZone(const std::string& zoneId)
     // update dynamic config
     remove(mDynamicConfig.zoneConfigs, getConfigName(zoneId));
     saveDynamicConfig();
+    updateDefaultId();
+
+    refocus();
 }
 
 void ZonesManager::focus(const std::string& zoneId)
 {
     Lock lock(mMutex);
 
+    if (zoneId == mActiveZoneId) {
+        // nothing to do
+        return;
+    }
+
+    if (zoneId.empty()) {
+        LOGI("Focus to: host");
+        // give back the focus to the host
+        // TODO switch to host vt
+        mActiveZoneId.clear();
+        return;
+    }
+
+    LOGI("Focus to: " << zoneId);
+
     /* try to access the object first to throw immediately if it doesn't exist */
-    ZoneMap::mapped_type& foregroundZone = mZones.at(zoneId);
+    auto& foregroundZone = mZones.at(zoneId);
+
+    assert(foregroundZone->isRunning());
 
     if (!foregroundZone->activateVT()) {
         LOGE("Failed to activate zones VT. Aborting focus.");
@@ -279,12 +316,44 @@ void ZonesManager::focus(const std::string& zoneId)
     }
 
     for (auto& zone : mZones) {
-        LOGD(zone.second->getId() << ": being sent to background");
-        zone.second->goBackground();
+        if (zone.first == zoneId) {
+            LOGD(zone.first << ": being sent to foreground");
+            zone.second->goForeground();
+        } else {
+            LOGD(zone.first << ": being sent to background");
+            zone.second->goBackground();
+        }
+    }
+    mActiveZoneId = zoneId;
+}
+
+void ZonesManager::refocus()
+{
+    Lock lock(mMutex);
+
+    // check if refocus is required
+    auto oldIter = mZones.find(mActiveZoneId);
+    if (oldIter != mZones.end() && oldIter->second->isRunning()) {
+        return;
+    }
+
+    // try to refocus to defaultId
+    auto iter = mZones.find(mDynamicConfig.defaultId);
+    if (iter != mZones.end() && iter->second->isRunning()) {
+        // focus to default
+        focus(iter->first);
+    } else {
+        // focus to any running or to host if not found
+        auto zoneIsRunning = [](const ZoneMap::value_type& pair) {
+            return pair.second->isRunning();
+        };
+        auto iter = std::find_if(mZones.begin(), mZones.end(), zoneIsRunning);
+        if (iter == mZones.end()) {
+            focus(std::string());
+        } else {
+            focus(iter->first);
+        }
     }
-    mConfig.foregroundId = foregroundZone->getId();
-    LOGD(mConfig.foregroundId << ": being sent to foreground");
-    foregroundZone->goForeground();
 }
 
 void ZonesManager::startAll()
@@ -293,30 +362,11 @@ void ZonesManager::startAll()
 
     Lock lock(mMutex);
 
-    bool isForegroundFound = false;
-
     for (auto& zone : mZones) {
         zone.second->start();
-
-        if (zone.first == mConfig.foregroundId) {
-            isForegroundFound = true;
-            LOGI(zone.second->getId() << ": set as the foreground zone");
-            zone.second->goForeground();
-        }
     }
 
-    if (!isForegroundFound) {
-        auto foregroundIterator = std::min_element(mZones.begin(), mZones.end(),
-                                                   [](ZoneMap::value_type &c1, ZoneMap::value_type &c2) {
-                                                       return c1.second->getPrivilege() < c2.second->getPrivilege();
-                                                   });
-
-        if (foregroundIterator != mZones.end()) {
-            mConfig.foregroundId = foregroundIterator->second->getId();
-            LOGI(mConfig.foregroundId << ": no foreground zone configured, setting one with highest priority");
-            foregroundIterator->second->goForeground();
-        }
-    }
+    refocus();
 }
 
 void ZonesManager::stopAll()
@@ -328,6 +378,8 @@ void ZonesManager::stopAll()
     for (auto& zone : mZones) {
         zone.second->stop();
     }
+
+    refocus();
 }
 
 bool ZonesManager::isPaused(const std::string& zoneId)
@@ -359,13 +411,15 @@ std::string ZonesManager::getRunningForegroundZoneId() const
 {
     Lock lock(mMutex);
 
-    for (auto& zone : mZones) {
-        if (zone.first == mConfig.foregroundId &&
-            zone.second->isRunning()) {
-            return zone.first;
-        }
+    if (!mActiveZoneId.empty() && !mZones.at(mActiveZoneId)->isRunning()) {
+        // Can zone change its state by itself?
+        // Maybe when it is shut down by itself? TODO check it
+        LOGW("Active zone " << mActiveZoneId << " is not running any more!");
+        assert(false);
+        return std::string();
     }
-    return std::string();
+
+    return mActiveZoneId;
 }
 
 std::string ZonesManager::getNextToForegroundZoneId()
@@ -378,22 +432,21 @@ std::string ZonesManager::getNextToForegroundZoneId()
     }
 
     for (auto it = mZones.begin(); it != mZones.end(); ++it) {
-        if (it->first == mConfig.foregroundId &&
-            it->second->isRunning()) {
+        if (it->first == mActiveZoneId && it->second->isRunning()) {
             auto nextIt = std::next(it);
             if (nextIt != mZones.end()) {
                 return nextIt->first;
             }
         }
     }
-    return mZones.begin()->first;
+    return mZones.begin()->first;//TODO fix - check isRunning
 }
 
 void ZonesManager::switchingSequenceMonitorNotify()
 {
     LOGI("switchingSequenceMonitorNotify() called");
 
-    auto nextZoneId = getNextToForegroundZoneId();
+    std::string nextZoneId = getNextToForegroundZoneId();
 
     if (!nextZoneId.empty()) {
         focus(nextZoneId);
@@ -436,13 +489,15 @@ void ZonesManager::displayOffHandler(const std::string& /*caller*/)
     // get config of currently set zone and switch if switchToDefaultAfterTimeout is true
     Lock lock(mMutex);
 
-    const std::string activeZoneName = getRunningForegroundZoneId();
-    const auto& activeZone = mZones.find(activeZoneName);
+    auto activeZone = mZones.find(mActiveZoneId);
 
     if (activeZone != mZones.end() &&
-        activeZone->second->isSwitchToDefaultAfterTimeoutAllowed()) {
-        LOGI("Switching to default zone " << mConfig.defaultId);
-        focus(mConfig.defaultId);
+        activeZone->second->isSwitchToDefaultAfterTimeoutAllowed() &&
+        !mDynamicConfig.defaultId.empty() &&
+        mZones.at(mDynamicConfig.defaultId)->isRunning()) {
+
+        LOGI("Switching to default zone " << mDynamicConfig.defaultId);
+        focus(mDynamicConfig.defaultId);
     }
 }
 
@@ -630,11 +685,9 @@ void ZonesManager::handleGetActiveZoneIdCall(dbus::MethodResultBuilder::Pointer
 
     Lock lock(mMutex);
 
-    if (!mConfig.foregroundId.empty() && mZones[mConfig.foregroundId]->isRunning()){
-        result->set(g_variant_new("(s)", mConfig.foregroundId.c_str()));
-    } else {
-        result->set(g_variant_new("(s)", ""));
-    }
+    std::string id = getRunningForegroundZoneId();
+
+    result->set(g_variant_new("(s)", id.c_str()));
 }
 
 void ZonesManager::handleGetZoneInfoCall(const std::string& id,
@@ -651,7 +704,7 @@ void ZonesManager::handleGetZoneInfoCall(const std::string& id,
     }
     const auto& zone = mZones[id];
     const char* state;
-    //TODO: Use the lookup map.
+
     if (zone->isRunning()) {
         state = "RUNNING";
     } else if (zone->isStopped()) {
@@ -752,10 +805,10 @@ void ZonesManager::handleSetActiveZoneCall(const std::string& id,
         return;
     }
 
-    if (zone->second->isStopped()){
-        LOGE("Could not activate a stopped zone");
-        result->setError(api::host::ERROR_ZONE_STOPPED,
-                         "Could not activate a stopped zone");
+    if (!zone->second->isRunning()){
+        LOGE("Could not activate stopped or paused zone");
+        result->setError(api::host::ERROR_ZONE_NOT_RUNNING,
+                         "Could not activate stopped or paused zone");
         return;
     }
 
@@ -891,6 +944,7 @@ void ZonesManager::handleCreateZoneCall(const std::string& id,
 
     mDynamicConfig.zoneConfigs.push_back(newConfigName);
     saveDynamicConfig();
+    updateDefaultId();
 
     result->setVoid();
 }
@@ -939,13 +993,19 @@ void ZonesManager::handleShutdownZoneCall(const std::string& id,
 
     auto shutdown = [id, result, this] {
         try {
-            mZones[id]->stop();
+            ZoneMap::mapped_type zone;
+            {
+                Lock lock(mMutex);
+                zone = mZones.at(id);
+            }
+            zone->stop();
+            refocus();
+            result->setVoid();
         } catch (ZoneOperationException& e) {
             LOGE("Error during zone shutdown: " << e.what());
             result->setError(api::ERROR_INTERNAL, "Failed to shutdown zone");
             return;
         }
-        result->setVoid();
     };
 
     mWorker->addTask(shutdown);
@@ -1008,6 +1068,7 @@ void ZonesManager::handleLockZoneCall(const std::string& id,
     LOGT("Lock zone");
     try {
         zone.suspend();
+        refocus();
     } catch (ZoneOperationException& e) {
         LOGE(e.what());
         result->setError(api::ERROR_INTERNAL, e.what());
index 677b056..72dd952 100644 (file)
@@ -117,11 +117,14 @@ private:
     // to hold InputMonitor pointer to monitor if zone switching sequence is recognized
     std::unique_ptr<InputMonitor> mSwitchingSequenceMonitor;
     std::unique_ptr<ProxyCallPolicy> mProxyCallPolicy;
-    typedef std::unordered_map<std::string, std::shared_ptr<Zone>> ZoneMap;
+    typedef std::unordered_map<std::string, std::shared_ptr<Zone>> ZoneMap;//TODO should keep order of insertions
     ZoneMap mZones; // map of zones, id is the key
+    std::string mActiveZoneId;
     bool mDetachOnExit;
 
     void saveDynamicConfig();
+    void updateDefaultId();
+    void refocus();
     void switchingSequenceMonitorNotify();
     void generateNewConfig(const std::string& id,
                            const std::string& templatePath,
index 544accc..e0af664 100644 (file)
@@ -3,7 +3,6 @@
     "zoneConfigs" : ["zones/console1-dbus.conf",
                           "zones/console2-dbus.conf",
                           "zones/console3-dbus.conf"],
-    "foregroundId" : "ut-zones-manager-console1-dbus",
     "defaultId" : "ut-zones-manager-console1-dbus",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
index 596c123..fac9d99 100644 (file)
@@ -50,10 +50,6 @@ CONFIGURE_FILE(ut-zones-manager/test-daemon.conf.in
                ${CMAKE_BINARY_DIR}/ut-zones-manager/test-daemon.conf @ONLY)
 CONFIGURE_FILE(ut-zones-manager/buggy-daemon.conf.in
                ${CMAKE_BINARY_DIR}/ut-zones-manager/buggy-daemon.conf @ONLY)
-CONFIGURE_FILE(ut-zones-manager/buggy-default-daemon.conf.in
-               ${CMAKE_BINARY_DIR}/ut-zones-manager/buggy-default-daemon.conf @ONLY)
-CONFIGURE_FILE(ut-zones-manager/buggy-foreground-daemon.conf.in
-               ${CMAKE_BINARY_DIR}/ut-zones-manager/buggy-foreground-daemon.conf @ONLY)
 CONFIGURE_FILE(ut-zones-manager/test-dbus-daemon.conf.in
                ${CMAKE_BINARY_DIR}/ut-zones-manager/test-dbus-daemon.conf @ONLY)
 CONFIGURE_FILE(ut-zones-manager/empty-dbus-daemon.conf.in
index 9df74dc..bf274de 100644 (file)
@@ -6,7 +6,6 @@
     "zoneTemplatePath" : "no_need_for_templates_in_this_test",
     "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-server/",
     "runMountPointPrefix" : "",
-    "foregroundId" : "ut-server-zone1",
     "defaultId" : "ut-server-zone1",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index 697a468..e1a67e8 100644 (file)
@@ -6,7 +6,6 @@
     "zoneTemplatePath" : "no_need_for_templates_in_this_test",
     "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-server/",
     "runMountPointPrefix" : "",
-    "foregroundId" : "ut-server-zone1",
     "defaultId" : "ut-server-zone1",
     "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
     "inputConfig" : {"enabled" : false,
index 754594f..d07ab4c 100644 (file)
@@ -2,7 +2,6 @@
     "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1.conf", "missing/file/path/missing.conf", "zones/console3.conf"],
     "runMountPointPrefix" : "",
-    "foregroundId" : "ut-zones-manager-console1",
     "defaultId" : "ut-zones-manager-console1",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/buggy-default-daemon.conf.in
deleted file mode 100644 (file)
index 3eb9e02..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "dbPath" : "/tmp/ut-zones/vasum.db",
-    "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
-    "runMountPointPrefix" : "",
-    "foregroundId" : "ut-zones-manager-console1",
-    "defaultId" : "in_no_way_there_is_a_valid_id_here",
-    "zonesPath" : "/tmp/ut-zones",
-    "zoneImagePath" : "",
-    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
-    "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
-    "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
-    "inputConfig" : {"enabled" : false,
-                     "device" : "/dev/doesnotexist",
-                     "code" : 139,
-                     "numberOfEvents" : 2,
-                     "timeWindowMs" : 500},
-    "proxyCallRules" : []
-}
diff --git a/tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/buggy-foreground-daemon.conf.in
deleted file mode 100644 (file)
index 6e02372..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "dbPath" : "/tmp/ut-zones/vasum.db",
-    "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
-    "runMountPointPrefix" : "",
-    "foregroundId" : "this_id_does_not_exist",
-    "defaultId" : "ut-zones-manager-console1",
-    "zonesPath" : "/tmp/ut-zones",
-    "zoneImagePath" : "",
-    "zoneTemplatePath" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/templates/template.conf",
-    "zoneNewConfigPrefix" : "@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/",
-    "lxcTemplatePrefix" : "@VSM_TEST_LXC_TEMPLATES_INSTALL_DIR@",
-    "inputConfig" : {"enabled" : false,
-                     "device" : "/dev/doesnotexist",
-                     "code" : 139,
-                     "numberOfEvents" : 2,
-                     "timeWindowMs" : 500},
-    "proxyCallRules" : []
-}
index a80be26..943ade9 100644 (file)
@@ -1,7 +1,6 @@
 {
     "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : [],
-    "foregroundId" : "",
     "defaultId" : "",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
index 14cea0b..f3cddde 100644 (file)
@@ -2,7 +2,6 @@
     "dbPath" : "/tmp/ut-zones/vasum.db",
     "zoneConfigs" : ["zones/console1.conf", "zones/console2.conf", "zones/console3.conf"],
     "runMountPointPrefix" : "",
-    "foregroundId" : "ut-zones-manager-console1",
     "defaultId" : "ut-zones-manager-console1",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
index 2a55718..fc47ff9 100644 (file)
@@ -3,7 +3,6 @@
     "zoneConfigs" : ["zones/console1-dbus.conf",
                           "zones/console2-dbus.conf",
                           "zones/console3-dbus.conf"],
-    "foregroundId" : "ut-zones-manager-console1-dbus",
     "defaultId" : "ut-zones-manager-console1-dbus",
     "zonesPath" : "/tmp/ut-zones",
     "zoneImagePath" : "",
index 5925052..3929c77 100644 (file)
@@ -65,11 +65,10 @@ const std::string TEST_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zon
 const std::string TEST_DBUS_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/test-dbus-daemon.conf";
 const std::string EMPTY_DBUS_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/empty-dbus-daemon.conf";
 const std::string BUGGY_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/buggy-daemon.conf";
-const std::string BUGGY_FOREGROUND_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/buggy-foreground-daemon.conf";
-const std::string BUGGY_DEFAULTID_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/buggy-default-daemon.conf";
 const std::string TEST_ZONE_CONF_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zones-manager/zones/";
 const std::string MISSING_CONFIG_PATH = "/this/is/a/missing/file/path/missing-daemon.conf";
 const int EVENT_TIMEOUT = 5000;
+const int UNEXPECTED_EVENT_TIMEOUT = EVENT_TIMEOUT / 5;
 const int TEST_DBUS_CONNECTION_ZONES_COUNT = 3;
 const std::string PREFIX_CONSOLE_NAME = "ut-zones-manager-console";
 const std::string TEST_APP_NAME = "testapp";
@@ -438,7 +437,8 @@ private:
     std::mutex mMutex;
     std::condition_variable mNameCondition;
 
-    bool isHost() const {
+    bool isHost() const
+    {
         return mId == HOST_ID;
     }
 
@@ -452,12 +452,26 @@ private:
     }
 };
 
-std::function<bool(const std::exception&)> expectedMessage(const std::string& message) {
+std::function<bool(const std::exception&)> expectedMessage(const std::string& message)
+{
     return [=](const std::exception& e) {
         return e.what() == message;
     };
 }
 
+template<class Predicate>
+bool spinWaitFor(int timeoutMs, Predicate pred)
+{
+    auto until = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeoutMs);
+    while (!pred()) {
+        if (std::chrono::steady_clock::now() >= until) {
+            return false;
+        }
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    }
+    return true;
+}
+
 struct Fixture {
     vasum::utils::ScopedGlibLoop mLoop;
 
@@ -499,19 +513,6 @@ BOOST_AUTO_TEST_CASE(StartAllTest)
     BOOST_CHECK(cm.getRunningForegroundZoneId() == "ut-zones-manager-console1");
 }
 
-BOOST_AUTO_TEST_CASE(BuggyForegroundTest)
-{
-    ZonesManager cm(BUGGY_FOREGROUND_CONFIG_PATH);
-    cm.startAll();
-    BOOST_CHECK(cm.getRunningForegroundZoneId() == "ut-zones-manager-console2");
-}
-
-BOOST_AUTO_TEST_CASE(BuggyDefaultTest)
-{
-    BOOST_REQUIRE_THROW(ZonesManager cm(BUGGY_DEFAULTID_CONFIG_PATH),
-                        ZoneOperationException);
-}
-
 BOOST_AUTO_TEST_CASE(StopAllTest)
 {
     ZonesManager cm(TEST_CONFIG_PATH);
@@ -626,9 +627,6 @@ BOOST_AUTO_TEST_CASE(DisplayOffTest)
         client->setName(fake_power_manager_api::BUS_NAME);
     }
 
-    std::mutex Mutex;
-    std::unique_lock<std::mutex> Lock(Mutex);
-    std::condition_variable Condition;
     auto cond = [&cm]() -> bool {
         return cm.getRunningForegroundZoneId() == "ut-zones-manager-console1-dbus";
     };
@@ -645,7 +643,7 @@ BOOST_AUTO_TEST_CASE(DisplayOffTest)
                            nullptr);
 
         // check if default zone has focus
-        BOOST_CHECK(Condition.wait_for(Lock, std::chrono::milliseconds(EVENT_TIMEOUT), cond));
+        BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, cond));
     }
 }
 
@@ -761,9 +759,6 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest)
         client->setName(fake_power_manager_api::BUS_NAME);
     }
 
-    std::mutex condMutex;
-    std::unique_lock<std::mutex> condLock(condMutex);
-    std::condition_variable condition;
     auto cond = [&cm]() -> bool {
         return cm.getRunningForegroundZoneId() == "ut-zones-manager-console1-dbus";
     };
@@ -779,7 +774,7 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest)
                            nullptr);
 
         // check if default zone has focus
-        BOOST_CHECK(condition.wait_for(condLock, std::chrono::milliseconds(EVENT_TIMEOUT), cond));
+        BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, cond));
 
         // focus non-default zone with disabled switching
         cm.focus("ut-zones-manager-console2-dbus");
@@ -791,7 +786,7 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest)
                            nullptr);
 
         // now default zone should not be focused
-        BOOST_CHECK(!condition.wait_for(condLock, std::chrono::milliseconds(EVENT_TIMEOUT), cond));
+        BOOST_CHECK(!spinWaitFor(UNEXPECTED_EVENT_TIMEOUT, cond));
     }
 }
 
@@ -1048,6 +1043,8 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest)
 
     cm.startAll();
 
+    BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1);
+    cm.focus(zone3);
     BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone3);
 
     // destroy zone2
@@ -1058,7 +1055,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest)
     // destroy zone3
     dbus.callAsyncMethodDestroyZone(zone3, resultCallback);
     BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
-    //BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1);//TODO fix it
+    BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1);
 
     // destroy zone1
     dbus.callAsyncMethodDestroyZone(zone1, resultCallback);
@@ -1159,7 +1156,7 @@ BOOST_AUTO_TEST_CASE(LockUnlockZoneTest)
                                         "ut-zones-manager-console2-dbus",
                                         "ut-zones-manager-console3-dbus"};
 
-    for (std::string& zoneId: zoneIds){
+    for (const std::string& zoneId: zoneIds){
         dbus.callMethodLockZone(zoneId);
         BOOST_CHECK(cm.isPaused(zoneId));
         dbus.callMethodUnlockZone(zoneId);