Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/startupcache/test/TestStartupCache.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "gtest/gtest.h"
7
8
#include "mozilla/scache/StartupCache.h"
9
#include "mozilla/scache/StartupCacheUtils.h"
10
11
#include "nsDirectoryServiceDefs.h"
12
#include "nsIClassInfo.h"
13
#include "nsIOutputStream.h"
14
#include "nsIObserver.h"
15
#include "nsISerializable.h"
16
#include "nsISupports.h"
17
#include "nsIStringStream.h"
18
#include "nsIStorageStream.h"
19
#include "nsIObjectInputStream.h"
20
#include "nsIObjectOutputStream.h"
21
#include "nsIURI.h"
22
#include "nsIPrefBranch.h"
23
#include "nsIPrefService.h"
24
#include "nsIXPConnect.h"
25
#include "nsThreadUtils.h"
26
#include "prenv.h"
27
#include "prio.h"
28
#include "prprf.h"
29
#include "mozilla/Maybe.h"
30
#include "mozilla/Printf.h"
31
#include "mozilla/UniquePtr.h"
32
#include "nsNetCID.h"
33
#include "nsIURIMutator.h"
34
35
using namespace JS;
36
37
using namespace mozilla::scache;
38
using mozilla::UniquePtr;
39
40
void
41
WaitForStartupTimer()
42
0
{
43
0
  StartupCache* sc = StartupCache::GetSingleton();
44
0
  PR_Sleep(10 * PR_TicksPerSecond());
45
0
46
0
  while (true) {
47
0
    NS_ProcessPendingEvents(nullptr);
48
0
    if (sc->StartupWriteComplete()) {
49
0
      return;
50
0
    }
51
0
    PR_Sleep(1 * PR_TicksPerSecond());
52
0
  }
53
0
}
54
55
class TestStartupCache : public ::testing::Test
56
{
57
protected:
58
  TestStartupCache();
59
  ~TestStartupCache();
60
61
  nsCOMPtr<nsIFile> mSCFile;
62
};
63
64
TestStartupCache::TestStartupCache()
65
0
{
66
0
  NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mSCFile));
67
0
  mSCFile->AppendNative(NS_LITERAL_CSTRING("test-startupcache.tmp"));
68
#ifdef XP_WIN
69
  nsAutoString env(NS_LITERAL_STRING("MOZ_STARTUP_CACHE="));
70
  env.Append(mSCFile->NativePath());
71
  _wputenv(env.get());
72
#else
73
  nsAutoCString path;
74
0
  mSCFile->GetNativePath(path);
75
0
  char* env = mozilla::Smprintf("MOZ_STARTUP_CACHE=%s", path.get()).release();
76
0
  PR_SetEnv(env);
77
0
  // We intentionally leak `env` here because it is required by PR_SetEnv
78
0
  MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(env);
79
0
#endif
80
0
  StartupCache::GetSingleton()->InvalidateCache();
81
0
}
82
TestStartupCache::~TestStartupCache()
83
0
{
84
0
  PR_SetEnv("MOZ_STARTUP_CACHE=");
85
0
  StartupCache::GetSingleton()->InvalidateCache();
86
0
}
87
88
89
TEST_F(TestStartupCache, StartupWriteRead)
90
0
{
91
0
  nsresult rv;
92
0
  StartupCache* sc = StartupCache::GetSingleton();
93
0
94
0
  const char* buf = "Market opportunities for BeardBook";
95
0
  const char* id = "id";
96
0
  UniquePtr<char[]> outbuf;
97
0
  uint32_t len;
98
0
99
0
  rv = sc->PutBuffer(id, UniquePtr<char[]>(strdup(buf)), strlen(buf) + 1);
100
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
101
0
102
0
  rv = sc->GetBuffer(id, &outbuf, &len);
103
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
104
0
  EXPECT_STREQ(buf, outbuf.get());
105
0
106
0
  rv = sc->ResetStartupWriteTimer();
107
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
108
0
  WaitForStartupTimer();
109
0
110
0
  rv = sc->GetBuffer(id, &outbuf, &len);
111
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
112
0
  EXPECT_STREQ(buf, outbuf.get());
113
0
}
114
115
TEST_F(TestStartupCache, WriteInvalidateRead)
116
0
{
117
0
  nsresult rv;
118
0
  const char* buf = "BeardBook competitive analysis";
119
0
  const char* id = "id";
120
0
  UniquePtr<char[]> outbuf;
121
0
  uint32_t len;
122
0
  StartupCache* sc = StartupCache::GetSingleton();
123
0
  ASSERT_TRUE(sc);
124
0
125
0
  rv = sc->PutBuffer(id, UniquePtr<char[]>(strdup(buf)), strlen(buf) + 1);
126
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
127
0
128
0
  sc->InvalidateCache();
129
0
130
0
  rv = sc->GetBuffer(id, &outbuf, &len);
131
0
  EXPECT_EQ(rv, NS_ERROR_NOT_AVAILABLE);
132
0
}
133
134
TEST_F(TestStartupCache, WriteObject)
135
0
{
136
0
  nsresult rv;
137
0
138
0
  nsCOMPtr<nsIURI> obj;
139
0
140
0
  NS_NAMED_LITERAL_CSTRING(spec, "http://www.mozilla.org");
141
0
  rv = NS_MutateURI(NS_SIMPLEURIMUTATOR_CONTRACTID)
142
0
         .SetSpec(spec)
143
0
         .Finalize(obj);
144
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
145
0
146
0
  StartupCache* sc = StartupCache::GetSingleton();
147
0
148
0
  // Create an object stream. Usually this is done with
149
0
  // NewObjectOutputWrappedStorageStream, but that uses
150
0
  // StartupCache::GetSingleton in debug builds, and we
151
0
  // don't have access to that here. Obviously.
152
0
  const char* id = "id";
153
0
  nsCOMPtr<nsIStorageStream> storageStream
154
0
    = do_CreateInstance("@mozilla.org/storagestream;1");
155
0
  ASSERT_TRUE(storageStream);
156
0
157
0
  rv = storageStream->Init(256, (uint32_t) -1);
158
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
159
0
160
0
  nsCOMPtr<nsIObjectOutputStream> objectOutput
161
0
    = do_CreateInstance("@mozilla.org/binaryoutputstream;1");
162
0
  ASSERT_TRUE(objectOutput);
163
0
164
0
  nsCOMPtr<nsIOutputStream> outputStream
165
0
    = do_QueryInterface(storageStream);
166
0
167
0
  rv = objectOutput->SetOutputStream(outputStream);
168
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
169
0
170
0
  nsCOMPtr<nsISupports> objQI(do_QueryInterface(obj));
171
0
  rv = objectOutput->WriteObject(objQI, true);
172
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
173
0
174
0
  UniquePtr<char[]> buf;
175
0
  uint32_t len;
176
0
  NewBufferFromStorageStream(storageStream, &buf, &len);
177
0
178
0
  // Since this is a post-startup write, it should be written and
179
0
  // available.
180
0
  rv = sc->PutBuffer(id, std::move(buf), len);
181
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
182
0
183
0
  UniquePtr<char[]> buf2;
184
0
  uint32_t len2;
185
0
  nsCOMPtr<nsIObjectInputStream> objectInput;
186
0
  rv = sc->GetBuffer(id, &buf2, &len2);
187
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
188
0
189
0
  rv = NewObjectInputStreamFromBuffer(std::move(buf2), len2,
190
0
                                      getter_AddRefs(objectInput));
191
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
192
0
193
0
  nsCOMPtr<nsISupports> deserialized;
194
0
  rv = objectInput->ReadObject(true, getter_AddRefs(deserialized));
195
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
196
0
197
0
  nsCOMPtr<nsIURI> uri(do_QueryInterface(deserialized));
198
0
  ASSERT_TRUE(uri);
199
0
200
0
  nsCString outSpec;
201
0
  rv = uri->GetSpec(outSpec);
202
0
  EXPECT_TRUE(NS_SUCCEEDED(rv));
203
0
  ASSERT_TRUE(outSpec.Equals(spec));
204
0
}