Rework postinstall unittests to pass on Android.
Postinstall unittests were creating and mounting an image on each test
run. This patch adds several test scripts to one of the pre-generated
images and uses that image during postinstall testing instead.
To workaround problems with mount/umount of loop devices on Android,
this patch rewrites the `losetup` logic to make the appropriate
syscalls and create the loop device with mknod if it doesn't exists.
The tests require some extra SELinux policies to run in enforcing mode.
Bug: 26955860
TEST=Ran all Postinstall unittests.
Change-Id: I47a56b80b97596bc65ffe30cbc8118f05faff0ae
diff --git a/common/test_utils.h b/common/test_utils.h
index 7be027a..2c8a6de 100644
--- a/common/test_utils.h
+++ b/common/test_utils.h
@@ -57,8 +57,15 @@
bool WriteFileVector(const std::string& path, const brillo::Blob& data);
bool WriteFileString(const std::string& path, const std::string& data);
-bool BindToUnusedLoopDevice(const std::string &filename,
- std::string* lo_dev_name_ptr);
+// Binds provided |filename| to an unused loopback device, whose name is written
+// to the string pointed to by |out_lo_dev_name|. The new loop device will be
+// read-only unless |writable| is set to true. Returns true on success, false
+// otherwise (along with corresponding test failures), in which case the content
+// of |out_lo_dev_name| is unknown.
+bool BindToUnusedLoopDevice(const std::string& filename,
+ bool writable,
+ std::string* out_lo_dev_name);
+bool UnbindLoopDevice(const std::string& lo_dev_name);
// Returns true iff a == b
bool ExpectVectorsEq(const brillo::Blob& a, const brillo::Blob& b);
@@ -120,8 +127,10 @@
class ScopedLoopbackDeviceBinder {
public:
- ScopedLoopbackDeviceBinder(const std::string& file, std::string* dev) {
- is_bound_ = BindToUnusedLoopDevice(file, &dev_);
+ ScopedLoopbackDeviceBinder(const std::string& file,
+ bool writable,
+ std::string* dev) {
+ is_bound_ = BindToUnusedLoopDevice(file, writable, &dev_);
EXPECT_TRUE(is_bound_);
if (is_bound_ && dev)
@@ -133,15 +142,8 @@
return;
for (int retry = 0; retry < 5; retry++) {
- std::vector<std::string> args;
- args.push_back("/sbin/losetup");
- args.push_back("-d");
- args.push_back(dev_);
- int return_code = 0;
- EXPECT_TRUE(Subprocess::SynchronousExec(args, &return_code, nullptr));
- if (return_code == 0) {
+ if (UnbindLoopDevice(dev_))
return;
- }
sleep(1);
}
ADD_FAILURE();