1 // Copyright 2012 Google Inc. All Rights Reserved.
3 package com
.google
.appengine
.tools
.development
.testing
;
5 import com
.google
.appengine
.api
.basement
.dev
.LocalBasementService
;
6 import com
.google
.appengine
.tools
.development
.ApiProxyLocal
;
7 import com
.google
.common
.base
.Joiner
;
8 import com
.google
.common
.time
.Clock
;
9 import com
.google
.gaia
.mint
.GaiaMintScopeCode
;
10 import com
.google
.universalnav
.OneGoogleServerProto
;
12 import java
.io
.OutputStream
;
13 import java
.util
.LinkedList
;
16 * Config for accessing the LocalBasementService in tests. In order to verify that the expected
17 * data is being written, you will first need to provide an {@code OutputStream} for the
18 * data to be written to:
20 * private ByteArrayOutputStream out = new ByteArrayOutputStream();
21 * LocalServiceTestHelper helper;
23 * public void createService() {
24 * helper = new LocalServiceTestHelper(
25 * new LocalBasementServiceTestConfig().setProtoStream(out));
30 * Before reading the data from the {@code OutputStream} the test code must end the request
31 * by calling {@code LocalServiceTestHelper#endRequest()}. After doing that, the following
32 * code will read the data back out:
35 * public void verifyBehavior() {
37 * LocalServiceTestHelper.endRequest();
38 * AppExtensions appExtensions = parseProtoRecord();
39 * // Verify the expected AppExtension messages was written.
42 * private AppExtensions parseProtoRecord() throws IOException {
43 * InputRecordStream in = InputRecordStream.newInstance(new ByteArrayInputStream(
44 * protoStream.toByteArray()));
45 * Iterator<ByteBuffer> iterator = in.iterator();
46 * assertTrue("Expecting at least one record.", iterator.hasNext());
47 * AppExtensions appExtensions = new AppExtensions();
48 * assertTrue(appExtensions.mergeFrom(iterator.next()));
49 * assertFalse("Expecting no more than one record.", iterator.hasNext());
50 * return appExtensions;
54 * If you need to simulate multiple requests from a single test, you will need to parse the full
57 * private List<AppExtensions> parseProtoStream() throws IOException {
58 * List<AppExtensions> appExtensionsList = new ArrayList<AppExtensions>();
59 * InputRecordStream in = InputRecordStream.newInstance(new ByteArrayInputStream(
60 * protoStream.toByteArray()));
61 * for (ByteBuffer buffer : in) {
62 * AppExtensions appExtensions = new AppExtensions();
63 * assertTrue(appExtensions.mergeFrom(buffer));
64 * appExtensionsList.add(appExtensions);
66 * return appExtensionsList;
71 public class LocalBasementServiceTestConfig
implements LocalServiceTestConfig
{
72 private boolean logToSawmillEnable
= true;
73 private boolean logToSawmillIgnore
= false;
74 private boolean logToSawmillLogEveryCall
= false;
75 private OutputStream logToSawmillFinalProtoStream
= null;
76 private String gaiaMintEmail
= null;
77 private String gaiaMintUserId
= null;
78 private String gaiaMintAuthDomain
= null;
79 private Boolean gaiaMintIsAdmin
= null;
80 private Long gaiaMintGaiaId
= null;
81 private LinkedList
<GaiaMintScopeCode
.ScopeCode
> gaiaMintAllowedScopes
=
82 new LinkedList
<GaiaMintScopeCode
.ScopeCode
>();
83 private String oneGoogleServerSpec
= null;
84 private OneGoogleServerProto
.OneGoogleService
.Stub oneGoogleStub
= null;
85 private Clock clock
= null;
89 ApiProxyLocal proxy
= LocalServiceTestHelper
.getApiProxyLocal();
90 proxy
.setProperty(LocalBasementService
.LOG_TO_SAWMILL_ENABLE_PROPERTY
,
91 Boolean
.toString(logToSawmillEnable
));
92 proxy
.setProperty(LocalBasementService
.LOG_TO_SAWMILL_IGNORE_PROPERTY
,
93 Boolean
.toString(logToSawmillIgnore
));
94 proxy
.setProperty(LocalBasementService
.LOG_TO_SAWMILL_LOG_EVERY_CALL_PROPERTY
,
95 Boolean
.toString(logToSawmillLogEveryCall
));
96 proxy
.setProperty(LocalBasementService
.LOG_TO_SAWMILL_WRITE_FINAL_PROTO_PROPERTY
,
97 (logToSawmillFinalProtoStream
!= null ? Boolean
.TRUE
: Boolean
.FALSE
).toString());
99 if (gaiaMintEmail
!= null) {
100 proxy
.setProperty(LocalBasementService
.GAIA_MINT_EMAIL_PROPERTY
, gaiaMintEmail
);
102 if (gaiaMintUserId
!= null) {
103 proxy
.setProperty(LocalBasementService
.GAIA_MINT_USER_ID_PROPERTY
, gaiaMintUserId
);
105 if (gaiaMintAuthDomain
!= null) {
106 proxy
.setProperty(LocalBasementService
.GAIA_MINT_AUTH_DOMAIN_PROPERTY
, gaiaMintAuthDomain
);
108 if (gaiaMintIsAdmin
!= null) {
110 LocalBasementService
.GAIA_MINT_IS_ADMIN_PROPERTY
, gaiaMintIsAdmin
.toString());
112 if (gaiaMintGaiaId
!= null) {
113 proxy
.setProperty(LocalBasementService
.GAIA_MINT_GAIA_ID_PROPERTY
, gaiaMintGaiaId
.toString());
115 if (!gaiaMintAllowedScopes
.isEmpty()) {
116 proxy
.setProperty(LocalBasementService
.GAIA_MINT_ALLOWED_SCOPES_PROPERTY
,
117 Joiner
.on(',').join(gaiaMintAllowedScopes
));
119 if (oneGoogleServerSpec
!= null) {
120 proxy
.setProperty(LocalBasementService
.ONE_GOOGLE_SERVER_SPEC
, oneGoogleServerSpec
);
123 LocalBasementService localBasementService
= getLocalBasementService();
124 if (logToSawmillFinalProtoStream
!= null) {
125 localBasementService
.injectLogToSawmillOutputStream(logToSawmillFinalProtoStream
);
127 if (oneGoogleStub
!= null) {
128 localBasementService
.injectOneGoogleStub(oneGoogleStub
);
131 localBasementService
.injectClock(clock
);
136 public void tearDown() {}
138 public static LocalBasementService
getLocalBasementService() {
139 return (LocalBasementService
)
140 LocalServiceTestHelper
.getLocalService(LocalBasementService
.PACKAGE
);
144 * Configure the {@code LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
145 * so that it will write a request's final merged proto to the specified {@code OutputStream}. If
146 * this method is not called or is called with {@code null}, the final merged proto will not
147 * be written. Defaults to {@code null} and must be called (note: only applies to unit tests, in
148 * the Dev App Server defaults to writing to the filesystem).
150 * The final merged proto is only written once the request is over. You can indicate this
151 * to the unit test by either calling {@code LocalServiceTestHelper#endRequest()} or {@code
152 * LocalServiceTestHelper#tearDown()}.
154 * This method must be called prior to calling {@code LocalServiceTestHelper#setUp()}.
156 * @param out A non-closed OutputStream.
157 * @return itself for call chaining
159 public LocalBasementServiceTestConfig
setLogToSawmillProtoStream(OutputStream out
) {
160 logToSawmillFinalProtoStream
= out
;
165 * Configure the {@code LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
166 * with the specified enable state. When disabled, the {@LogToSawmillService} entry points will
167 * throw just like the production environment when the app is missing the
168 * SAWMILL_APP_EXTENSIONS_ENABLE permission. Defaults to {@code true}.
170 * This method must be called prior to calling {@code LocalServiceTestHelper#setUp()}.
172 * @param b True to allow the service to log.
173 * @return itself for call chaining
175 public LocalBasementServiceTestConfig
setLogToSawmillEnable(boolean b
) {
176 logToSawmillEnable
= b
;
181 * Configure the {@code LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
182 * with the specified ignore state. When ignored, {@code LogToSawmillService#log(byte[])} will
183 * drop all date and the the {@LogToSawmillService} entry points will indicate this in their
184 * return value. Defaults to {@code false}.
186 * This method must be called prior to calling {@code LocalServiceTestHelper#setUp()}.
188 * @param b False to allow the service to log.
189 * @return itself for call chaining
191 public LocalBasementServiceTestConfig
setLogToSawmillIgnore(boolean b
) {
192 logToSawmillIgnore
= b
;
197 * Configure the {@code LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
198 * so that it will log every call to {@code LogToSawmillService#log(byte[])} with {@code Logger}.
199 * Defaults to {@code false} (note: only applies to unit tests; in the Dev App Server defaults
202 * This method must be called prior to calling {@code LocalServiceTestHelper#setUp()}.
204 * @param b True to have the local service log each call.
205 * @return itself for call chaining
207 public LocalBasementServiceTestConfig
setLogToSawmillLogEveryCall(boolean b
) {
208 logToSawmillLogEveryCall
= b
;
213 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
214 * so that it will return the specified email address from calls to {@code
215 * GaiaMintService#getUserinfoFromGaiaMint}. Defaults to "example@example.com".
217 * This method must be called prior to calling {@link LocalServiceTestHelper#setUp()}.
219 * @param email The email address to return from {@code GaiaMintService#getUserinfoFromGaiaMint}.
220 * @return itself for call chaining
222 public LocalBasementServiceTestConfig
setGaiaMintEmail(String email
) {
223 gaiaMintEmail
= email
;
228 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
229 * so that it will return the specified user id from calls to {@code
230 * GaiaMintService#getUserinfoFromGaiaMint}. Defaults to "135705915318242114242".
232 * This method must be called prior to calling {@link LocalServiceTestHelper#setUp()}.
234 * @param userId The user id to return from {@code GaiaMintService#getUserinfoFromGaiaMint}.
235 * @return itself for call chaining
237 public LocalBasementServiceTestConfig
setGaiaMintUserId(String userId
) {
238 gaiaMintUserId
= userId
;
243 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
244 * so that it will return the specified auth domain from calls to
245 * {@code GaiaMintService#getUserinfoFromGaiaMint}. Defaults to "gmail.com".
247 * This method must be called prior to calling {@link LocalServiceTestHelper#setUp()}.
249 * @param authDomain The auth domain to return from {@code
250 * GaiaMintService#getUserinfoFromGaiaMint}.
251 * @return itself for call chaining
253 public LocalBasementServiceTestConfig
setGaiaMintAuthDomain(String authDomain
) {
254 gaiaMintAuthDomain
= authDomain
;
259 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
260 * so that it will return whether the user is an admin from calls to {@code
261 * GaiaMintService#getUserinfoFromGaiaMint}. Defaults to false.
263 * This method must be called prior to calling {@link LocalServiceTestHelper#setUp()}.
265 * @param isAdmin Whether to make the user an admin in calls to {@code
266 * GaiaMintService#getUserinfoFromGaiaMint}.
267 * @return itself for call chaining
269 public LocalBasementServiceTestConfig
setGaiaMintIsAdmin(boolean isAdmin
) {
270 gaiaMintIsAdmin
= isAdmin
;
275 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
276 * so that it will return the specified gaid ID from calls to
277 * {@code GaiaMintService#getUserinfoFromGaiaMint}. Defaults to 8242114242L.
279 * This method must be called prior to calling {@link LocalServiceTestHelper#setUp()}.
281 * @param authDomain The gaia ID to return from {@code GaiaMintService#getUserinfoFromGaiaMint}.
282 * @return itself for call chaining
284 public LocalBasementServiceTestConfig
setGaiaMintGaiaId(long gaiaId
) {
285 gaiaMintGaiaId
= gaiaId
;
290 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
291 * so that the specific {@link GaiaMintScopeCode.ScopeCode} is allowed. Calls to {@code
292 * GaiaMintService#getUserinfoFromGaiaMint} with non allowed scopes will fail. If the allowed list
293 * of scopes code is empty or it includes {@link GaiaMintScopeCode.ScopeCode#API_ALL_SCOPES} all
294 * scopes will be allowed.
296 * This method must be called prior to calling {@link LocalServiceTestHelper#setUp()}.
298 * @param allowedScope A {@link GaiaMintScopeCode.ScopeCode} to allow for calls to {@code
299 * GaiaMintService#getUserinfoFromGaiaMint}.
300 * @return itself for call chaining
302 public LocalBasementServiceTestConfig
addGaiaMintAllowedScope(
303 GaiaMintScopeCode
.ScopeCode allowedScope
) {
304 gaiaMintAllowedScopes
.add(allowedScope
);
309 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
310 * to use the specified server spec for the OneGoogle backend instead of the default (see
311 * {@link LocalBasementService.ONE_GOOGLE_SERVER_SPEC_DEFAULT}).
313 * NOTE: most unit tests should not bother with this method and should
314 * use {@link LocalBasementServiceTestConfig#setOneGoogleStub(
315 * OneGoogleServerProto.OneGoogleService.Stub)} to install a mock stub.
317 * @param serverSpec the OneGoogle backend server spec to connect to
318 * @return itself for call chaining
320 public LocalBasementServiceTestConfig
setOneGoogleServerSpec(String serverSpec
) {
321 oneGoogleServerSpec
= serverSpec
;
326 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
327 * to use the the specified {@link OneGoogleServerProto.OneGoogleService.Stub}
328 * to send RPCs to the OneGoogleService server.
330 * @param stub a {@link OneGoogleServerProto.OneGoogleService.Stub}
331 * @return itself for call chaining
333 public LocalBasementServiceTestConfig
setOneGoogleStub(
334 OneGoogleServerProto
.OneGoogleService
.Stub stub
) {
335 oneGoogleStub
= stub
;
340 * Configure the {@link LocalBasementServiceTestConfig} to create the {@code LocalBasementService}
341 * to use the specified (@link com.google.common.time.Clock) when determing
344 * @param clock a {@link com.google.common.time.Clock}
345 * @return itself for call chaining
347 public LocalBasementServiceTestConfig
setClock(Clock clock
) {