TestFileSystemHashSource.cpp (5675B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "FileSystemHashSource.h" 8 #include "FileSystemParentTypes.h" 9 #include "TestHelpers.h" 10 #include "gtest/gtest.h" 11 #include "mozilla/Array.h" 12 #include "mozilla/dom/FileSystemTypes.h" 13 #include "nsContentUtils.h" 14 #include "nsLiteralString.h" 15 #include "nsString.h" 16 #include "nsStringFwd.h" 17 #include "nsTArray.h" 18 #include "nsTHashSet.h" 19 20 namespace mozilla::dom::fs::test { 21 22 using mozilla::dom::fs::data::FileSystemHashSource; 23 24 namespace { 25 26 constexpr size_t sha256ByteLength = 32u; 27 28 constexpr size_t kExpectedLength = 52u; 29 30 std::wstring asWide(const nsString& aStr) { 31 std::wstring result; 32 result.reserve(aStr.Length()); 33 for (const auto* it = aStr.BeginReading(); it != aStr.EndReading(); ++it) { 34 result.push_back(static_cast<wchar_t>(*it)); 35 } 36 return result; 37 } 38 39 } // namespace 40 41 TEST(TestFileSystemHashSource, isHashLengthAsExpected) 42 { 43 EntryId parent = "a"_ns; 44 Name name = u"b"_ns; 45 TEST_TRY_UNWRAP(EntryId result, 46 FileSystemHashSource::GenerateHash(parent, name)); 47 ASSERT_EQ(sha256ByteLength, result.Length()); 48 }; 49 50 TEST(TestFileSystemHashSource, areNestedNameHashesValidAndUnequal) 51 { 52 EntryId emptyParent = ""_ns; 53 Name name = u"a"_ns; 54 const size_t nestingNumber = 500u; 55 56 nsTHashSet<EntryId> results; 57 nsTHashSet<Name> names; 58 59 auto previousParent = emptyParent; 60 for (size_t i = 0; i < nestingNumber; ++i) { 61 TEST_TRY_UNWRAP(EntryId result, 62 FileSystemHashSource::GenerateHash(previousParent, name)); 63 64 TEST_TRY_UNWRAP(Name encoded, 65 FileSystemHashSource::EncodeHash(FileId(result))); 66 67 // Validity checks 68 ASSERT_TRUE(mozilla::IsAscii(encoded)) 69 << encoded; 70 Name upperCaseVersion; 71 nsContentUtils::ASCIIToUpper(encoded, upperCaseVersion); 72 ASSERT_STREQ(asWide(upperCaseVersion).c_str(), asWide(encoded).c_str()); 73 74 // Is the same hash encountered? 75 ASSERT_FALSE(results.Contains(result)); 76 ASSERT_TRUE(results.Insert(result, mozilla::fallible)); 77 78 // Is the same name encountered? 79 ASSERT_FALSE(names.Contains(encoded)); 80 ASSERT_TRUE(names.Insert(encoded, mozilla::fallible)); 81 82 previousParent = result; 83 } 84 }; 85 86 TEST(TestFileSystemHashSource, areNameCombinationHashesUnequal) 87 { 88 EntryId emptyParent = ""_ns; 89 90 mozilla::Array<Name, 2> inputs = {u"a"_ns, u"b"_ns}; 91 nsTArray<EntryId> results; 92 nsTArray<Name> names; 93 94 for (const auto& name : inputs) { 95 TEST_TRY_UNWRAP(EntryId result, 96 FileSystemHashSource::GenerateHash(emptyParent, name)); 97 TEST_TRY_UNWRAP(Name encoded, 98 FileSystemHashSource::EncodeHash(FileId(result))); 99 100 // Validity checks 101 ASSERT_TRUE(mozilla::IsAscii(encoded)) 102 << encoded; 103 Name upperCaseVersion; 104 nsContentUtils::ASCIIToUpper(encoded, upperCaseVersion); 105 ASSERT_STREQ(asWide(upperCaseVersion).c_str(), asWide(encoded).c_str()); 106 107 results.AppendElement(result); 108 names.AppendElement(encoded); 109 } 110 111 nsTArray<EntryId> more_results; 112 nsTArray<Name> more_names; 113 for (const auto& parent : results) { 114 for (const auto& name : inputs) { 115 TEST_TRY_UNWRAP(EntryId result, 116 FileSystemHashSource::GenerateHash(parent, name)); 117 TEST_TRY_UNWRAP(Name encoded, 118 FileSystemHashSource::EncodeHash(FileId(result))); 119 120 // Validity checks 121 ASSERT_TRUE(mozilla::IsAscii(encoded)) 122 << encoded; 123 Name upperCaseVersion; 124 nsContentUtils::ASCIIToUpper(encoded, upperCaseVersion); 125 ASSERT_STREQ(asWide(upperCaseVersion).c_str(), asWide(encoded).c_str()); 126 127 more_results.AppendElement(result); 128 more_names.AppendElement(encoded); 129 } 130 } 131 132 results.AppendElements(more_results); 133 names.AppendElements(more_names); 134 135 // Is the same hash encountered? 136 for (size_t i = 0; i < results.Length(); ++i) { 137 for (size_t j = i + 1; j < results.Length(); ++j) { 138 ASSERT_STRNE(results[i].get(), results[j].get()); 139 } 140 } 141 142 // Is the same name encountered? 143 for (size_t i = 0; i < names.Length(); ++i) { 144 for (size_t j = i + 1; j < names.Length(); ++j) { 145 ASSERT_STRNE(asWide(names[i]).c_str(), asWide(names[j]).c_str()); 146 } 147 } 148 }; 149 150 TEST(TestFileSystemHashSource, encodeGeneratedHash) 151 { 152 Name expected = u"HF6FOFV72G3NMDEJKYMVRIFJO4X5ZNZCF2GM7Q4Y5Q3E7NPQKSLA"_ns; 153 ASSERT_EQ(kExpectedLength, expected.Length()); 154 155 EntryId parent = "a"_ns; 156 Name name = u"b"_ns; 157 TEST_TRY_UNWRAP(EntryId entry, 158 FileSystemHashSource::GenerateHash(parent, name)); 159 ASSERT_EQ(sha256ByteLength, entry.Length()); 160 161 TEST_TRY_UNWRAP(Name result, FileSystemHashSource::EncodeHash(FileId(entry))); 162 ASSERT_EQ(kExpectedLength, result.Length()); 163 ASSERT_STREQ(asWide(expected).c_str(), asWide(result).c_str()); 164 165 // Generate further hashes 166 TEST_TRY_UNWRAP(entry, FileSystemHashSource::GenerateHash(entry, result)); 167 ASSERT_EQ(sha256ByteLength, entry.Length()); 168 169 TEST_TRY_UNWRAP(result, FileSystemHashSource::EncodeHash(FileId(entry))); 170 171 // Always the same length 172 ASSERT_EQ(kExpectedLength, result.Length()); 173 174 // Encoded versions should differ 175 ASSERT_STRNE(asWide(expected).c_str(), asWide(result).c_str()); 176 177 // Padding length should have been stripped 178 char16_t padding = u"="_ns[0]; 179 const int32_t paddingStart = result.FindChar(padding); 180 ASSERT_EQ(-1, paddingStart); 181 }; 182 183 } // namespace mozilla::dom::fs::test