blob: 27dbc56d1e0252c56a9f623a4b0a2cdee6d4f79a [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2009 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#include "update_engine/common/hash_calculator.h"
Alex Deymoaab50e32014-11-10 19:55:35 -080018
rspangler@google.com49fdf182009-10-10 00:57:34 +000019#include <math.h>
20#include <unistd.h>
Darin Petkovd7061ab2010-10-06 14:37:09 -070021
Darin Petkov36a58222010-10-07 22:00:09 -070022#include <string>
Darin Petkovd7061ab2010-10-06 14:37:09 -070023#include <vector>
24
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070025#include <brillo/secure_blob.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000026#include <gtest/gtest.h>
Darin Petkovd7061ab2010-10-06 14:37:09 -070027
Alex Deymo39910dc2015-11-09 17:04:30 -080028#include "update_engine/common/libcurl_http_fetcher.h"
29#include "update_engine/common/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000030
Darin Petkov36a58222010-10-07 22:00:09 -070031using std::string;
Darin Petkovd7061ab2010-10-06 14:37:09 -070032using std::vector;
33
rspangler@google.com49fdf182009-10-10 00:57:34 +000034namespace chromeos_update_engine {
35
Darin Petkovd7061ab2010-10-06 14:37:09 -070036// Generated by running this on a linux shell:
37// $ echo -n hi | openssl dgst -sha256 -binary | openssl base64
38static const char kExpectedHash[] =
39 "j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ=";
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080040static const uint8_t kExpectedRawHash[] = {
Darin Petkovd7061ab2010-10-06 14:37:09 -070041 0x8f, 0x43, 0x43, 0x46, 0x64, 0x8f, 0x6b, 0x96,
42 0xdf, 0x89, 0xdd, 0xa9, 0x01, 0xc5, 0x17, 0x6b,
43 0x10, 0xa6, 0xd8, 0x39, 0x61, 0xdd, 0x3c, 0x1a,
44 0xc8, 0x8b, 0x59, 0xb2, 0xdc, 0x32, 0x7a, 0xa4
45};
46
Alex Deymo39910dc2015-11-09 17:04:30 -080047class HashCalculatorTest : public ::testing::Test {
Alex Vakulenkod2779df2014-06-16 13:19:00 -070048 public:
Alex Deymo39910dc2015-11-09 17:04:30 -080049 HashCalculatorTest() {}
Han Shen2643cb72012-06-26 14:45:33 -070050};
51
Alex Deymo39910dc2015-11-09 17:04:30 -080052TEST_F(HashCalculatorTest, SimpleTest) {
53 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000054 calc.Update("hi", 2);
55 calc.Finalize();
Darin Petkovd7061ab2010-10-06 14:37:09 -070056 EXPECT_EQ(kExpectedHash, calc.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070057 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
58 std::end(kExpectedRawHash));
Darin Petkovd7061ab2010-10-06 14:37:09 -070059 EXPECT_TRUE(raw_hash == calc.raw_hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +000060}
61
Alex Deymo39910dc2015-11-09 17:04:30 -080062TEST_F(HashCalculatorTest, MultiUpdateTest) {
63 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000064 calc.Update("h", 1);
65 calc.Update("i", 1);
66 calc.Finalize();
Darin Petkovd7061ab2010-10-06 14:37:09 -070067 EXPECT_EQ(kExpectedHash, calc.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070068 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
69 std::end(kExpectedRawHash));
Darin Petkovd7061ab2010-10-06 14:37:09 -070070 EXPECT_TRUE(raw_hash == calc.raw_hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +000071}
72
Alex Deymo39910dc2015-11-09 17:04:30 -080073TEST_F(HashCalculatorTest, ContextTest) {
74 HashCalculator calc;
Darin Petkov73058b42010-10-06 16:32:19 -070075 calc.Update("h", 1);
Darin Petkov36a58222010-10-07 22:00:09 -070076 string calc_context = calc.GetContext();
77 calc.Finalize();
Alex Deymo39910dc2015-11-09 17:04:30 -080078 HashCalculator calc_next;
Darin Petkov36a58222010-10-07 22:00:09 -070079 calc_next.SetContext(calc_context);
Darin Petkov73058b42010-10-06 16:32:19 -070080 calc_next.Update("i", 1);
81 calc_next.Finalize();
Darin Petkov36a58222010-10-07 22:00:09 -070082 EXPECT_EQ(kExpectedHash, calc_next.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070083 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
84 std::end(kExpectedRawHash));
Darin Petkov36a58222010-10-07 22:00:09 -070085 EXPECT_TRUE(raw_hash == calc_next.raw_hash());
Darin Petkov73058b42010-10-06 16:32:19 -070086}
87
Alex Deymo39910dc2015-11-09 17:04:30 -080088TEST_F(HashCalculatorTest, BigTest) {
89 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000090
Andrew de los Reyes21067cc2011-06-28 15:27:03 -070091 int digit_count = 1;
92 int next_overflow = 10;
rspangler@google.com49fdf182009-10-10 00:57:34 +000093 for (int i = 0; i < 1000000; i++) {
94 char buf[8];
Andrew de los Reyes21067cc2011-06-28 15:27:03 -070095 if (i == next_overflow) {
96 next_overflow *= 10;
97 digit_count++;
98 }
99 ASSERT_EQ(digit_count, snprintf(buf, sizeof(buf), "%d", i)) << " i = " << i;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000100 calc.Update(buf, strlen(buf));
101 }
102 calc.Finalize();
103
104 // Hash constant generated by running this on a linux shell:
105 // $ C=0
106 // $ while [ $C -lt 1000000 ]; do
107 // echo -n $C
108 // let C=C+1
Darin Petkovd22cb292010-09-29 10:02:29 -0700109 // done | openssl dgst -sha256 -binary | openssl base64
110 EXPECT_EQ("NZf8k6SPBkYMvhaX8YgzuMgbkLP1XZ+neM8K5wcSsf8=", calc.hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000111}
112
Alex Deymo39910dc2015-11-09 17:04:30 -0800113TEST_F(HashCalculatorTest, UpdateFileSimpleTest) {
Darin Petkov36a58222010-10-07 22:00:09 -0700114 string data_path;
115 ASSERT_TRUE(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700116 utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
Darin Petkov36a58222010-10-07 22:00:09 -0700117 ScopedPathUnlinker data_path_unlinker(data_path);
118 ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));
119
120 static const int kLengths[] = { -1, 2, 10 };
121 for (size_t i = 0; i < arraysize(kLengths); i++) {
Alex Deymo39910dc2015-11-09 17:04:30 -0800122 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700123 EXPECT_EQ(2, calc.UpdateFile(data_path, kLengths[i]));
124 EXPECT_TRUE(calc.Finalize());
125 EXPECT_EQ(kExpectedHash, calc.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700126 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
127 std::end(kExpectedRawHash));
Darin Petkov36a58222010-10-07 22:00:09 -0700128 EXPECT_TRUE(raw_hash == calc.raw_hash());
129 }
130
Alex Deymo39910dc2015-11-09 17:04:30 -0800131 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700132 EXPECT_EQ(0, calc.UpdateFile(data_path, 0));
133 EXPECT_EQ(1, calc.UpdateFile(data_path, 1));
134 EXPECT_TRUE(calc.Finalize());
135 // echo -n h | openssl dgst -sha256 -binary | openssl base64
136 EXPECT_EQ("qqlAJmTxpB9A67xSyZk+tmrrNmYClY/fqig7ceZNsSM=", calc.hash());
137}
138
Alex Deymo39910dc2015-11-09 17:04:30 -0800139TEST_F(HashCalculatorTest, RawHashOfFileSimpleTest) {
Darin Petkov698d0412010-10-13 10:59:44 -0700140 string data_path;
141 ASSERT_TRUE(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700142 utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
Darin Petkov698d0412010-10-13 10:59:44 -0700143 ScopedPathUnlinker data_path_unlinker(data_path);
144 ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));
145
146 static const int kLengths[] = { -1, 2, 10 };
147 for (size_t i = 0; i < arraysize(kLengths); i++) {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700148 brillo::Blob exp_raw_hash(std::begin(kExpectedRawHash),
149 std::end(kExpectedRawHash));
150 brillo::Blob raw_hash;
Alex Deymo39910dc2015-11-09 17:04:30 -0800151 EXPECT_EQ(2, HashCalculator::RawHashOfFile(data_path,
152 kLengths[i],
153 &raw_hash));
Darin Petkov698d0412010-10-13 10:59:44 -0700154 EXPECT_TRUE(exp_raw_hash == raw_hash);
155 }
156}
157
Alex Deymo39910dc2015-11-09 17:04:30 -0800158TEST_F(HashCalculatorTest, UpdateFileNonexistentTest) {
159 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700160 EXPECT_EQ(-1, calc.UpdateFile("/some/non-existent/file", -1));
161}
162
Alex Deymo39910dc2015-11-09 17:04:30 -0800163TEST_F(HashCalculatorTest, AbortTest) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000164 // Just make sure we don't crash and valgrind doesn't detect memory leaks
165 {
Alex Deymo39910dc2015-11-09 17:04:30 -0800166 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000167 }
168 {
Alex Deymo39910dc2015-11-09 17:04:30 -0800169 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000170 calc.Update("h", 1);
171 }
172}
173
174} // namespace chromeos_update_engine