• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/file_util.h"
6 #include "base/memory/scoped_temp_dir.h"
7 #include "base/stl_util-inl.h"
8 #include "base/string_util.h"
9 #include "chrome/browser/sessions/session_backend.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 
12 namespace {
13 
14 typedef std::vector<SessionCommand*> SessionCommands;
15 
16 struct TestData {
17   SessionCommand::id_type command_id;
18   std::string data;
19 };
20 
CreateCommandFromData(const TestData & data)21 SessionCommand* CreateCommandFromData(const TestData& data) {
22   SessionCommand* command =
23       new SessionCommand(
24           data.command_id,
25           static_cast<SessionCommand::size_type>(data.data.size()));
26   if (!data.data.empty())
27     memcpy(command->contents(), data.data.c_str(), data.data.size());
28   return command;
29 }
30 
31 }  // namespace
32 
33 class SessionBackendTest : public testing::Test {
34  protected:
SetUp()35   virtual void SetUp() {
36     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
37     path_ = temp_dir_.path().Append(FILE_PATH_LITERAL("SessionTestDirs"));
38     file_util::CreateDirectory(path_);
39   }
40 
AssertCommandEqualsData(const TestData & data,SessionCommand * command)41   void AssertCommandEqualsData(const TestData& data, SessionCommand* command) {
42     EXPECT_EQ(data.command_id, command->id());
43     EXPECT_EQ(data.data.size(), command->size());
44     EXPECT_TRUE(
45         memcmp(command->contents(), data.data.c_str(), command->size()) == 0);
46   }
47 
48   // Path used in testing.
49   FilePath path_;
50   ScopedTempDir temp_dir_;
51 };
52 
TEST_F(SessionBackendTest,SimpleReadWrite)53 TEST_F(SessionBackendTest, SimpleReadWrite) {
54   scoped_refptr<SessionBackend> backend(
55       new SessionBackend(BaseSessionService::SESSION_RESTORE, path_));
56   struct TestData data = { 1,  "a" };
57   std::vector<SessionCommand*> commands;
58   commands.push_back(CreateCommandFromData(data));
59   backend->AppendCommands(new SessionCommands(commands), false);
60   commands.clear();
61 
62   // Read it back in.
63   backend = NULL;
64   backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_);
65   backend->ReadLastSessionCommandsImpl(&commands);
66 
67   ASSERT_EQ(1U, commands.size());
68   AssertCommandEqualsData(data, commands[0]);
69 
70   STLDeleteElements(&commands);
71 
72   backend = NULL;
73   backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_);
74   backend->ReadLastSessionCommandsImpl(&commands);
75 
76   ASSERT_EQ(0U, commands.size());
77 
78   // Make sure we can delete.
79   backend->DeleteLastSession();
80   backend->ReadLastSessionCommandsImpl(&commands);
81   ASSERT_EQ(0U, commands.size());
82 }
83 
TEST_F(SessionBackendTest,RandomData)84 TEST_F(SessionBackendTest, RandomData) {
85   struct TestData data[] = {
86     { 1,  "a" },
87     { 2,  "ab" },
88     { 3,  "abc" },
89     { 4,  "abcd" },
90     { 5,  "abcde" },
91     { 6,  "abcdef" },
92     { 7,  "abcdefg" },
93     { 8,  "abcdefgh" },
94     { 9,  "abcdefghi" },
95     { 10, "abcdefghij" },
96     { 11, "abcdefghijk" },
97     { 12, "abcdefghijkl" },
98     { 13, "abcdefghijklm" },
99   };
100 
101   for (size_t i = 0; i < arraysize(data); ++i) {
102     scoped_refptr<SessionBackend> backend(
103         new SessionBackend(BaseSessionService::SESSION_RESTORE, path_));
104     std::vector<SessionCommand*> commands;
105     if (i != 0) {
106       // Read previous data.
107       backend->ReadLastSessionCommandsImpl(&commands);
108       ASSERT_EQ(i, commands.size());
109       for (std::vector<SessionCommand*>::iterator j = commands.begin();
110            j != commands.end(); ++j) {
111         AssertCommandEqualsData(data[j - commands.begin()], *j);
112       }
113       backend->AppendCommands(new SessionCommands(commands), false);
114       commands.clear();
115     }
116     commands.push_back(CreateCommandFromData(data[i]));
117     backend->AppendCommands(new SessionCommands(commands), false);
118   }
119 }
120 
TEST_F(SessionBackendTest,BigData)121 TEST_F(SessionBackendTest, BigData) {
122   struct TestData data[] = {
123     { 1,  "a" },
124     { 2,  "ab" },
125   };
126 
127   scoped_refptr<SessionBackend> backend(
128       new SessionBackend(BaseSessionService::SESSION_RESTORE, path_));
129   std::vector<SessionCommand*> commands;
130   commands.push_back(CreateCommandFromData(data[0]));
131   const SessionCommand::size_type big_size =
132       SessionBackend::kFileReadBufferSize + 100;
133   const SessionCommand::id_type big_id = 50;
134   SessionCommand* big_command = new SessionCommand(big_id, big_size);
135   reinterpret_cast<char*>(big_command->contents())[0] = 'a';
136   reinterpret_cast<char*>(big_command->contents())[big_size - 1] = 'z';
137   commands.push_back(big_command);
138   commands.push_back(CreateCommandFromData(data[1]));
139   backend->AppendCommands(new SessionCommands(commands), false);
140   commands.clear();
141 
142   backend = NULL;
143   backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_);
144   commands.clear();
145   backend->ReadLastSessionCommandsImpl(&commands);
146   ASSERT_EQ(3U, commands.size());
147   AssertCommandEqualsData(data[0], commands[0]);
148   AssertCommandEqualsData(data[1], commands[2]);
149 
150   EXPECT_EQ(big_id, commands[1]->id());
151   ASSERT_EQ(big_size, commands[1]->size());
152   EXPECT_EQ('a', reinterpret_cast<char*>(commands[1]->contents())[0]);
153   EXPECT_EQ('z',
154             reinterpret_cast<char*>(commands[1]->contents())[big_size - 1]);
155   STLDeleteElements(&commands);
156 }
157 
TEST_F(SessionBackendTest,EmptyCommand)158 TEST_F(SessionBackendTest, EmptyCommand) {
159   TestData empty_command;
160   empty_command.command_id = 1;
161   scoped_refptr<SessionBackend> backend(
162       new SessionBackend(BaseSessionService::SESSION_RESTORE, path_));
163   std::vector<SessionCommand*>* empty_commands =
164       new std::vector<SessionCommand*>();
165   empty_commands->push_back(CreateCommandFromData(empty_command));
166   backend->AppendCommands(empty_commands, true);
167   backend->MoveCurrentSessionToLastSession();
168 
169   std::vector<SessionCommand*> commands;
170   backend->ReadLastSessionCommandsImpl(&commands);
171   ASSERT_EQ(1U, commands.size());
172   AssertCommandEqualsData(empty_command, commands[0]);
173   STLDeleteElements(&commands);
174 }
175 
176 // Writes a command, appends another command with reset to true, then reads
177 // making sure we only get back the second command.
TEST_F(SessionBackendTest,Truncate)178 TEST_F(SessionBackendTest, Truncate) {
179   scoped_refptr<SessionBackend> backend(
180       new SessionBackend(BaseSessionService::SESSION_RESTORE, path_));
181   struct TestData first_data = { 1,  "a" };
182   std::vector<SessionCommand*> commands;
183   commands.push_back(CreateCommandFromData(first_data));
184   backend->AppendCommands(new SessionCommands(commands), false);
185   commands.clear();
186 
187   // Write another command, this time resetting the file when appending.
188   struct TestData second_data = { 2,  "b" };
189   commands.push_back(CreateCommandFromData(second_data));
190   backend->AppendCommands(new SessionCommands(commands), true);
191   commands.clear();
192 
193   // Read it back in.
194   backend = NULL;
195   backend = new SessionBackend(BaseSessionService::SESSION_RESTORE, path_);
196   backend->ReadLastSessionCommandsImpl(&commands);
197 
198   // And make sure we get back the expected data.
199   ASSERT_EQ(1U, commands.size());
200   AssertCommandEqualsData(second_data, commands[0]);
201 
202   STLDeleteElements(&commands);
203 }
204