blob: 3747ce0e3ae05db5bf3e139d25502e5daa50b8cd [file]
#include "apex_update_listener.h"
#include <android-base/file.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <log/log.h>
#include <fstream>
#include <iostream>
#include <set>
#include <thread>
#undef LOG_TAG
#define LOG_TAG "apex_update_listener_test"
namespace {
using InfoSet = std::set<ApexUpdateListener::Info>;
using testing::MockFunction;
using testing::StrictMock;
const std::string kApexInfoStateJustPreinstalled = R"xml(
<?xml version="1.0" encoding="utf-8"?>
<apex-info-list>
<apex-info moduleName="com.test.apex" modulePath="/vendor/apex/com.test.apex" preinstalledModulePath="/vendor/apex/com.test.apex" versionCode="100" versionName="" isFactory="true" isActive="true"></apex-info>
</apex-info-list>
)xml";
const std::string kApexInfoStateOneOnData = R"xml(
<?xml version="1.0" encoding="utf-8"?>
<apex-info-list>
<apex-info moduleName="com.test.apex" modulePath="/data/apex/com.test.apex@200" preinstalledModulePath="/vendor/apex/com.test.apex" versionCode="200" versionName="" isFactory="false" isActive="true"></apex-info>
<apex-info moduleName="com.test.apex" modulePath="/vendor/apex/com.test.apex" preinstalledModulePath="/vendor/apex/com.test.apex" versionCode="100" versionName="" isFactory="true" isActive="false"></apex-info>
</apex-info-list>
)xml";
void WriteStringToFile(const char* filename, const std::string& data) {
std::ofstream xml_stream(filename);
xml_stream.write(data.data(), data.size());
}
} // namespace
TEST(ApexUpdateListener, InstallUpdate) {
TemporaryFile tmp_xml_file;
StrictMock<MockFunction<ApexUpdateListener::CallbackFunction>> callback;
std::mutex mutex;
std::condition_variable wait_cv;
EXPECT_CALL(
callback,
Call(InfoSet{{.module_name = "com.test.apex",
.module_path = "/vendor/apex/com.test.apex",
.preinstalled_module_path = "/vendor/apex/com.test.apex",
.version_code = 100,
.version_name = "",
.is_factory = true,
.is_active = true}},
InfoSet{{.module_name = "com.test.apex",
.module_path = "/vendor/apex/com.test.apex",
.preinstalled_module_path = "/vendor/apex/com.test.apex",
.version_code = 100,
.version_name = "",
.is_factory = true,
.is_active = false},
{.module_name = "com.test.apex",
.module_path = "/data/apex/com.test.apex@200",
.preinstalled_module_path = "/vendor/apex/com.test.apex",
.version_code = 200,
.version_name = "",
.is_factory = false,
.is_active = true}}))
.WillOnce([&mutex, &wait_cv]() {
std::lock_guard<std::mutex> lock(mutex);
wait_cv.notify_one();
});
WriteStringToFile(tmp_xml_file.path, kApexInfoStateJustPreinstalled);
std::unique_ptr<ApexUpdateListener> ptr = ApexUpdateListener::Make(
"com.test.apex", callback.AsStdFunction(), false, tmp_xml_file.path);
EXPECT_NE(ptr, nullptr);
WriteStringToFile(tmp_xml_file.path, kApexInfoStateOneOnData);
std::unique_lock<std::mutex> lock(mutex);
wait_cv.wait_for(lock, std::chrono::milliseconds(30000));
}
TEST(ApexUpdateListener, InvokeWithInitialVersion) {
TemporaryFile tmp_xml_file;
StrictMock<MockFunction<ApexUpdateListener::CallbackFunction>> callback;
std::mutex mutex;
std::condition_variable wait_cv;
EXPECT_CALL(
callback,
Call(InfoSet{},
InfoSet{{.module_name = "com.test.apex",
.module_path = "/vendor/apex/com.test.apex",
.preinstalled_module_path = "/vendor/apex/com.test.apex",
.version_code = 100,
.version_name = "",
.is_factory = true,
.is_active = true}}))
.WillOnce([&mutex, &wait_cv]() {
std::lock_guard<std::mutex> lock(mutex);
wait_cv.notify_one();
});
WriteStringToFile(tmp_xml_file.path, kApexInfoStateJustPreinstalled);
std::unique_ptr<ApexUpdateListener> ptr = ApexUpdateListener::Make(
"com.test.apex", callback.AsStdFunction(), true, tmp_xml_file.path);
EXPECT_NE(ptr, nullptr);
std::unique_lock<std::mutex> lock(mutex);
wait_cv.wait_for(lock, std::chrono::milliseconds(30000));
}