summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/flash/log_store_unittest.cc
blob: 2678316d499ee3c27001dead7a494baa2ed1930a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) 2012 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 "net/disk_cache/flash/flash_cache_test_base.h"
#include "net/disk_cache/flash/format.h"
#include "net/disk_cache/flash/log_store.h"
#include "net/disk_cache/flash/segment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace disk_cache {

TEST_F(FlashCacheTest, LogStoreCreateEntry) {
  LogStore log_store(path_, kStorageSize);
  EXPECT_TRUE(log_store.Init());

  const int32 kSize = 100;
  const std::string buf(kSize, 0);

  int32 id;
  EXPECT_TRUE(log_store.CreateEntry(kSize, &id));
  EXPECT_TRUE(log_store.WriteData(buf.data(), kSize/2));
  EXPECT_TRUE(log_store.WriteData(buf.data(), kSize/2));
  log_store.CloseEntry(id);

  EXPECT_TRUE(log_store.Close());
}

// Also tests reading from current segment.
TEST_F(FlashCacheTest, LogStoreOpenEntry) {
  LogStore log_store(path_, kStorageSize);
  EXPECT_TRUE(log_store.Init());

  const int32 kSize = 100;
  const std::vector<char> expected(kSize, 'b');

  int32 id;
  EXPECT_TRUE(log_store.CreateEntry(kSize, &id));
  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize));
  log_store.CloseEntry(id);

  EXPECT_TRUE(log_store.OpenEntry(id));
  std::vector<char> actual(kSize, 0);
  EXPECT_TRUE(log_store.ReadData(id, &actual[0], kSize, 0));
  log_store.CloseEntry(id);

  EXPECT_EQ(expected, actual);
  EXPECT_TRUE(log_store.Close());
}

// Also tests that writing advances segments.
TEST_F(FlashCacheTest, LogStoreReadFromClosedSegment) {
  LogStore log_store(path_, kStorageSize);
  EXPECT_TRUE(log_store.Init());

  const int32 kSize = disk_cache::kFlashSegmentFreeSpace;
  const std::vector<char> expected(kSize, 'a');

  // First two entries go to segment 0.
  int32 id1;
  EXPECT_EQ(0, log_store.write_index_);
  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id1));
  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
  log_store.CloseEntry(id1);

  int32 id2;
  EXPECT_EQ(0, log_store.write_index_);
  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id2));
  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
  log_store.CloseEntry(id2);

  // This entry goes to segment 1.
  int32 id3;
  EXPECT_TRUE(log_store.CreateEntry(kSize, &id3));
  EXPECT_EQ(1, log_store.write_index_);
  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize));
  log_store.CloseEntry(id3);

  // We read from segment 0.
  EXPECT_TRUE(log_store.OpenEntry(id1));
  std::vector<char> actual(kSize, 0);
  EXPECT_TRUE(log_store.ReadData(id1, &actual[0], kSize, id1));
  log_store.CloseEntry(id1);

  EXPECT_EQ(expected, actual);
  EXPECT_TRUE(log_store.Close());
}

TEST_F(FlashCacheTest, LogStoreReadFromCurrentAfterClose) {
  LogStore log_store(path_, kStorageSize);
  EXPECT_TRUE(log_store.Init());

  const int32 kSize = disk_cache::kFlashSegmentFreeSpace;
  const std::vector<char> expected(kSize, 'a');

  int32 id1;
  EXPECT_EQ(0, log_store.write_index_);
  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id1));
  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
  log_store.CloseEntry(id1);

  // Create a reference to above entry.
  EXPECT_TRUE(log_store.OpenEntry(id1));

  // This entry fills the first segment.
  int32 id2;
  EXPECT_EQ(0, log_store.write_index_);
  EXPECT_TRUE(log_store.CreateEntry(kSize/2, &id2));
  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize/2));
  log_store.CloseEntry(id2);

  // Creating this entry forces closing of the first segment.
  int32 id3;
  EXPECT_TRUE(log_store.CreateEntry(kSize, &id3));
  EXPECT_EQ(1, log_store.write_index_);
  EXPECT_TRUE(log_store.WriteData(&expected[0], kSize));
  log_store.CloseEntry(id3);

  // Now attempt to read from the closed segment.
  std::vector<char> actual(kSize, 0);
  EXPECT_TRUE(log_store.ReadData(id1, &actual[0], kSize, id1));
  log_store.CloseEntry(id1);

  EXPECT_EQ(expected, actual);
  EXPECT_TRUE(log_store.Close());
}

// TODO(agayev): Add a test that confirms that in-use segment is not selected as
// the next write segment.

}  // namespace disk_cache