xpcom/tests/TestHarness.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:37b39425a436
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/. */
5
6 /*
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.
10 */
11
12 #ifndef TestHarness_h__
13 #define TestHarness_h__
14
15 #if defined(_MSC_VER) && defined(MOZ_STATIC_JS)
16 /*
17 * Including js/OldDebugAPI.h may cause build break with --disable-shared-js
18 * This is a workaround for bug 673616.
19 */
20 #define STATIC_JS_API
21 #endif
22
23 #include "mozilla/ArrayUtils.h"
24
25 #include "prenv.h"
26 #include "nsComponentManagerUtils.h"
27 #include "nsServiceManagerUtils.h"
28 #include "nsCOMPtr.h"
29 #include "nsAutoPtr.h"
30 #include "nsStringGlue.h"
31 #include "nsAppDirectoryServiceDefs.h"
32 #include "nsDirectoryServiceDefs.h"
33 #include "nsDirectoryServiceUtils.h"
34 #include "nsIDirectoryService.h"
35 #include "nsIFile.h"
36 #include "nsIProperties.h"
37 #include "nsIObserverService.h"
38 #include "nsXULAppAPI.h"
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <stdarg.h>
42
43 static uint32_t gFailCount = 0;
44
45 /**
46 * Prints the given failure message and arguments using printf, prepending
47 * "TEST-UNEXPECTED-FAIL " for the benefit of the test harness and
48 * appending "\n" to eliminate having to type it at each call site.
49 */
50 void fail(const char* msg, ...)
51 {
52 va_list ap;
53
54 printf("TEST-UNEXPECTED-FAIL | ");
55
56 va_start(ap, msg);
57 vprintf(msg, ap);
58 va_end(ap);
59
60 putchar('\n');
61 ++gFailCount;
62 }
63
64 /**
65 * Prints the given success message and arguments using printf, prepending
66 * "TEST-PASS " for the benefit of the test harness and
67 * appending "\n" to eliminate having to type it at each call site.
68 */
69 void passed(const char* msg, ...)
70 {
71 va_list ap;
72
73 printf("TEST-PASS | ");
74
75 va_start(ap, msg);
76 vprintf(msg, ap);
77 va_end(ap);
78
79 putchar('\n');
80 }
81
82 //-----------------------------------------------------------------------------
83
84 class ScopedLogging
85 {
86 public:
87 ScopedLogging()
88 {
89 NS_LogInit();
90 }
91
92 ~ScopedLogging()
93 {
94 NS_LogTerm();
95 }
96 };
97
98 class ScopedXPCOM : public nsIDirectoryServiceProvider2
99 {
100 public:
101 NS_DECL_ISUPPORTS
102
103 ScopedXPCOM(const char* testName,
104 nsIDirectoryServiceProvider *dirSvcProvider = nullptr)
105 : mDirSvcProvider(dirSvcProvider)
106 {
107 mTestName = testName;
108 printf("Running %s tests...\n", mTestName);
109
110 nsresult rv = NS_InitXPCOM2(&mServMgr, nullptr, this);
111 if (NS_FAILED(rv))
112 {
113 fail("NS_InitXPCOM2 returned failure code 0x%x", rv);
114 mServMgr = nullptr;
115 return;
116 }
117 }
118
119 ~ScopedXPCOM()
120 {
121 // If we created a profile directory, we need to remove it.
122 if (mProfD) {
123 nsCOMPtr<nsIObserverService> os =
124 do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
125 MOZ_ASSERT(os);
126 if (os) {
127 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(os->NotifyObservers(nullptr, "profile-change-net-teardown", nullptr)));
128 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(os->NotifyObservers(nullptr, "profile-change-teardown", nullptr)));
129 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(os->NotifyObservers(nullptr, "profile-before-change", nullptr)));
130 MOZ_ALWAYS_TRUE(NS_SUCCEEDED(os->NotifyObservers(nullptr, "profile-before-change2", nullptr)));
131 }
132
133 if (NS_FAILED(mProfD->Remove(true))) {
134 NS_WARNING("Problem removing profile directory");
135 }
136
137 mProfD = nullptr;
138 }
139
140 if (mServMgr)
141 {
142 NS_RELEASE(mServMgr);
143 nsresult rv = NS_ShutdownXPCOM(nullptr);
144 if (NS_FAILED(rv))
145 {
146 fail("XPCOM shutdown failed with code 0x%x", rv);
147 exit(1);
148 }
149 }
150
151 printf("Finished running %s tests.\n", mTestName);
152 }
153
154 bool failed()
155 {
156 return mServMgr == nullptr;
157 }
158
159 already_AddRefed<nsIFile> GetProfileDirectory()
160 {
161 if (mProfD) {
162 nsCOMPtr<nsIFile> copy = mProfD;
163 return copy.forget();
164 }
165
166 // Create a unique temporary folder to use for this test.
167 // Note that runcppunittests.py will run tests with a temp
168 // directory as the cwd, so just put something under that.
169 nsCOMPtr<nsIFile> profD;
170 nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_PROCESS_DIR,
171 getter_AddRefs(profD));
172 NS_ENSURE_SUCCESS(rv, nullptr);
173
174 rv = profD->Append(NS_LITERAL_STRING("cpp-unit-profd"));
175 NS_ENSURE_SUCCESS(rv, nullptr);
176
177 rv = profD->CreateUnique(nsIFile::DIRECTORY_TYPE, 0755);
178 NS_ENSURE_SUCCESS(rv, nullptr);
179
180 mProfD = profD;
181 return profD.forget();
182 }
183
184 already_AddRefed<nsIFile> GetGREDirectory()
185 {
186 if (mGRED) {
187 nsCOMPtr<nsIFile> copy = mGRED;
188 return copy.forget();
189 }
190
191 char* env = PR_GetEnv("MOZ_XRE_DIR");
192 nsCOMPtr<nsIFile> greD;
193 if (env) {
194 NS_NewLocalFile(NS_ConvertUTF8toUTF16(env), false,
195 getter_AddRefs(greD));
196 }
197
198 mGRED = greD;
199 return greD.forget();
200 }
201
202 ////////////////////////////////////////////////////////////////////////////
203 //// nsIDirectoryServiceProvider
204
205 NS_IMETHODIMP GetFile(const char *aProperty, bool *_persistent,
206 nsIFile **_result)
207 {
208 // If we were supplied a directory service provider, ask it first.
209 if (mDirSvcProvider &&
210 NS_SUCCEEDED(mDirSvcProvider->GetFile(aProperty, _persistent,
211 _result))) {
212 return NS_OK;
213 }
214
215 // Otherwise, the test harness provides some directories automatically.
216 if (0 == strcmp(aProperty, NS_APP_USER_PROFILE_50_DIR) ||
217 0 == strcmp(aProperty, NS_APP_USER_PROFILE_LOCAL_50_DIR) ||
218 0 == strcmp(aProperty, NS_APP_PROFILE_LOCAL_DIR_STARTUP)) {
219 nsCOMPtr<nsIFile> profD = GetProfileDirectory();
220 NS_ENSURE_TRUE(profD, NS_ERROR_FAILURE);
221
222 nsCOMPtr<nsIFile> clone;
223 nsresult rv = profD->Clone(getter_AddRefs(clone));
224 NS_ENSURE_SUCCESS(rv, rv);
225
226 *_persistent = true;
227 clone.forget(_result);
228 return NS_OK;
229 }
230
231 if (0 == strcmp(aProperty, NS_GRE_DIR)) {
232 nsCOMPtr<nsIFile> greD = GetGREDirectory();
233 NS_ENSURE_TRUE(greD, NS_ERROR_FAILURE);
234
235 *_persistent = true;
236 greD.forget(_result);
237 return NS_OK;
238 }
239
240 return NS_ERROR_FAILURE;
241 }
242
243 ////////////////////////////////////////////////////////////////////////////
244 //// nsIDirectoryServiceProvider2
245
246 NS_IMETHODIMP GetFiles(const char *aProperty, nsISimpleEnumerator **_enum)
247 {
248 // If we were supplied a directory service provider, ask it first.
249 nsCOMPtr<nsIDirectoryServiceProvider2> provider =
250 do_QueryInterface(mDirSvcProvider);
251 if (provider && NS_SUCCEEDED(provider->GetFiles(aProperty, _enum))) {
252 return NS_OK;
253 }
254
255 return NS_ERROR_FAILURE;
256 }
257
258 private:
259 const char* mTestName;
260 nsIServiceManager* mServMgr;
261 nsCOMPtr<nsIDirectoryServiceProvider> mDirSvcProvider;
262 nsCOMPtr<nsIFile> mProfD;
263 nsCOMPtr<nsIFile> mGRED;
264 };
265
266 NS_IMPL_QUERY_INTERFACE(
267 ScopedXPCOM,
268 nsIDirectoryServiceProvider,
269 nsIDirectoryServiceProvider2
270 )
271
272 NS_IMETHODIMP_(MozExternalRefCountType)
273 ScopedXPCOM::AddRef()
274 {
275 return 2;
276 }
277
278 NS_IMETHODIMP_(MozExternalRefCountType)
279 ScopedXPCOM::Release()
280 {
281 return 1;
282 }
283
284 #endif // TestHarness_h__

mercurial