blob: 436e6a7f1a9b123d66c4f428f9f4e8b53533233d [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/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000029
Darin Petkov36a58222010-10-07 22:00:09 -070030using std::string;
Darin Petkovd7061ab2010-10-06 14:37:09 -070031using std::vector;
32
rspangler@google.com49fdf182009-10-10 00:57:34 +000033namespace chromeos_update_engine {
34
Darin Petkovd7061ab2010-10-06 14:37:09 -070035// Generated by running this on a linux shell:
36// $ echo -n hi | openssl dgst -sha256 -binary | openssl base64
37static const char kExpectedHash[] =
38 "j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ=";
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080039static const uint8_t kExpectedRawHash[] = {
Darin Petkovd7061ab2010-10-06 14:37:09 -070040 0x8f, 0x43, 0x43, 0x46, 0x64, 0x8f, 0x6b, 0x96,
41 0xdf, 0x89, 0xdd, 0xa9, 0x01, 0xc5, 0x17, 0x6b,
42 0x10, 0xa6, 0xd8, 0x39, 0x61, 0xdd, 0x3c, 0x1a,
43 0xc8, 0x8b, 0x59, 0xb2, 0xdc, 0x32, 0x7a, 0xa4
44};
45
Alex Deymo39910dc2015-11-09 17:04:30 -080046class HashCalculatorTest : public ::testing::Test {
Alex Vakulenkod2779df2014-06-16 13:19:00 -070047 public:
Alex Deymo39910dc2015-11-09 17:04:30 -080048 HashCalculatorTest() {}
Han Shen2643cb72012-06-26 14:45:33 -070049};
50
Alex Deymo39910dc2015-11-09 17:04:30 -080051TEST_F(HashCalculatorTest, SimpleTest) {
52 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000053 calc.Update("hi", 2);
54 calc.Finalize();
Darin Petkovd7061ab2010-10-06 14:37:09 -070055 EXPECT_EQ(kExpectedHash, calc.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070056 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
57 std::end(kExpectedRawHash));
Darin Petkovd7061ab2010-10-06 14:37:09 -070058 EXPECT_TRUE(raw_hash == calc.raw_hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +000059}
60
Alex Deymo39910dc2015-11-09 17:04:30 -080061TEST_F(HashCalculatorTest, MultiUpdateTest) {
62 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000063 calc.Update("h", 1);
64 calc.Update("i", 1);
65 calc.Finalize();
Darin Petkovd7061ab2010-10-06 14:37:09 -070066 EXPECT_EQ(kExpectedHash, calc.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070067 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
68 std::end(kExpectedRawHash));
Darin Petkovd7061ab2010-10-06 14:37:09 -070069 EXPECT_TRUE(raw_hash == calc.raw_hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +000070}
71
Alex Deymo39910dc2015-11-09 17:04:30 -080072TEST_F(HashCalculatorTest, ContextTest) {
73 HashCalculator calc;
Darin Petkov73058b42010-10-06 16:32:19 -070074 calc.Update("h", 1);
Darin Petkov36a58222010-10-07 22:00:09 -070075 string calc_context = calc.GetContext();
76 calc.Finalize();
Alex Deymo39910dc2015-11-09 17:04:30 -080077 HashCalculator calc_next;
Darin Petkov36a58222010-10-07 22:00:09 -070078 calc_next.SetContext(calc_context);
Darin Petkov73058b42010-10-06 16:32:19 -070079 calc_next.Update("i", 1);
80 calc_next.Finalize();
Darin Petkov36a58222010-10-07 22:00:09 -070081 EXPECT_EQ(kExpectedHash, calc_next.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070082 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
83 std::end(kExpectedRawHash));
Darin Petkov36a58222010-10-07 22:00:09 -070084 EXPECT_TRUE(raw_hash == calc_next.raw_hash());
Darin Petkov73058b42010-10-06 16:32:19 -070085}
86
Alex Deymo39910dc2015-11-09 17:04:30 -080087TEST_F(HashCalculatorTest, BigTest) {
88 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +000089
Andrew de los Reyes21067cc2011-06-28 15:27:03 -070090 int digit_count = 1;
91 int next_overflow = 10;
rspangler@google.com49fdf182009-10-10 00:57:34 +000092 for (int i = 0; i < 1000000; i++) {
93 char buf[8];
Andrew de los Reyes21067cc2011-06-28 15:27:03 -070094 if (i == next_overflow) {
95 next_overflow *= 10;
96 digit_count++;
97 }
98 ASSERT_EQ(digit_count, snprintf(buf, sizeof(buf), "%d", i)) << " i = " << i;
rspangler@google.com49fdf182009-10-10 00:57:34 +000099 calc.Update(buf, strlen(buf));
100 }
101 calc.Finalize();
102
103 // Hash constant generated by running this on a linux shell:
104 // $ C=0
105 // $ while [ $C -lt 1000000 ]; do
106 // echo -n $C
107 // let C=C+1
Darin Petkovd22cb292010-09-29 10:02:29 -0700108 // done | openssl dgst -sha256 -binary | openssl base64
109 EXPECT_EQ("NZf8k6SPBkYMvhaX8YgzuMgbkLP1XZ+neM8K5wcSsf8=", calc.hash());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000110}
111
Alex Deymo39910dc2015-11-09 17:04:30 -0800112TEST_F(HashCalculatorTest, UpdateFileSimpleTest) {
Darin Petkov36a58222010-10-07 22:00:09 -0700113 string data_path;
114 ASSERT_TRUE(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700115 utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
Darin Petkov36a58222010-10-07 22:00:09 -0700116 ScopedPathUnlinker data_path_unlinker(data_path);
117 ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));
118
119 static const int kLengths[] = { -1, 2, 10 };
120 for (size_t i = 0; i < arraysize(kLengths); i++) {
Alex Deymo39910dc2015-11-09 17:04:30 -0800121 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700122 EXPECT_EQ(2, calc.UpdateFile(data_path, kLengths[i]));
123 EXPECT_TRUE(calc.Finalize());
124 EXPECT_EQ(kExpectedHash, calc.hash());
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700125 brillo::Blob raw_hash(std::begin(kExpectedRawHash),
126 std::end(kExpectedRawHash));
Darin Petkov36a58222010-10-07 22:00:09 -0700127 EXPECT_TRUE(raw_hash == calc.raw_hash());
128 }
129
Alex Deymo39910dc2015-11-09 17:04:30 -0800130 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700131 EXPECT_EQ(0, calc.UpdateFile(data_path, 0));
132 EXPECT_EQ(1, calc.UpdateFile(data_path, 1));
133 EXPECT_TRUE(calc.Finalize());
134 // echo -n h | openssl dgst -sha256 -binary | openssl base64
135 EXPECT_EQ("qqlAJmTxpB9A67xSyZk+tmrrNmYClY/fqig7ceZNsSM=", calc.hash());
136}
137
Alex Deymo39910dc2015-11-09 17:04:30 -0800138TEST_F(HashCalculatorTest, RawHashOfFileSimpleTest) {
Darin Petkov698d0412010-10-13 10:59:44 -0700139 string data_path;
140 ASSERT_TRUE(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700141 utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
Darin Petkov698d0412010-10-13 10:59:44 -0700142 ScopedPathUnlinker data_path_unlinker(data_path);
143 ASSERT_TRUE(utils::WriteFile(data_path.c_str(), "hi", 2));
144
145 static const int kLengths[] = { -1, 2, 10 };
146 for (size_t i = 0; i < arraysize(kLengths); i++) {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700147 brillo::Blob exp_raw_hash(std::begin(kExpectedRawHash),
148 std::end(kExpectedRawHash));
149 brillo::Blob raw_hash;
Alex Deymo39910dc2015-11-09 17:04:30 -0800150 EXPECT_EQ(2, HashCalculator::RawHashOfFile(data_path,
151 kLengths[i],
152 &raw_hash));
Darin Petkov698d0412010-10-13 10:59:44 -0700153 EXPECT_TRUE(exp_raw_hash == raw_hash);
154 }
155}
156
Alex Deymo39910dc2015-11-09 17:04:30 -0800157TEST_F(HashCalculatorTest, UpdateFileNonexistentTest) {
158 HashCalculator calc;
Darin Petkov36a58222010-10-07 22:00:09 -0700159 EXPECT_EQ(-1, calc.UpdateFile("/some/non-existent/file", -1));
160}
161
Alex Deymo39910dc2015-11-09 17:04:30 -0800162TEST_F(HashCalculatorTest, AbortTest) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000163 // Just make sure we don't crash and valgrind doesn't detect memory leaks
164 {
Alex Deymo39910dc2015-11-09 17:04:30 -0800165 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000166 }
167 {
Alex Deymo39910dc2015-11-09 17:04:30 -0800168 HashCalculator calc;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000169 calc.Update("h", 1);
170 }
171}
172
173} // namespace chromeos_update_engine