Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / base / files / important_file_writer_unittest.cc
1 // Copyright (c) 2012 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/files/important_file_writer.h"
6
7 #include "base/bind.h"
8 #include "base/compiler_specific.h"
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h"
15 #include "base/threading/thread.h"
16 #include "base/time/time.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace base {
20
21 namespace {
22
23 std::string GetFileContent(const FilePath& path) {
24   std::string content;
25   if (!ReadFileToString(path, &content)) {
26     NOTREACHED();
27   }
28   return content;
29 }
30
31 class DataSerializer : public ImportantFileWriter::DataSerializer {
32  public:
33   explicit DataSerializer(const std::string& data) : data_(data) {
34   }
35
36   virtual bool SerializeData(std::string* output) OVERRIDE {
37     output->assign(data_);
38     return true;
39   }
40
41  private:
42   const std::string data_;
43 };
44
45 class SuccessfulWriteObserver {
46  public:
47   SuccessfulWriteObserver() : successful_write_observed_(false) {}
48
49   // Register on_successful_write() to be called on the next successful write
50   // of |writer|.
51   void ObserveNextSuccessfulWrite(ImportantFileWriter* writer);
52
53   // Returns true if a successful write was observed via on_successful_write()
54   // and resets the observation state to false regardless.
55   bool GetAndResetObservationState();
56
57  private:
58   void on_successful_write() {
59     EXPECT_FALSE(successful_write_observed_);
60     successful_write_observed_ = true;
61   }
62
63   bool successful_write_observed_;
64
65   DISALLOW_COPY_AND_ASSIGN(SuccessfulWriteObserver);
66 };
67
68 void SuccessfulWriteObserver::ObserveNextSuccessfulWrite(
69     ImportantFileWriter* writer) {
70   writer->RegisterOnNextSuccessfulWriteCallback(base::Bind(
71       &SuccessfulWriteObserver::on_successful_write, base::Unretained(this)));
72 }
73
74 bool SuccessfulWriteObserver::GetAndResetObservationState() {
75   bool was_successful_write_observed = successful_write_observed_;
76   successful_write_observed_ = false;
77   return was_successful_write_observed;
78 }
79
80 }  // namespace
81
82 class ImportantFileWriterTest : public testing::Test {
83  public:
84   ImportantFileWriterTest() { }
85   virtual void SetUp() {
86     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
87     file_ = temp_dir_.path().AppendASCII("test-file");
88   }
89
90  protected:
91   SuccessfulWriteObserver successful_write_observer_;
92   FilePath file_;
93   MessageLoop loop_;
94
95  private:
96   ScopedTempDir temp_dir_;
97 };
98
99 TEST_F(ImportantFileWriterTest, Basic) {
100   ImportantFileWriter writer(file_, MessageLoopProxy::current().get());
101   EXPECT_FALSE(PathExists(writer.path()));
102   EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
103   writer.WriteNow("foo");
104   RunLoop().RunUntilIdle();
105
106   EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
107   ASSERT_TRUE(PathExists(writer.path()));
108   EXPECT_EQ("foo", GetFileContent(writer.path()));
109 }
110
111 TEST_F(ImportantFileWriterTest, BasicWithSuccessfulWriteObserver) {
112   ImportantFileWriter writer(file_, MessageLoopProxy::current().get());
113   EXPECT_FALSE(PathExists(writer.path()));
114   EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
115   successful_write_observer_.ObserveNextSuccessfulWrite(&writer);
116   writer.WriteNow("foo");
117   RunLoop().RunUntilIdle();
118
119   // Confirm that the observer is invoked.
120   EXPECT_TRUE(successful_write_observer_.GetAndResetObservationState());
121   ASSERT_TRUE(PathExists(writer.path()));
122   EXPECT_EQ("foo", GetFileContent(writer.path()));
123
124   // Confirm that re-installing the observer works for another write.
125   EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
126   successful_write_observer_.ObserveNextSuccessfulWrite(&writer);
127   writer.WriteNow("bar");
128   RunLoop().RunUntilIdle();
129
130   EXPECT_TRUE(successful_write_observer_.GetAndResetObservationState());
131   ASSERT_TRUE(PathExists(writer.path()));
132   EXPECT_EQ("bar", GetFileContent(writer.path()));
133
134   // Confirm that writing again without re-installing the observer doesn't
135   // result in a notification.
136   EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
137   writer.WriteNow("baz");
138   RunLoop().RunUntilIdle();
139
140   EXPECT_FALSE(successful_write_observer_.GetAndResetObservationState());
141   ASSERT_TRUE(PathExists(writer.path()));
142   EXPECT_EQ("baz", GetFileContent(writer.path()));
143 }
144
145 TEST_F(ImportantFileWriterTest, ScheduleWrite) {
146   ImportantFileWriter writer(file_, MessageLoopProxy::current().get());
147   writer.set_commit_interval(TimeDelta::FromMilliseconds(25));
148   EXPECT_FALSE(writer.HasPendingWrite());
149   DataSerializer serializer("foo");
150   writer.ScheduleWrite(&serializer);
151   EXPECT_TRUE(writer.HasPendingWrite());
152   MessageLoop::current()->PostDelayedTask(
153       FROM_HERE,
154       MessageLoop::QuitWhenIdleClosure(),
155       TimeDelta::FromMilliseconds(100));
156   MessageLoop::current()->Run();
157   EXPECT_FALSE(writer.HasPendingWrite());
158   ASSERT_TRUE(PathExists(writer.path()));
159   EXPECT_EQ("foo", GetFileContent(writer.path()));
160 }
161
162 TEST_F(ImportantFileWriterTest, DoScheduledWrite) {
163   ImportantFileWriter writer(file_, MessageLoopProxy::current().get());
164   EXPECT_FALSE(writer.HasPendingWrite());
165   DataSerializer serializer("foo");
166   writer.ScheduleWrite(&serializer);
167   EXPECT_TRUE(writer.HasPendingWrite());
168   writer.DoScheduledWrite();
169   MessageLoop::current()->PostDelayedTask(
170       FROM_HERE,
171       MessageLoop::QuitWhenIdleClosure(),
172       TimeDelta::FromMilliseconds(100));
173   MessageLoop::current()->Run();
174   EXPECT_FALSE(writer.HasPendingWrite());
175   ASSERT_TRUE(PathExists(writer.path()));
176   EXPECT_EQ("foo", GetFileContent(writer.path()));
177 }
178
179 TEST_F(ImportantFileWriterTest, BatchingWrites) {
180   ImportantFileWriter writer(file_, MessageLoopProxy::current().get());
181   writer.set_commit_interval(TimeDelta::FromMilliseconds(25));
182   DataSerializer foo("foo"), bar("bar"), baz("baz");
183   writer.ScheduleWrite(&foo);
184   writer.ScheduleWrite(&bar);
185   writer.ScheduleWrite(&baz);
186   MessageLoop::current()->PostDelayedTask(
187       FROM_HERE,
188       MessageLoop::QuitWhenIdleClosure(),
189       TimeDelta::FromMilliseconds(100));
190   MessageLoop::current()->Run();
191   ASSERT_TRUE(PathExists(writer.path()));
192   EXPECT_EQ("baz", GetFileContent(writer.path()));
193 }
194
195 }  // namespace base