| OLD | NEW | 
|    1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include <sys/types.h> |    5 #include <sys/types.h> | 
|    6 #include <sys/stat.h> |    6 #include <sys/stat.h> | 
|    7 #include <fcntl.h> |    7 #include <fcntl.h> | 
|    8 #include <unistd.h> |    8 #include <unistd.h> | 
|    9 #include <set> |    9 #include <set> | 
|   10 #include <string> |   10 #include <string> | 
|   11 #include <vector> |   11 #include <vector> | 
|   12 #include "base/string_util.h" |   12 #include "base/string_util.h" | 
|   13 #include <gtest/gtest.h> |   13 #include <gtest/gtest.h> | 
|   14 #include "chromeos/obsolete_logging.h" |   14 #include "chromeos/obsolete_logging.h" | 
|   15 #include "update_engine/decompressing_file_writer.h" |   15 #include "update_engine/decompressing_file_writer.h" | 
|   16 #include "update_engine/delta_diff_generator.h" |   16 #include "update_engine/delta_diff_generator.h" | 
|   17 #include "update_engine/delta_diff_parser.h" |   17 #include "update_engine/delta_diff_parser.h" | 
|   18 #include "update_engine/gzip.h" |   18 #include "update_engine/gzip.h" | 
|   19 #include "update_engine/mock_file_writer.h" |   19 #include "update_engine/mock_file_writer.h" | 
|   20 #include "update_engine/subprocess.h" |   20 #include "update_engine/subprocess.h" | 
|   21 #include "update_engine/test_utils.h" |   21 #include "update_engine/test_utils.h" | 
|   22 #include "update_engine/utils.h" |   22 #include "update_engine/utils.h" | 
|   23  |   23  | 
|   24 namespace chromeos_update_engine { |   24 namespace chromeos_update_engine { | 
|   25  |   25  | 
|   26 using std::set; |   26 class DeltaDiffGeneratorTest : public ::testing::Test {}; | 
|   27 using std::string; |  | 
|   28 using std::vector; |  | 
|   29  |  | 
|   30 class DeltaDiffGeneratorTest : public ::testing::Test { |  | 
|   31   virtual void TearDown() { |  | 
|   32     EXPECT_EQ(0, system("rm -rf diff-gen-test")); |  | 
|   33   } |  | 
|   34 protected: |  | 
|   35   void FakerootEncodeDataToDeltaFileTest(bool test_diff_exclusion); |  | 
|   36 }; |  | 
|   37  |  | 
|   38 namespace { |  | 
|   39 void DumpProto(const DeltaArchiveManifest* archive) { |  | 
|   40   for (int i = 0; i < archive->files_size(); i++) { |  | 
|   41     printf("Node %d\n", i); |  | 
|   42     const DeltaArchiveManifest_File& file = archive->files(i); |  | 
|   43     for (int j = 0; j < file.children_size(); j++) { |  | 
|   44       const DeltaArchiveManifest_File_Child& child = file.children(j); |  | 
|   45       printf("  %d %s\n", child.index(), child.name().c_str()); |  | 
|   46     } |  | 
|   47   } |  | 
|   48 } |  | 
|   49  |  | 
|   50 const char* const kWellCompressingFilename = |  | 
|   51     "this_compresses_well_xxxxxxxxxxxxxxxxx" |  | 
|   52     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |  | 
|   53     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |  | 
|   54     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |  | 
|   55     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; |  | 
|   56 // The following files are generated at the path 'base': |  | 
|   57 // / |  | 
|   58 //  cdev (c 2 1) |  | 
|   59 //  dir/ |  | 
|   60 //      bdev (b 3 1) |  | 
|   61 //      emptydir/ (owner:group = 501:503) |  | 
|   62 //      hello ("hello") |  | 
|   63 //      newempty ("") |  | 
|   64 //      subdir/ |  | 
|   65 //             fifo |  | 
|   66 //             link -> /target |  | 
|   67 //  encoding/ |  | 
|   68 //           long_new |  | 
|   69 //           long_small_change |  | 
|   70 //           nochange |  | 
|   71 //           onebyte |  | 
|   72 //  hi ("hi") |  | 
|   73 void GenerateFilesAtPath(const string& base) { |  | 
|   74   const char* base_c = base.c_str(); |  | 
|   75   EXPECT_EQ(0, System(StringPrintf("echo hi > '%s/hi'", base_c))); |  | 
|   76   EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/dir'", base_c))); |  | 
|   77   EXPECT_EQ(0, System(StringPrintf("rm -f '%s/dir/bdev'", base_c))); |  | 
|   78   EXPECT_EQ(0, System(StringPrintf("mknod '%s/dir/bdev' b 3 1", base_c))); |  | 
|   79   EXPECT_EQ(0, System(StringPrintf("rm -f '%s/cdev'", base_c))); |  | 
|   80   EXPECT_EQ(0, System(StringPrintf("mknod '%s/cdev' c 2 1", base_c))); |  | 
|   81   EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/dir/subdir'", base_c))); |  | 
|   82   EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/dir/emptydir'", base_c))); |  | 
|   83   EXPECT_EQ(0, System(StringPrintf("chown 501:503 '%s/dir/emptydir'", base_c))); |  | 
|   84   EXPECT_EQ(0, System(StringPrintf("rm -f '%s/dir/subdir/fifo'", base_c))); |  | 
|   85   EXPECT_EQ(0, System(StringPrintf("mkfifo '%s/dir/subdir/fifo'", base_c))); |  | 
|   86   EXPECT_EQ(0, System(StringPrintf("ln -f -s /target '%s/dir/subdir/link'", |  | 
|   87                                    base_c))); |  | 
|   88   EXPECT_EQ(0, System(StringPrintf("rm -f '%s/hard_link'", base_c))); |  | 
|   89   EXPECT_EQ(0, System(StringPrintf("ln '%s/hi' '%s/hard_link'", |  | 
|   90                                    base_c, base_c))); |  | 
|   91   EXPECT_EQ(0, System(StringPrintf( |  | 
|   92       "ln -f -s '%s' '%s/compress_link'", kWellCompressingFilename, base_c))); |  | 
|   93  |  | 
|   94   // Things that will encode differently: |  | 
|   95   EXPECT_EQ(0, System(StringPrintf("mkdir -p '%s/encoding'", base_c))); |  | 
|   96   EXPECT_EQ(0, System(StringPrintf("echo nochange > '%s/encoding/nochange'", |  | 
|   97                                    base_c))); |  | 
|   98   EXPECT_EQ(0, System(StringPrintf("echo -n > '%s/encoding/onebyte'", base_c))); |  | 
|   99   EXPECT_EQ(0, System(StringPrintf("echo -n > '%s/encoding/long_new'", |  | 
|  100                                    base_c))); |  | 
|  101   // Random 1 MiB byte length file |  | 
|  102   EXPECT_TRUE(utils::WriteFile((base + |  | 
|  103                                 "/encoding/long_small_change").c_str(), |  | 
|  104                                reinterpret_cast<const char*>(kRandomString), |  | 
|  105                                sizeof(kRandomString))); |  | 
|  106 } |  | 
|  107 // base points to a folder that was passed to GenerateFilesAtPath(). |  | 
|  108 // This edits some, so that one can make a diff from the original data |  | 
|  109 // and the edited data. |  | 
|  110 void EditFilesAtPath(const string& base) { |  | 
|  111   CHECK_EQ(0, System(string("echo hello > ") + base + "/dir/hello")); |  | 
|  112   CHECK_EQ(0, System(string("echo -n > ") + base + "/dir/newempty")); |  | 
|  113   CHECK_EQ(0, System(string("echo newhi > ") + base + "/hi")); |  | 
|  114   CHECK_EQ(0, System(string("echo -n h >> ") + base + |  | 
|  115                      "/encoding/onebyte")); |  | 
|  116   CHECK_EQ(0, System(string("echo -n h >> ") + base + |  | 
|  117                      "/encoding/long_small_change")); |  | 
|  118   CHECK_EQ(0, System(string("echo -n This is a pice of text that should " |  | 
|  119                             "compress well since it is just ascii and it " |  | 
|  120                             "has repetition xxxxxxxxxxxxxxxxxxxxx" |  | 
|  121                             "xxxxxxxxxxxxxxxxxxxx > ") + base + |  | 
|  122                      "/encoding/long_new")); |  | 
|  123 } |  | 
|  124  |  | 
|  125 }  // namespace {} |  | 
|  126  |  | 
|  127 TEST_F(DeltaDiffGeneratorTest, FakerootEncodeMetadataToProtoBufferTest) { |  | 
|  128   char cwd[1000]; |  | 
|  129   ASSERT_EQ(cwd, getcwd(cwd, sizeof(cwd))) << "cwd buf possibly too small"; |  | 
|  130   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test")); |  | 
|  131   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/old")); |  | 
|  132   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/new")); |  | 
|  133   GenerateFilesAtPath(string(cwd) + "/diff-gen-test/old"); |  | 
|  134   GenerateFilesAtPath(string(cwd) + "/diff-gen-test/new"); |  | 
|  135   EditFilesAtPath(string(cwd) + "/diff-gen-test/new"); |  | 
|  136  |  | 
|  137   DeltaArchiveManifest* archive = |  | 
|  138       DeltaDiffGenerator::EncodeMetadataToProtoBuffer( |  | 
|  139           (string(cwd) + "/diff-gen-test/new").c_str()); |  | 
|  140   EXPECT_TRUE(NULL != archive); |  | 
|  141  |  | 
|  142   EXPECT_EQ(18, archive->files_size()); |  | 
|  143   //DumpProto(archive); |  | 
|  144   const DeltaArchiveManifest_File& root = archive->files(0); |  | 
|  145   EXPECT_TRUE(S_ISDIR(root.mode())); |  | 
|  146   EXPECT_EQ(0, root.uid()); |  | 
|  147   EXPECT_EQ(0, root.gid()); |  | 
|  148   ASSERT_EQ(6, root.children_size()); |  | 
|  149   EXPECT_EQ("cdev", root.children(0).name()); |  | 
|  150   EXPECT_EQ("compress_link", root.children(1).name()); |  | 
|  151   EXPECT_EQ("dir", root.children(2).name()); |  | 
|  152   EXPECT_EQ("encoding", root.children(3).name()); |  | 
|  153   EXPECT_EQ("hard_link", root.children(4).name()); |  | 
|  154   EXPECT_EQ("hi", root.children(5).name()); |  | 
|  155   EXPECT_FALSE(root.has_hardlink_path()); |  | 
|  156   EXPECT_FALSE(root.has_data_format()); |  | 
|  157   EXPECT_FALSE(root.has_data_offset()); |  | 
|  158   EXPECT_FALSE(root.has_data_length()); |  | 
|  159  |  | 
|  160   const DeltaArchiveManifest_File& cdev = |  | 
|  161       archive->files(root.children(0).index()); |  | 
|  162   EXPECT_EQ(0, cdev.children_size()); |  | 
|  163   EXPECT_TRUE(S_ISCHR(cdev.mode())); |  | 
|  164   EXPECT_EQ(0, cdev.uid()); |  | 
|  165   EXPECT_EQ(0, cdev.gid()); |  | 
|  166   EXPECT_FALSE(cdev.has_hardlink_path()); |  | 
|  167   EXPECT_FALSE(cdev.has_data_format()); |  | 
|  168   EXPECT_FALSE(cdev.has_data_offset()); |  | 
|  169   EXPECT_FALSE(cdev.has_data_length()); |  | 
|  170  |  | 
|  171   const DeltaArchiveManifest_File& compress_link = |  | 
|  172       archive->files(root.children(1).index()); |  | 
|  173   EXPECT_EQ(0, compress_link.children_size()); |  | 
|  174   EXPECT_TRUE(S_ISLNK(compress_link.mode())); |  | 
|  175   EXPECT_EQ(0, compress_link.uid()); |  | 
|  176   EXPECT_EQ(0, compress_link.gid()); |  | 
|  177   EXPECT_FALSE(compress_link.has_hardlink_path()); |  | 
|  178   EXPECT_FALSE(compress_link.has_data_format()); |  | 
|  179   EXPECT_FALSE(compress_link.has_data_offset()); |  | 
|  180   EXPECT_FALSE(compress_link.has_data_length()); |  | 
|  181  |  | 
|  182   const DeltaArchiveManifest_File& hard_link = |  | 
|  183       archive->files(root.children(4).index()); |  | 
|  184   EXPECT_EQ(0, hard_link.children_size()); |  | 
|  185   EXPECT_TRUE(S_ISREG(hard_link.mode())); |  | 
|  186   EXPECT_EQ(0, hard_link.uid()); |  | 
|  187   EXPECT_EQ(0, hard_link.gid()); |  | 
|  188   EXPECT_FALSE(hard_link.has_hardlink_path()); |  | 
|  189   EXPECT_FALSE(hard_link.has_data_format()); |  | 
|  190   EXPECT_FALSE(hard_link.has_data_offset()); |  | 
|  191   EXPECT_FALSE(hard_link.has_data_length()); |  | 
|  192  |  | 
|  193   const DeltaArchiveManifest_File& hi = |  | 
|  194       archive->files(root.children(5).index()); |  | 
|  195   EXPECT_EQ(0, hi.children_size()); |  | 
|  196   EXPECT_TRUE(S_ISREG(hi.mode())); |  | 
|  197   EXPECT_EQ(0, hi.uid()); |  | 
|  198   EXPECT_EQ(0, hi.gid()); |  | 
|  199   EXPECT_TRUE(hi.has_hardlink_path()); |  | 
|  200   EXPECT_EQ("/hard_link", hi.hardlink_path()); |  | 
|  201   EXPECT_FALSE(hi.has_data_format()); |  | 
|  202   EXPECT_FALSE(hi.has_data_offset()); |  | 
|  203   EXPECT_FALSE(hi.has_data_length()); |  | 
|  204  |  | 
|  205   const DeltaArchiveManifest_File& encoding = |  | 
|  206       archive->files(root.children(3).index()); |  | 
|  207   EXPECT_TRUE(S_ISDIR(encoding.mode())); |  | 
|  208   EXPECT_EQ(0, encoding.uid()); |  | 
|  209   EXPECT_EQ(0, encoding.gid()); |  | 
|  210   EXPECT_EQ(4, encoding.children_size()); |  | 
|  211   EXPECT_EQ("long_new", encoding.children(0).name()); |  | 
|  212   EXPECT_EQ("long_small_change", encoding.children(1).name()); |  | 
|  213   EXPECT_EQ("nochange", encoding.children(2).name()); |  | 
|  214   EXPECT_EQ("onebyte", encoding.children(3).name()); |  | 
|  215   EXPECT_FALSE(encoding.has_hardlink_path()); |  | 
|  216   EXPECT_FALSE(encoding.has_data_format()); |  | 
|  217   EXPECT_FALSE(encoding.has_data_offset()); |  | 
|  218   EXPECT_FALSE(encoding.has_data_length()); |  | 
|  219  |  | 
|  220   const DeltaArchiveManifest_File& long_new = |  | 
|  221       archive->files(encoding.children(0).index()); |  | 
|  222   EXPECT_EQ(0, long_new.children_size()); |  | 
|  223   EXPECT_TRUE(S_ISREG(long_new.mode())); |  | 
|  224   EXPECT_EQ(0, long_new.uid()); |  | 
|  225   EXPECT_EQ(0, long_new.gid()); |  | 
|  226   EXPECT_FALSE(long_new.has_hardlink_path()); |  | 
|  227   EXPECT_FALSE(long_new.has_data_format()); |  | 
|  228   EXPECT_FALSE(long_new.has_data_offset()); |  | 
|  229   EXPECT_FALSE(long_new.has_data_length()); |  | 
|  230  |  | 
|  231   const DeltaArchiveManifest_File& long_small_change = |  | 
|  232       archive->files(encoding.children(1).index()); |  | 
|  233   EXPECT_EQ(0, long_small_change.children_size()); |  | 
|  234   EXPECT_TRUE(S_ISREG(long_small_change.mode())); |  | 
|  235   EXPECT_EQ(0, long_small_change.uid()); |  | 
|  236   EXPECT_EQ(0, long_small_change.gid()); |  | 
|  237   EXPECT_FALSE(long_small_change.has_hardlink_path()); |  | 
|  238   EXPECT_FALSE(long_small_change.has_data_format()); |  | 
|  239   EXPECT_FALSE(long_small_change.has_data_offset()); |  | 
|  240   EXPECT_FALSE(long_small_change.has_data_length()); |  | 
|  241  |  | 
|  242   const DeltaArchiveManifest_File& nochange = |  | 
|  243       archive->files(encoding.children(2).index()); |  | 
|  244   EXPECT_EQ(0, nochange.children_size()); |  | 
|  245   EXPECT_TRUE(S_ISREG(nochange.mode())); |  | 
|  246   EXPECT_EQ(0, nochange.uid()); |  | 
|  247   EXPECT_EQ(0, nochange.gid()); |  | 
|  248   EXPECT_FALSE(nochange.has_hardlink_path()); |  | 
|  249   EXPECT_FALSE(nochange.has_data_format()); |  | 
|  250   EXPECT_FALSE(nochange.has_data_offset()); |  | 
|  251   EXPECT_FALSE(nochange.has_data_length()); |  | 
|  252  |  | 
|  253   const DeltaArchiveManifest_File& onebyte = |  | 
|  254       archive->files(encoding.children(3).index()); |  | 
|  255   EXPECT_EQ(0, onebyte.children_size()); |  | 
|  256   EXPECT_TRUE(S_ISREG(onebyte.mode())); |  | 
|  257   EXPECT_EQ(0, onebyte.uid()); |  | 
|  258   EXPECT_EQ(0, onebyte.gid()); |  | 
|  259   EXPECT_FALSE(onebyte.has_hardlink_path()); |  | 
|  260   EXPECT_FALSE(onebyte.has_data_format()); |  | 
|  261   EXPECT_FALSE(onebyte.has_data_offset()); |  | 
|  262   EXPECT_FALSE(onebyte.has_data_length()); |  | 
|  263  |  | 
|  264   const DeltaArchiveManifest_File& dir = |  | 
|  265       archive->files(root.children(2).index()); |  | 
|  266   EXPECT_TRUE(S_ISDIR(dir.mode())); |  | 
|  267   EXPECT_EQ(0, dir.uid()); |  | 
|  268   EXPECT_EQ(0, dir.gid()); |  | 
|  269   ASSERT_EQ(5, dir.children_size()); |  | 
|  270   EXPECT_EQ("bdev", dir.children(0).name()); |  | 
|  271   EXPECT_EQ("emptydir", dir.children(1).name()); |  | 
|  272   EXPECT_EQ("hello", dir.children(2).name()); |  | 
|  273   EXPECT_EQ("newempty", dir.children(3).name()); |  | 
|  274   EXPECT_EQ("subdir", dir.children(4).name()); |  | 
|  275   EXPECT_FALSE(dir.has_hardlink_path()); |  | 
|  276   EXPECT_FALSE(dir.has_data_format()); |  | 
|  277   EXPECT_FALSE(dir.has_data_offset()); |  | 
|  278   EXPECT_FALSE(dir.has_data_length()); |  | 
|  279  |  | 
|  280   const DeltaArchiveManifest_File& bdev = |  | 
|  281       archive->files(dir.children(0).index()); |  | 
|  282   EXPECT_EQ(0, bdev.children_size()); |  | 
|  283   EXPECT_TRUE(S_ISBLK(bdev.mode())); |  | 
|  284   EXPECT_EQ(0, bdev.uid()); |  | 
|  285   EXPECT_EQ(0, bdev.gid()); |  | 
|  286   EXPECT_FALSE(bdev.has_hardlink_path()); |  | 
|  287   EXPECT_FALSE(bdev.has_data_format()); |  | 
|  288   EXPECT_FALSE(bdev.has_data_offset()); |  | 
|  289   EXPECT_FALSE(bdev.has_data_length()); |  | 
|  290  |  | 
|  291   const DeltaArchiveManifest_File& emptydir = |  | 
|  292       archive->files(dir.children(1).index()); |  | 
|  293   EXPECT_EQ(0, emptydir.children_size()); |  | 
|  294   EXPECT_TRUE(S_ISDIR(emptydir.mode())); |  | 
|  295   EXPECT_EQ(501, emptydir.uid()); |  | 
|  296   EXPECT_EQ(503, emptydir.gid()); |  | 
|  297   EXPECT_FALSE(emptydir.has_hardlink_path()); |  | 
|  298   EXPECT_FALSE(emptydir.has_data_format()); |  | 
|  299   EXPECT_FALSE(emptydir.has_data_offset()); |  | 
|  300   EXPECT_FALSE(emptydir.has_data_length()); |  | 
|  301  |  | 
|  302   const DeltaArchiveManifest_File& hello = |  | 
|  303       archive->files(dir.children(2).index()); |  | 
|  304   EXPECT_EQ(0, hello.children_size()); |  | 
|  305   EXPECT_TRUE(S_ISREG(hello.mode())); |  | 
|  306   EXPECT_EQ(0, hello.uid()); |  | 
|  307   EXPECT_EQ(0, hello.gid()); |  | 
|  308   EXPECT_FALSE(hello.has_hardlink_path()); |  | 
|  309   EXPECT_FALSE(hello.has_data_format()); |  | 
|  310   EXPECT_FALSE(hello.has_data_offset()); |  | 
|  311   EXPECT_FALSE(hello.has_data_length()); |  | 
|  312  |  | 
|  313   const DeltaArchiveManifest_File& newempty = |  | 
|  314       archive->files(dir.children(3).index()); |  | 
|  315   EXPECT_EQ(0, newempty.children_size()); |  | 
|  316   EXPECT_TRUE(S_ISREG(newempty.mode())); |  | 
|  317   EXPECT_EQ(0, newempty.uid()); |  | 
|  318   EXPECT_EQ(0, newempty.gid()); |  | 
|  319   EXPECT_FALSE(newempty.has_hardlink_path()); |  | 
|  320   EXPECT_FALSE(newempty.has_data_format()); |  | 
|  321   EXPECT_FALSE(newempty.has_data_offset()); |  | 
|  322   EXPECT_FALSE(newempty.has_data_length()); |  | 
|  323  |  | 
|  324   const DeltaArchiveManifest_File& subdir = |  | 
|  325       archive->files(dir.children(4).index()); |  | 
|  326   EXPECT_EQ(2, subdir.children_size()); |  | 
|  327   EXPECT_EQ("fifo", subdir.children(0).name()); |  | 
|  328   EXPECT_EQ("link", subdir.children(1).name()); |  | 
|  329   EXPECT_TRUE(S_ISDIR(subdir.mode())); |  | 
|  330   EXPECT_EQ(0, subdir.uid()); |  | 
|  331   EXPECT_EQ(0, subdir.gid()); |  | 
|  332   EXPECT_FALSE(subdir.has_hardlink_path()); |  | 
|  333   EXPECT_FALSE(subdir.has_data_format()); |  | 
|  334   EXPECT_FALSE(subdir.has_data_offset()); |  | 
|  335   EXPECT_FALSE(subdir.has_data_length()); |  | 
|  336  |  | 
|  337   const DeltaArchiveManifest_File& fifo = |  | 
|  338       archive->files(subdir.children(0).index()); |  | 
|  339   EXPECT_EQ(0, fifo.children_size()); |  | 
|  340   EXPECT_TRUE(S_ISFIFO(fifo.mode())); |  | 
|  341   EXPECT_EQ(0, fifo.uid()); |  | 
|  342   EXPECT_EQ(0, fifo.gid()); |  | 
|  343   EXPECT_FALSE(fifo.has_hardlink_path()); |  | 
|  344   EXPECT_FALSE(fifo.has_data_format()); |  | 
|  345   EXPECT_FALSE(fifo.has_data_offset()); |  | 
|  346   EXPECT_FALSE(fifo.has_data_length()); |  | 
|  347  |  | 
|  348   const DeltaArchiveManifest_File& link = |  | 
|  349       archive->files(subdir.children(1).index()); |  | 
|  350   EXPECT_EQ(0, link.children_size()); |  | 
|  351   EXPECT_TRUE(S_ISLNK(link.mode())); |  | 
|  352   EXPECT_EQ(0, link.uid()); |  | 
|  353   EXPECT_EQ(0, link.gid()); |  | 
|  354   EXPECT_FALSE(link.has_hardlink_path()); |  | 
|  355   EXPECT_FALSE(link.has_data_format()); |  | 
|  356   EXPECT_FALSE(link.has_data_offset()); |  | 
|  357   EXPECT_FALSE(link.has_data_length()); |  | 
|  358 } |  | 
|  359  |  | 
|  360 TEST_F(DeltaDiffGeneratorTest, FakerootEncodeDataToDeltaFileTest) { |  | 
|  361   FakerootEncodeDataToDeltaFileTest(false); |  | 
|  362 } |  | 
|  363 TEST_F(DeltaDiffGeneratorTest, FakerootDiffExclusionsTest) { |  | 
|  364   FakerootEncodeDataToDeltaFileTest(true); |  | 
|  365 } |  | 
|  366  |  | 
|  367 void DeltaDiffGeneratorTest::FakerootEncodeDataToDeltaFileTest( |  | 
|  368     bool test_diff_exclusion) { |  | 
|  369   char cwd[1000]; |  | 
|  370   ASSERT_EQ(cwd, getcwd(cwd, sizeof(cwd))) << "cwd buf possibly too small"; |  | 
|  371   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test")); |  | 
|  372   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/old")); |  | 
|  373   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/new")); |  | 
|  374   GenerateFilesAtPath(string(cwd) + "/diff-gen-test/old"); |  | 
|  375   GenerateFilesAtPath(string(cwd) + "/diff-gen-test/new"); |  | 
|  376   EditFilesAtPath(string(cwd) + "/diff-gen-test/new"); |  | 
|  377  |  | 
|  378   set<string> diff_exclusions; |  | 
|  379   if (test_diff_exclusion) { |  | 
|  380     diff_exclusions.insert("/encoding/long_small_change"); |  | 
|  381   } else { |  | 
|  382     diff_exclusions.insert("/hi"); |  | 
|  383   } |  | 
|  384  |  | 
|  385   DeltaArchiveManifest* archive = |  | 
|  386       DeltaDiffGenerator::EncodeMetadataToProtoBuffer( |  | 
|  387           (string(cwd) + "/diff-gen-test/new").c_str()); |  | 
|  388   EXPECT_TRUE(NULL != archive); |  | 
|  389  |  | 
|  390   EXPECT_TRUE(DeltaDiffGenerator::EncodeDataToDeltaFile( |  | 
|  391       archive, |  | 
|  392       string(cwd) + "/diff-gen-test/old", |  | 
|  393       string(cwd) + "/diff-gen-test/new", |  | 
|  394       string(cwd) + "/diff-gen-test/out.dat", |  | 
|  395       diff_exclusions, "")); |  | 
|  396  |  | 
|  397   EXPECT_EQ(18, archive->files_size()); |  | 
|  398  |  | 
|  399   const DeltaArchiveManifest_File& root = archive->files(0); |  | 
|  400   EXPECT_TRUE(S_ISDIR(root.mode())); |  | 
|  401   EXPECT_EQ(0, root.uid()); |  | 
|  402   EXPECT_EQ(0, root.gid()); |  | 
|  403   ASSERT_EQ(6, root.children_size()); |  | 
|  404   EXPECT_EQ("cdev", root.children(0).name()); |  | 
|  405   EXPECT_EQ("compress_link", root.children(1).name()); |  | 
|  406   EXPECT_EQ("dir", root.children(2).name()); |  | 
|  407   EXPECT_EQ("encoding", root.children(3).name()); |  | 
|  408   EXPECT_EQ("hard_link", root.children(4).name()); |  | 
|  409   EXPECT_EQ("hi", root.children(5).name()); |  | 
|  410   EXPECT_FALSE(root.has_hardlink_path()); |  | 
|  411   EXPECT_FALSE(root.has_data_format()); |  | 
|  412   EXPECT_FALSE(root.has_data_offset()); |  | 
|  413   EXPECT_FALSE(root.has_data_length()); |  | 
|  414  |  | 
|  415   const DeltaArchiveManifest_File& cdev = |  | 
|  416       archive->files(root.children(0).index()); |  | 
|  417   EXPECT_EQ(0, cdev.children_size()); |  | 
|  418   EXPECT_TRUE(S_ISCHR(cdev.mode())); |  | 
|  419   EXPECT_EQ(0, cdev.uid()); |  | 
|  420   EXPECT_EQ(0, cdev.gid()); |  | 
|  421   ASSERT_TRUE(cdev.has_data_format()); |  | 
|  422   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, cdev.data_format()); |  | 
|  423   EXPECT_TRUE(cdev.has_data_offset()); |  | 
|  424   ASSERT_TRUE(cdev.has_data_length()); |  | 
|  425   EXPECT_GT(cdev.data_length(), 0); |  | 
|  426   EXPECT_FALSE(cdev.has_hardlink_path()); |  | 
|  427  |  | 
|  428   const DeltaArchiveManifest_File& compress_link = |  | 
|  429       archive->files(root.children(1).index()); |  | 
|  430   EXPECT_EQ(0, compress_link.children_size()); |  | 
|  431   EXPECT_TRUE(S_ISLNK(compress_link.mode())); |  | 
|  432   EXPECT_EQ(0, compress_link.uid()); |  | 
|  433   EXPECT_EQ(0, compress_link.gid()); |  | 
|  434   ASSERT_TRUE(compress_link.has_data_format()); |  | 
|  435   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ, |  | 
|  436             compress_link.data_format()); |  | 
|  437   EXPECT_TRUE(compress_link.has_data_offset()); |  | 
|  438   ASSERT_TRUE(compress_link.has_data_length()); |  | 
|  439   EXPECT_GT(compress_link.data_length(), 0); |  | 
|  440   EXPECT_FALSE(compress_link.has_hardlink_path()); |  | 
|  441  |  | 
|  442   const DeltaArchiveManifest_File& hard_link = |  | 
|  443       archive->files(root.children(4).index()); |  | 
|  444   EXPECT_EQ(0, hard_link.children_size()); |  | 
|  445   EXPECT_TRUE(S_ISREG(hard_link.mode())); |  | 
|  446   EXPECT_EQ(0, hard_link.uid()); |  | 
|  447   EXPECT_EQ(0, hard_link.gid()); |  | 
|  448   ASSERT_TRUE(hard_link.has_data_format()); |  | 
|  449   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, hard_link.data_format()); |  | 
|  450   EXPECT_TRUE(hard_link.has_data_offset()); |  | 
|  451   ASSERT_TRUE(hard_link.has_data_length()); |  | 
|  452   EXPECT_GT(hard_link.data_length(), 0); |  | 
|  453   EXPECT_FALSE(hard_link.has_hardlink_path()); |  | 
|  454  |  | 
|  455   const DeltaArchiveManifest_File& hi = |  | 
|  456       archive->files(root.children(5).index()); |  | 
|  457   EXPECT_EQ(0, hi.children_size()); |  | 
|  458   EXPECT_TRUE(S_ISREG(hi.mode())); |  | 
|  459   EXPECT_EQ(0, hi.uid()); |  | 
|  460   EXPECT_EQ(0, hi.gid()); |  | 
|  461   EXPECT_FALSE(hi.has_data_format()); |  | 
|  462   EXPECT_FALSE(hi.has_data_offset()); |  | 
|  463   EXPECT_FALSE(hi.has_data_length()); |  | 
|  464   EXPECT_TRUE(hi.has_hardlink_path()); |  | 
|  465   EXPECT_EQ("/hard_link", hi.hardlink_path()); |  | 
|  466  |  | 
|  467   const DeltaArchiveManifest_File& encoding = |  | 
|  468       archive->files(root.children(3).index()); |  | 
|  469   EXPECT_TRUE(S_ISDIR(encoding.mode())); |  | 
|  470   EXPECT_EQ(0, encoding.uid()); |  | 
|  471   EXPECT_EQ(0, encoding.gid()); |  | 
|  472   EXPECT_EQ(4, encoding.children_size()); |  | 
|  473   EXPECT_EQ("long_new", encoding.children(0).name()); |  | 
|  474   EXPECT_EQ("long_small_change", encoding.children(1).name()); |  | 
|  475   EXPECT_EQ("nochange", encoding.children(2).name()); |  | 
|  476   EXPECT_EQ("onebyte", encoding.children(3).name()); |  | 
|  477   EXPECT_FALSE(encoding.has_data_format()); |  | 
|  478   EXPECT_FALSE(encoding.has_data_offset()); |  | 
|  479   EXPECT_FALSE(encoding.has_data_length()); |  | 
|  480   EXPECT_FALSE(encoding.has_hardlink_path()); |  | 
|  481  |  | 
|  482   const DeltaArchiveManifest_File& long_new = |  | 
|  483       archive->files(encoding.children(0).index()); |  | 
|  484   EXPECT_EQ(0, long_new.children_size()); |  | 
|  485   EXPECT_TRUE(S_ISREG(long_new.mode())); |  | 
|  486   EXPECT_EQ(0, long_new.uid()); |  | 
|  487   EXPECT_EQ(0, long_new.gid()); |  | 
|  488   EXPECT_TRUE(long_new.has_data_format()); |  | 
|  489   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ, |  | 
|  490             long_new.data_format()); |  | 
|  491   EXPECT_TRUE(long_new.has_data_offset()); |  | 
|  492   EXPECT_TRUE(long_new.has_data_length()); |  | 
|  493   EXPECT_FALSE(long_new.has_hardlink_path()); |  | 
|  494  |  | 
|  495   const DeltaArchiveManifest_File& long_small_change = |  | 
|  496       archive->files(encoding.children(1).index()); |  | 
|  497   EXPECT_EQ(0, long_small_change.children_size()); |  | 
|  498   EXPECT_TRUE(S_ISREG(long_small_change.mode())); |  | 
|  499   EXPECT_EQ(0, long_small_change.uid()); |  | 
|  500   EXPECT_EQ(0, long_small_change.gid()); |  | 
|  501   EXPECT_TRUE(long_small_change.has_data_format()); |  | 
|  502   DeltaArchiveManifest_File_DataFormat expected_format = |  | 
|  503       DeltaArchiveManifest_File_DataFormat_BSDIFF; |  | 
|  504   if (test_diff_exclusion) |  | 
|  505     expected_format = DeltaArchiveManifest_File_DataFormat_FULL; |  | 
|  506   EXPECT_EQ(expected_format, long_small_change.data_format()); |  | 
|  507   EXPECT_TRUE(long_small_change.has_data_offset()); |  | 
|  508   EXPECT_TRUE(long_small_change.has_data_length()); |  | 
|  509   EXPECT_FALSE(long_small_change.has_hardlink_path()); |  | 
|  510  |  | 
|  511   const DeltaArchiveManifest_File& nochange = |  | 
|  512       archive->files(encoding.children(2).index()); |  | 
|  513   EXPECT_EQ(0, nochange.children_size()); |  | 
|  514   EXPECT_TRUE(S_ISREG(nochange.mode())); |  | 
|  515   EXPECT_EQ(0, nochange.uid()); |  | 
|  516   EXPECT_EQ(0, nochange.gid()); |  | 
|  517   EXPECT_FALSE(nochange.has_data_format()); |  | 
|  518   EXPECT_FALSE(nochange.has_data_offset()); |  | 
|  519   EXPECT_FALSE(nochange.has_data_length()); |  | 
|  520   EXPECT_FALSE(nochange.has_hardlink_path()); |  | 
|  521  |  | 
|  522   const DeltaArchiveManifest_File& onebyte = |  | 
|  523       archive->files(encoding.children(3).index()); |  | 
|  524   EXPECT_EQ(0, onebyte.children_size()); |  | 
|  525   EXPECT_TRUE(S_ISREG(onebyte.mode())); |  | 
|  526   EXPECT_EQ(0, onebyte.uid()); |  | 
|  527   EXPECT_EQ(0, onebyte.gid()); |  | 
|  528   EXPECT_TRUE(onebyte.has_data_format()); |  | 
|  529   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, onebyte.data_format()); |  | 
|  530   EXPECT_TRUE(onebyte.has_data_offset()); |  | 
|  531   EXPECT_TRUE(onebyte.has_data_length()); |  | 
|  532   EXPECT_EQ(1, onebyte.data_length()); |  | 
|  533   EXPECT_FALSE(onebyte.has_hardlink_path()); |  | 
|  534  |  | 
|  535   const DeltaArchiveManifest_File& dir = |  | 
|  536       archive->files(root.children(2).index()); |  | 
|  537   EXPECT_TRUE(S_ISDIR(dir.mode())); |  | 
|  538   EXPECT_EQ(0, dir.uid()); |  | 
|  539   EXPECT_EQ(0, dir.gid()); |  | 
|  540   ASSERT_EQ(5, dir.children_size()); |  | 
|  541   EXPECT_EQ("bdev", dir.children(0).name()); |  | 
|  542   EXPECT_EQ("emptydir", dir.children(1).name()); |  | 
|  543   EXPECT_EQ("hello", dir.children(2).name()); |  | 
|  544   EXPECT_EQ("newempty", dir.children(3).name()); |  | 
|  545   EXPECT_EQ("subdir", dir.children(4).name()); |  | 
|  546   EXPECT_FALSE(dir.has_data_format()); |  | 
|  547   EXPECT_FALSE(dir.has_data_offset()); |  | 
|  548   EXPECT_FALSE(dir.has_data_length()); |  | 
|  549   EXPECT_FALSE(dir.has_hardlink_path()); |  | 
|  550  |  | 
|  551   const DeltaArchiveManifest_File& bdev = |  | 
|  552       archive->files(dir.children(0).index()); |  | 
|  553   EXPECT_EQ(0, bdev.children_size()); |  | 
|  554   EXPECT_TRUE(S_ISBLK(bdev.mode())); |  | 
|  555   EXPECT_EQ(0, bdev.uid()); |  | 
|  556   EXPECT_EQ(0, bdev.gid()); |  | 
|  557   ASSERT_TRUE(bdev.has_data_format()); |  | 
|  558   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, bdev.data_format()); |  | 
|  559   EXPECT_TRUE(bdev.has_data_offset()); |  | 
|  560   ASSERT_TRUE(bdev.has_data_length()); |  | 
|  561   EXPECT_GT(bdev.data_length(), 0); |  | 
|  562   EXPECT_FALSE(bdev.has_hardlink_path()); |  | 
|  563  |  | 
|  564   const DeltaArchiveManifest_File& emptydir = |  | 
|  565       archive->files(dir.children(1).index()); |  | 
|  566   EXPECT_EQ(0, emptydir.children_size()); |  | 
|  567   EXPECT_TRUE(S_ISDIR(emptydir.mode())); |  | 
|  568   EXPECT_EQ(501, emptydir.uid()); |  | 
|  569   EXPECT_EQ(503, emptydir.gid()); |  | 
|  570   EXPECT_FALSE(emptydir.has_data_format()); |  | 
|  571   EXPECT_FALSE(emptydir.has_data_offset()); |  | 
|  572   EXPECT_FALSE(emptydir.has_data_length()); |  | 
|  573   EXPECT_FALSE(emptydir.has_hardlink_path()); |  | 
|  574  |  | 
|  575   const DeltaArchiveManifest_File& hello = |  | 
|  576       archive->files(dir.children(2).index()); |  | 
|  577   EXPECT_EQ(0, hello.children_size()); |  | 
|  578   EXPECT_TRUE(S_ISREG(hello.mode())); |  | 
|  579   EXPECT_EQ(0, hello.uid()); |  | 
|  580   EXPECT_EQ(0, hello.gid()); |  | 
|  581   ASSERT_TRUE(hello.has_data_format()); |  | 
|  582   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, hello.data_format()); |  | 
|  583   EXPECT_TRUE(hello.has_data_offset()); |  | 
|  584   ASSERT_TRUE(hello.has_data_length()); |  | 
|  585   EXPECT_GT(hello.data_length(), 0); |  | 
|  586   EXPECT_FALSE(hello.has_hardlink_path()); |  | 
|  587  |  | 
|  588   const DeltaArchiveManifest_File& newempty = |  | 
|  589       archive->files(dir.children(3).index()); |  | 
|  590   EXPECT_EQ(0, newempty.children_size()); |  | 
|  591   EXPECT_TRUE(S_ISREG(newempty.mode())); |  | 
|  592   EXPECT_EQ(0, newempty.uid()); |  | 
|  593   EXPECT_EQ(0, newempty.gid()); |  | 
|  594   EXPECT_TRUE(newempty.has_data_format()); |  | 
|  595   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, newempty.data_format()); |  | 
|  596   EXPECT_TRUE(newempty.has_data_offset()); |  | 
|  597   EXPECT_TRUE(newempty.has_data_length()); |  | 
|  598   EXPECT_FALSE(newempty.has_hardlink_path()); |  | 
|  599  |  | 
|  600   const DeltaArchiveManifest_File& subdir = |  | 
|  601       archive->files(dir.children(4).index()); |  | 
|  602   EXPECT_EQ(2, subdir.children_size()); |  | 
|  603   EXPECT_EQ("fifo", subdir.children(0).name()); |  | 
|  604   EXPECT_EQ("link", subdir.children(1).name()); |  | 
|  605   EXPECT_TRUE(S_ISDIR(subdir.mode())); |  | 
|  606   EXPECT_EQ(0, subdir.uid()); |  | 
|  607   EXPECT_EQ(0, subdir.gid()); |  | 
|  608   EXPECT_FALSE(subdir.has_data_format()); |  | 
|  609   EXPECT_FALSE(subdir.has_data_offset()); |  | 
|  610   EXPECT_FALSE(subdir.has_data_length()); |  | 
|  611   EXPECT_FALSE(subdir.has_hardlink_path()); |  | 
|  612  |  | 
|  613   const DeltaArchiveManifest_File& fifo = |  | 
|  614       archive->files(subdir.children(0).index()); |  | 
|  615   EXPECT_EQ(0, fifo.children_size()); |  | 
|  616   EXPECT_TRUE(S_ISFIFO(fifo.mode())); |  | 
|  617   EXPECT_EQ(0, fifo.uid()); |  | 
|  618   EXPECT_EQ(0, fifo.gid()); |  | 
|  619   EXPECT_FALSE(fifo.has_data_format()); |  | 
|  620   EXPECT_FALSE(fifo.has_data_offset()); |  | 
|  621   EXPECT_FALSE(fifo.has_data_length()); |  | 
|  622   EXPECT_FALSE(fifo.has_hardlink_path()); |  | 
|  623  |  | 
|  624   const DeltaArchiveManifest_File& link = |  | 
|  625       archive->files(subdir.children(1).index()); |  | 
|  626   EXPECT_EQ(0, link.children_size()); |  | 
|  627   EXPECT_TRUE(S_ISLNK(link.mode())); |  | 
|  628   EXPECT_EQ(0, link.uid()); |  | 
|  629   EXPECT_EQ(0, link.gid()); |  | 
|  630   ASSERT_TRUE(link.has_data_format()); |  | 
|  631   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, link.data_format()); |  | 
|  632   EXPECT_TRUE(link.has_data_offset()); |  | 
|  633   ASSERT_TRUE(link.has_data_length()); |  | 
|  634   EXPECT_GT(link.data_length(), 0); |  | 
|  635   EXPECT_FALSE(link.has_hardlink_path()); |  | 
|  636 } |  | 
|  637  |  | 
|  638 class DeltaDiffParserTest : public ::testing::Test { |  | 
|  639   virtual void TearDown() { |  | 
|  640     EXPECT_EQ(0, system("rm -rf diff-gen-test")); |  | 
|  641   } |  | 
|  642 }; |  | 
|  643  |  | 
|  644 namespace { |  | 
|  645 // Reads part of a file into memory |  | 
|  646 vector<char> ReadFilePart(const string& path, off_t start, off_t size) { |  | 
|  647   vector<char> ret; |  | 
|  648   int fd = open(path.c_str(), O_RDONLY, 0); |  | 
|  649   if (fd < 0) |  | 
|  650     return ret; |  | 
|  651   ret.resize(size); |  | 
|  652   EXPECT_EQ(size, pread(fd, &ret[0], size, start)); |  | 
|  653   close(fd); |  | 
|  654   return ret; |  | 
|  655 } |  | 
|  656  |  | 
|  657 string ReadFilePartToString(const string& path, off_t start, off_t size) { |  | 
|  658   vector<char> bytes = ReadFilePart(path, start, size); |  | 
|  659   string ret; |  | 
|  660   ret.append(&bytes[0], bytes.size()); |  | 
|  661   return ret; |  | 
|  662 } |  | 
|  663  |  | 
|  664 string StringFromVectorChar(const vector<char>& in) { |  | 
|  665   return string(&in[0], in.size()); |  | 
|  666 } |  | 
|  667  |  | 
|  668 string GzipDecompressToString(const vector<char>& in) { |  | 
|  669   vector<char> out; |  | 
|  670   EXPECT_TRUE(GzipDecompress(in, &out)); |  | 
|  671   return StringFromVectorChar(out); |  | 
|  672 } |  | 
|  673  |  | 
|  674 } |  | 
|  675  |  | 
|  676 TEST_F(DeltaDiffParserTest, FakerootDecodeDataFromDeltaFileTest) { |  | 
|  677   char cwd[1000]; |  | 
|  678   ASSERT_EQ(cwd, getcwd(cwd, sizeof(cwd))) << "cwd buf possibly too small"; |  | 
|  679   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test")); |  | 
|  680   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/old")); |  | 
|  681   ASSERT_EQ(0, System(string("mkdir -p ") + cwd + "/diff-gen-test/new")); |  | 
|  682   GenerateFilesAtPath(string(cwd) + "/diff-gen-test/old"); |  | 
|  683   GenerateFilesAtPath(string(cwd) + "/diff-gen-test/new"); |  | 
|  684   EditFilesAtPath(string(cwd) + "/diff-gen-test/new"); |  | 
|  685  |  | 
|  686   DeltaArchiveManifest* archive = |  | 
|  687       DeltaDiffGenerator::EncodeMetadataToProtoBuffer( |  | 
|  688           (string(cwd) + "/diff-gen-test/new").c_str()); |  | 
|  689   EXPECT_TRUE(NULL != archive); |  | 
|  690  |  | 
|  691   EXPECT_TRUE(DeltaDiffGenerator::EncodeDataToDeltaFile( |  | 
|  692       archive, |  | 
|  693       string(cwd) + "/diff-gen-test/old", |  | 
|  694       string(cwd) + "/diff-gen-test/new", |  | 
|  695       string(cwd) + "/diff-gen-test/out.dat", |  | 
|  696       set<string>(), "")); |  | 
|  697   // parse the file |  | 
|  698  |  | 
|  699   DeltaDiffParser parser(string(cwd) + "/diff-gen-test/out.dat"); |  | 
|  700   ASSERT_TRUE(parser.valid()); |  | 
|  701   DeltaDiffParser::Iterator it = parser.Begin(); |  | 
|  702   string expected_paths[] = { |  | 
|  703     "", |  | 
|  704     "/cdev", |  | 
|  705     "/compress_link", |  | 
|  706     "/dir", |  | 
|  707     "/dir/bdev", |  | 
|  708     "/dir/emptydir", |  | 
|  709     "/dir/hello", |  | 
|  710     "/dir/newempty", |  | 
|  711     "/dir/subdir", |  | 
|  712     "/dir/subdir/fifo", |  | 
|  713     "/dir/subdir/link", |  | 
|  714     "/encoding", |  | 
|  715     "/encoding/long_new", |  | 
|  716     "/encoding/long_small_change", |  | 
|  717     "/encoding/nochange", |  | 
|  718     "/encoding/onebyte", |  | 
|  719     "/hard_link", |  | 
|  720     "/hi" |  | 
|  721   }; |  | 
|  722   for (unsigned int i = 0; |  | 
|  723        i < (sizeof(expected_paths)/sizeof(expected_paths[0])); i++) { |  | 
|  724     ASSERT_TRUE(it != parser.End()); |  | 
|  725     ASSERT_TRUE(parser.ContainsPath(expected_paths[i])); |  | 
|  726     EXPECT_EQ(expected_paths[i], it.path()); |  | 
|  727     EXPECT_EQ(expected_paths[i].substr(expected_paths[i].find_last_of('/') + 1), |  | 
|  728               it.GetName()); |  | 
|  729     DeltaArchiveManifest_File f1 = parser.GetFileAtPath(expected_paths[i]); |  | 
|  730     DeltaArchiveManifest_File f2 = it.GetFile(); |  | 
|  731     EXPECT_EQ(f1.mode(), f2.mode()) << it.path(); |  | 
|  732     EXPECT_EQ(f1.uid(), f2.uid()); |  | 
|  733     EXPECT_EQ(f1.gid(), f2.gid()); |  | 
|  734     EXPECT_EQ(f1.has_data_format(), f2.has_data_format()); |  | 
|  735     if (f1.has_data_format()) { |  | 
|  736       EXPECT_EQ(f1.data_format(), f2.data_format()); |  | 
|  737       EXPECT_TRUE(f1.has_data_offset()); |  | 
|  738       EXPECT_TRUE(f2.has_data_offset()); |  | 
|  739       EXPECT_EQ(f1.data_offset(), f2.data_offset()); |  | 
|  740     } else { |  | 
|  741       EXPECT_FALSE(f2.has_data_format()); |  | 
|  742       EXPECT_FALSE(f1.has_data_offset()); |  | 
|  743       EXPECT_FALSE(f2.has_data_offset()); |  | 
|  744     } |  | 
|  745     EXPECT_EQ(f1.children_size(), f2.children_size()); |  | 
|  746     for (int j = 0; j < f1.children_size(); j++) { |  | 
|  747       EXPECT_EQ(f1.children(j).name(), f2.children(j).name()); |  | 
|  748       EXPECT_EQ(f1.children(j).index(), f2.children(j).index()); |  | 
|  749     } |  | 
|  750     it.Increment(); |  | 
|  751   } |  | 
|  752   EXPECT_TRUE(it == parser.End()); |  | 
|  753   EXPECT_FALSE(parser.ContainsPath("/cdew")); |  | 
|  754   EXPECT_FALSE(parser.ContainsPath("/hi/hi")); |  | 
|  755   EXPECT_FALSE(parser.ContainsPath("/dir/newempty/hi")); |  | 
|  756   EXPECT_TRUE(parser.ContainsPath("/dir/")); |  | 
|  757  |  | 
|  758   // Check the data |  | 
|  759   // root |  | 
|  760   DeltaArchiveManifest_File file = parser.GetFileAtPath(""); |  | 
|  761   EXPECT_TRUE(S_ISDIR(file.mode())); |  | 
|  762   EXPECT_FALSE(file.has_data_format()); |  | 
|  763  |  | 
|  764   // cdev |  | 
|  765   file = parser.GetFileAtPath("/cdev"); |  | 
|  766   EXPECT_TRUE(S_ISCHR(file.mode())); |  | 
|  767   EXPECT_TRUE(file.has_data_format()); |  | 
|  768   vector<char> data = ReadFilePart(string(cwd) + "/diff-gen-test/out.dat", |  | 
|  769                                    file.data_offset(), file.data_length()); |  | 
|  770   LinuxDevice linux_device; |  | 
|  771   linux_device.ParseFromArray(&data[0], data.size()); |  | 
|  772   EXPECT_EQ(linux_device.major(), 2); |  | 
|  773   EXPECT_EQ(linux_device.minor(), 1); |  | 
|  774  |  | 
|  775   // compress_link |  | 
|  776   file = parser.GetFileAtPath("/compress_link"); |  | 
|  777   EXPECT_TRUE(S_ISLNK(file.mode())); |  | 
|  778   EXPECT_TRUE(file.has_data_format()); |  | 
|  779   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ, file.data_format()); |  | 
|  780   EXPECT_EQ(kWellCompressingFilename, |  | 
|  781             GzipDecompressToString(ReadFilePart(string(cwd) + |  | 
|  782                                                 "/diff-gen-test/out.dat", |  | 
|  783                                                 file.data_offset(), |  | 
|  784                                                 file.data_length()))); |  | 
|  785   // dir |  | 
|  786   file = parser.GetFileAtPath("/dir"); |  | 
|  787   EXPECT_TRUE(S_ISDIR(file.mode())); |  | 
|  788   EXPECT_FALSE(file.has_data_format()); |  | 
|  789  |  | 
|  790   // bdev |  | 
|  791   file = parser.GetFileAtPath("/dir/bdev"); |  | 
|  792   EXPECT_TRUE(S_ISBLK(file.mode())); |  | 
|  793   EXPECT_TRUE(file.has_data_format()); |  | 
|  794   data = ReadFilePart(string(cwd) + "/diff-gen-test/out.dat", |  | 
|  795                       file.data_offset(), file.data_length()); |  | 
|  796   linux_device.ParseFromArray(&data[0], data.size()); |  | 
|  797   EXPECT_EQ(linux_device.major(), 3); |  | 
|  798   EXPECT_EQ(linux_device.minor(), 1); |  | 
|  799  |  | 
|  800   // emptydir |  | 
|  801   file = parser.GetFileAtPath("/dir/emptydir"); |  | 
|  802   EXPECT_TRUE(S_ISDIR(file.mode())); |  | 
|  803   EXPECT_FALSE(file.has_data_format()); |  | 
|  804  |  | 
|  805   // hello |  | 
|  806   file = parser.GetFileAtPath("/dir/hello"); |  | 
|  807   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  808   EXPECT_TRUE(file.has_data_format()); |  | 
|  809   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format()); |  | 
|  810   EXPECT_EQ("hello\n", ReadFilePartToString(string(cwd) + |  | 
|  811                                             "/diff-gen-test/out.dat", |  | 
|  812                                             file.data_offset(), |  | 
|  813                                             file.data_length())); |  | 
|  814  |  | 
|  815   // newempty |  | 
|  816   file = parser.GetFileAtPath("/dir/newempty"); |  | 
|  817   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  818   EXPECT_TRUE(file.has_data_format()); |  | 
|  819   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format()); |  | 
|  820  |  | 
|  821   // subdir |  | 
|  822   file = parser.GetFileAtPath("/dir/subdir"); |  | 
|  823   EXPECT_TRUE(S_ISDIR(file.mode())); |  | 
|  824   EXPECT_FALSE(file.has_data_format()); |  | 
|  825  |  | 
|  826   // fifo |  | 
|  827   file = parser.GetFileAtPath("/dir/subdir/fifo"); |  | 
|  828   EXPECT_TRUE(S_ISFIFO(file.mode())); |  | 
|  829   EXPECT_FALSE(file.has_data_format()); |  | 
|  830  |  | 
|  831   // link |  | 
|  832   file = parser.GetFileAtPath("/dir/subdir/link"); |  | 
|  833   EXPECT_TRUE(S_ISLNK(file.mode())); |  | 
|  834   EXPECT_TRUE(file.has_data_format()); |  | 
|  835   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format()); |  | 
|  836   EXPECT_EQ("/target", ReadFilePartToString(string(cwd) + |  | 
|  837                                             "/diff-gen-test/out.dat", |  | 
|  838                                             file.data_offset(), |  | 
|  839                                             file.data_length())); |  | 
|  840  |  | 
|  841   // encoding |  | 
|  842   file = parser.GetFileAtPath("/encoding"); |  | 
|  843   EXPECT_TRUE(S_ISDIR(file.mode())); |  | 
|  844   EXPECT_FALSE(file.has_data_format()); |  | 
|  845  |  | 
|  846   // long_new |  | 
|  847   file = parser.GetFileAtPath("/encoding/long_new"); |  | 
|  848   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  849   EXPECT_TRUE(file.has_data_format()); |  | 
|  850   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL_GZ, file.data_format()); |  | 
|  851   EXPECT_EQ("This is a pice of text that should " |  | 
|  852             "compress well since it is just ascii and it " |  | 
|  853             "has repetition xxxxxxxxxxxxxxxxxxxxx" |  | 
|  854             "xxxxxxxxxxxxxxxxxxxx", |  | 
|  855             GzipDecompressToString(ReadFilePart(string(cwd) + |  | 
|  856                                                 "/diff-gen-test/out.dat", |  | 
|  857                                                 file.data_offset(), |  | 
|  858                                                 file.data_length()))); |  | 
|  859  |  | 
|  860   // long_small_change |  | 
|  861   file = parser.GetFileAtPath("/encoding/long_small_change"); |  | 
|  862   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  863   EXPECT_TRUE(file.has_data_format()); |  | 
|  864   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_BSDIFF, file.data_format()); |  | 
|  865   data = ReadFilePart(string(cwd) + "/diff-gen-test/out.dat", |  | 
|  866                       file.data_offset(), file.data_length()); |  | 
|  867   WriteFileVector(string(cwd) + "/diff-gen-test/patch", data); |  | 
|  868   int rc = 1; |  | 
|  869   vector<string> cmd; |  | 
|  870   cmd.push_back("/usr/bin/bspatch"); |  | 
|  871   cmd.push_back(string(cwd) + "/diff-gen-test/old/encoding/long_small_change"); |  | 
|  872   cmd.push_back(string(cwd) + "/diff-gen-test/patch_result"); |  | 
|  873   cmd.push_back(string(cwd) + "/diff-gen-test/patch"); |  | 
|  874   Subprocess::SynchronousExec(cmd, &rc); |  | 
|  875   ASSERT_EQ(0, rc); |  | 
|  876   vector<char> patch_result; |  | 
|  877   EXPECT_TRUE(utils::ReadFile(string(cwd) + "/diff-gen-test/patch_result", |  | 
|  878                               &patch_result)); |  | 
|  879   vector<char> expected_data(sizeof(kRandomString) + 1); |  | 
|  880   memcpy(&expected_data[0], kRandomString, sizeof(kRandomString)); |  | 
|  881   expected_data[expected_data.size() - 1] = 'h'; |  | 
|  882   ExpectVectorsEq(expected_data, patch_result); |  | 
|  883  |  | 
|  884   // nochange |  | 
|  885   file = parser.GetFileAtPath("/encoding/nochange"); |  | 
|  886   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  887   EXPECT_FALSE(file.has_data_format()); |  | 
|  888   EXPECT_FALSE(file.has_data_offset()); |  | 
|  889   EXPECT_FALSE(file.has_data_length()); |  | 
|  890  |  | 
|  891   // onebyte |  | 
|  892   file = parser.GetFileAtPath("/encoding/onebyte"); |  | 
|  893   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  894   EXPECT_TRUE(file.has_data_format()); |  | 
|  895   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format()); |  | 
|  896   EXPECT_EQ("h", ReadFilePartToString(string(cwd) + |  | 
|  897                                       "/diff-gen-test/out.dat", |  | 
|  898                                       file.data_offset(), |  | 
|  899                                       file.data_length())); |  | 
|  900  |  | 
|  901   // hard_link |  | 
|  902   file = parser.GetFileAtPath("/hard_link"); |  | 
|  903   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  904   EXPECT_TRUE(file.has_data_format()); |  | 
|  905   EXPECT_EQ(DeltaArchiveManifest_File_DataFormat_FULL, file.data_format()); |  | 
|  906   EXPECT_EQ("newhi\n", ReadFilePartToString(string(cwd) + |  | 
|  907                                             "/diff-gen-test/out.dat", |  | 
|  908                                             file.data_offset(), |  | 
|  909                                             file.data_length())); |  | 
|  910  |  | 
|  911   // hi |  | 
|  912   file = parser.GetFileAtPath("/hi"); |  | 
|  913   EXPECT_TRUE(S_ISREG(file.mode())); |  | 
|  914   EXPECT_FALSE(file.has_data_format()); |  | 
|  915   EXPECT_TRUE(file.has_hardlink_path()); |  | 
|  916   EXPECT_EQ("/hard_link", file.hardlink_path()); |  | 
|  917 } |  | 
|  918  |  | 
|  919 TEST_F(DeltaDiffParserTest, FakerootInvalidTest) { |  | 
|  920   ASSERT_EQ(0, mkdir("diff-gen-test", 0777)); |  | 
|  921   { |  | 
|  922     DeltaDiffParser parser("/no/such/file"); |  | 
|  923     EXPECT_FALSE(parser.valid()); |  | 
|  924   } |  | 
|  925   { |  | 
|  926     vector<char> data(3); |  | 
|  927     memcpy(&data[0], "CrA", 3); |  | 
|  928     WriteFileVector("diff-gen-test/baddelta", data); |  | 
|  929     DeltaDiffParser parser("diff-gen-test/baddelta"); |  | 
|  930     EXPECT_FALSE(parser.valid()); |  | 
|  931   } |  | 
|  932   { |  | 
|  933     vector<char> data(5); |  | 
|  934     memcpy(&data[0], "CrAPx", 5); |  | 
|  935     WriteFileVector("diff-gen-test/baddelta", data); |  | 
|  936     DeltaDiffParser parser("diff-gen-test/baddelta"); |  | 
|  937     EXPECT_FALSE(parser.valid()); |  | 
|  938   } |  | 
|  939   { |  | 
|  940     vector<char> data(5); |  | 
|  941     memcpy(&data[0], "CrAU\0", 5); |  | 
|  942     WriteFileVector("diff-gen-test/baddelta", data); |  | 
|  943     DeltaDiffParser parser("diff-gen-test/baddelta"); |  | 
|  944     EXPECT_FALSE(parser.valid()); |  | 
|  945   } |  | 
|  946   { |  | 
|  947     vector<char> data(14); |  | 
|  948     memcpy(&data[0], "CrAU\0\0\0\0\0\0\0\x0cxx", 12); |  | 
|  949     WriteFileVector("diff-gen-test/baddelta", data); |  | 
|  950     DeltaDiffParser parser("diff-gen-test/baddelta"); |  | 
|  951     EXPECT_FALSE(parser.valid()); |  | 
|  952   } |  | 
|  953 } |  | 
|  954  |   27  | 
|  955 }  // namespace chromeos_update_engine |   28 }  // namespace chromeos_update_engine | 
| OLD | NEW |