OLD | NEW |
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium OS 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/mount.h> | 5 #include <sys/mount.h> |
6 #include <inttypes.h> | 6 #include <inttypes.h> |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include <google/protobuf/repeated_field.h> | 12 #include <google/protobuf/repeated_field.h> |
13 #include <gtest/gtest.h> | 13 #include <gtest/gtest.h> |
14 | 14 |
15 #include "base/scoped_ptr.h" | 15 #include "base/scoped_ptr.h" |
16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
17 #include "update_engine/delta_diff_generator.h" | 17 #include "update_engine/delta_diff_generator.h" |
18 #include "update_engine/delta_performer.h" | 18 #include "update_engine/delta_performer.h" |
19 #include "update_engine/graph_types.h" | 19 #include "update_engine/graph_types.h" |
| 20 #include "update_engine/payload_signer.h" |
20 #include "update_engine/test_utils.h" | 21 #include "update_engine/test_utils.h" |
21 #include "update_engine/update_metadata.pb.h" | 22 #include "update_engine/update_metadata.pb.h" |
22 #include "update_engine/utils.h" | 23 #include "update_engine/utils.h" |
23 | 24 |
24 namespace chromeos_update_engine { | 25 namespace chromeos_update_engine { |
25 | 26 |
26 using std::min; | 27 using std::min; |
27 using std::string; | 28 using std::string; |
28 using std::vector; | 29 using std::vector; |
29 | 30 |
| 31 extern const char* kUnittestPrivateKeyPath; |
| 32 |
30 class DeltaPerformerTest : public ::testing::Test { }; | 33 class DeltaPerformerTest : public ::testing::Test { }; |
31 | 34 |
32 TEST(DeltaPerformerTest, ExtentsToByteStringTest) { | 35 TEST(DeltaPerformerTest, ExtentsToByteStringTest) { |
33 uint64_t test[] = {1, 1, 4, 2, kSparseHole, 1, 0, 1}; | 36 uint64_t test[] = {1, 1, 4, 2, kSparseHole, 1, 0, 1}; |
34 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven); | 37 COMPILE_ASSERT(arraysize(test) % 2 == 0, array_size_uneven); |
35 const uint64_t block_size = 4096; | 38 const uint64_t block_size = 4096; |
36 const uint64_t file_length = 5 * block_size - 13; | 39 const uint64_t file_length = 5 * block_size - 13; |
37 | 40 |
38 google::protobuf::RepeatedPtrField<Extent> extents; | 41 google::protobuf::RepeatedPtrField<Extent> extents; |
39 for (size_t i = 0; i < arraysize(test); i += 2) { | 42 for (size_t i = 0; i < arraysize(test); i += 2) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 ScopedPathUnlinker old_kernel_unlinker(old_kernel); | 162 ScopedPathUnlinker old_kernel_unlinker(old_kernel); |
160 | 163 |
161 string new_kernel; | 164 string new_kernel; |
162 EXPECT_TRUE(utils::MakeTempFile("/tmp/new_kernel.XXXXXX", &new_kernel, NULL)); | 165 EXPECT_TRUE(utils::MakeTempFile("/tmp/new_kernel.XXXXXX", &new_kernel, NULL)); |
163 ScopedPathUnlinker new_kernel_unlinker(new_kernel); | 166 ScopedPathUnlinker new_kernel_unlinker(new_kernel); |
164 | 167 |
165 vector<char> old_kernel_data(4096); // Something small for a test | 168 vector<char> old_kernel_data(4096); // Something small for a test |
166 vector<char> new_kernel_data(old_kernel_data.size()); | 169 vector<char> new_kernel_data(old_kernel_data.size()); |
167 FillWithData(&old_kernel_data); | 170 FillWithData(&old_kernel_data); |
168 FillWithData(&new_kernel_data); | 171 FillWithData(&new_kernel_data); |
169 | 172 |
170 // change the new kernel data | 173 // change the new kernel data |
171 const char* new_data_string = "This is new data."; | 174 const char* new_data_string = "This is new data."; |
172 strcpy(&new_kernel_data[0], new_data_string); | 175 strcpy(&new_kernel_data[0], new_data_string); |
173 | 176 |
174 // Write kernels to disk | 177 // Write kernels to disk |
175 EXPECT_TRUE(utils::WriteFile( | 178 EXPECT_TRUE(utils::WriteFile( |
176 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size())); | 179 old_kernel.c_str(), &old_kernel_data[0], old_kernel_data.size())); |
177 EXPECT_TRUE(utils::WriteFile( | 180 EXPECT_TRUE(utils::WriteFile( |
178 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size())); | 181 new_kernel.c_str(), &new_kernel_data[0], new_kernel_data.size())); |
179 | 182 |
180 string delta_path; | 183 string delta_path; |
181 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL)); | 184 EXPECT_TRUE(utils::MakeTempFile("/tmp/delta.XXXXXX", &delta_path, NULL)); |
| 185 LOG(INFO) << "delta path: " << delta_path; |
182 ScopedPathUnlinker delta_path_unlinker(delta_path); | 186 ScopedPathUnlinker delta_path_unlinker(delta_path); |
183 { | 187 { |
184 string a_mnt, b_mnt; | 188 string a_mnt, b_mnt; |
185 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY); | 189 ScopedLoopMounter a_mounter(a_img, &a_mnt, MS_RDONLY); |
186 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY); | 190 ScopedLoopMounter b_mounter(b_img, &b_mnt, MS_RDONLY); |
187 | 191 |
188 EXPECT_TRUE(DeltaDiffGenerator::GenerateDeltaUpdateFile(a_mnt, | 192 EXPECT_TRUE( |
189 a_img, | 193 DeltaDiffGenerator::GenerateDeltaUpdateFile(a_mnt, |
190 b_mnt, | 194 a_img, |
191 b_img, | 195 b_mnt, |
192 old_kernel, | 196 b_img, |
193 new_kernel, | 197 old_kernel, |
194 delta_path)); | 198 new_kernel, |
| 199 delta_path, |
| 200 kUnittestPrivateKeyPath)); |
195 } | 201 } |
196 | 202 |
197 // Read delta into memory. | 203 // Read delta into memory. |
198 vector<char> delta; | 204 vector<char> delta; |
199 EXPECT_TRUE(utils::ReadFile(delta_path, &delta)); | 205 EXPECT_TRUE(utils::ReadFile(delta_path, &delta)); |
200 | 206 |
| 207 // Check that the null signature blob exists |
| 208 { |
| 209 LOG(INFO) << "delta size: " << delta.size(); |
| 210 DeltaArchiveManifest manifest; |
| 211 const int kManifestSizeOffset = 12; |
| 212 const int kManifestOffset = 20; |
| 213 uint64_t manifest_size = 0; |
| 214 memcpy(&manifest_size, &delta[kManifestSizeOffset], sizeof(manifest_size)); |
| 215 manifest_size = be64toh(manifest_size); |
| 216 LOG(INFO) << "manifest size: " << manifest_size; |
| 217 EXPECT_TRUE(manifest.ParseFromArray(&delta[kManifestOffset], |
| 218 manifest_size)); |
| 219 EXPECT_TRUE(manifest.has_signatures_offset()); |
| 220 |
| 221 Signatures sigs_message; |
| 222 EXPECT_TRUE(sigs_message.ParseFromArray( |
| 223 &delta[kManifestOffset + manifest_size + manifest.signatures_offset()], |
| 224 manifest.signatures_size())); |
| 225 EXPECT_EQ(1, sigs_message.signatures_size()); |
| 226 const Signatures_Signature& signature = sigs_message.signatures(0); |
| 227 EXPECT_EQ(1, signature.version()); |
| 228 |
| 229 uint64_t expected_sig_data_length = 0; |
| 230 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(kUnittestPrivateKeyPath, |
| 231 &expected_sig_data_length)); |
| 232 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size()); |
| 233 EXPECT_FALSE(signature.data().empty()); |
| 234 } |
| 235 |
201 // Update the A image in place. | 236 // Update the A image in place. |
202 DeltaPerformer performer; | 237 DeltaPerformer performer; |
203 | 238 |
204 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0)); | 239 EXPECT_EQ(0, performer.Open(a_img.c_str(), 0, 0)); |
205 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str())); | 240 EXPECT_TRUE(performer.OpenKernel(old_kernel.c_str())); |
206 | 241 |
207 // Write at some number of bytes per operation. Arbitrarily chose 5. | 242 // Write at some number of bytes per operation. Arbitrarily chose 5. |
208 const size_t kBytesPerWrite = 5; | 243 const size_t kBytesPerWrite = 5; |
209 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) { | 244 for (size_t i = 0; i < delta.size(); i += kBytesPerWrite) { |
210 size_t count = min(delta.size() - i, kBytesPerWrite); | 245 size_t count = min(delta.size() - i, kBytesPerWrite); |
211 EXPECT_EQ(count, performer.Write(&delta[i], count)); | 246 EXPECT_EQ(count, performer.Write(&delta[i], count)); |
212 } | 247 } |
213 | 248 |
214 // Wrapper around close. Returns 0 on success or -errno on error. | 249 // Wrapper around close. Returns 0 on success or -errno on error. |
215 EXPECT_EQ(0, performer.Close()); | 250 EXPECT_EQ(0, performer.Close()); |
216 | 251 |
217 CompareFilesByBlock(old_kernel, new_kernel); | 252 CompareFilesByBlock(old_kernel, new_kernel); |
218 | 253 |
219 vector<char> updated_kernel_partition; | 254 vector<char> updated_kernel_partition; |
220 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition)); | 255 EXPECT_TRUE(utils::ReadFile(old_kernel, &updated_kernel_partition)); |
221 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string, | 256 EXPECT_EQ(0, strncmp(&updated_kernel_partition[0], new_data_string, |
222 strlen(new_data_string))); | 257 strlen(new_data_string))); |
223 } | 258 } |
224 | 259 |
225 } // namespace chromeos_update_engine | 260 } // namespace chromeos_update_engine |
OLD | NEW |