Implement shutdown/start function in server, client and cli 69/32669/2
authorDariusz Michaluk <d.michaluk@samsung.com>
Thu, 18 Dec 2014 08:56:02 +0000 (09:56 +0100)
committerPiotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
Tue, 23 Dec 2014 11:04:48 +0000 (03:04 -0800)
[Bug/Feature]   Implement shutdown/start function in server, client and cli
[Cause]         N/A
[Solution]      N/A
[Verification]  Build, run appropriate function (through cli)

Change-Id: Ib06feff13305db134cf3415c38e83d0e836f149a
Signed-off-by: Dariusz Michaluk <d.michaluk@samsung.com>
cli/command-line-interface.cpp
cli/command-line-interface.hpp
cli/main.cpp
client/vasum-client-impl.cpp
server/host-connection.cpp
server/host-connection.hpp
server/host-dbus-definitions.hpp
server/zones-manager.cpp
server/zones-manager.hpp
tests/unit_tests/client/ut-client.cpp
tests/unit_tests/server/ut-zones-manager.cpp

index d7d8439..8120ca8 100644 (file)
@@ -165,6 +165,28 @@ void destroy_zone(int pos, int argc, const char** argv)
     one_shot(bind(vsm_destroy_zone, _1, argv[pos + 1], 1));
 }
 
+void shutdown_zone(int pos, int argc, const char** argv)
+{
+    using namespace std::placeholders;
+
+    if (argc <= pos + 1) {
+        throw runtime_error("Not enough parameters");
+    }
+
+    one_shot(bind(vsm_shutdown_zone, _1, argv[pos + 1]));
+}
+
+void start_zone(int pos, int argc, const char** argv)
+{
+    using namespace std::placeholders;
+
+    if (argc <= pos + 1) {
+        throw runtime_error("Not enough parameters");
+    }
+
+    one_shot(bind(vsm_start_zone, _1, argv[pos + 1]));
+}
+
 void lock_zone(int pos, int argc, const char** argv)
 {
     using namespace std::placeholders;
index d2fe6be..789abd6 100644 (file)
@@ -118,6 +118,20 @@ void create_zone(int pos, int argc, const char** argv);
 void destroy_zone(int pos, int argc, const char** argv);
 
 /**
+ * Parses command line arguments and call vsm_shutdown_zone
+ *
+ * @see vsm_shutdown_zone
+ */
+void shutdown_zone(int pos, int argc, const char** argv);
+
+/**
+ * Parses command line arguments and call vsm_start_zone
+ *
+ * @see vsm_start_zone
+ */
+void start_zone(int pos, int argc, const char** argv);
+
+/**
  * Parses command line arguments and call vsm_lock_zone
  *
  * @see vsm_lock_zone
index 448d32d..b91d4e1 100644 (file)
@@ -60,6 +60,22 @@ std::map<std::string, CommandLineInterface> commands = {
         }
     },
     {
+        "shutdown_zone", {
+            shutdown_zone,
+            "shutdown_zone zone_id",
+            "Shutdown zone",
+            {{"zone_id", "id zone name"}}
+        }
+    },
+    {
+        "start_zone", {
+            start_zone,
+            "start_zone zone_id",
+            "Start zone",
+            {{"zone_id", "id zone name"}}
+        }
+    },
+    {
         "lock_zone", {
             lock_zone,
             "lock_zone zone_id",
index 2aa923d..749b155 100644 (file)
@@ -460,16 +460,18 @@ VsmStatus Client::vsm_destroy_zone(const char* id) noexcept
     return callMethod(HOST_INTERFACE, api::host::METHOD_DESTROY_ZONE, args_in);
 }
 
-VsmStatus Client::vsm_shutdown_zone(const char*) noexcept
+VsmStatus Client::vsm_shutdown_zone(const char* id) noexcept
 {
-    mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
-    return vsm_get_status();
+    assert(id);
+    GVariant* args_in = g_variant_new("(s)", id);
+    return callMethod(HOST_INTERFACE, api::host::METHOD_SHUTDOWN_ZONE, args_in);
 }
 
-VsmStatus Client::vsm_start_zone(const char*) noexcept
+VsmStatus Client::vsm_start_zone(const char* id) noexcept
 {
-    mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented");
-    return vsm_get_status();
+    assert(id);
+    GVariant* args_in = g_variant_new("(s)", id);
+    return callMethod(HOST_INTERFACE, api::host::METHOD_START_ZONE, args_in);
 }
 
 VsmStatus Client::vsm_lock_zone(const char* id) noexcept
index 1eed929..621e3a2 100644 (file)
@@ -160,6 +160,16 @@ void HostConnection::setDestroyZoneCallback(const DestroyZoneCallback& callback)
     mDestroyZoneCallback = callback;
 }
 
+void HostConnection::setShutdownZoneCallback(const ShutdownZoneCallback& callback)
+{
+    mShutdownZoneCallback = callback;
+}
+
+void HostConnection::setStartZoneCallback(const StartZoneCallback& callback)
+{
+    mStartZoneCallback = callback;
+}
+
 void HostConnection::setLockZoneCallback(const LockZoneCallback& callback)
 {
     mLockZoneCallback = callback;
@@ -172,10 +182,10 @@ void HostConnection::setUnlockZoneCallback(const UnlockZoneCallback& callback)
 
 
 void HostConnection::onMessageCall(const std::string& objectPath,
-                                        const std::string& interface,
-                                        const std::string& methodName,
-                                        GVariant* parameters,
-                                        dbus::MethodResultBuilder::Pointer result)
+                                   const std::string& interface,
+                                   const std::string& methodName,
+                                   GVariant* parameters,
+                                   dbus::MethodResultBuilder::Pointer result)
 {
     if (objectPath != api::host::OBJECT_PATH || interface != api::host::INTERFACE) {
         return;
@@ -317,6 +327,24 @@ void HostConnection::onMessageCall(const std::string& objectPath,
         }
     }
 
+    if (methodName == api::host::METHOD_SHUTDOWN_ZONE) {
+        const gchar* id = NULL;
+        g_variant_get(parameters, "(&s)", &id);
+
+        if (mShutdownZoneCallback){
+            mShutdownZoneCallback(id, result);
+        }
+    }
+
+    if (methodName == api::host::METHOD_START_ZONE) {
+        const gchar* id = NULL;
+        g_variant_get(parameters, "(&s)", &id);
+
+        if (mStartZoneCallback){
+            mStartZoneCallback(id, result);
+        }
+    }
+
     if (methodName == api::host::METHOD_LOCK_ZONE) {
         const gchar* id = NULL;
         g_variant_get(parameters, "(&s)", &id);
@@ -353,7 +381,7 @@ void HostConnection::proxyCallAsync(const std::string& busName,
 }
 
 void HostConnection::signalZoneDbusState(const std::string& zoneId,
-                                              const std::string& dbusAddress)
+                                         const std::string& dbusAddress)
 {
     GVariant* parameters = g_variant_new("(ss)", zoneId.c_str(), dbusAddress.c_str());
     mDbusConnection->emitSignal(api::host::OBJECT_PATH,
index 68e3a73..49e2a08 100644 (file)
@@ -91,6 +91,12 @@ public:
                               )> DestroyZoneCallback;
     typedef std::function<void(const std::string& id,
                                dbus::MethodResultBuilder::Pointer result
+                              )> ShutdownZoneCallback;
+    typedef std::function<void(const std::string& id,
+                               dbus::MethodResultBuilder::Pointer result
+                              )> StartZoneCallback;
+    typedef std::function<void(const std::string& id,
+                               dbus::MethodResultBuilder::Pointer result
                               )> LockZoneCallback;
     typedef std::function<void(const std::string& id,
                                dbus::MethodResultBuilder::Pointer result
@@ -157,6 +163,16 @@ public:
     void setDestroyZoneCallback(const DestroyZoneCallback& callback);
 
     /**
+     * Register a callback called to shutdown zone
+     */
+    void setShutdownZoneCallback(const ShutdownZoneCallback& callback);
+
+    /**
+     * Register a callback called to start zone
+     */
+    void setStartZoneCallback(const StartZoneCallback& callback);
+
+    /**
      * Register a callback called to lock zone
      */
     void setLockZoneCallback(const LockZoneCallback& callback);
@@ -193,6 +209,8 @@ private:
     SetActiveZoneCallback mSetActiveZoneCallback;
     CreateZoneCallback mCreateZoneCallback;
     DestroyZoneCallback mDestroyZoneCallback;
+    ShutdownZoneCallback mShutdownZoneCallback;
+    StartZoneCallback mStartZoneCallback;
     LockZoneCallback mLockZoneCallback;
     UnlockZoneCallback mUnlockZoneCallback;
 
index 998c720..74ba96d 100644 (file)
@@ -32,9 +32,9 @@ namespace vasum {
 namespace api {
 namespace host {
 
-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 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";
 
@@ -42,12 +42,14 @@ const std::string METHOD_GET_ZONE_DBUSES    = "GetZoneDbuses";
 const std::string METHOD_GET_ZONE_ID_LIST   = "GetZoneIds";
 const std::string METHOD_GET_ACTIVE_ZONE_ID = "GetActiveZoneId";
 const std::string METHOD_GET_ZONE_INFO      = "GetZoneInfo";
-const std::string METHOD_DECLARE_FILE            = "DeclareFile";
-const std::string METHOD_DECLARE_MOUNT           = "DeclareMount";
-const std::string METHOD_DECLARE_LINK            = "DeclareLink";
+const std::string METHOD_DECLARE_FILE       = "DeclareFile";
+const std::string METHOD_DECLARE_MOUNT      = "DeclareMount";
+const std::string METHOD_DECLARE_LINK       = "DeclareLink";
 const std::string METHOD_SET_ACTIVE_ZONE    = "SetActiveZone";
 const std::string METHOD_CREATE_ZONE        = "CreateZone";
 const std::string METHOD_DESTROY_ZONE       = "DestroyZone";
+const std::string METHOD_SHUTDOWN_ZONE      = "ShutdownZone";
+const std::string METHOD_START_ZONE         = "StartZone";
 const std::string METHOD_LOCK_ZONE          = "LockZone";
 const std::string METHOD_UNLOCK_ZONE        = "UnlockZone";
 
@@ -108,6 +110,12 @@ const std::string DEFINITION =
     "    <method name='" + METHOD_DESTROY_ZONE + "'>"
     "      <arg type='s' name='id' direction='in'/>"
     "    </method>"
+    "    <method name='" + METHOD_SHUTDOWN_ZONE + "'>"
+    "      <arg type='s' name='id' direction='in'/>"
+    "    </method>"
+    "    <method name='" + METHOD_START_ZONE + "'>"
+    "      <arg type='s' name='id' direction='in'/>"
+    "    </method>"
     "    <method name='" + METHOD_LOCK_ZONE + "'>"
     "      <arg type='s' name='id' direction='in'/>"
     "    </method>"
index 1f9bef0..dcfa04c 100644 (file)
@@ -90,17 +90,17 @@ ZonesManager::ZonesManager(const std::string& managerConfigPath)
     mHostConnection.setProxyCallCallback(bind(&ZonesManager::handleProxyCall,
                                               this, HOST_ID, _1, _2, _3, _4, _5, _6, _7));
 
-    mHostConnection.setGetZoneDbusesCallback(bind(
-                &ZonesManager::handleGetZoneDbuses, this, _1));
+    mHostConnection.setGetZoneDbusesCallback(bind(&ZonesManager::handleGetZoneDbuses,
+                                                  this, _1));
 
     mHostConnection.setGetZoneIdsCallback(bind(&ZonesManager::handleGetZoneIdsCall,
-                                                    this, _1));
+                                               this, _1));
 
     mHostConnection.setGetActiveZoneIdCallback(bind(&ZonesManager::handleGetActiveZoneIdCall,
-                                                         this, _1));
+                                                    this, _1));
 
     mHostConnection.setGetZoneInfoCallback(bind(&ZonesManager::handleGetZoneInfoCall,
-                                                     this, _1, _2));
+                                                this, _1, _2));
 
     mHostConnection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall,
                                                 this, _1, _2, _3, _4, _5, _6));
@@ -112,19 +112,25 @@ ZonesManager::ZonesManager(const std::string& managerConfigPath)
                                                 this, _1, _2, _3, _4));
 
     mHostConnection.setSetActiveZoneCallback(bind(&ZonesManager::handleSetActiveZoneCall,
-                                                       this, _1, _2));
+                                                  this, _1, _2));
 
     mHostConnection.setCreateZoneCallback(bind(&ZonesManager::handleCreateZoneCall,
-                                                    this, _1, _2));
+                                               this, _1, _2));
 
     mHostConnection.setDestroyZoneCallback(bind(&ZonesManager::handleDestroyZoneCall,
-                                                     this, _1, _2));
+                                                this, _1, _2));
+
+    mHostConnection.setShutdownZoneCallback(bind(&ZonesManager::handleShutdownZoneCall,
+                                                 this, _1, _2));
+
+    mHostConnection.setStartZoneCallback(bind(&ZonesManager::handleStartZoneCall,
+                                              this, _1, _2));
 
     mHostConnection.setLockZoneCallback(bind(&ZonesManager::handleLockZoneCall,
-                                                  this, _1, _2));
+                                             this, _1, _2));
 
     mHostConnection.setUnlockZoneCallback(bind(&ZonesManager::handleUnlockZoneCall,
-                                                    this, _1, _2));
+                                               this, _1, _2));
 
     for (auto& zoneConfig : mConfig.zoneConfigs) {
         createZone(zoneConfig);
@@ -378,8 +384,8 @@ void ZonesManager::setZonesDetachOnExit()
 }
 
 void ZonesManager::notifyActiveZoneHandler(const std::string& caller,
-                                                     const std::string& application,
-                                                     const std::string& message)
+                                           const std::string& application,
+                                           const std::string& message)
 {
     LOGI("notifyActiveZoneHandler(" << caller << ", " << application << ", " << message
          << ") called");
@@ -412,9 +418,9 @@ void ZonesManager::displayOffHandler(const std::string& /*caller*/)
 }
 
 void ZonesManager::handleZoneMoveFileRequest(const std::string& srcZoneId,
-                                                       const std::string& dstZoneId,
-                                                       const std::string& path,
-                                                       dbus::MethodResultBuilder::Pointer result)
+                                             const std::string& dstZoneId,
+                                             const std::string& path,
+                                             dbus::MethodResultBuilder::Pointer result)
 {
     // TODO: this implementation is only a placeholder.
     // There are too many unanswered questions and security concerns:
@@ -493,13 +499,13 @@ void ZonesManager::handleZoneMoveFileRequest(const std::string& srcZoneId,
 }
 
 void ZonesManager::handleProxyCall(const std::string& caller,
-                                        const std::string& target,
-                                        const std::string& targetBusName,
-                                        const std::string& targetObjectPath,
-                                        const std::string& targetInterface,
-                                        const std::string& targetMethod,
-                                        GVariant* parameters,
-                                        dbus::MethodResultBuilder::Pointer result)
+                                   const std::string& target,
+                                   const std::string& targetBusName,
+                                   const std::string& targetObjectPath,
+                                   const std::string& targetInterface,
+                                   const std::string& targetMethod,
+                                   GVariant* parameters,
+                                   dbus::MethodResultBuilder::Pointer result)
 {
     if (!mProxyCallPolicy->isProxyCallAllowed(caller,
                                               target,
@@ -569,7 +575,7 @@ void ZonesManager::handleGetZoneDbuses(dbus::MethodResultBuilder::Pointer result
 }
 
 void ZonesManager::handleDbusStateChanged(const std::string& zoneId,
-                                               const std::string& dbusAddress)
+                                          const std::string& dbusAddress)
 {
     mHostConnection.signalZoneDbusState(zoneId, dbusAddress);
 }
@@ -603,7 +609,7 @@ void ZonesManager::handleGetActiveZoneIdCall(dbus::MethodResultBuilder::Pointer
 }
 
 void ZonesManager::handleGetZoneInfoCall(const std::string& id,
-                                                   dbus::MethodResultBuilder::Pointer result)
+                                         dbus::MethodResultBuilder::Pointer result)
 {
     LOGI("GetZoneInfo call");
 
@@ -637,11 +643,11 @@ void ZonesManager::handleGetZoneInfoCall(const std::string& id,
 }
 
 void ZonesManager::handleDeclareFileCall(const std::string& zone,
-                                              const int32_t& type,
-                                              const std::string& path,
-                                              const int32_t& flags,
-                                              const int32_t& mode,
-                                              dbus::MethodResultBuilder::Pointer result)
+                                         const int32_t& type,
+                                         const std::string& path,
+                                         const int32_t& flags,
+                                         const int32_t& mode,
+                                         dbus::MethodResultBuilder::Pointer result)
 {
     LOGI("DeclareFile call");
 
@@ -660,12 +666,12 @@ void ZonesManager::handleDeclareFileCall(const std::string& zone,
 }
 
 void ZonesManager::handleDeclareMountCall(const std::string& source,
-                                               const std::string& zone,
-                                               const std::string& target,
-                                               const std::string& type,
-                                               const uint64_t& flags,
-                                               const std::string& data,
-                                               dbus::MethodResultBuilder::Pointer result)
+                                          const std::string& zone,
+                                          const std::string& target,
+                                          const std::string& type,
+                                          const uint64_t& flags,
+                                          const std::string& data,
+                                          dbus::MethodResultBuilder::Pointer result)
 {
     LOGI("DeclareMount call");
 
@@ -684,9 +690,9 @@ void ZonesManager::handleDeclareMountCall(const std::string& source,
 }
 
 void ZonesManager::handleDeclareLinkCall(const std::string& source,
-                                              const std::string& zone,
-                                              const std::string& target,
-                                              dbus::MethodResultBuilder::Pointer result)
+                                         const std::string& zone,
+                                         const std::string& target,
+                                         dbus::MethodResultBuilder::Pointer result)
 {
     LOGI("DeclareLink call");
     try {
@@ -704,7 +710,7 @@ void ZonesManager::handleDeclareLinkCall(const std::string& source,
 }
 
 void ZonesManager::handleSetActiveZoneCall(const std::string& id,
-                                                     dbus::MethodResultBuilder::Pointer result)
+                                           dbus::MethodResultBuilder::Pointer result)
 {
     LOGI("SetActiveZone call; Id=" << id );
 
@@ -730,8 +736,8 @@ void ZonesManager::handleSetActiveZoneCall(const std::string& id,
 
 
 void ZonesManager::generateNewConfig(const std::string& id,
-                                          const std::string& templatePath,
-                                          const std::string& resultPath)
+                                     const std::string& templatePath,
+                                     const std::string& resultPath)
 {
     namespace fs = boost::filesystem;
 
@@ -781,7 +787,7 @@ void ZonesManager::generateNewConfig(const std::string& id,
 }
 
 void ZonesManager::handleCreateZoneCall(const std::string& id,
-                                                  dbus::MethodResultBuilder::Pointer result)
+                                        dbus::MethodResultBuilder::Pointer result)
 {
     if (id.empty()) {
         LOGE("Failed to add zone - invalid name.");
@@ -863,7 +869,7 @@ void ZonesManager::handleCreateZoneCall(const std::string& id,
 }
 
 void ZonesManager::handleDestroyZoneCall(const std::string& id,
-                                                   dbus::MethodResultBuilder::Pointer result)
+                                         dbus::MethodResultBuilder::Pointer result)
 {
     Lock lock(mMutex);
 
@@ -889,8 +895,65 @@ void ZonesManager::handleDestroyZoneCall(const std::string& id,
     mWorker->addTask(destroyer);
 }
 
+void ZonesManager::handleShutdownZoneCall(const std::string& id,
+                                          dbus::MethodResultBuilder::Pointer result)
+{
+    LOGI("ShutdownZone call; Id=" << id );
+
+    Lock lock(mMutex);
+
+    if (mZones.find(id) == mZones.end()) {
+        LOGE("Failed to shutdown zone - no such zone id: " << id);
+        result->setError(api::ERROR_INVALID_ID, "No such zone id");
+        return;
+    }
+
+    LOGT("Shutdown zone " << id);
+
+    auto shutdown = [id, result, this] {
+        try {
+            mZones[id]->stop();
+        } 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);
+}
+
+void ZonesManager::handleStartZoneCall(const std::string& id,
+                                       dbus::MethodResultBuilder::Pointer result)
+{
+    LOGI("StartZone call; Id=" << id );
+
+    Lock lock(mMutex);
+
+    if (mZones.find(id) == mZones.end()) {
+        LOGE("Failed to start zone - no such zone id: " << id);
+        result->setError(api::ERROR_INVALID_ID, "No such zone id");
+        return;
+    }
+
+    LOGT("Start zone " << id);
+
+    auto resultCallback = [this, id, result](bool succeeded) {
+        if (succeeded) {
+            focus(id);
+            result->setVoid();
+        } else {
+            LOGE("Failed to start zone.");
+            result->setError(api::ERROR_INTERNAL, "Failed to start zone");
+        }
+    };
+
+    mZones[id]->startAsync(resultCallback);
+}
+
 void ZonesManager::handleLockZoneCall(const std::string& id,
-                                                dbus::MethodResultBuilder::Pointer result)
+                                      dbus::MethodResultBuilder::Pointer result)
 {
     LOGI("LockZone call; Id=" << id );
 
@@ -923,7 +986,7 @@ void ZonesManager::handleLockZoneCall(const std::string& id,
 }
 
 void ZonesManager::handleUnlockZoneCall(const std::string& id,
-                                                  dbus::MethodResultBuilder::Pointer result)
+                                        dbus::MethodResultBuilder::Pointer result)
 {
     LOGI("UnlockZone call; Id=" << id );
 
index 2ed5312..ccf834a 100644 (file)
@@ -127,13 +127,13 @@ private:
                            const std::string& resultPath);
 
     void notifyActiveZoneHandler(const std::string& caller,
-                                      const std::string& appliaction,
-                                      const std::string& message);
+                                 const std::string& appliaction,
+                                 const std::string& message);
     void displayOffHandler(const std::string& caller);
     void handleZoneMoveFileRequest(const std::string& srcZoneId,
-                                        const std::string& dstZoneId,
-                                        const std::string& path,
-                                        dbus::MethodResultBuilder::Pointer result);
+                                   const std::string& dstZoneId,
+                                   const std::string& path,
+                                   dbus::MethodResultBuilder::Pointer result);
     void handleProxyCall(const std::string& caller,
                          const std::string& target,
                          const std::string& targetBusName,
@@ -165,15 +165,19 @@ private:
                                const std::string& target,
                                dbus::MethodResultBuilder::Pointer result);
     void handleSetActiveZoneCall(const std::string& id,
-                                      dbus::MethodResultBuilder::Pointer result);
+                                 dbus::MethodResultBuilder::Pointer result);
     void handleCreateZoneCall(const std::string& id,
-                                   dbus::MethodResultBuilder::Pointer result);
+                              dbus::MethodResultBuilder::Pointer result);
     void handleDestroyZoneCall(const std::string& id,
-                                    dbus::MethodResultBuilder::Pointer result);
+                               dbus::MethodResultBuilder::Pointer result);
+    void handleShutdownZoneCall(const std::string& id,
+                                dbus::MethodResultBuilder::Pointer result);
+    void handleStartZoneCall(const std::string& id,
+                             dbus::MethodResultBuilder::Pointer result);
     void handleLockZoneCall(const std::string& id,
-                                 dbus::MethodResultBuilder::Pointer result);
+                            dbus::MethodResultBuilder::Pointer result);
     void handleUnlockZoneCall(const std::string& id,
-                                   dbus::MethodResultBuilder::Pointer result);
+                              dbus::MethodResultBuilder::Pointer result);
 };
 
 
index 1e23e81..180b5eb 100644 (file)
@@ -221,6 +221,20 @@ BOOST_AUTO_TEST_CASE(CreateZoneTest)
     vsm_client_free(client);
 }
 
+BOOST_AUTO_TEST_CASE(StartShutdownZoneTest)
+{
+    const std::string newActiveZoneId = "ut-zones-manager-console1-dbus";
+
+    VsmClient client = vsm_client_create();
+    VsmStatus status = vsm_connect(client);
+    BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status);
+    status = vsm_shutdown_zone(client, newActiveZoneId.c_str());
+    BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status);
+    status = vsm_start_zone(client, newActiveZoneId.c_str());
+    BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status);
+    vsm_client_free(client);
+}
+
 BOOST_AUTO_TEST_CASE(LockUnlockZoneTest)
 {
     const std::string newActiveZoneId = "ut-zones-manager-console2-dbus";
index 3c62478..06af8eb 100644 (file)
@@ -310,7 +310,7 @@ public:
     }
 
     void callAsyncMethodCreateZone(const std::string& id,
-                                        const VoidResultCallback& result)
+                                   const VoidResultCallback& result)
     {
         auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
             BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT));
@@ -329,7 +329,7 @@ public:
     }
 
     void callAsyncMethodDestroyZone(const std::string& id,
-                                     const VoidResultCallback& result)
+                                    const VoidResultCallback& result)
     {
         auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
             BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT));
@@ -347,6 +347,44 @@ public:
                                  asyncResult);
     }
 
+    void callAsyncMethodShutdownZone(const std::string& id,
+                                     const VoidResultCallback& result)
+    {
+        auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
+            BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT));
+            result();
+        };
+
+        assert(isHost());
+        GVariant* parameters = g_variant_new("(s)", id.c_str());
+        mClient->callMethodAsync(api::host::BUS_NAME,
+                                 api::host::OBJECT_PATH,
+                                 api::host::INTERFACE,
+                                 api::host::METHOD_SHUTDOWN_ZONE,
+                                 parameters,
+                                 "()",
+                                 asyncResult);
+    }
+
+    void callAsyncMethodStartZone(const std::string& id,
+                                  const VoidResultCallback& result)
+    {
+        auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) {
+            BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT));
+            result();
+        };
+
+        assert(isHost());
+        GVariant* parameters = g_variant_new("(s)", id.c_str());
+        mClient->callMethodAsync(api::host::BUS_NAME,
+                                 api::host::OBJECT_PATH,
+                                 api::host::INTERFACE,
+                                 api::host::METHOD_START_ZONE,
+                                 parameters,
+                                 "()",
+                                 asyncResult);
+    }
+
     void callMethodLockZone(const std::string& id)
     {
         assert(isHost());
@@ -904,8 +942,8 @@ BOOST_AUTO_TEST_CASE(GetZoneIdsTest)
     DbusAccessory dbus(DbusAccessory::HOST_ID);
 
     std::vector<std::string> zoneIds = {"ut-zones-manager-console1-dbus",
-                                             "ut-zones-manager-console2-dbus",
-                                             "ut-zones-manager-console3-dbus"};
+                                        "ut-zones-manager-console2-dbus",
+                                        "ut-zones-manager-console3-dbus"};
     std::vector<std::string> returnedIds = dbus.callMethodGetZoneIds();
 
     BOOST_CHECK(std::is_permutation(returnedIds.begin(),
@@ -921,8 +959,8 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneIdTest)
     DbusAccessory dbus(DbusAccessory::HOST_ID);
 
     std::vector<std::string> zoneIds = {"ut-zones-manager-console1-dbus",
-                                             "ut-zones-manager-console2-dbus",
-                                             "ut-zones-manager-console3-dbus"};
+                                        "ut-zones-manager-console2-dbus",
+                                        "ut-zones-manager-console3-dbus"};
 
     for (std::string& zoneId: zoneIds){
         cm.focus(zoneId);
@@ -941,8 +979,8 @@ BOOST_AUTO_TEST_CASE(SetActiveZoneTest)
     DbusAccessory dbus(DbusAccessory::HOST_ID);
 
     std::vector<std::string> zoneIds = {"ut-zones-manager-console1-dbus",
-                                             "ut-zones-manager-console2-dbus",
-                                             "ut-zones-manager-console3-dbus"};
+                                        "ut-zones-manager-console2-dbus",
+                                        "ut-zones-manager-console3-dbus"};
 
     for (std::string& zoneId: zoneIds){
         dbus.callMethodSetActiveZone(zoneId);
@@ -1007,6 +1045,44 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest)
     BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), "");
 }
 
+BOOST_AUTO_TEST_CASE(StartShutdownZoneTest)
+{
+    const std::string zone1 = "ut-zones-manager-console1-dbus";
+    const std::string zone2 = "ut-zones-manager-console2-dbus";
+
+    ZonesManager cm(TEST_DBUS_CONFIG_PATH);
+
+    Latch callDone;
+    auto resultCallback = [&]() {
+        callDone.set();
+    };
+
+    DbusAccessory dbus(DbusAccessory::HOST_ID);
+
+    // start zone1
+    dbus.callAsyncMethodStartZone(zone1, resultCallback);
+    BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+    BOOST_CHECK(cm.isRunning(zone1));
+    BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1);
+
+    // start zone2
+    dbus.callAsyncMethodStartZone(zone2, resultCallback);
+    BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+    BOOST_CHECK(cm.isRunning(zone2));
+    BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone2);
+
+    // shutdown zone2
+    dbus.callAsyncMethodShutdownZone(zone2, resultCallback);
+    BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+    BOOST_CHECK(!cm.isRunning(zone2));
+
+    // shutdown zone1
+    dbus.callAsyncMethodShutdownZone(zone1, resultCallback);
+    BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+    BOOST_CHECK(!cm.isRunning(zone1));
+    BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), "");
+}
+
 BOOST_AUTO_TEST_CASE(LockUnlockZoneTest)
 {
     ZonesManager cm(TEST_DBUS_CONFIG_PATH);
@@ -1015,8 +1091,8 @@ BOOST_AUTO_TEST_CASE(LockUnlockZoneTest)
     DbusAccessory dbus(DbusAccessory::HOST_ID);
 
     std::vector<std::string> zoneIds = {"ut-zones-manager-console1-dbus",
-                                             "ut-zones-manager-console2-dbus",
-                                             "ut-zones-manager-console3-dbus"};
+                                        "ut-zones-manager-console2-dbus",
+                                        "ut-zones-manager-console3-dbus"};
 
     for (std::string& zoneId: zoneIds){
         dbus.callMethodLockZone(zoneId);