| // Copyright (c) 2011 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 "base/file_util.h" |
| #include "base/memory/scoped_temp_dir.h" |
| #include "base/stl_util-inl.h" |
| #include "base/string_util.h" |
| #include "chrome/browser/sessions/session_backend.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| typedef std::vector<SessionCommand*> SessionCommands; |
| |
| struct TestData { |
| SessionCommand::id_type command_id; |
| std::string data; |
| }; |
| |
| SessionCommand* CreateCommandFromData(const TestData& data) { |
| SessionCommand* command = |
| new SessionCommand( |
| data.command_id, |
| static_cast<SessionCommand::size_type>(data.data.size())); |
| if (!data.data.empty()) |
| memcpy(command->contents(), data.data.c_str(), data.data.size()); |
| return command; |
| } |
| |
| } // namespace |
| |
| class SessionBackendTest : public testing::Test { |
| protected: |
| virtual void SetUp() { |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| path_ = temp_dir_.path().Append(FILE_PATH_LITERAL("SessionTestDirs")); |
| file_util::CreateDirectory(path_); |
| } |
| |
| void AssertCommandEqualsData(const TestData& data, SessionCommand* command) { |
| EXPECT_EQ(data.command_id, command->id()); |
| EXPECT_EQ(data.data.size(), command->size()); |
| EXPECT_TRUE( |
| memcmp(command->contents(), data.data.c_str(), command->size()) == 0); |
| } |
| |
| // Path used in testing. |
| FilePath path_; |
| ScopedTempDir temp_dir_; |
| }; |
| |
| TEST_F(SessionBackendTest, SimpleReadWrite) { |
| scoped_refptr<SessionBackend> backend( |
| new SessionBackend(BaseSessionService::SESSION_RESTORE, path_)); |
| struct TestData data = { 1, "a" }; |
| std::vector<SessionCommand*> commands; |
| commands.push_back(CreateCommandFromData(data)); |
| backend->AppendCommands(new SessionCommands(commands), false); |
| commands.clear(); |
| |
| // Read it back in. |
| backend = NULL; |
| backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_); |
| backend->ReadLastSessionCommandsImpl(&commands); |
| |
| ASSERT_EQ(1U, commands.size()); |
| AssertCommandEqualsData(data, commands[0]); |
| |
| STLDeleteElements(&commands); |
| |
| backend = NULL; |
| backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_); |
| backend->ReadLastSessionCommandsImpl(&commands); |
| |
| ASSERT_EQ(0U, commands.size()); |
| |
| // Make sure we can delete. |
| backend->DeleteLastSession(); |
| backend->ReadLastSessionCommandsImpl(&commands); |
| ASSERT_EQ(0U, commands.size()); |
| } |
| |
| TEST_F(SessionBackendTest, RandomData) { |
| struct TestData data[] = { |
| { 1, "a" }, |
| { 2, "ab" }, |
| { 3, "abc" }, |
| { 4, "abcd" }, |
| { 5, "abcde" }, |
| { 6, "abcdef" }, |
| { 7, "abcdefg" }, |
| { 8, "abcdefgh" }, |
| { 9, "abcdefghi" }, |
| { 10, "abcdefghij" }, |
| { 11, "abcdefghijk" }, |
| { 12, "abcdefghijkl" }, |
| { 13, "abcdefghijklm" }, |
| }; |
| |
| for (size_t i = 0; i < arraysize(data); ++i) { |
| scoped_refptr<SessionBackend> backend( |
| new SessionBackend(BaseSessionService::SESSION_RESTORE, path_)); |
| std::vector<SessionCommand*> commands; |
| if (i != 0) { |
| // Read previous data. |
| backend->ReadLastSessionCommandsImpl(&commands); |
| ASSERT_EQ(i, commands.size()); |
| for (std::vector<SessionCommand*>::iterator j = commands.begin(); |
| j != commands.end(); ++j) { |
| AssertCommandEqualsData(data[j - commands.begin()], *j); |
| } |
| backend->AppendCommands(new SessionCommands(commands), false); |
| commands.clear(); |
| } |
| commands.push_back(CreateCommandFromData(data[i])); |
| backend->AppendCommands(new SessionCommands(commands), false); |
| } |
| } |
| |
| TEST_F(SessionBackendTest, BigData) { |
| struct TestData data[] = { |
| { 1, "a" }, |
| { 2, "ab" }, |
| }; |
| |
| scoped_refptr<SessionBackend> backend( |
| new SessionBackend(BaseSessionService::SESSION_RESTORE, path_)); |
| std::vector<SessionCommand*> commands; |
| commands.push_back(CreateCommandFromData(data[0])); |
| const SessionCommand::size_type big_size = |
| SessionBackend::kFileReadBufferSize + 100; |
| const SessionCommand::id_type big_id = 50; |
| SessionCommand* big_command = new SessionCommand(big_id, big_size); |
| reinterpret_cast<char*>(big_command->contents())[0] = 'a'; |
| reinterpret_cast<char*>(big_command->contents())[big_size - 1] = 'z'; |
| commands.push_back(big_command); |
| commands.push_back(CreateCommandFromData(data[1])); |
| backend->AppendCommands(new SessionCommands(commands), false); |
| commands.clear(); |
| |
| backend = NULL; |
| backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_); |
| commands.clear(); |
| backend->ReadLastSessionCommandsImpl(&commands); |
| ASSERT_EQ(3U, commands.size()); |
| AssertCommandEqualsData(data[0], commands[0]); |
| AssertCommandEqualsData(data[1], commands[2]); |
| |
| EXPECT_EQ(big_id, commands[1]->id()); |
| ASSERT_EQ(big_size, commands[1]->size()); |
| EXPECT_EQ('a', reinterpret_cast<char*>(commands[1]->contents())[0]); |
| EXPECT_EQ('z', |
| reinterpret_cast<char*>(commands[1]->contents())[big_size - 1]); |
| STLDeleteElements(&commands); |
| } |
| |
| TEST_F(SessionBackendTest, EmptyCommand) { |
| TestData empty_command; |
| empty_command.command_id = 1; |
| scoped_refptr<SessionBackend> backend( |
| new SessionBackend(BaseSessionService::SESSION_RESTORE, path_)); |
| std::vector<SessionCommand*>* empty_commands = |
| new std::vector<SessionCommand*>(); |
| empty_commands->push_back(CreateCommandFromData(empty_command)); |
| backend->AppendCommands(empty_commands, true); |
| backend->MoveCurrentSessionToLastSession(); |
| |
| std::vector<SessionCommand*> commands; |
| backend->ReadLastSessionCommandsImpl(&commands); |
| ASSERT_EQ(1U, commands.size()); |
| AssertCommandEqualsData(empty_command, commands[0]); |
| STLDeleteElements(&commands); |
| } |
| |
| // Writes a command, appends another command with reset to true, then reads |
| // making sure we only get back the second command. |
| TEST_F(SessionBackendTest, Truncate) { |
| scoped_refptr<SessionBackend> backend( |
| new SessionBackend(BaseSessionService::SESSION_RESTORE, path_)); |
| struct TestData first_data = { 1, "a" }; |
| std::vector<SessionCommand*> commands; |
| commands.push_back(CreateCommandFromData(first_data)); |
| backend->AppendCommands(new SessionCommands(commands), false); |
| commands.clear(); |
| |
| // Write another command, this time resetting the file when appending. |
| struct TestData second_data = { 2, "b" }; |
| commands.push_back(CreateCommandFromData(second_data)); |
| backend->AppendCommands(new SessionCommands(commands), true); |
| commands.clear(); |
| |
| // Read it back in. |
| backend = NULL; |
| backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_); |
| backend->ReadLastSessionCommandsImpl(&commands); |
| |
| // And make sure we get back the expected data. |
| ASSERT_EQ(1U, commands.size()); |
| AssertCommandEqualsData(second_data, commands[0]); |
| |
| STLDeleteElements(&commands); |
| } |