1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/fileapi/sandbox_database_test_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <functional>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FilePathToString;
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace content {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CorruptDatabase(const base::FilePath& db_path,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     leveldb::FileType type,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ptrdiff_t offset,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     size_t size) {
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FileEnumerator file_enum(db_path, false /* not recursive */,
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath file_path;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath picked_file_path;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 picked_file_number = kuint64max;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!(file_path = file_enum.Next()).empty()) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint64 number = kuint64max;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    leveldb::FileType file_type;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &number, &file_type));
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (file_type == type &&
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (picked_file_number == kuint64max || picked_file_number < number)) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      picked_file_path = file_path;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      picked_file_number = number;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(picked_file_path.empty());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(kuint64max, picked_file_number);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File file(picked_file_path,
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  base::File::FLAG_OPEN | base::File::FLAG_READ |
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      base::File::FLAG_WRITE);
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(file.IsValid());
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(file.created());
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Info file_info;
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(file.GetInfo(&file_info));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (offset < 0)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    offset += file_info.size;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(offset, 0);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(offset, file_info.size);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size = std::min(size, static_cast<size_t>(file_info.size - offset));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<char> buf(size);
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int read_size = file.Read(offset, vector_as_array(&buf), buf.size());
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(0, read_size);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(buf.size(), static_cast<size_t>(read_size));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buf.resize(read_size);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::transform(buf.begin(), buf.end(), buf.begin(),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 std::logical_not<char>());
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int written_size = file.Write(offset, vector_as_array(&buf), buf.size());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(written_size, 0);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buf.size(), static_cast<size_t>(written_size));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeleteDatabaseFile(const base::FilePath& db_path,
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        leveldb::FileType type) {
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FileEnumerator file_enum(db_path, false /* not recursive */,
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES);
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath file_path;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!(file_path = file_enum.Next()).empty()) {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    uint64 number = kuint64max;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    leveldb::FileType file_type;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       &number, &file_type));
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (file_type == type) {
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::DeleteFile(file_path, false);
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // We may have multiple files for the same type, so don't break here.
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace content
94