// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include #include "base/macros.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" #include "third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h" using testing::_; using testing::Invoke; using testing::StrictMock; using testing::WithArgs; namespace blink { class WebIDBDatabaseImplTest : public testing::Test {}; TEST_F(WebIDBDatabaseImplTest, ValueSizeTest) { // For testing use a much smaller maximum size to prevent allocating >100 MB // of memory, which crashes on memory-constrained systems. const size_t kMaxValueSizeForTesting = 10 * 1024 * 1024; // 10 MB const std::vector data(kMaxValueSizeForTesting + 1); const scoped_refptr value_data = SharedBuffer::Create(&data.front(), data.size()); const Vector blob_info; std::unique_ptr value = IDBValue::Create(value_data, blob_info); std::unique_ptr key = IDBKey::CreateNumber(0); const int64_t transaction_id = 1; const int64_t object_store_id = 2; StrictMock callbacks; ASSERT_GT(value_data->size() + key->SizeEstimate(), kMaxValueSizeForTesting); ThreadState::Current()->CollectAllGarbage(); EXPECT_CALL(callbacks, Error(_, _)).Times(1); WebIDBDatabaseImpl database_impl( nullptr, blink::scheduler::GetSingleThreadTaskRunnerForTesting()); database_impl.max_put_value_size_ = kMaxValueSizeForTesting; database_impl.Put(transaction_id, object_store_id, std::move(value), std::move(key), mojom::IDBPutMode::AddOrUpdate, &callbacks, Vector()); } TEST_F(WebIDBDatabaseImplTest, KeyAndValueSizeTest) { // For testing use a much smaller maximum size to prevent allocating >100 MB // of memory, which crashes on memory-constrained systems. const size_t kMaxValueSizeForTesting = 10 * 1024 * 1024; // 10 MB const size_t kKeySize = 1024 * 1024; const std::vector data(kMaxValueSizeForTesting - kKeySize); const scoped_refptr value_data = SharedBuffer::Create(&data.front(), data.size()); const Vector blob_info; std::unique_ptr value = IDBValue::Create(value_data, blob_info); const int64_t transaction_id = 1; const int64_t object_store_id = 2; StrictMock callbacks; // For this test, we want IDBKey::SizeEstimate() minus kKeySize to be the // smallest value > 0. An IDBKey with a string has a size_estimate_ equal to // kOverheadSize (~16) + (string.length * sizeof(UChar)). Create // |kKeySize / sizeof(UChar)| characters in String. const unsigned int number_of_chars = kKeySize / sizeof(UChar); Vector key_string_vector; key_string_vector.ReserveInitialCapacity(number_of_chars); key_string_vector.Fill(u'0', number_of_chars); String key_string(key_string_vector); DCHECK_EQ(key_string.length(), number_of_chars); std::unique_ptr key = IDBKey::CreateString(key_string); DCHECK_EQ(value_data->size(), kMaxValueSizeForTesting - kKeySize); DCHECK_GT(key->SizeEstimate() - kKeySize, static_cast(0)); DCHECK_GT(value_data->size() + key->SizeEstimate(), kMaxValueSizeForTesting); ThreadState::Current()->CollectAllGarbage(); EXPECT_CALL(callbacks, Error(_, _)).Times(1); WebIDBDatabaseImpl database_impl( nullptr, blink::scheduler::GetSingleThreadTaskRunnerForTesting()); database_impl.max_put_value_size_ = kMaxValueSizeForTesting; database_impl.Put(transaction_id, object_store_id, std::move(value), std::move(key), mojom::IDBPutMode::AddOrUpdate, &callbacks, Vector()); } } // namespace blink