1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2011 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 16d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 17d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes#include <string.h> 18d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes#include <unistd.h> 197ed561bfe6019ed4b988142e97505d7c643e119cDarin Petkov 20d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes#include <string> 21d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes#include <vector> 227ed561bfe6019ed4b988142e97505d7c643e119cDarin Petkov 235ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#include <brillo/make_unique_ptr.h> 24d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes#include <gtest/gtest.h> 257ed561bfe6019ed4b988142e97505d7c643e119cDarin Petkov 2639910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/test_utils.h" 275ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#include "update_engine/payload_consumer/bzip_extent_writer.h" 285ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#include "update_engine/payload_consumer/extent_writer.h" 295ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#include "update_engine/payload_consumer/xz_extent_writer.h" 300bc2611b49aba30202fdb9c23871430eb67e4738Alex Deymo#include "update_engine/payload_generator/bzip.h" 315ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#include "update_engine/payload_generator/xz.h" 32d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 3310875d90cf67f883ba7c9ed13bc8d706aa8c6fbcAlex Deymousing chromeos_update_engine::test_utils::kRandomString; 34d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyesusing std::string; 35d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyesusing std::vector; 36d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 37d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyesnamespace chromeos_update_engine { 38d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 395ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymonamespace { 405ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 415ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo// ExtentWriter class that writes to memory, used to test the decompression 425ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo// step with the corresponding extent writer. 435ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymoclass MemoryExtentWriter : public ExtentWriter { 445ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo public: 455ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo // Creates the ExtentWriter that will write all the bytes to the passed |data| 465ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo // blob. 475ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo explicit MemoryExtentWriter(brillo::Blob* data) : data_(data) { 485ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo data_->clear(); 495ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo } 505ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo ~MemoryExtentWriter() override = default; 515ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 525ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo bool Init(FileDescriptorPtr fd, 535ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo const vector<Extent>& extents, 545ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo uint32_t block_size) override { 555ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo return true; 565ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo } 575ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo bool Write(const void* bytes, size_t count) override { 585ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo data_->reserve(data_->size() + count); 595ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo data_->insert(data_->end(), 605ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo static_cast<const uint8_t*>(bytes), 615ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo static_cast<const uint8_t*>(bytes) + count); 625ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo return true; 635ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo } 645ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo bool EndImpl() override { return true; } 655ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 665ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo private: 675ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo brillo::Blob* data_; 685ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo}; 695ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 705ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymotemplate <typename W> 715ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymobool DecompressWithWriter(const brillo::Blob& in, brillo::Blob* out) { 725ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo std::unique_ptr<ExtentWriter> writer( 735ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo new W(brillo::make_unique_ptr(new MemoryExtentWriter(out)))); 745ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo // Init() parameters are ignored by the testing MemoryExtentWriter. 755ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo TEST_AND_RETURN_FALSE(writer->Init(nullptr, {}, 1)); 765ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo TEST_AND_RETURN_FALSE(writer->Write(in.data(), in.size())); 775ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo TEST_AND_RETURN_FALSE(writer->End()); 785ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo return true; 795ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo} 805ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 815ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo} // namespace 825ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 83d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyestemplate <typename T> 84d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyesclass ZipTest : public ::testing::Test { 85d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes public: 860bc2611b49aba30202fdb9c23871430eb67e4738Alex Deymo bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const = 0; 875ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const = 0; 88d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes}; 89d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 90d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyesclass BzipTest {}; 91d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 92d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyestemplate <> 93d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyesclass ZipTest<BzipTest> : public ::testing::Test { 94d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes public: 950bc2611b49aba30202fdb9c23871430eb67e4738Alex Deymo bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const { 96d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes return BzipCompress(in, out); 97d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes } 985ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const { 995ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo return DecompressWithWriter<BzipExtentWriter>(in, out); 100d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes } 1015ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo}; 1025ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 1035ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymoclass XzTest {}; 1045ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo 1055ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymotemplate <> 1065ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymoclass ZipTest<XzTest> : public ::testing::Test { 1075ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo public: 1085ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const { 1095ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo return XzCompress(in, out); 1105ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo } 1115ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const { 1125ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo return DecompressWithWriter<XzExtentWriter>(in, out); 113d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes } 114d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes}; 115d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 1165ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#ifdef __ANDROID__ 1175ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymotypedef ::testing::Types<BzipTest, XzTest> ZipTestTypes; 1185ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#else 1195ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo// Chrome OS implementation of Xz compressor just returns false. 1207ed561bfe6019ed4b988142e97505d7c643e119cDarin Petkovtypedef ::testing::Types<BzipTest> ZipTestTypes; 1215ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo#endif // __ANDROID__ 122d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 1235ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex DeymoTYPED_TEST_CASE(ZipTest, ZipTestTypes); 124d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 125d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los ReyesTYPED_TEST(ZipTest, SimpleTest) { 1265ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo string in_str( 1275ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo "this should compress well xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 1285ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 1295ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 1305ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 1315ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 1325ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); 1335ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo brillo::Blob in(in_str.begin(), in_str.end()); 1343f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob out; 1355ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo EXPECT_TRUE(this->ZipCompress(in, &out)); 136d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes EXPECT_LT(out.size(), in.size()); 13780f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_GT(out.size(), 0U); 1383f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob decompressed; 139d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes EXPECT_TRUE(this->ZipDecompress(out, &decompressed)); 140d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes EXPECT_EQ(in.size(), decompressed.size()); 141f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko EXPECT_TRUE(!memcmp(in.data(), decompressed.data(), in.size())); 142d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes} 143d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 144d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los ReyesTYPED_TEST(ZipTest, PoorCompressionTest) { 1455ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo brillo::Blob in(std::begin(kRandomString), std::end(kRandomString)); 1463f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob out; 1475ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo EXPECT_TRUE(this->ZipCompress(in, &out)); 148d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes EXPECT_GT(out.size(), in.size()); 1493f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob decompressed; 1505ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo EXPECT_TRUE(this->ZipDecompress(out, &decompressed)); 151d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes EXPECT_EQ(in.size(), decompressed.size()); 1525ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo EXPECT_EQ(in, decompressed); 153d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes} 154d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 155d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los ReyesTYPED_TEST(ZipTest, MalformedZipTest) { 1565ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo brillo::Blob in(std::begin(kRandomString), std::end(kRandomString)); 1573f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob out; 1585ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo EXPECT_FALSE(this->ZipDecompress(in, &out)); 159d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes} 160d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 161d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los ReyesTYPED_TEST(ZipTest, EmptyInputsTest) { 1625ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo brillo::Blob in; 1633f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob out; 1645ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo EXPECT_TRUE(this->ZipDecompress(in, &out)); 16580f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(0U, out.size()); 166d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 1675ee71ba372ddef9bc2b5e12f55f0b449d320282cAlex Deymo EXPECT_TRUE(this->ZipCompress(in, &out)); 16880f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(0U, out.size()); 169d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes} 170d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes 171d2135f3946c7c551f152c0a595c5528cd186afefAndrew de los Reyes} // namespace chromeos_update_engine 172