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 "net/disk_cache/flash/flash_cache_test_base.h"
6#include "net/disk_cache/flash/format.h"
7#include "net/disk_cache/flash/log_store.h"
8#include "net/disk_cache/flash/segment.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace disk_cache {
12
13TEST_F(FlashCacheTest, LogStoreCreateEntry) {
14  LogStore log_store(path_, kStorageSize);
15  EXPECT_TRUE(log_store.Init());
16
17  const int32 kSize = 100;
18  const std::string buf(kSize, 0);
19
20  int32 id;
21  EXPECT_TRUE(log_store.CreateEntry(kSize, &id));
22  EXPECT_TRUE(log_store.WriteData(buf.data(), kSize/2));
23  EXPECT_TRUE(log_store.WriteData(buf.data(), kSize/2));
24  log_store.CloseEntry(id);
25
26  EXPECT_TRUE(log_store.Close());
27}
28
29// Also tests reading from current segment.
30TEST_F(FlashCacheTest, LogStoreOpenEntry) {
31  LogStore log_store(path_, kStorageSize);
32  EXPECT_TRUE(log_store.Init());
33
34  const int32 kSize = 100;
35  const std::vector<char> expected(kSize, 'b');
36
37  int32 id;
38  EXPECT_TRUE(log_store.CreateEntry(kSize, &id));
39  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize));
40  log_store.CloseEntry(id);
41
42  EXPECT_TRUE(log_store.OpenEntry(id));
43  std::vector<char> actual(kSize, 0);
44  EXPECT_TRUE(log_store.ReadData(id, &actual[0], kSize, 0));
45  log_store.CloseEntry(id);
46
47  EXPECT_EQ(expected, actual);
48  EXPECT_TRUE(log_store.Close());
49}
50
51// Also tests that writing advances segments.
52TEST_F(FlashCacheTest, LogStoreReadFromClosedSegment) {
53  LogStore log_store(path_, kStorageSize);
54  EXPECT_TRUE(log_store.Init());
55
56  const int32 kSize = disk_cache::kFlashSegmentFreeSpace;
57  const std::vector<char> expected(kSize, 'a');
58
59  // First two entries go to segment 0.
60  int32 id1;
61  EXPECT_EQ(0, log_store.write_index_);
62  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id1));
63  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
64  log_store.CloseEntry(id1);
65
66  int32 id2;
67  EXPECT_EQ(0, log_store.write_index_);
68  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id2));
69  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
70  log_store.CloseEntry(id2);
71
72  // This entry goes to segment 1.
73  int32 id3;
74  EXPECT_TRUE(log_store.CreateEntry(kSize, &id3));
75  EXPECT_EQ(1, log_store.write_index_);
76  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize));
77  log_store.CloseEntry(id3);
78
79  // We read from segment 0.
80  EXPECT_TRUE(log_store.OpenEntry(id1));
81  std::vector<char> actual(kSize, 0);
82  EXPECT_TRUE(log_store.ReadData(id1, &actual[0], kSize, id1));
83  log_store.CloseEntry(id1);
84
85  EXPECT_EQ(expected, actual);
86  EXPECT_TRUE(log_store.Close());
87}
88
89TEST_F(FlashCacheTest, LogStoreReadFromCurrentAfterClose) {
90  LogStore log_store(path_, kStorageSize);
91  EXPECT_TRUE(log_store.Init());
92
93  const int32 kSize = disk_cache::kFlashSegmentFreeSpace;
94  const std::vector<char> expected(kSize, 'a');
95
96  int32 id1;
97  EXPECT_EQ(0, log_store.write_index_);
98  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id1));
99  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
100  log_store.CloseEntry(id1);
101
102  // Create a reference to above entry.
103  EXPECT_TRUE(log_store.OpenEntry(id1));
104
105  // This entry fills the first segment.
106  int32 id2;
107  EXPECT_EQ(0, log_store.write_index_);
108  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id2));
109  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
110  log_store.CloseEntry(id2);
111
112  // Creating this entry forces closing of the first segment.
113  int32 id3;
114  EXPECT_TRUE(log_store.CreateEntry(kSize, &id3));
115  EXPECT_EQ(1, log_store.write_index_);
116  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize));
117  log_store.CloseEntry(id3);
118
119  // Now attempt to read from the closed segment.
120  std::vector<char> actual(kSize, 0);
121  EXPECT_TRUE(log_store.ReadData(id1, &actual[0], kSize, id1));
122  log_store.CloseEntry(id1);
123
124  EXPECT_EQ(expected, actual);
125  EXPECT_TRUE(log_store.Close());
126}
127
128// TODO(agayev): Add a test that confirms that in-use segment is not selected as
129// the next write segment.
130
131}  // namespace disk_cache
132