Activation: check compatiblity of uploaded software

Before activation, check if the PSU inventory's manufacturer and model
matches the uploaded software, to make sure the software is not updated
to a incompatible PSU.

The model check is mandatory, and if the PSU manufacturer is empty,
ignore the manufacturer check.

Tested: Upload a dummy tarball with incompatible model, verify the
        activation fails;
        Upload a dummy tarball with compatible model, verify the
        activation succeeds with a dummy update service.
        Also added unit tests for several cases:
        * Update on a PSU that model is incompatible;
        * Update on a PSU that the manufacture is incompatible;
        * Update on a PSU that the menufacture is empty;
        * Update on 4 PSUs that the second one is incompatible.

Signed-off-by: Lei YU <mine260309@gmail.com>
Change-Id: Ia1b6a3fa6c98cdea1ea93c917c0938d4a60f0911
diff --git a/src/version.cpp b/src/version.cpp
index 0ea6cc9..02cf6af 100644
--- a/src/version.cpp
+++ b/src/version.cpp
@@ -53,6 +53,29 @@
     return ret;
 }
 
+std::map<std::string, std::string>
+    Version::getExtVersionInfo(const std::string& extVersion)
+{
+    // The extVersion shall be key/value pairs separated by comma,
+    // e.g. key1=value1,key2=value2
+    std::map<std::string, std::string> result;
+    std::stringstream ss(extVersion);
+
+    while (ss.good())
+    {
+        std::string substr;
+        getline(ss, substr, ',');
+        auto pos = substr.find('=');
+        if (pos != std::string::npos)
+        {
+            std::string key = substr.substr(0, pos);
+            std::string value = substr.substr(pos + 1);
+            result.emplace(key, value);
+        }
+    }
+    return result;
+}
+
 void Delete::delete_()
 {
     if (version.eraseCallback)