blob: 17e8f01206dae2dfc37c406569c256d7ac16ecf6 [file] [log] [blame]
Wyatt Heplerec4b9352020-01-31 15:51:50 -08001// Copyright 2020 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15#include "pw_kvs/checksum.h"
16
17#include "gtest/gtest.h"
18#include "pw_kvs/crc16_checksum.h"
19
20namespace pw::kvs {
21namespace {
22
23using std::byte;
24
25constexpr std::string_view kString =
26 "In the beginning the Universe was created. This has made a lot of "
27 "people very angry and been widely regarded as a bad move.";
28constexpr uint16_t kStringCrc = 0xC184;
29
30TEST(Checksum, UpdateAndVerify) {
31 ChecksumCrc16 crc16_algo;
32 ChecksumAlgorithm& algo = crc16_algo;
33
34 algo.Update(kString.data(), kString.size());
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080035 EXPECT_EQ(OkStatus(), algo.Verify(std::as_bytes(std::span(&kStringCrc, 1))));
Wyatt Heplerec4b9352020-01-31 15:51:50 -080036}
37
38TEST(Checksum, Verify_Failure) {
39 ChecksumCrc16 algo;
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070040 EXPECT_EQ(Status::DataLoss(),
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070041 algo.Verify(std::as_bytes(std::span(kString.data(), 2))));
Wyatt Heplerec4b9352020-01-31 15:51:50 -080042}
43
44TEST(Checksum, Verify_InvalidSize) {
45 ChecksumCrc16 algo;
Wyatt Heplerd78f7c62020-09-28 14:27:32 -070046 EXPECT_EQ(Status::InvalidArgument(), algo.Verify({}));
47 EXPECT_EQ(Status::InvalidArgument(),
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070048 algo.Verify(std::as_bytes(std::span(kString.substr(0, 1)))));
Wyatt Hepler6e3a83b2020-02-04 07:36:45 -080049}
50
51TEST(Checksum, Verify_LargerState_ComparesToTruncatedData) {
52 byte crc[3] = {byte{0x84}, byte{0xC1}, byte{0x33}};
53 ChecksumCrc16 algo;
54 ASSERT_GT(sizeof(crc), algo.size_bytes());
55
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070056 algo.Update(std::as_bytes(std::span(kString)));
Wyatt Hepler6e3a83b2020-02-04 07:36:45 -080057
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080058 EXPECT_EQ(OkStatus(), algo.Verify(crc));
Wyatt Heplerec4b9352020-01-31 15:51:50 -080059}
60
61TEST(Checksum, Reset) {
62 ChecksumCrc16 crc_algo;
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070063 crc_algo.Update(std::as_bytes(std::span(kString)));
Wyatt Heplerec4b9352020-01-31 15:51:50 -080064 crc_algo.Reset();
Wyatt Hepler6e3a83b2020-02-04 07:36:45 -080065
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070066 std::span state = crc_algo.Finish();
Alexei Frolov56034622020-02-07 13:17:00 -080067 EXPECT_EQ(state[0], byte{0xFF});
68 EXPECT_EQ(state[1], byte{0xFF});
Wyatt Heplerec4b9352020-01-31 15:51:50 -080069}
70
Wyatt Hepler613625e2020-03-05 14:56:08 -080071TEST(IgnoreChecksum, NeverUpdate_VerifyWithoutData) {
72 IgnoreChecksum checksum;
73
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080074 EXPECT_EQ(OkStatus(), checksum.Verify({}));
Wyatt Hepler613625e2020-03-05 14:56:08 -080075}
76
77TEST(IgnoreChecksum, NeverUpdate_VerifyWithData) {
78 IgnoreChecksum checksum;
79
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080080 EXPECT_EQ(OkStatus(), checksum.Verify(std::as_bytes(std::span(kString))));
Wyatt Hepler613625e2020-03-05 14:56:08 -080081}
82
83TEST(IgnoreChecksum, AfterUpdate_Verify) {
84 IgnoreChecksum checksum;
85
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070086 checksum.Update(std::as_bytes(std::span(kString)));
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -080087 EXPECT_EQ(OkStatus(), checksum.Verify({}));
Wyatt Hepler613625e2020-03-05 14:56:08 -080088}
89
Wyatt Heplerc656af22020-02-12 14:49:14 -080090constexpr size_t kAlignment = 10;
91
92constexpr std::string_view kData =
93 "123456789_123456789_123456789_123456789_123456789_" // 50
94 "123456789_123456789_123456789_123456789_123456789_"; // 100
Wyatt Heplere2cbadf2020-06-22 11:21:45 -070095const std::span<const byte> kBytes = std::as_bytes(std::span(kData));
Wyatt Heplerc656af22020-02-12 14:49:14 -080096
97class PickyChecksum final : public AlignedChecksum<kAlignment, 32> {
98 public:
99 PickyChecksum() : AlignedChecksum(data_), data_{}, size_(0) {}
100
101 void Reset() override {}
102
103 void FinalizeAligned() override { EXPECT_EQ(kData.size(), size_); }
104
Wyatt Heplere2cbadf2020-06-22 11:21:45 -0700105 void UpdateAligned(std::span<const std::byte> data) override {
Wyatt Heplerc656af22020-02-12 14:49:14 -0800106 ASSERT_EQ(data.size() % kAlignment, 0u);
107 EXPECT_EQ(kData.substr(0, data.size()),
108 std::string_view(reinterpret_cast<const char*>(data.data()),
109 data.size()));
110
111 std::memcpy(&data_[size_], data.data(), data.size());
112 size_ += data.size();
113 }
114
115 private:
116 std::byte data_[kData.size()];
117 size_t size_;
118};
119
120TEST(AlignedChecksum, MaintainsAlignment) {
121 PickyChecksum checksum;
122
123 // Write values smaller than the alignment.
124 checksum.Update(kBytes.subspan(0, 1));
125 checksum.Update(kBytes.subspan(1, 9));
126
127 // Write values larger than the alignment but smaller than the buffer.
128 checksum.Update(kBytes.subspan(10, 11));
129
130 // Exactly fill the remainder of the buffer.
131 checksum.Update(kBytes.subspan(21, 11));
132
133 // Fill the buffer more than once.
134 checksum.Update(kBytes.subspan(32, 66));
135
136 // Write nothing.
137 checksum.Update(kBytes.subspan(98, 0));
138
139 // Write the remaining data.
140 checksum.Update(kBytes.subspan(98, 2));
141
142 auto state = checksum.Finish();
143 EXPECT_EQ(std::string_view(reinterpret_cast<const char*>(state.data()),
144 state.size()),
145 kData);
Wyatt Hepler1b3da3a2021-01-07 13:26:57 -0800146 EXPECT_EQ(OkStatus(), checksum.Verify(kBytes));
Wyatt Heplerc656af22020-02-12 14:49:14 -0800147}
148
Wyatt Heplerec4b9352020-01-31 15:51:50 -0800149} // namespace
150} // namespace pw::kvs