1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
7 * Test harness for XPCOM objects, providing a scoped XPCOM initializer,
8 * nsCOMPtr, nsRefPtr, do_CreateInstance, do_GetService, ns(Auto|C|)String,
9 * and stdio.h/stdlib.h.
12 #ifndef TestHarness_h__
13 #define TestHarness_h__
15 #include "mozilla/ArrayUtils.h"
16 #include "mozilla/Attributes.h"
19 #include "nsComponentManagerUtils.h"
20 #include "nsServiceManagerUtils.h"
23 #include "nsAppDirectoryServiceDefs.h"
24 #include "nsDirectoryServiceDefs.h"
25 #include "nsDirectoryServiceUtils.h"
26 #include "nsIDirectoryService.h"
28 #include "nsIObserverService.h"
29 #include "nsXULAppAPI.h"
33 #include "mozilla/AppShutdown.h"
35 static uint32_t gFailCount
= 0;
38 * Prints the given failure message and arguments using printf, prepending
39 * "TEST-UNEXPECTED-FAIL " for the benefit of the test harness and
40 * appending "\n" to eliminate having to type it at each call site.
42 MOZ_FORMAT_PRINTF(1, 2) void fail(const char* msg
, ...) {
45 printf("TEST-UNEXPECTED-FAIL | ");
56 * Prints the given success message and arguments using printf, prepending
57 * "TEST-PASS " for the benefit of the test harness and
58 * appending "\n" to eliminate having to type it at each call site.
60 MOZ_FORMAT_PRINTF(1, 2) void passed(const char* msg
, ...) {
63 printf("TEST-PASS | ");
72 //-----------------------------------------------------------------------------
74 class ScopedXPCOM
: public nsIDirectoryServiceProvider2
{
78 explicit ScopedXPCOM(const char* testName
,
79 nsIDirectoryServiceProvider
* dirSvcProvider
= nullptr)
80 : mDirSvcProvider(dirSvcProvider
) {
82 printf("Running %s tests...\n", mTestName
);
84 mInitRv
= NS_InitXPCOM(nullptr, nullptr, this);
85 if (NS_FAILED(mInitRv
)) {
86 fail("NS_InitXPCOM returned failure code 0x%" PRIx32
,
87 static_cast<uint32_t>(mInitRv
));
93 // If we created a profile directory, we need to remove it.
95 mozilla::AppShutdown::AdvanceShutdownPhase(
96 mozilla::ShutdownPhase::AppShutdownNetTeardown
);
97 mozilla::AppShutdown::AdvanceShutdownPhase(
98 mozilla::ShutdownPhase::AppShutdownTeardown
);
99 mozilla::AppShutdown::AdvanceShutdownPhase(
100 mozilla::ShutdownPhase::AppShutdown
);
101 mozilla::AppShutdown::AdvanceShutdownPhase(
102 mozilla::ShutdownPhase::AppShutdownQM
);
103 mozilla::AppShutdown::AdvanceShutdownPhase(
104 mozilla::ShutdownPhase::AppShutdownTelemetry
);
106 if (NS_FAILED(mProfD
->Remove(true))) {
107 NS_WARNING("Problem removing profile directory");
113 if (NS_SUCCEEDED(mInitRv
)) {
114 nsresult rv
= NS_ShutdownXPCOM(nullptr);
116 fail("XPCOM shutdown failed with code 0x%" PRIx32
,
117 static_cast<uint32_t>(rv
));
122 printf("Finished running %s tests.\n", mTestName
);
125 bool failed() { return NS_FAILED(mInitRv
); }
127 already_AddRefed
<nsIFile
> GetProfileDirectory() {
129 nsCOMPtr
<nsIFile
> copy
= mProfD
;
130 return copy
.forget();
133 // Create a unique temporary folder to use for this test.
134 // Note that runcppunittests.py will run tests with a temp
135 // directory as the cwd, so just put something under that.
136 nsCOMPtr
<nsIFile
> profD
;
137 nsresult rv
= NS_GetSpecialDirectory(NS_OS_CURRENT_PROCESS_DIR
,
138 getter_AddRefs(profD
));
139 NS_ENSURE_SUCCESS(rv
, nullptr);
141 rv
= profD
->Append(u
"cpp-unit-profd"_ns
);
142 NS_ENSURE_SUCCESS(rv
, nullptr);
144 rv
= profD
->CreateUnique(nsIFile::DIRECTORY_TYPE
, 0755);
145 NS_ENSURE_SUCCESS(rv
, nullptr);
148 return profD
.forget();
151 already_AddRefed
<nsIFile
> GetGREDirectory() {
153 nsCOMPtr
<nsIFile
> copy
= mGRED
;
154 return copy
.forget();
157 char* env
= PR_GetEnv("MOZ_XRE_DIR");
158 nsCOMPtr
<nsIFile
> greD
;
160 NS_NewLocalFile(NS_ConvertUTF8toUTF16(env
), false, getter_AddRefs(greD
));
164 return greD
.forget();
167 already_AddRefed
<nsIFile
> GetGREBinDirectory() {
169 nsCOMPtr
<nsIFile
> copy
= mGREBinD
;
170 return copy
.forget();
173 nsCOMPtr
<nsIFile
> greD
= GetGREDirectory();
175 return greD
.forget();
177 greD
->Clone(getter_AddRefs(mGREBinD
));
180 nsAutoCString leafName
;
181 mGREBinD
->GetNativeLeafName(leafName
);
182 if (leafName
.EqualsLiteral("Resources")) {
183 mGREBinD
->SetNativeLeafName("MacOS"_ns
);
187 nsCOMPtr
<nsIFile
> copy
= mGREBinD
;
188 return copy
.forget();
191 ////////////////////////////////////////////////////////////////////////////
192 //// nsIDirectoryServiceProvider
194 NS_IMETHOD
GetFile(const char* aProperty
, bool* _persistent
,
195 nsIFile
** _result
) override
{
196 // If we were supplied a directory service provider, ask it first.
197 if (mDirSvcProvider
&& NS_SUCCEEDED(mDirSvcProvider
->GetFile(
198 aProperty
, _persistent
, _result
))) {
202 // Otherwise, the test harness provides some directories automatically.
203 if (0 == strcmp(aProperty
, NS_APP_USER_PROFILE_50_DIR
) ||
204 0 == strcmp(aProperty
, NS_APP_USER_PROFILE_LOCAL_50_DIR
) ||
205 0 == strcmp(aProperty
, NS_APP_PROFILE_LOCAL_DIR_STARTUP
)) {
206 nsCOMPtr
<nsIFile
> profD
= GetProfileDirectory();
207 NS_ENSURE_TRUE(profD
, NS_ERROR_FAILURE
);
209 nsCOMPtr
<nsIFile
> clone
;
210 nsresult rv
= profD
->Clone(getter_AddRefs(clone
));
211 NS_ENSURE_SUCCESS(rv
, rv
);
214 clone
.forget(_result
);
216 } else if (0 == strcmp(aProperty
, NS_GRE_DIR
)) {
217 nsCOMPtr
<nsIFile
> greD
= GetGREDirectory();
218 NS_ENSURE_TRUE(greD
, NS_ERROR_FAILURE
);
221 greD
.forget(_result
);
223 } else if (0 == strcmp(aProperty
, NS_GRE_BIN_DIR
)) {
224 nsCOMPtr
<nsIFile
> greBinD
= GetGREBinDirectory();
225 NS_ENSURE_TRUE(greBinD
, NS_ERROR_FAILURE
);
228 greBinD
.forget(_result
);
232 return NS_ERROR_FAILURE
;
235 ////////////////////////////////////////////////////////////////////////////
236 //// nsIDirectoryServiceProvider2
238 NS_IMETHOD
GetFiles(const char* aProperty
,
239 nsISimpleEnumerator
** _enum
) override
{
240 // If we were supplied a directory service provider, ask it first.
241 nsCOMPtr
<nsIDirectoryServiceProvider2
> provider
=
242 do_QueryInterface(mDirSvcProvider
);
243 if (provider
&& NS_SUCCEEDED(provider
->GetFiles(aProperty
, _enum
))) {
247 return NS_ERROR_FAILURE
;
251 const char* mTestName
;
252 nsresult mInitRv
= NS_ERROR_NOT_INITIALIZED
;
253 nsCOMPtr
<nsIDirectoryServiceProvider
> mDirSvcProvider
;
254 nsCOMPtr
<nsIFile
> mProfD
;
255 nsCOMPtr
<nsIFile
> mGRED
;
256 nsCOMPtr
<nsIFile
> mGREBinD
;
259 NS_IMPL_QUERY_INTERFACE(ScopedXPCOM
, nsIDirectoryServiceProvider
,
260 nsIDirectoryServiceProvider2
)
262 NS_IMETHODIMP_(MozExternalRefCountType
)
263 ScopedXPCOM::AddRef() { return 2; }
265 NS_IMETHODIMP_(MozExternalRefCountType
)
266 ScopedXPCOM::Release() { return 1; }
268 #endif // TestHarness_h__