2010-08-12 23:37:44 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
#include "gtest/gtest.h"
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
#include "mozilla/scache/StartupCache.h"
|
|
|
|
#include "mozilla/scache/StartupCacheUtils.h"
|
|
|
|
|
|
|
|
#include "nsDirectoryServiceDefs.h"
|
2010-08-12 23:37:44 +04:00
|
|
|
#include "nsIClassInfo.h"
|
|
|
|
#include "nsIOutputStream.h"
|
|
|
|
#include "nsIObserver.h"
|
|
|
|
#include "nsISerializable.h"
|
|
|
|
#include "nsISupports.h"
|
|
|
|
#include "nsIStringStream.h"
|
|
|
|
#include "nsIStorageStream.h"
|
|
|
|
#include "nsIObjectInputStream.h"
|
|
|
|
#include "nsIObjectOutputStream.h"
|
|
|
|
#include "nsIURI.h"
|
2011-11-04 23:13:40 +04:00
|
|
|
#include "nsIPrefBranch.h"
|
|
|
|
#include "nsIPrefService.h"
|
2013-04-29 22:16:22 +04:00
|
|
|
#include "nsIXPConnect.h"
|
2016-11-11 19:57:08 +03:00
|
|
|
#include "nsThreadUtils.h"
|
|
|
|
#include "prenv.h"
|
2012-10-11 12:17:15 +04:00
|
|
|
#include "prio.h"
|
2016-11-11 19:57:08 +03:00
|
|
|
#include "prprf.h"
|
2013-08-28 02:10:28 +04:00
|
|
|
#include "mozilla/Maybe.h"
|
2016-02-18 19:14:02 +03:00
|
|
|
#include "mozilla/UniquePtr.h"
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2013-04-27 08:08:15 +04:00
|
|
|
using namespace JS;
|
|
|
|
|
2010-08-12 23:37:44 +04:00
|
|
|
using namespace mozilla::scache;
|
2016-02-18 19:14:02 +03:00
|
|
|
using mozilla::UniquePtr;
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
void
|
|
|
|
WaitForStartupTimer()
|
|
|
|
{
|
|
|
|
StartupCache* sc = StartupCache::GetSingleton();
|
2010-08-12 23:37:44 +04:00
|
|
|
PR_Sleep(10 * PR_TicksPerSecond());
|
2016-11-11 19:57:08 +03:00
|
|
|
|
2010-08-12 23:37:44 +04:00
|
|
|
while (true) {
|
2012-07-30 18:20:58 +04:00
|
|
|
NS_ProcessPendingEvents(nullptr);
|
2016-11-11 19:57:08 +03:00
|
|
|
if (sc->StartupWriteComplete()) {
|
|
|
|
return;
|
|
|
|
}
|
2010-08-12 23:37:44 +04:00
|
|
|
PR_Sleep(1 * PR_TicksPerSecond());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
class TestStartupCache : public ::testing::Test
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
TestStartupCache();
|
|
|
|
~TestStartupCache();
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFile> mSCFile;
|
|
|
|
};
|
|
|
|
|
|
|
|
TestStartupCache::TestStartupCache()
|
|
|
|
{
|
|
|
|
NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(mSCFile));
|
|
|
|
mSCFile->AppendNative(NS_LITERAL_CSTRING("test-startupcache.tmp"));
|
|
|
|
nsAutoCString path;
|
|
|
|
mSCFile->GetNativePath(path);
|
|
|
|
char* env = PR_smprintf("MOZ_STARTUP_CACHE=%s", path.get());
|
|
|
|
PR_SetEnv(env);
|
|
|
|
// We intentionally leak `env` here because it is required by PR_SetEnv
|
|
|
|
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(env);
|
|
|
|
StartupCache::GetSingleton()->InvalidateCache();
|
|
|
|
}
|
|
|
|
TestStartupCache::~TestStartupCache()
|
|
|
|
{
|
|
|
|
PR_SetEnv("MOZ_STARTUP_CACHE=");
|
|
|
|
StartupCache::GetSingleton()->InvalidateCache();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST_F(TestStartupCache, StartupWriteRead)
|
|
|
|
{
|
2010-08-12 23:37:44 +04:00
|
|
|
nsresult rv;
|
2016-11-11 19:57:08 +03:00
|
|
|
StartupCache* sc = StartupCache::GetSingleton();
|
|
|
|
|
2011-12-30 00:06:00 +04:00
|
|
|
const char* buf = "Market opportunities for BeardBook";
|
|
|
|
const char* id = "id";
|
2016-11-11 19:57:08 +03:00
|
|
|
UniquePtr<char[]> outbuf;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t len;
|
2016-11-11 19:57:08 +03:00
|
|
|
|
2010-08-12 23:37:44 +04:00
|
|
|
rv = sc->PutBuffer(id, buf, strlen(buf) + 1);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
|
2016-02-18 22:35:21 +03:00
|
|
|
rv = sc->GetBuffer(id, &outbuf, &len);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
EXPECT_STREQ(buf, outbuf.get());
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2010-10-01 01:48:23 +04:00
|
|
|
rv = sc->ResetStartupWriteTimer();
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
WaitForStartupTimer();
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
rv = sc->GetBuffer(id, &outbuf, &len);
|
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
EXPECT_STREQ(buf, outbuf.get());
|
2010-08-12 23:37:44 +04:00
|
|
|
}
|
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
TEST_F(TestStartupCache, WriteInvalidateRead)
|
|
|
|
{
|
2010-08-12 23:37:44 +04:00
|
|
|
nsresult rv;
|
2011-12-30 00:06:00 +04:00
|
|
|
const char* buf = "BeardBook competitive analysis";
|
|
|
|
const char* id = "id";
|
2016-02-18 22:57:14 +03:00
|
|
|
UniquePtr<char[]> outbuf;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t len;
|
2016-11-11 19:57:08 +03:00
|
|
|
StartupCache* sc = StartupCache::GetSingleton();
|
|
|
|
ASSERT_TRUE(sc);
|
2010-08-12 23:37:44 +04:00
|
|
|
|
|
|
|
rv = sc->PutBuffer(id, buf, strlen(buf) + 1);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
2010-08-12 23:37:44 +04:00
|
|
|
|
|
|
|
sc->InvalidateCache();
|
|
|
|
|
|
|
|
rv = sc->GetBuffer(id, &outbuf, &len);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_EQ(rv, NS_ERROR_NOT_AVAILABLE);
|
2010-08-12 23:37:44 +04:00
|
|
|
}
|
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
TEST_F(TestStartupCache, WriteObject)
|
|
|
|
{
|
2010-08-12 23:37:44 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> obj
|
|
|
|
= do_CreateInstance("@mozilla.org/network/simple-uri;1");
|
2016-11-11 19:57:08 +03:00
|
|
|
ASSERT_TRUE(obj);
|
|
|
|
|
2010-08-12 23:37:44 +04:00
|
|
|
NS_NAMED_LITERAL_CSTRING(spec, "http://www.mozilla.org");
|
2016-08-31 02:08:42 +03:00
|
|
|
rv = obj->SetSpec(spec);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
|
|
|
|
StartupCache* sc = StartupCache::GetSingleton();
|
2010-08-12 23:37:44 +04:00
|
|
|
|
|
|
|
// Create an object stream. Usually this is done with
|
2011-07-20 11:39:09 +04:00
|
|
|
// NewObjectOutputWrappedStorageStream, but that uses
|
2010-08-12 23:37:44 +04:00
|
|
|
// StartupCache::GetSingleton in debug builds, and we
|
|
|
|
// don't have access to that here. Obviously.
|
2011-12-30 00:06:00 +04:00
|
|
|
const char* id = "id";
|
2010-08-12 23:37:44 +04:00
|
|
|
nsCOMPtr<nsIStorageStream> storageStream
|
|
|
|
= do_CreateInstance("@mozilla.org/storagestream;1");
|
2016-11-11 19:57:08 +03:00
|
|
|
ASSERT_TRUE(storageStream);
|
|
|
|
|
2013-12-11 23:14:56 +04:00
|
|
|
rv = storageStream->Init(256, (uint32_t) -1);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
|
2010-08-12 23:37:44 +04:00
|
|
|
nsCOMPtr<nsIObjectOutputStream> objectOutput
|
|
|
|
= do_CreateInstance("@mozilla.org/binaryoutputstream;1");
|
2016-11-11 19:57:08 +03:00
|
|
|
ASSERT_TRUE(objectOutput);
|
|
|
|
|
2010-08-12 23:37:44 +04:00
|
|
|
nsCOMPtr<nsIOutputStream> outputStream
|
|
|
|
= do_QueryInterface(storageStream);
|
2016-11-11 19:57:08 +03:00
|
|
|
|
2010-08-12 23:37:44 +04:00
|
|
|
rv = objectOutput->SetOutputStream(outputStream);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
2010-08-12 23:37:44 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> objQI(do_QueryInterface(obj));
|
2011-10-17 18:59:28 +04:00
|
|
|
rv = objectOutput->WriteObject(objQI, true);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2016-02-18 20:04:40 +03:00
|
|
|
UniquePtr<char[]> buf;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t len;
|
2016-02-18 20:04:40 +03:00
|
|
|
NewBufferFromStorageStream(storageStream, &buf, &len);
|
2010-08-12 23:37:44 +04:00
|
|
|
|
|
|
|
// Since this is a post-startup write, it should be written and
|
|
|
|
// available.
|
2016-02-18 20:04:40 +03:00
|
|
|
rv = sc->PutBuffer(id, buf.get(), len);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
|
2016-02-18 22:57:14 +03:00
|
|
|
UniquePtr<char[]> buf2;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t len2;
|
2010-08-12 23:37:44 +04:00
|
|
|
nsCOMPtr<nsIObjectInputStream> objectInput;
|
2016-02-18 22:57:14 +03:00
|
|
|
rv = sc->GetBuffer(id, &buf2, &len2);
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2016-02-18 22:57:14 +03:00
|
|
|
rv = NewObjectInputStreamFromBuffer(Move(buf2), len2,
|
2016-02-18 19:14:02 +03:00
|
|
|
getter_AddRefs(objectInput));
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
2010-08-12 23:37:44 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> deserialized;
|
2011-10-17 18:59:28 +04:00
|
|
|
rv = objectInput->ReadObject(true, getter_AddRefs(deserialized));
|
2016-11-11 19:57:08 +03:00
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
2012-10-11 12:17:15 +04:00
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
nsCOMPtr<nsIURI> uri(do_QueryInterface(deserialized));
|
|
|
|
ASSERT_TRUE(uri);
|
2010-08-12 23:37:44 +04:00
|
|
|
|
2016-11-11 19:57:08 +03:00
|
|
|
nsCString outSpec;
|
|
|
|
rv = uri->GetSpec(outSpec);
|
|
|
|
EXPECT_TRUE(NS_SUCCEEDED(rv));
|
|
|
|
ASSERT_TRUE(outSpec.Equals(spec));
|
2010-08-12 23:37:44 +04:00
|
|
|
}
|