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// This file contains test infrastructure for multiple files
6// (current cookie_monster_unittest.cc and cookie_monster_perftest.cc)
7// that need to test out CookieMonster interactions with the backing store.
8// It should only be included by test code.
9
10#ifndef NET_COOKIES_COOKIE_MONSTER_STORE_TEST_H_
11#define NET_COOKIES_COOKIE_MONSTER_STORE_TEST_H_
12
13#include <map>
14#include <string>
15#include <utility>
16#include <vector>
17#include "net/cookies/canonical_cookie.h"
18#include "net/cookies/cookie_monster.h"
19
20namespace base {
21class Time;
22}
23
24namespace net {
25
26// Wrapper class for posting a loaded callback. Since the Callback class is not
27// reference counted, we cannot post a callback to the message loop directly,
28// instead we post a LoadedCallbackTask.
29class LoadedCallbackTask
30    : public base::RefCountedThreadSafe<LoadedCallbackTask> {
31 public:
32  typedef CookieMonster::PersistentCookieStore::LoadedCallback LoadedCallback;
33
34  LoadedCallbackTask(LoadedCallback loaded_callback,
35                     std::vector<CanonicalCookie*> cookies);
36
37  void Run() {
38    loaded_callback_.Run(cookies_);
39  }
40
41 private:
42  friend class base::RefCountedThreadSafe<LoadedCallbackTask>;
43  ~LoadedCallbackTask();
44
45  LoadedCallback loaded_callback_;
46  std::vector<CanonicalCookie*> cookies_;
47
48  DISALLOW_COPY_AND_ASSIGN(LoadedCallbackTask);
49};  // Wrapper class LoadedCallbackTask
50
51// Describes a call to one of the 3 functions of PersistentCookieStore.
52struct CookieStoreCommand {
53  enum Type {
54    ADD,
55    UPDATE_ACCESS_TIME,
56    REMOVE,
57  };
58
59  CookieStoreCommand(Type type, const CanonicalCookie& cookie)
60      : type(type),
61        cookie(cookie) {}
62
63  Type type;
64  CanonicalCookie cookie;
65};
66
67// Implementation of PersistentCookieStore that captures the
68// received commands and saves them to a list.
69// The result of calls to Load() can be configured using SetLoadExpectation().
70class MockPersistentCookieStore
71    : public CookieMonster::PersistentCookieStore {
72 public:
73  typedef std::vector<CookieStoreCommand> CommandList;
74
75  MockPersistentCookieStore();
76
77  void SetLoadExpectation(
78      bool return_value,
79      const std::vector<CanonicalCookie*>& result);
80
81  const CommandList& commands() const {
82    return commands_;
83  }
84
85  virtual void Load(const LoadedCallback& loaded_callback) OVERRIDE;
86
87  virtual void LoadCookiesForKey(const std::string& key,
88    const LoadedCallback& loaded_callback) OVERRIDE;
89
90  virtual void AddCookie(const CanonicalCookie& cookie) OVERRIDE;
91
92  virtual void UpdateCookieAccessTime(
93      const CanonicalCookie& cookie) OVERRIDE;
94
95  virtual void DeleteCookie(
96      const CanonicalCookie& cookie) OVERRIDE;
97
98  virtual void Flush(const base::Closure& callback) OVERRIDE;
99
100  virtual void SetForceKeepSessionState() OVERRIDE;
101
102 protected:
103  virtual ~MockPersistentCookieStore();
104
105 private:
106  CommandList commands_;
107
108  // Deferred result to use when Load() is called.
109  bool load_return_value_;
110  std::vector<CanonicalCookie*> load_result_;
111  // Indicates if the store has been fully loaded to avoid returning duplicate
112  // cookies.
113  bool loaded_;
114
115  DISALLOW_COPY_AND_ASSIGN(MockPersistentCookieStore);
116};
117
118// Mock for CookieMonster::Delegate
119class MockCookieMonsterDelegate : public CookieMonster::Delegate {
120 public:
121  typedef std::pair<CanonicalCookie, bool>
122      CookieNotification;
123
124  MockCookieMonsterDelegate();
125
126  const std::vector<CookieNotification>& changes() const { return changes_; }
127
128  void reset() { changes_.clear(); }
129
130  virtual void OnCookieChanged(
131      const CanonicalCookie& cookie,
132      bool removed,
133      CookieMonster::Delegate::ChangeCause cause) OVERRIDE;
134
135 private:
136  virtual ~MockCookieMonsterDelegate();
137
138  std::vector<CookieNotification> changes_;
139
140  DISALLOW_COPY_AND_ASSIGN(MockCookieMonsterDelegate);
141};
142
143// Helper to build a single CanonicalCookie.
144CanonicalCookie BuildCanonicalCookie(const std::string& key,
145                                     const std::string& cookie_line,
146                                     const base::Time& creation_time);
147
148// Helper to build a list of CanonicalCookie*s.
149void AddCookieToList(
150    const std::string& key,
151    const std::string& cookie_line,
152    const base::Time& creation_time,
153    std::vector<CanonicalCookie*>* out_list);
154
155// Just act like a backing database.  Keep cookie information from
156// Add/Update/Delete and regurgitate it when Load is called.
157class MockSimplePersistentCookieStore
158    : public CookieMonster::PersistentCookieStore {
159 public:
160  MockSimplePersistentCookieStore();
161
162  virtual void Load(const LoadedCallback& loaded_callback) OVERRIDE;
163
164  virtual void LoadCookiesForKey(const std::string& key,
165      const LoadedCallback& loaded_callback) OVERRIDE;
166
167  virtual void AddCookie(const CanonicalCookie& cookie) OVERRIDE;
168
169  virtual void UpdateCookieAccessTime(const CanonicalCookie& cookie) OVERRIDE;
170
171  virtual void DeleteCookie(const CanonicalCookie& cookie) OVERRIDE;
172
173  virtual void Flush(const base::Closure& callback) OVERRIDE;
174
175  virtual void SetForceKeepSessionState() OVERRIDE;
176
177 protected:
178  virtual ~MockSimplePersistentCookieStore();
179
180 private:
181  typedef std::map<int64, CanonicalCookie> CanonicalCookieMap;
182
183  CanonicalCookieMap cookies_;
184
185  // Indicates if the store has been fully loaded to avoid return duplicate
186  // cookies in subsequent load requests
187  bool loaded_;
188};
189
190// Helper function for creating a CookieMonster backed by a
191// MockSimplePersistentCookieStore for garbage collection testing.
192//
193// Fill the store through import with |num_cookies| cookies, |num_old_cookies|
194// with access time Now()-days_old, the rest with access time Now().
195// Do two SetCookies().  Return whether each of the two SetCookies() took
196// longer than |gc_perf_micros| to complete, and how many cookie were
197// left in the store afterwards.
198CookieMonster* CreateMonsterFromStoreForGC(
199    int num_cookies,
200    int num_old_cookies,
201    int days_old);
202
203}  // namespace net
204
205#endif  // NET_COOKIES_COOKIE_MONSTER_STORE_TEST_H_
206