1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef IMAGEPATH_UNITTEST_H
17#define IMAGEPATH_UNITTEST_H
18#include <fcntl.h>
19#include <gtest/gtest.h>
20#include <iostream>
21#include <libgen.h>
22#include <memory>
23#include <string>
24#include <vector>
25#include "applypatch/block_set.h"
26#include "applypatch/block_writer.h"
27#include "applypatch/data_writer.h"
28#include "log.h"
29#include "mount.h"
30#include "patch/update_patch.h"
31#include "utils.h"
32
33constexpr int O_BINARY = 0;
34namespace UpdaterUt {
35#define UNUSED(x) (void)(x)
36using namespace Updater;
37class FileWriter : public DataWriter {
38public:
39    virtual bool Write(const uint8_t *addr, size_t len, const void *context)
40    {
41        UNUSED(context);
42        write(fd_, addr, len);
43
44        if (fsync(fd_) == -1) {
45            LOG(ERROR) << "Failed to fsync ";
46            return -1;
47        }
48        currentBlockLeft_ -= len;
49        totalWritten_ += len;
50        return true;
51    }
52    virtual ~FileWriter() {}
53    FileWriter(int fd, BlockSet &bs) : fd_(fd), bs_(bs), totalWritten_(0), currentBlockLeft_(0) {}
54    FileWriter(const FileWriter&) = delete;
55    const FileWriter& operator=(const FileWriter&) = delete;
56private:
57    int fd_;
58    BlockSet bs_;
59    size_t totalWritten_;
60    size_t currentBlockLeft_;
61};
62
63class ImagePatchTest : public ::testing::Test {
64public:
65    ImagePatchTest() = default;
66    virtual ~ImagePatchTest() {
67    }
68    int TestZipModeImagePatch() const;
69    int TestGZipModeImagePatch() const;
70    int TestLZ4ModeImagePatch() const;
71    int TestNormalModeImagePatch() const;
72    int RunImageApplyPatch(UpdatePatch::PatchParam &param, const std::string &target,
73        const std::string &expectedSHA256) const
74    {
75        mode_t mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
76        int fd = open(target.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY, mode);
77        EXPECT_GE(fd, 0);
78        BlockSet targetBlk;
79        targetBlk.ParserAndInsert({
80            "2", "0", "1"
81        });
82        std::unique_ptr<FileWriter> writer = std::make_unique<FileWriter>(fd, targetBlk);
83        std::vector<uint8_t> empty;
84        int32_t ret = UpdatePatch::UpdateApplyPatch::ApplyImagePatch(param, empty,
85            [&](size_t start, const UpdatePatch::BlockBuffer &data, size_t size) -> int {
86                bool ret = writer->Write(data.buffer, size, nullptr);
87                return ret ? 0 : -1;
88            }, expectedSHA256);
89        close(fd);
90        return ret;
91    }
92
93protected:
94    void SetUp()
95    {
96        LoadSpecificFstab("/data/updater/applypatch/etc/fstab.imagepatch");
97        std::string basePath = "/data/updater/imgpatch";
98        Updater::Utils::MkdirRecursive(basePath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
99    }
100    void TearDown() {}
101    void TestBody() {}
102
103private:
104    bool ReadContentFromFile(const std::string &file, std::string &content) const;
105};
106} // namespace updater_ut
107#endif // IMAGEPATH_UNITTEST_H
108