TEST(SideloadTest, run_fuse_sideload_wrong_parameters) { provider_vtab vtab; vtab.close = [](void) {}; ASSERT_EQ(-1, run_fuse_sideload(vtab, 4096, 4095)); ASSERT_EQ(-1, run_fuse_sideload(vtab, 4096, (1 << 22) + 1)); // Too many blocks. ASSERT_EQ(-1, run_fuse_sideload(vtab, ((1 << 18) + 1) * 4096, 4096)); }
static void* run_sdcard_fuse(void* cookie) { struct token* t = (struct token*)cookie; struct stat sb; if (stat(t->path, &sb) < 0) { fprintf(stderr, "failed to stat %s: %s\n", t->path, strerror(errno)); t->result = -1; return NULL; } struct file_data fd; struct provider_vtab vtab; fd.fd = open(t->path, O_RDONLY); if (fd.fd < 0) { fprintf(stderr, "failed to open %s: %s\n", t->path, strerror(errno)); t->result = -1; return NULL; } fd.file_size = sb.st_size; fd.block_size = 65536; vtab.read_block = read_block_file; vtab.close = close_file; t->result = run_fuse_sideload(&vtab, &fd, fd.file_size, fd.block_size); return NULL; }
TEST(SideloadTest, run_fuse_sideload) { const std::vector<std::string> blocks = { std::string(2048, 'a') + std::string(2048, 'b'), std::string(2048, 'c') + std::string(2048, 'd'), std::string(2048, 'e') + std::string(2048, 'f'), std::string(2048, 'g') + std::string(2048, 'h'), }; const std::string content = android::base::Join(blocks, ""); ASSERT_EQ(16384U, content.size()); provider_vtab vtab; vtab.close = [](void) {}; vtab.read_block = [&blocks](uint32_t block, uint8_t* buffer, uint32_t fetch_size) { if (block >= 4) return -1; blocks[block].copy(reinterpret_cast<char*>(buffer), fetch_size); return 0; }; TemporaryDir mount_point; pid_t pid = fork(); if (pid == 0) { ASSERT_EQ(0, run_fuse_sideload(vtab, 16384, 4096, mount_point.path)); _exit(EXIT_SUCCESS); } std::string package = std::string(mount_point.path) + "/" + FUSE_SIDELOAD_HOST_FILENAME; int status; static constexpr int kSideloadInstallTimeout = 10; for (int i = 0; i < kSideloadInstallTimeout; ++i) { ASSERT_NE(-1, waitpid(pid, &status, WNOHANG)); struct stat sb; if (stat(package.c_str(), &sb) == 0) { break; } if (errno == ENOENT && i < kSideloadInstallTimeout - 1) { sleep(1); continue; } FAIL() << "Timed out waiting for the fuse-provided package."; } std::string content_via_fuse; ASSERT_TRUE(android::base::ReadFileToString(package, &content_via_fuse)); ASSERT_EQ(content, content_via_fuse); std::string exit_flag = std::string(mount_point.path) + "/" + FUSE_SIDELOAD_HOST_EXIT_FLAG; struct stat sb; ASSERT_EQ(0, stat(exit_flag.c_str(), &sb)); waitpid(pid, &status, 0); ASSERT_EQ(0, WEXITSTATUS(status)); ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); }
int run_adb_fuse(int sfd, uint64_t file_size, uint32_t block_size) { adb_data ad; ad.sfd = sfd; ad.file_size = file_size; ad.block_size = block_size; provider_vtab vtab; vtab.read_block = read_block_adb; vtab.close = close_adb; return run_fuse_sideload(&vtab, &ad, file_size, block_size); }