|
@@ -1,5 +1,6 @@ |
1 |
1 |
|
package org.litesoft.gae.datastoreservice; |
2 |
2 |
|
|
|
3 |
+ |
import org.litesoft.core.typeutils.Objects; |
3 |
4 |
|
import java.util.*; |
4 |
5 |
|
|
5 |
6 |
|
import junit.framework.TestCase; |
|
@@ -23,748 +24,748 @@ |
23 |
24 |
|
|
24 |
25 |
|
public class DatastoreServiceTest extends TestCase |
25 |
26 |
|
{ |
26 |
|
- |
private static final String KIND = "TheFlintstones"; |
|
27 |
+ |
private static final String KIND = "TheFlintstones"; |
27 |
28 |
|
|
28 |
|
- |
private final LocalServiceTestHelper mHelper = new LocalServiceTestHelper( new LocalDatastoreServiceTestConfig() ); |
|
29 |
+ |
private final LocalServiceTestHelper mHelper = new LocalServiceTestHelper( new LocalDatastoreServiceTestConfig() ); |
29 |
30 |
|
|
30 |
|
- |
public static TestSuite suite() |
31 |
|
- |
{ |
32 |
|
- |
return new TestSuite( DatastoreServiceTest.class ); |
33 |
|
- |
} |
34 |
|
- |
|
35 |
|
- |
public DatastoreServiceTest( String name ) |
36 |
|
- |
{ |
37 |
|
- |
super( name ); |
38 |
|
- |
} |
39 |
|
- |
|
40 |
|
- |
public static void main( String[] args ) |
41 |
|
- |
{ |
42 |
|
- |
junit.textui.TestRunner.run( suite() ); |
43 |
|
- |
} |
44 |
|
- |
|
45 |
|
- |
@Override |
46 |
|
- |
protected void setUp() throws Exception |
47 |
|
- |
{ |
48 |
|
- |
super.setUp(); |
49 |
|
- |
mHelper.setUp(); |
50 |
|
- |
mConfig = DatastoreServiceConfig.Builder.withDefaults() // Deadline=null, |
51 |
|
- |
// ImplicitTransactionManagementPolicy=NONE, |
52 |
|
- |
// ReadPolicy.Consistency=STRONG |
53 |
|
- |
.deadline( 5 ); // Deadline=5 secs |
54 |
|
- |
mDatastoreService = DatastoreServiceFactory.getDatastoreService( mConfig ); |
55 |
|
- |
mGOD_Apollo = KeyFactory.createKey( "GODS", "Apollo" ); |
56 |
|
- |
mGOD_Venus = KeyFactory.createKey( "GODS", "Venus" ); |
57 |
|
- |
|
58 |
|
- |
} |
59 |
|
- |
|
60 |
|
- |
@Override |
61 |
|
- |
public void tearDown() |
62 |
|
- |
{ |
63 |
|
- |
mHelper.tearDown(); |
64 |
|
- |
} |
65 |
|
- |
|
66 |
|
- |
private DatastoreServiceConfig mConfig; |
67 |
|
- |
|
68 |
|
- |
private DatastoreService mDatastoreService; |
69 |
|
- |
|
70 |
|
- |
private Key mGOD_Apollo, mGOD_Venus; |
71 |
|
- |
|
72 |
|
- |
private Entity createEntity( Key pGOD, String pName ) |
73 |
|
- |
{ |
74 |
|
- |
Entity zEntity = new Entity( KIND, pName, pGOD ); |
75 |
|
- |
zEntity.setUnindexedProperty( "Version", 1L ); |
76 |
|
- |
|
77 |
|
- |
zEntity.setProperty( "Name", pName ); |
78 |
|
- |
zEntity.setUnindexedProperty( "Children", 0L ); |
79 |
|
- |
return zEntity; |
80 |
|
- |
} |
81 |
|
- |
|
82 |
|
- |
private void inc( Entity pEntity, String pProperty ) |
83 |
|
- |
{ |
84 |
|
- |
Long zLong = (Long) pEntity.getProperty( pProperty ); |
85 |
|
- |
pEntity.setUnindexedProperty( pProperty, zLong + 1 ); |
86 |
|
- |
} |
87 |
|
- |
|
88 |
|
- |
private Entity updateChildren( Entity pEntity ) |
89 |
|
- |
{ |
90 |
|
- |
inc( pEntity, "Version" ); |
91 |
|
- |
inc( pEntity, "Children" ); |
92 |
|
- |
return pEntity; |
93 |
|
- |
} |
94 |
|
- |
|
95 |
|
- |
public void test_DataStoreConfig() throws Exception |
96 |
|
- |
{ |
97 |
|
- |
assertEquals( 5.0d, mConfig.getDeadline(), 0.0001 ); |
98 |
|
- |
assertEquals( ImplicitTransactionManagementPolicy.NONE, mConfig.getImplicitTransactionManagementPolicy() ); |
99 |
|
- |
assertEquals( Consistency.STRONG, mConfig.getReadPolicy().getConsistency() ); |
100 |
|
- |
} |
101 |
|
- |
|
102 |
|
- |
public void test_NonConflictingDifferentGodsOverlapingTransactionsNew() throws Exception |
103 |
|
- |
{ |
104 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
105 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
106 |
|
- |
|
107 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
108 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
109 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
110 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
111 |
|
- |
|
112 |
|
- |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
113 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
114 |
|
- |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
115 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
116 |
|
- |
|
117 |
|
- |
zApolloTransaction.commit(); |
118 |
|
- |
zVenusTransaction.commit(); |
119 |
|
- |
|
120 |
|
- |
readAndValidate( null, zEntityFred, "Fred", 1, 0 ); |
121 |
|
- |
readAndValidate( null, zEntityWilma, "Wilma", 1, 0 ); |
122 |
|
- |
|
123 |
|
- |
readAndValidate( null, zEntityBarney, "Barney", 1, 0 ); |
124 |
|
- |
readAndValidate( null, zEntityBetty, "Betty", 1, 0 ); |
125 |
|
- |
} |
126 |
|
- |
|
127 |
|
- |
public void test_TransactionReadMultiGOD() throws Exception |
128 |
|
- |
{ |
129 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
130 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
131 |
|
- |
|
132 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
133 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
134 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
135 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
136 |
|
- |
|
137 |
|
- |
zApolloTransaction.commit(); |
138 |
|
- |
zVenusTransaction.commit(); |
139 |
|
- |
|
140 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
141 |
|
- |
mDatastoreService.get( zTransaction, zEntityFred.getKey() ); // will |
142 |
|
- |
// succeed! |
143 |
|
- |
try |
144 |
|
- |
{ |
145 |
|
- |
mDatastoreService.get( zTransaction, zEntityWilma.getKey() ); // will |
146 |
|
- |
// Fail! |
147 |
|
- |
fail( "Fred & Wilma - Did NOT Fail with different GODS (Entity Groups)" ); |
148 |
|
- |
} |
149 |
|
- |
catch ( IllegalArgumentException expected ) |
150 |
|
- |
{ |
151 |
|
- |
String zMessage = expected.getMessage(); |
152 |
|
- |
assertTrue( zMessage, zMessage |
153 |
|
- |
.startsWith( "can't operate on multiple entity groups in a single transaction." ) ); |
154 |
|
- |
} |
155 |
|
- |
zTransaction.rollback(); |
156 |
|
- |
} |
157 |
|
- |
|
158 |
|
- |
public void test_TransactionUpdate() throws Exception |
159 |
|
- |
{ |
160 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
161 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
162 |
|
- |
|
163 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
164 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
165 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
166 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
167 |
|
- |
|
168 |
|
- |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
169 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
170 |
|
- |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
171 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
172 |
|
- |
|
173 |
|
- |
zApolloTransaction.commit(); |
174 |
|
- |
zVenusTransaction.commit(); |
175 |
|
- |
|
176 |
|
- |
zVenusTransaction = mDatastoreService.beginTransaction(); |
177 |
|
- |
|
178 |
|
- |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
179 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
180 |
|
- |
|
181 |
|
- |
Entity zEntityPebbles = createEntity( mGOD_Venus, "Pebbles" ); |
182 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityPebbles ); |
183 |
|
- |
|
184 |
|
- |
// Can't Update Fred! |
185 |
|
- |
|
186 |
|
- |
zVenusTransaction.commit(); |
187 |
|
- |
|
188 |
|
- |
zApolloTransaction = mDatastoreService.beginTransaction(); |
189 |
|
- |
|
190 |
|
- |
zEntityBarney = updateChildren( readAndValidate( zApolloTransaction, zEntityBarney, "Barney", 1, 0 ) ); |
191 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
192 |
|
- |
|
193 |
|
- |
Entity zEntityBammBamm = createEntity( mGOD_Apollo, "BammBamm" ); |
194 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBammBamm ); |
195 |
|
- |
|
196 |
|
- |
// Can't Update Betty! |
197 |
|
- |
|
198 |
|
- |
zApolloTransaction.commit(); |
199 |
|
- |
|
200 |
|
- |
readAndValidate( null, zEntityFred, "Fred", 1, 0 ); |
201 |
|
- |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
202 |
|
- |
readAndValidate( null, zEntityPebbles, "Pebbles", 1, 0 ); |
203 |
|
- |
|
204 |
|
- |
readAndValidate( null, zEntityBarney, "Barney", 2, 1 ); |
205 |
|
- |
readAndValidate( null, zEntityBetty, "Betty", 1, 0 ); |
206 |
|
- |
readAndValidate( null, zEntityBammBamm, "BammBamm", 1, 0 ); |
207 |
|
- |
} |
208 |
|
- |
|
209 |
|
- |
public void test_NonConflictingDifferentGodsOverlapingTransactionsUpdate() throws Exception |
210 |
|
- |
{ |
211 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
212 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
213 |
|
- |
|
214 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
215 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
216 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
217 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
218 |
|
- |
|
219 |
|
- |
zApolloTransaction.commit(); |
220 |
|
- |
zVenusTransaction.commit(); |
221 |
|
- |
|
222 |
|
- |
zApolloTransaction = mDatastoreService.beginTransaction(); |
223 |
|
- |
zVenusTransaction = mDatastoreService.beginTransaction(); |
224 |
|
- |
|
225 |
|
- |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
226 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
227 |
|
- |
|
228 |
|
- |
Entity zEntityPebbles = createEntity( mGOD_Venus, "Pebbles" ); |
229 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityPebbles ); |
230 |
|
- |
|
231 |
|
- |
zEntityFred = updateChildren( readAndValidate( zApolloTransaction, zEntityFred, "Fred", 1, 0 ) ); |
232 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
233 |
|
- |
|
234 |
|
- |
zApolloTransaction.commit(); |
235 |
|
- |
zVenusTransaction.commit(); |
236 |
|
- |
|
237 |
|
- |
readAndValidate( null, zEntityFred, "Fred", 2, 1 ); |
238 |
|
- |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
239 |
|
- |
|
240 |
|
- |
readAndValidate( null, zEntityPebbles, "Pebbles", 1, 0 ); |
241 |
|
- |
} |
242 |
|
- |
|
243 |
|
- |
public void test_ConflictingSameEntityOverlapingTransactionsUpdate() throws Exception |
244 |
|
- |
{ |
245 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
246 |
|
- |
|
247 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
248 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
249 |
|
- |
|
250 |
|
- |
zVenusTransaction.commit(); |
251 |
|
- |
|
252 |
|
- |
zVenusTransaction = mDatastoreService.beginTransaction(); |
253 |
|
- |
|
254 |
|
- |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
255 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
256 |
|
- |
|
257 |
|
- |
Entity zEntityPebbles = createEntity( mGOD_Venus, "Pebbles" ); |
258 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityPebbles ); |
259 |
|
- |
|
260 |
|
- |
Transaction zVenus2Transaction = mDatastoreService.beginTransaction(); |
261 |
|
- |
|
262 |
|
- |
Entity zEntityWilma2 = updateChildren( readAndValidate2( zVenus2Transaction, zEntityWilma, "Wilma", 1, 0 ) ); |
263 |
|
- |
mDatastoreService.put( zVenus2Transaction, zEntityWilma2 ); |
264 |
|
- |
|
265 |
|
- |
zVenusTransaction.commit(); |
266 |
|
- |
|
267 |
|
- |
try |
268 |
|
- |
{ |
269 |
|
- |
zVenus2Transaction.commit(); |
270 |
|
- |
fail( "Two Transaction Wilma Update - Did NOT Fail" ); |
271 |
|
- |
} |
272 |
|
- |
catch ( ConcurrentModificationException expected ) |
273 |
|
- |
{ |
274 |
|
- |
String zMessage = expected.getMessage(); |
275 |
|
- |
assertTrue( zMessage, zMessage.startsWith( "too much contention on these datastore entities. please try again." ) ); |
276 |
|
- |
} |
277 |
|
- |
|
278 |
|
- |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
279 |
|
- |
} |
280 |
|
- |
|
281 |
|
- |
public void test_NonConflictingSameGodDifferentEntityOverlapingTransactionsUpdate() throws Exception |
282 |
|
- |
{ |
283 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
284 |
|
- |
|
285 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
286 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
287 |
|
- |
|
288 |
|
- |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
289 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
290 |
|
- |
|
291 |
|
- |
zVenusTransaction.commit(); |
292 |
|
- |
|
293 |
|
- |
zVenusTransaction = mDatastoreService.beginTransaction(); |
294 |
|
- |
|
295 |
|
- |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
296 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
297 |
|
- |
|
298 |
|
- |
Transaction zVenus2Transaction = mDatastoreService.beginTransaction(); |
299 |
|
- |
|
300 |
|
- |
zEntityBetty = updateChildren( readAndValidate( zVenus2Transaction, zEntityBetty, "Betty", 1, 0 ) ); |
301 |
|
- |
mDatastoreService.put( zVenus2Transaction, zEntityBetty ); |
302 |
|
- |
|
303 |
|
- |
zVenusTransaction.commit(); |
304 |
|
- |
|
305 |
|
- |
try |
306 |
|
- |
{ |
307 |
|
- |
zVenus2Transaction.commit(); |
308 |
|
- |
fail( "Two Transaction Wilma & Betty Update - Did NOT Fail" ); |
309 |
|
- |
} |
310 |
|
- |
catch ( ConcurrentModificationException expected ) |
311 |
|
- |
{ |
312 |
|
- |
String zMessage = expected.getMessage(); |
313 |
|
- |
assertTrue( zMessage, zMessage.startsWith( "too much contention on these datastore entities. please try again." ) ); |
314 |
|
- |
} |
315 |
|
- |
|
316 |
|
- |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
317 |
|
- |
readAndValidate2( null, zEntityBetty, "Betty", 1, 0 ); |
318 |
|
- |
} |
319 |
|
- |
|
320 |
|
- |
public void test_QueryAllDifferentGods() throws Exception |
321 |
|
- |
{ |
322 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
323 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
324 |
|
- |
|
325 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
326 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
327 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
328 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
329 |
|
- |
|
330 |
|
- |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
331 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
332 |
|
- |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
333 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
334 |
|
- |
|
335 |
|
- |
zApolloTransaction.commit(); |
336 |
|
- |
zVenusTransaction.commit(); |
337 |
|
- |
|
338 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND ).addSort( "Name" ) ); |
339 |
|
- |
|
340 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
341 |
|
- |
|
342 |
|
- |
assertEquals( "Entities", 4, zList.size() ); |
343 |
|
- |
|
344 |
|
- |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
345 |
|
- |
validate( zList.get( 1 ), "Betty", 1, 0 ); |
346 |
|
- |
validate( zList.get( 2 ), "Fred", 1, 0 ); |
347 |
|
- |
validate( zList.get( 3 ), "Wilma", 1, 0 ); |
348 |
|
- |
} |
349 |
|
- |
|
350 |
|
- |
public void test_QuerySpecificGod() throws Exception |
351 |
|
- |
{ |
352 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
353 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
354 |
|
- |
|
355 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
356 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
357 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
358 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
359 |
|
- |
|
360 |
|
- |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
361 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
362 |
|
- |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
363 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
364 |
|
- |
|
365 |
|
- |
zApolloTransaction.commit(); |
366 |
|
- |
zVenusTransaction.commit(); |
367 |
|
- |
|
368 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND, mGOD_Apollo ).addSort( "Name" ) ); |
369 |
|
- |
|
370 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
371 |
|
- |
|
372 |
|
- |
assertEquals( "Entities", 2, zList.size() ); |
373 |
|
- |
|
374 |
|
- |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
375 |
|
- |
validate( zList.get( 1 ), "Fred", 1, 0 ); |
376 |
|
- |
} |
377 |
|
- |
|
378 |
|
- |
public void test_QueryEqualsFilter() throws Exception |
379 |
|
- |
{ |
380 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
381 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
382 |
|
- |
|
383 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
384 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
385 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
386 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
387 |
|
- |
|
388 |
|
- |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
389 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
390 |
|
- |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
391 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
392 |
|
- |
|
393 |
|
- |
zApolloTransaction.commit(); |
394 |
|
- |
zVenusTransaction.commit(); |
395 |
|
- |
|
396 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND ).addSort( "Name" ).addFilter( "Name", Query.FilterOperator.EQUAL, "Barney") ); |
397 |
|
- |
|
398 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
399 |
|
- |
|
400 |
|
- |
assertEquals( "Entities", 1, zList.size() ); |
401 |
|
- |
|
402 |
|
- |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
403 |
|
- |
} |
404 |
|
- |
|
405 |
|
- |
public void test_QueryLessThanFilter() throws Exception |
406 |
|
- |
{ |
407 |
|
- |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
408 |
|
- |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
409 |
|
- |
|
410 |
|
- |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
411 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
412 |
|
- |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
413 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
414 |
|
- |
|
415 |
|
- |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
416 |
|
- |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
417 |
|
- |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
418 |
|
- |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
419 |
|
- |
|
420 |
|
- |
zApolloTransaction.commit(); |
421 |
|
- |
zVenusTransaction.commit(); |
422 |
|
- |
|
423 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND ).addSort( "Name" ).addFilter( "Name", Query.FilterOperator.LESS_THAN, "C") ); |
424 |
|
- |
|
425 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
426 |
|
- |
|
427 |
|
- |
assertEquals( "Entities", 2, zList.size() ); |
428 |
|
- |
|
429 |
|
- |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
430 |
|
- |
validate( zList.get( 1 ), "Betty", 1, 0 ); |
431 |
|
- |
} |
432 |
|
- |
|
433 |
|
- |
public void test_NullKey() throws Exception |
434 |
|
- |
{ |
435 |
|
- |
try |
436 |
|
- |
{ |
437 |
|
- |
KeyFactory.createKey( KIND, null ); |
438 |
|
- |
fail( "null Key did NOT fail" ); |
439 |
|
- |
} |
440 |
|
- |
catch ( IllegalArgumentException expected ) |
441 |
|
- |
{ |
442 |
|
- |
String zMessage = expected.getMessage(); |
443 |
|
- |
assertTrue( zMessage, zMessage.startsWith( "name cannot be null or empty" ) ); |
444 |
|
- |
} |
445 |
|
- |
// new Entity( KIND, null, pGOD ); // Does Not Fail, but |
446 |
|
- |
// implicitly creates a auto-generated id key!! |
447 |
|
- |
} |
448 |
|
- |
|
449 |
|
- |
public void test_EmptyKey() throws Exception |
450 |
|
- |
{ |
451 |
|
- |
try |
452 |
|
- |
{ |
453 |
|
- |
KeyFactory.createKey( KIND, "" ); |
454 |
|
- |
fail( "empty Key did NOT fail" ); |
455 |
|
- |
} |
456 |
|
- |
catch ( IllegalArgumentException expected ) |
457 |
|
- |
{ |
458 |
|
- |
String zMessage = expected.getMessage(); |
459 |
|
- |
assertTrue( zMessage, zMessage.startsWith( "name cannot be null or empty" ) ); |
460 |
|
- |
} |
461 |
|
- |
} |
462 |
|
- |
|
463 |
|
- |
public void test_IndexingString() throws Exception |
464 |
|
- |
{ |
465 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
466 |
|
- |
|
467 |
|
- |
String v1, v2; |
468 |
|
- |
|
469 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Strings", null ) ); |
470 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Strings", v1 = "" ) ); |
471 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Strings", v2 = "Fred" ) ); |
472 |
|
- |
|
473 |
|
- |
zTransaction.commit(); |
474 |
|
- |
|
475 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Strings" ).addSort( "FieldValue" ) ); |
476 |
|
- |
|
477 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
478 |
|
- |
|
479 |
|
- |
assertEquals( "Entities", 3, zList.size() ); |
480 |
|
- |
|
481 |
|
- |
validate( zList.get( 0 ), null ); |
482 |
|
- |
validate( zList.get( 1 ), v1 ); |
483 |
|
- |
validate( zList.get( 2 ), v2 ); |
484 |
|
- |
} |
485 |
|
- |
|
486 |
|
- |
public void test_IndexingBoolean() throws Exception |
487 |
|
- |
{ |
488 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
489 |
|
- |
|
490 |
|
- |
Boolean v1, v2; |
491 |
|
- |
|
492 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Booleans", null ) ); |
493 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Booleans", v1 = Boolean.FALSE ) ); |
494 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Booleans", v2 = Boolean.TRUE ) ); |
495 |
|
- |
|
496 |
|
- |
zTransaction.commit(); |
497 |
|
- |
|
498 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Booleans" ).addSort( "FieldValue" ) ); |
499 |
|
- |
|
500 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
501 |
|
- |
|
502 |
|
- |
assertEquals( "Entities", 3, zList.size() ); |
503 |
|
- |
|
504 |
|
- |
validate( zList.get( 0 ), null ); |
505 |
|
- |
validate( zList.get( 1 ), v1 ); |
506 |
|
- |
validate( zList.get( 2 ), v2 ); |
507 |
|
- |
} |
508 |
|
- |
|
509 |
|
- |
public void test_IndexingLong() throws Exception |
510 |
|
- |
{ |
511 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
512 |
|
- |
|
513 |
|
- |
Long v1, v2; |
514 |
|
- |
|
515 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Longs", null ) ); |
516 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Longs", v1 = 1L ) ); |
517 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Longs", v2 = 100L ) ); |
518 |
|
- |
|
519 |
|
- |
zTransaction.commit(); |
520 |
|
- |
|
521 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Longs" ).addSort( "FieldValue" ) ); |
522 |
|
- |
|
523 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
524 |
|
- |
|
525 |
|
- |
assertEquals( "Entities", 3, zList.size() ); |
526 |
|
- |
|
527 |
|
- |
validate( zList.get( 0 ), null ); |
528 |
|
- |
validate( zList.get( 1 ), v1 ); |
529 |
|
- |
validate( zList.get( 2 ), v2 ); |
530 |
|
- |
} |
531 |
|
- |
|
532 |
|
- |
public void test_IndexingDouble() throws Exception |
533 |
|
- |
{ |
534 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
535 |
|
- |
|
536 |
|
- |
Double v1, v2; |
537 |
|
- |
|
538 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Doubles", null ) ); |
539 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Doubles", v1 = 1.1D ) ); |
540 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Doubles", v2 = 11.2D ) ); |
541 |
|
- |
|
542 |
|
- |
zTransaction.commit(); |
543 |
|
- |
|
544 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Doubles" ).addSort( "FieldValue" ) ); |
545 |
|
- |
|
546 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
547 |
|
- |
|
548 |
|
- |
assertEquals( "Entities", 3, zList.size() ); |
549 |
|
- |
|
550 |
|
- |
validate( zList.get( 0 ), null ); |
551 |
|
- |
validate( zList.get( 1 ), v1 ); |
552 |
|
- |
validate( zList.get( 2 ), v2 ); |
553 |
|
- |
} |
554 |
|
- |
|
555 |
|
- |
public void test_IndexingDate() throws Exception |
556 |
|
- |
{ |
557 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
558 |
|
- |
|
559 |
|
- |
Date v1, v2; |
560 |
|
- |
|
561 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Dates", null ) ); |
562 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Dates", v1 = createDate( 1957, 1, 4, 11, 12, 13, 14 ) ) ); |
563 |
|
- |
mDatastoreService.put( zTransaction, createIndexingEntity( "Dates", v2 = createDate( 2000, 2, 29, 0, 0, 0, 0 ) ) ); |
564 |
|
- |
|
565 |
|
- |
zTransaction.commit(); |
566 |
|
- |
|
567 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Dates" ).addSort( "FieldValue" ) ); |
568 |
|
- |
|
569 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
570 |
|
- |
|
571 |
|
- |
assertEquals( "Entities", 3, zList.size() ); |
572 |
|
- |
|
573 |
|
- |
validate( zList.get( 0 ), null ); |
574 |
|
- |
validate( zList.get( 1 ), v1 ); |
575 |
|
- |
validate( zList.get( 2 ), v2 ); |
576 |
|
- |
} |
577 |
|
- |
|
578 |
|
- |
public void test_LargeCollections() throws Exception |
579 |
|
- |
{ |
580 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
581 |
|
- |
|
582 |
|
- |
long zMaxLongsThatWork = 62645L; |
583 |
|
- |
|
584 |
|
- |
Entity zEntity; |
585 |
|
- |
Set<Long> zLongs; |
586 |
|
- |
|
587 |
|
- |
try |
588 |
|
- |
{ |
589 |
|
- |
zLongs = createLongs( zMaxLongsThatWork + 1 ); // Too Big! |
590 |
|
- |
|
591 |
|
- |
zEntity = new Entity( "LargeCollections", "Test" ); |
592 |
|
- |
zEntity.setProperty( "FieldValue", "Test" ); |
593 |
|
- |
zEntity.setUnindexedProperty( "Longs", zLongs ); |
594 |
|
- |
|
595 |
|
- |
mDatastoreService.put( zTransaction, zEntity ); |
596 |
|
- |
|
597 |
|
- |
fail( "Too Many did not fail w/ too large" ); |
598 |
|
- |
} |
599 |
|
- |
catch ( Exception expected ) |
600 |
|
- |
{ |
601 |
|
- |
assertNotNull( expected ); // com.google.apphosting.api.ApiProxy$RequestTooLargeException: The request to API call datastore_v3.Put() was too large. |
602 |
|
- |
} |
603 |
|
- |
zLongs = createLongs( zMaxLongsThatWork ); // Just Small Enough! |
604 |
|
- |
|
605 |
|
- |
zEntity = new Entity( "LargeCollections", "Test" ); |
606 |
|
- |
zEntity.setProperty( "FieldValue", "Test" ); |
607 |
|
- |
zEntity.setUnindexedProperty( "Longs", zLongs ); |
608 |
|
- |
|
609 |
|
- |
mDatastoreService.put( zTransaction, zEntity ); |
610 |
|
- |
|
611 |
|
- |
zTransaction.commit(); |
612 |
|
- |
|
613 |
|
- |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "LargeCollections" ).addSort( "FieldValue" ) ); |
614 |
|
- |
|
615 |
|
- |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
616 |
|
- |
|
617 |
|
- |
assertEquals( "Entities", 1, zList.size() ); |
618 |
|
- |
|
619 |
|
- |
zEntity = zList.get( 0 ); |
620 |
|
- |
|
621 |
|
- |
assertEquals( "FieldValue", "Test", zEntity.getProperty( "FieldValue" ) ); |
622 |
|
- |
|
623 |
|
- |
validate( zLongs, zEntity.getProperty( "Longs" ) ); |
624 |
|
- |
} |
625 |
|
- |
|
626 |
|
- |
private Set<Long> createLongs( long pLongsToCreate ) |
627 |
|
- |
{ |
628 |
|
- |
HashSet<Long> zSet = new HashSet<Long>(); |
629 |
|
- |
while ( --pLongsToCreate >= 0 ) |
630 |
|
- |
{ |
631 |
|
- |
zSet.add( pLongsToCreate ); |
632 |
|
- |
} |
633 |
|
- |
return zSet; |
634 |
|
- |
} |
635 |
|
- |
|
636 |
|
- |
@SuppressWarnings("unchecked") |
637 |
|
- |
private void validate( Set<Long> zExpected, Object pFieldValue ) |
638 |
|
- |
{ |
639 |
|
- |
List<Long> zReadList = (List<Long>)pFieldValue; |
640 |
|
- |
for (Long zLong : zReadList) |
641 |
|
- |
{ |
642 |
|
- |
if ( !zExpected.remove( zLong ) ) |
643 |
|
- |
{ |
644 |
|
- |
fail( "Found value (" + zLong + "), not written" ); |
645 |
|
- |
} |
646 |
|
- |
} |
647 |
|
- |
if ( !zExpected.isEmpty() ) |
648 |
|
- |
{ |
649 |
|
- |
fail( "Did NOT read: " + zExpected ); |
650 |
|
- |
} |
651 |
|
- |
} |
652 |
|
- |
|
653 |
|
- |
@SuppressWarnings("deprecation") |
654 |
|
- |
private Date createDate( int pYear, int pMonth, int pDay, int pHour, int pMin, int pSec, int pMilliSecs ) |
655 |
|
- |
{ |
656 |
|
- |
Date zDate = new Date( pYear - 1900, pMonth - 1, pDay, pHour, pMin, pSec ); |
657 |
|
- |
if ( pMilliSecs != 0 ) |
658 |
|
- |
{ |
659 |
|
- |
zDate = new Date( zDate.getTime() + pMilliSecs ); |
660 |
|
- |
} |
661 |
|
- |
return zDate; |
662 |
|
- |
} |
663 |
|
- |
|
664 |
|
- |
@SuppressWarnings("deprecation") |
665 |
|
- |
private String simpleDateToString( Date pDate ) |
666 |
|
- |
{ |
667 |
|
- |
int zYear = pDate.getYear() + 1900; |
668 |
|
- |
int zMonth = pDate.getMonth() + 1; |
669 |
|
- |
int zDay = pDate.getDate(); |
670 |
|
- |
int zHour = pDate.getHours(); |
671 |
|
- |
int zMin = pDate.getMinutes(); |
672 |
|
- |
int zSec = pDate.getSeconds(); |
673 |
|
- |
int zMilliSecs = (int)(pDate.getTime() - new Date( zYear - 1900, zMonth - 1, zDay, zHour, zMin, zSec ).getTime()); |
674 |
|
- |
return "" + zYear + "/" + zMonth + "/" + zDay + "-" + zHour + ":" + zMin + ":" + zSec + "." + zMilliSecs; |
675 |
|
- |
} |
676 |
|
- |
|
677 |
|
- |
private String createIndexKey( Object pFieldValue ) |
678 |
|
- |
{ |
679 |
|
- |
if ( pFieldValue == null ) |
680 |
|
- |
{ |
681 |
|
- |
return " "; |
682 |
|
- |
} |
683 |
|
- |
if ( pFieldValue instanceof String ) |
684 |
|
- |
{ |
685 |
|
- |
return pFieldValue + " "; |
686 |
|
- |
} |
687 |
|
- |
if ( pFieldValue instanceof Date ) |
688 |
|
- |
{ |
689 |
|
- |
return simpleDateToString( (Date)pFieldValue ); |
690 |
|
- |
} |
691 |
|
- |
return pFieldValue.toString(); |
692 |
|
- |
} |
693 |
|
- |
|
694 |
|
- |
private Entity createIndexingEntity( String pKind, Object pFieldValue ) |
695 |
|
- |
{ |
696 |
|
- |
Entity zEntity = new Entity( pKind, createIndexKey( pFieldValue ), mGOD_Apollo ); |
697 |
|
- |
zEntity.setProperty( "FieldValue", pFieldValue ); |
698 |
|
- |
return zEntity; |
699 |
|
- |
} |
700 |
|
- |
|
701 |
|
- |
private void validate( Entity pEntity, Object pExpectedFieldValue ) |
702 |
|
- |
{ |
703 |
|
- |
validate( pEntity, createIndexKey( pExpectedFieldValue ), pExpectedFieldValue ); |
704 |
|
- |
} |
705 |
|
- |
|
706 |
|
- |
private void validate( Entity pEntity, String pExpectedKey, Object pExpectedFieldValue ) |
707 |
|
- |
{ |
708 |
|
- |
assertEquals( "Entity Key", pExpectedKey, pEntity.getKey().getName() ); |
709 |
|
- |
Object zFieldValue = pEntity.getProperty( "FieldValue" ); |
710 |
|
- |
if ( pExpectedFieldValue == null ) |
711 |
|
- |
{ |
712 |
|
- |
assertNull( "FieldValue", zFieldValue ); |
713 |
|
- |
} |
714 |
|
- |
else |
715 |
|
- |
{ |
716 |
|
- |
assertEquals( "Entity FieldValue", pExpectedFieldValue, zFieldValue ); |
717 |
|
- |
assertEquals( "Entity FieldValue Class", pExpectedFieldValue.getClass(), zFieldValue.getClass() ); |
718 |
|
- |
} |
719 |
|
- |
} |
720 |
|
- |
|
721 |
|
- |
private Entity readAndValidate( Transaction pTransaction, Entity pEntity, String pName, long pCurrentVersion, long pCurrentChildren ) |
722 |
|
- |
throws EntityNotFoundException |
723 |
|
- |
{ |
724 |
|
- |
validate( pEntity, pName, pCurrentVersion, pCurrentChildren ); |
725 |
|
- |
|
726 |
|
- |
return readAndValidate2( pTransaction, pEntity, pName, pCurrentVersion, pCurrentChildren ); |
727 |
|
- |
} |
728 |
|
- |
|
729 |
|
- |
private void validate( Entity pEntity, String pName, long pCurrentVersion, long pCurrentChildren ) |
730 |
|
- |
{ |
731 |
|
- |
assertEquals( "Current Entity Version", pCurrentVersion, pEntity.getProperty( "Version" ) ); |
732 |
|
- |
assertEquals( "Current Entity Name", pName, pEntity.getProperty( "Name" ) ); |
733 |
|
- |
assertEquals( "Current Entity Children", pCurrentChildren, pEntity.getProperty( "Children" ) ); |
734 |
|
- |
} |
735 |
|
- |
|
736 |
|
- |
private Entity readAndValidate2( Transaction pTransaction, Entity pEntity, String pName, long pCurrentVersion, long pCurrentChildren ) |
737 |
|
- |
throws EntityNotFoundException |
738 |
|
- |
{ |
739 |
|
- |
Key zKey = pEntity.getKey(); |
740 |
|
- |
|
741 |
|
- |
return readAndValidate3( pTransaction, zKey, pName, pCurrentVersion, pCurrentChildren ); |
742 |
|
- |
} |
743 |
|
- |
|
744 |
|
- |
private Entity readAndValidate3( Transaction pTransaction, Key zKey, String pName, long pCurrentVersion, long pCurrentChildren ) |
745 |
|
- |
throws EntityNotFoundException |
746 |
|
- |
{ |
747 |
|
- |
assertEquals( "Key Kind", KIND, zKey.getKind() ); |
748 |
|
- |
assertEquals( "Key Name (Our Key Value)", pName, zKey.getName() ); |
749 |
|
- |
|
750 |
|
- |
Entity zEntity = mDatastoreService.get( pTransaction, zKey ); |
751 |
|
- |
|
752 |
|
- |
if ( pTransaction == null ) |
753 |
|
- |
{ |
754 |
|
- |
Object zVersion = zEntity.getProperty( "Version" ); |
755 |
|
- |
assertNotNull( "Read Entity Version", zVersion ); |
756 |
|
- |
if ( !zVersion.equals( pCurrentVersion ) ) |
757 |
|
- |
{ |
758 |
|
- |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
759 |
|
- |
zEntity = mDatastoreService.get( zTransaction, zKey ); |
760 |
|
- |
zTransaction.rollback(); |
761 |
|
- |
} |
762 |
|
- |
} |
763 |
|
- |
|
764 |
|
- |
assertEquals( "Read Entity Version", pCurrentVersion, zEntity.getProperty( "Version" ) ); |
765 |
|
- |
assertEquals( "Read Entity Name", pName, zEntity.getProperty( "Name" ) ); |
766 |
|
- |
assertEquals( "Read Entity Children", pCurrentChildren, zEntity.getProperty( "Children" ) ); |
|
31 |
+ |
public static TestSuite suite() |
|
32 |
+ |
{ |
|
33 |
+ |
return new TestSuite( DatastoreServiceTest.class ); |
|
34 |
+ |
} |
|
35 |
+ |
|
|
36 |
+ |
public DatastoreServiceTest( String name ) |
|
37 |
+ |
{ |
|
38 |
+ |
super( name ); |
|
39 |
+ |
} |
|
40 |
+ |
|
|
41 |
+ |
public static void main( String[] args ) |
|
42 |
+ |
{ |
|
43 |
+ |
junit.textui.TestRunner.run( suite() ); |
|
44 |
+ |
} |
|
45 |
+ |
|
|
46 |
+ |
@Override |
|
47 |
+ |
protected void setUp() throws Exception |
|
48 |
+ |
{ |
|
49 |
+ |
super.setUp(); |
|
50 |
+ |
mHelper.setUp(); |
|
51 |
+ |
mConfig = DatastoreServiceConfig.Builder.withDefaults() // Deadline=null, |
|
52 |
+ |
// ImplicitTransactionManagementPolicy=NONE, |
|
53 |
+ |
// ReadPolicy.Consistency=STRONG |
|
54 |
+ |
.deadline( 5 ); // Deadline=5 secs |
|
55 |
+ |
mDatastoreService = DatastoreServiceFactory.getDatastoreService( mConfig ); |
|
56 |
+ |
mGOD_Apollo = KeyFactory.createKey( "GODS", "Apollo" ); |
|
57 |
+ |
mGOD_Venus = KeyFactory.createKey( "GODS", "Venus" ); |
|
58 |
+ |
|
|
59 |
+ |
} |
|
60 |
+ |
|
|
61 |
+ |
@Override |
|
62 |
+ |
public void tearDown() |
|
63 |
+ |
{ |
|
64 |
+ |
mHelper.tearDown(); |
|
65 |
+ |
} |
|
66 |
+ |
|
|
67 |
+ |
private DatastoreServiceConfig mConfig; |
|
68 |
+ |
|
|
69 |
+ |
private DatastoreService mDatastoreService; |
|
70 |
+ |
|
|
71 |
+ |
private Key mGOD_Apollo, mGOD_Venus; |
|
72 |
+ |
|
|
73 |
+ |
private Entity createEntity( Key pGOD, String pName ) |
|
74 |
+ |
{ |
|
75 |
+ |
Entity zEntity = new Entity( KIND, pName, pGOD ); |
|
76 |
+ |
zEntity.setUnindexedProperty( "Version", 1L ); |
|
77 |
+ |
|
|
78 |
+ |
zEntity.setProperty( "Name", pName ); |
|
79 |
+ |
zEntity.setUnindexedProperty( "Children", 0L ); |
|
80 |
+ |
return zEntity; |
|
81 |
+ |
} |
|
82 |
+ |
|
|
83 |
+ |
private void inc( Entity pEntity, String pProperty ) |
|
84 |
+ |
{ |
|
85 |
+ |
Long zLong = (Long) pEntity.getProperty( pProperty ); |
|
86 |
+ |
pEntity.setUnindexedProperty( pProperty, zLong + 1 ); |
|
87 |
+ |
} |
|
88 |
+ |
|
|
89 |
+ |
private Entity updateChildren( Entity pEntity ) |
|
90 |
+ |
{ |
|
91 |
+ |
inc( pEntity, "Version" ); |
|
92 |
+ |
inc( pEntity, "Children" ); |
|
93 |
+ |
return pEntity; |
|
94 |
+ |
} |
|
95 |
+ |
|
|
96 |
+ |
public void test_DataStoreConfig() throws Exception |
|
97 |
+ |
{ |
|
98 |
+ |
assertEquals( 5.0d, mConfig.getDeadline(), 0.0001 ); |
|
99 |
+ |
assertEquals( ImplicitTransactionManagementPolicy.NONE, mConfig.getImplicitTransactionManagementPolicy() ); |
|
100 |
+ |
assertEquals( Consistency.STRONG, mConfig.getReadPolicy().getConsistency() ); |
|
101 |
+ |
} |
|
102 |
+ |
|
|
103 |
+ |
public void test_NonConflictingDifferentGodsOverlapingTransactionsNew() throws Exception |
|
104 |
+ |
{ |
|
105 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
106 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
107 |
+ |
|
|
108 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
109 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
110 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
111 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
112 |
+ |
|
|
113 |
+ |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
|
114 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
|
115 |
+ |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
|
116 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
|
117 |
+ |
|
|
118 |
+ |
zApolloTransaction.commit(); |
|
119 |
+ |
zVenusTransaction.commit(); |
|
120 |
+ |
|
|
121 |
+ |
readAndValidate( null, zEntityFred, "Fred", 1, 0 ); |
|
122 |
+ |
readAndValidate( null, zEntityWilma, "Wilma", 1, 0 ); |
|
123 |
+ |
|
|
124 |
+ |
readAndValidate( null, zEntityBarney, "Barney", 1, 0 ); |
|
125 |
+ |
readAndValidate( null, zEntityBetty, "Betty", 1, 0 ); |
|
126 |
+ |
} |
|
127 |
+ |
|
|
128 |
+ |
public void test_TransactionReadMultiGOD() throws Exception |
|
129 |
+ |
{ |
|
130 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
131 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
132 |
+ |
|
|
133 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
134 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
135 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
136 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
137 |
+ |
|
|
138 |
+ |
zApolloTransaction.commit(); |
|
139 |
+ |
zVenusTransaction.commit(); |
|
140 |
+ |
|
|
141 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
142 |
+ |
mDatastoreService.get( zTransaction, zEntityFred.getKey() ); // will |
|
143 |
+ |
// succeed! |
|
144 |
+ |
try |
|
145 |
+ |
{ |
|
146 |
+ |
mDatastoreService.get( zTransaction, zEntityWilma.getKey() ); // will |
|
147 |
+ |
// Fail! |
|
148 |
+ |
fail( "Fred & Wilma - Did NOT Fail with different GODS (Entity Groups)" ); |
|
149 |
+ |
} |
|
150 |
+ |
catch ( IllegalArgumentException expected ) |
|
151 |
+ |
{ |
|
152 |
+ |
String zMessage = expected.getMessage(); |
|
153 |
+ |
assertTrue( zMessage, zMessage |
|
154 |
+ |
.startsWith( "can't operate on multiple entity groups in a single transaction." ) ); |
|
155 |
+ |
} |
|
156 |
+ |
zTransaction.rollback(); |
|
157 |
+ |
} |
|
158 |
+ |
|
|
159 |
+ |
public void test_TransactionUpdate() throws Exception |
|
160 |
+ |
{ |
|
161 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
162 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
163 |
+ |
|
|
164 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
165 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
166 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
167 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
168 |
+ |
|
|
169 |
+ |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
|
170 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
|
171 |
+ |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
|
172 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
|
173 |
+ |
|
|
174 |
+ |
zApolloTransaction.commit(); |
|
175 |
+ |
zVenusTransaction.commit(); |
|
176 |
+ |
|
|
177 |
+ |
zVenusTransaction = mDatastoreService.beginTransaction(); |
|
178 |
+ |
|
|
179 |
+ |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
|
180 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
181 |
+ |
|
|
182 |
+ |
Entity zEntityPebbles = createEntity( mGOD_Venus, "Pebbles" ); |
|
183 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityPebbles ); |
|
184 |
+ |
|
|
185 |
+ |
// Can't Update Fred! |
|
186 |
+ |
|
|
187 |
+ |
zVenusTransaction.commit(); |
|
188 |
+ |
|
|
189 |
+ |
zApolloTransaction = mDatastoreService.beginTransaction(); |
|
190 |
+ |
|
|
191 |
+ |
zEntityBarney = updateChildren( readAndValidate( zApolloTransaction, zEntityBarney, "Barney", 1, 0 ) ); |
|
192 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
|
193 |
+ |
|
|
194 |
+ |
Entity zEntityBammBamm = createEntity( mGOD_Apollo, "BammBamm" ); |
|
195 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBammBamm ); |
|
196 |
+ |
|
|
197 |
+ |
// Can't Update Betty! |
|
198 |
+ |
|
|
199 |
+ |
zApolloTransaction.commit(); |
|
200 |
+ |
|
|
201 |
+ |
readAndValidate( null, zEntityFred, "Fred", 1, 0 ); |
|
202 |
+ |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
|
203 |
+ |
readAndValidate( null, zEntityPebbles, "Pebbles", 1, 0 ); |
|
204 |
+ |
|
|
205 |
+ |
readAndValidate( null, zEntityBarney, "Barney", 2, 1 ); |
|
206 |
+ |
readAndValidate( null, zEntityBetty, "Betty", 1, 0 ); |
|
207 |
+ |
readAndValidate( null, zEntityBammBamm, "BammBamm", 1, 0 ); |
|
208 |
+ |
} |
|
209 |
+ |
|
|
210 |
+ |
public void test_NonConflictingDifferentGodsOverlapingTransactionsUpdate() throws Exception |
|
211 |
+ |
{ |
|
212 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
213 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
214 |
+ |
|
|
215 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
216 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
217 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
218 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
219 |
+ |
|
|
220 |
+ |
zApolloTransaction.commit(); |
|
221 |
+ |
zVenusTransaction.commit(); |
|
222 |
+ |
|
|
223 |
+ |
zApolloTransaction = mDatastoreService.beginTransaction(); |
|
224 |
+ |
zVenusTransaction = mDatastoreService.beginTransaction(); |
|
225 |
+ |
|
|
226 |
+ |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
|
227 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
228 |
+ |
|
|
229 |
+ |
Entity zEntityPebbles = createEntity( mGOD_Venus, "Pebbles" ); |
|
230 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityPebbles ); |
|
231 |
+ |
|
|
232 |
+ |
zEntityFred = updateChildren( readAndValidate( zApolloTransaction, zEntityFred, "Fred", 1, 0 ) ); |
|
233 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
234 |
+ |
|
|
235 |
+ |
zApolloTransaction.commit(); |
|
236 |
+ |
zVenusTransaction.commit(); |
|
237 |
+ |
|
|
238 |
+ |
readAndValidate( null, zEntityFred, "Fred", 2, 1 ); |
|
239 |
+ |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
|
240 |
+ |
|
|
241 |
+ |
readAndValidate( null, zEntityPebbles, "Pebbles", 1, 0 ); |
|
242 |
+ |
} |
|
243 |
+ |
|
|
244 |
+ |
public void test_ConflictingSameEntityOverlapingTransactionsUpdate() throws Exception |
|
245 |
+ |
{ |
|
246 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
247 |
+ |
|
|
248 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
249 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
250 |
+ |
|
|
251 |
+ |
zVenusTransaction.commit(); |
|
252 |
+ |
|
|
253 |
+ |
zVenusTransaction = mDatastoreService.beginTransaction(); |
|
254 |
+ |
|
|
255 |
+ |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
|
256 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
257 |
+ |
|
|
258 |
+ |
Entity zEntityPebbles = createEntity( mGOD_Venus, "Pebbles" ); |
|
259 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityPebbles ); |
|
260 |
+ |
|
|
261 |
+ |
Transaction zVenus2Transaction = mDatastoreService.beginTransaction(); |
|
262 |
+ |
|
|
263 |
+ |
Entity zEntityWilma2 = updateChildren( readAndValidate2( zVenus2Transaction, zEntityWilma, "Wilma", 1, 0 ) ); |
|
264 |
+ |
mDatastoreService.put( zVenus2Transaction, zEntityWilma2 ); |
|
265 |
+ |
|
|
266 |
+ |
zVenusTransaction.commit(); |
|
267 |
+ |
|
|
268 |
+ |
try |
|
269 |
+ |
{ |
|
270 |
+ |
zVenus2Transaction.commit(); |
|
271 |
+ |
fail( "Two Transaction Wilma Update - Did NOT Fail" ); |
|
272 |
+ |
} |
|
273 |
+ |
catch ( ConcurrentModificationException expected ) |
|
274 |
+ |
{ |
|
275 |
+ |
String zMessage = expected.getMessage(); |
|
276 |
+ |
assertTrue( zMessage, zMessage.startsWith( "too much contention on these datastore entities. please try again." ) ); |
|
277 |
+ |
} |
|
278 |
+ |
|
|
279 |
+ |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
|
280 |
+ |
} |
|
281 |
+ |
|
|
282 |
+ |
public void test_NonConflictingSameGodDifferentEntityOverlapingTransactionsUpdate() throws Exception |
|
283 |
+ |
{ |
|
284 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
285 |
+ |
|
|
286 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
287 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
288 |
+ |
|
|
289 |
+ |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
|
290 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
|
291 |
+ |
|
|
292 |
+ |
zVenusTransaction.commit(); |
|
293 |
+ |
|
|
294 |
+ |
zVenusTransaction = mDatastoreService.beginTransaction(); |
|
295 |
+ |
|
|
296 |
+ |
zEntityWilma = updateChildren( readAndValidate( zVenusTransaction, zEntityWilma, "Wilma", 1, 0 ) ); |
|
297 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
298 |
+ |
|
|
299 |
+ |
Transaction zVenus2Transaction = mDatastoreService.beginTransaction(); |
|
300 |
+ |
|
|
301 |
+ |
zEntityBetty = updateChildren( readAndValidate( zVenus2Transaction, zEntityBetty, "Betty", 1, 0 ) ); |
|
302 |
+ |
mDatastoreService.put( zVenus2Transaction, zEntityBetty ); |
|
303 |
+ |
|
|
304 |
+ |
zVenusTransaction.commit(); |
|
305 |
+ |
|
|
306 |
+ |
try |
|
307 |
+ |
{ |
|
308 |
+ |
zVenus2Transaction.commit(); |
|
309 |
+ |
fail( "Two Transaction Wilma & Betty Update - Did NOT Fail" ); |
|
310 |
+ |
} |
|
311 |
+ |
catch ( ConcurrentModificationException expected ) |
|
312 |
+ |
{ |
|
313 |
+ |
String zMessage = expected.getMessage(); |
|
314 |
+ |
assertTrue( zMessage, zMessage.startsWith( "too much contention on these datastore entities. please try again." ) ); |
|
315 |
+ |
} |
|
316 |
+ |
|
|
317 |
+ |
readAndValidate( null, zEntityWilma, "Wilma", 2, 1 ); |
|
318 |
+ |
readAndValidate2( null, zEntityBetty, "Betty", 1, 0 ); |
|
319 |
+ |
} |
|
320 |
+ |
|
|
321 |
+ |
public void test_QueryAllDifferentGods() throws Exception |
|
322 |
+ |
{ |
|
323 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
324 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
325 |
+ |
|
|
326 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
327 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
328 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
329 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
330 |
+ |
|
|
331 |
+ |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
|
332 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
|
333 |
+ |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
|
334 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
|
335 |
+ |
|
|
336 |
+ |
zApolloTransaction.commit(); |
|
337 |
+ |
zVenusTransaction.commit(); |
|
338 |
+ |
|
|
339 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND ).addSort( "Name" ) ); |
|
340 |
+ |
|
|
341 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
342 |
+ |
|
|
343 |
+ |
assertEquals( "Entities", 4, zList.size() ); |
|
344 |
+ |
|
|
345 |
+ |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
|
346 |
+ |
validate( zList.get( 1 ), "Betty", 1, 0 ); |
|
347 |
+ |
validate( zList.get( 2 ), "Fred", 1, 0 ); |
|
348 |
+ |
validate( zList.get( 3 ), "Wilma", 1, 0 ); |
|
349 |
+ |
} |
|
350 |
+ |
|
|
351 |
+ |
public void test_QuerySpecificGod() throws Exception |
|
352 |
+ |
{ |
|
353 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
354 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
355 |
+ |
|
|
356 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
357 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
358 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
359 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
360 |
+ |
|
|
361 |
+ |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
|
362 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
|
363 |
+ |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
|
364 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
|
365 |
+ |
|
|
366 |
+ |
zApolloTransaction.commit(); |
|
367 |
+ |
zVenusTransaction.commit(); |
|
368 |
+ |
|
|
369 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND, mGOD_Apollo ).addSort( "Name" ) ); |
|
370 |
+ |
|
|
371 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
372 |
+ |
|
|
373 |
+ |
assertEquals( "Entities", 2, zList.size() ); |
|
374 |
+ |
|
|
375 |
+ |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
|
376 |
+ |
validate( zList.get( 1 ), "Fred", 1, 0 ); |
|
377 |
+ |
} |
|
378 |
+ |
|
|
379 |
+ |
public void test_QueryEqualsFilter() throws Exception |
|
380 |
+ |
{ |
|
381 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
382 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
383 |
+ |
|
|
384 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
385 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
386 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
387 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
388 |
+ |
|
|
389 |
+ |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
|
390 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
|
391 |
+ |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
|
392 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
|
393 |
+ |
|
|
394 |
+ |
zApolloTransaction.commit(); |
|
395 |
+ |
zVenusTransaction.commit(); |
|
396 |
+ |
|
|
397 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND ).addSort( "Name" ).addFilter( "Name", Query.FilterOperator.EQUAL, "Barney") ); |
|
398 |
+ |
|
|
399 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
400 |
+ |
|
|
401 |
+ |
assertEquals( "Entities", 1, zList.size() ); |
|
402 |
+ |
|
|
403 |
+ |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
|
404 |
+ |
} |
|
405 |
+ |
|
|
406 |
+ |
public void test_QueryLessThanFilter() throws Exception |
|
407 |
+ |
{ |
|
408 |
+ |
Transaction zApolloTransaction = mDatastoreService.beginTransaction(); |
|
409 |
+ |
Transaction zVenusTransaction = mDatastoreService.beginTransaction(); |
|
410 |
+ |
|
|
411 |
+ |
Entity zEntityFred = createEntity( mGOD_Apollo, "Fred" ); |
|
412 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityFred ); |
|
413 |
+ |
Entity zEntityWilma = createEntity( mGOD_Venus, "Wilma" ); |
|
414 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityWilma ); |
|
415 |
+ |
|
|
416 |
+ |
Entity zEntityBarney = createEntity( mGOD_Apollo, "Barney" ); |
|
417 |
+ |
mDatastoreService.put( zApolloTransaction, zEntityBarney ); |
|
418 |
+ |
Entity zEntityBetty = createEntity( mGOD_Venus, "Betty" ); |
|
419 |
+ |
mDatastoreService.put( zVenusTransaction, zEntityBetty ); |
|
420 |
+ |
|
|
421 |
+ |
zApolloTransaction.commit(); |
|
422 |
+ |
zVenusTransaction.commit(); |
|
423 |
+ |
|
|
424 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( KIND ).addSort( "Name" ).addFilter( "Name", Query.FilterOperator.LESS_THAN, "C") ); |
|
425 |
+ |
|
|
426 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
427 |
+ |
|
|
428 |
+ |
assertEquals( "Entities", 2, zList.size() ); |
|
429 |
+ |
|
|
430 |
+ |
validate( zList.get( 0 ), "Barney", 1, 0 ); |
|
431 |
+ |
validate( zList.get( 1 ), "Betty", 1, 0 ); |
|
432 |
+ |
} |
|
433 |
+ |
|
|
434 |
+ |
public void test_NullKey() throws Exception |
|
435 |
+ |
{ |
|
436 |
+ |
try |
|
437 |
+ |
{ |
|
438 |
+ |
KeyFactory.createKey( KIND, null ); |
|
439 |
+ |
fail( "null Key did NOT fail" ); |
|
440 |
+ |
} |
|
441 |
+ |
catch ( IllegalArgumentException expected ) |
|
442 |
+ |
{ |
|
443 |
+ |
String zMessage = expected.getMessage(); |
|
444 |
+ |
assertTrue( zMessage, zMessage.startsWith( "name cannot be null or empty" ) ); |
|
445 |
+ |
} |
|
446 |
+ |
// new Entity( KIND, null, pGOD ); // Does Not Fail, but |
|
447 |
+ |
// implicitly creates a auto-generated id key!! |
|
448 |
+ |
} |
|
449 |
+ |
|
|
450 |
+ |
public void test_EmptyKey() throws Exception |
|
451 |
+ |
{ |
|
452 |
+ |
try |
|
453 |
+ |
{ |
|
454 |
+ |
KeyFactory.createKey( KIND, "" ); |
|
455 |
+ |
fail( "empty Key did NOT fail" ); |
|
456 |
+ |
} |
|
457 |
+ |
catch ( IllegalArgumentException expected ) |
|
458 |
+ |
{ |
|
459 |
+ |
String zMessage = expected.getMessage(); |
|
460 |
+ |
assertTrue( zMessage, zMessage.startsWith( "name cannot be null or empty" ) ); |
|
461 |
+ |
} |
|
462 |
+ |
} |
|
463 |
+ |
|
|
464 |
+ |
public void test_IndexingString() throws Exception |
|
465 |
+ |
{ |
|
466 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
467 |
+ |
|
|
468 |
+ |
String v1, v2; |
|
469 |
+ |
|
|
470 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Strings", null ) ); |
|
471 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Strings", v1 = "" ) ); |
|
472 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Strings", v2 = "Fred" ) ); |
|
473 |
+ |
|
|
474 |
+ |
zTransaction.commit(); |
|
475 |
+ |
|
|
476 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Strings" ).addSort( "FieldValue" ) ); |
|
477 |
+ |
|
|
478 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
479 |
+ |
|
|
480 |
+ |
assertEquals( "Entities", 3, zList.size() ); |
|
481 |
+ |
|
|
482 |
+ |
validate( zList.get( 0 ), null ); |
|
483 |
+ |
validate( zList.get( 1 ), v1 ); |
|
484 |
+ |
validate( zList.get( 2 ), v2 ); |
|
485 |
+ |
} |
|
486 |
+ |
|
|
487 |
+ |
public void test_IndexingBoolean() throws Exception |
|
488 |
+ |
{ |
|
489 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
490 |
+ |
|
|
491 |
+ |
Boolean v1, v2; |
|
492 |
+ |
|
|
493 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Booleans", null ) ); |
|
494 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Booleans", v1 = Boolean.FALSE ) ); |
|
495 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Booleans", v2 = Boolean.TRUE ) ); |
|
496 |
+ |
|
|
497 |
+ |
zTransaction.commit(); |
|
498 |
+ |
|
|
499 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Booleans" ).addSort( "FieldValue" ) ); |
|
500 |
+ |
|
|
501 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
502 |
+ |
|
|
503 |
+ |
assertEquals( "Entities", 3, zList.size() ); |
|
504 |
+ |
|
|
505 |
+ |
validate( zList.get( 0 ), null ); |
|
506 |
+ |
validate( zList.get( 1 ), v1 ); |
|
507 |
+ |
validate( zList.get( 2 ), v2 ); |
|
508 |
+ |
} |
|
509 |
+ |
|
|
510 |
+ |
public void test_IndexingLong() throws Exception |
|
511 |
+ |
{ |
|
512 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
513 |
+ |
|
|
514 |
+ |
Long v1, v2; |
|
515 |
+ |
|
|
516 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Longs", null ) ); |
|
517 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Longs", v1 = 1L ) ); |
|
518 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Longs", v2 = 100L ) ); |
|
519 |
+ |
|
|
520 |
+ |
zTransaction.commit(); |
|
521 |
+ |
|
|
522 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Longs" ).addSort( "FieldValue" ) ); |
|
523 |
+ |
|
|
524 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
525 |
+ |
|
|
526 |
+ |
assertEquals( "Entities", 3, zList.size() ); |
|
527 |
+ |
|
|
528 |
+ |
validate( zList.get( 0 ), null ); |
|
529 |
+ |
validate( zList.get( 1 ), v1 ); |
|
530 |
+ |
validate( zList.get( 2 ), v2 ); |
|
531 |
+ |
} |
|
532 |
+ |
|
|
533 |
+ |
public void test_IndexingDouble() throws Exception |
|
534 |
+ |
{ |
|
535 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
536 |
+ |
|
|
537 |
+ |
Double v1, v2; |
|
538 |
+ |
|
|
539 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Doubles", null ) ); |
|
540 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Doubles", v1 = 1.1D ) ); |
|
541 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Doubles", v2 = 11.2D ) ); |
|
542 |
+ |
|
|
543 |
+ |
zTransaction.commit(); |
|
544 |
+ |
|
|
545 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Doubles" ).addSort( "FieldValue" ) ); |
|
546 |
+ |
|
|
547 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
548 |
+ |
|
|
549 |
+ |
assertEquals( "Entities", 3, zList.size() ); |
|
550 |
+ |
|
|
551 |
+ |
validate( zList.get( 0 ), null ); |
|
552 |
+ |
validate( zList.get( 1 ), v1 ); |
|
553 |
+ |
validate( zList.get( 2 ), v2 ); |
|
554 |
+ |
} |
|
555 |
+ |
|
|
556 |
+ |
public void test_IndexingDate() throws Exception |
|
557 |
+ |
{ |
|
558 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
559 |
+ |
|
|
560 |
+ |
Date v1, v2; |
|
561 |
+ |
|
|
562 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Dates", null ) ); |
|
563 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Dates", v1 = createDate( 1957, 1, 4, 11, 12, 13, 14 ) ) ); |
|
564 |
+ |
mDatastoreService.put( zTransaction, createIndexingEntity( "Dates", v2 = createDate( 2000, 2, 29, 0, 0, 0, 0 ) ) ); |
|
565 |
+ |
|
|
566 |
+ |
zTransaction.commit(); |
|
567 |
+ |
|
|
568 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "Dates" ).addSort( "FieldValue" ) ); |
|
569 |
+ |
|
|
570 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
571 |
+ |
|
|
572 |
+ |
assertEquals( "Entities", 3, zList.size() ); |
|
573 |
+ |
|
|
574 |
+ |
validate( zList.get( 0 ), null ); |
|
575 |
+ |
validate( zList.get( 1 ), v1 ); |
|
576 |
+ |
validate( zList.get( 2 ), v2 ); |
|
577 |
+ |
} |
|
578 |
+ |
|
|
579 |
+ |
public void test_LargeCollections() throws Exception |
|
580 |
+ |
{ |
|
581 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
582 |
+ |
|
|
583 |
+ |
long zMaxLongsThatWork = 62645L; |
|
584 |
+ |
|
|
585 |
+ |
Entity zEntity; |
|
586 |
+ |
Set<Long> zLongs; |
|
587 |
+ |
|
|
588 |
+ |
try |
|
589 |
+ |
{ |
|
590 |
+ |
zLongs = createLongs( zMaxLongsThatWork + 1 ); // Too Big! |
|
591 |
+ |
|
|
592 |
+ |
zEntity = new Entity( "LargeCollections", "Test" ); |
|
593 |
+ |
zEntity.setProperty( "FieldValue", "Test" ); |
|
594 |
+ |
zEntity.setUnindexedProperty( "Longs", zLongs ); |
|
595 |
+ |
|
|
596 |
+ |
mDatastoreService.put( zTransaction, zEntity ); |
|
597 |
+ |
|
|
598 |
+ |
fail( "Too Many did not fail w/ too large" ); |
|
599 |
+ |
} |
|
600 |
+ |
catch ( Exception expected ) |
|
601 |
+ |
{ |
|
602 |
+ |
assertNotNull( expected ); // com.google.apphosting.api.ApiProxy$RequestTooLargeException: The request to API call datastore_v3.Put() was too large. |
|
603 |
+ |
} |
|
604 |
+ |
zLongs = createLongs( zMaxLongsThatWork ); // Just Small Enough! |
|
605 |
+ |
|
|
606 |
+ |
zEntity = new Entity( "LargeCollections", "Test" ); |
|
607 |
+ |
zEntity.setProperty( "FieldValue", "Test" ); |
|
608 |
+ |
zEntity.setUnindexedProperty( "Longs", zLongs ); |
|
609 |
+ |
|
|
610 |
+ |
mDatastoreService.put( zTransaction, zEntity ); |
|
611 |
+ |
|
|
612 |
+ |
zTransaction.commit(); |
|
613 |
+ |
|
|
614 |
+ |
PreparedQuery zQuery = mDatastoreService.prepare( new Query( "LargeCollections" ).addSort( "FieldValue" ) ); |
|
615 |
+ |
|
|
616 |
+ |
List<Entity> zList = zQuery.asList( FetchOptions.Builder.withOffset( 0 ) ); |
|
617 |
+ |
|
|
618 |
+ |
assertEquals( "Entities", 1, zList.size() ); |
|
619 |
+ |
|
|
620 |
+ |
zEntity = zList.get( 0 ); |
|
621 |
+ |
|
|
622 |
+ |
assertEquals( "FieldValue", "Test", zEntity.getProperty( "FieldValue" ) ); |
|
623 |
+ |
|
|
624 |
+ |
validate( zLongs, zEntity.getProperty( "Longs" ) ); |
|
625 |
+ |
} |
|
626 |
+ |
|
|
627 |
+ |
private Set<Long> createLongs( long pLongsToCreate ) |
|
628 |
+ |
{ |
|
629 |
+ |
HashSet<Long> zSet = new HashSet<Long>(); |
|
630 |
+ |
while ( --pLongsToCreate >= 0 ) |
|
631 |
+ |
{ |
|
632 |
+ |
zSet.add( pLongsToCreate ); |
|
633 |
+ |
} |
|
634 |
+ |
return zSet; |
|
635 |
+ |
} |
|
636 |
+ |
|
|
637 |
+ |
@SuppressWarnings("unchecked") |
|
638 |
+ |
private void validate( Set<Long> zExpected, Object pFieldValue ) |
|
639 |
+ |
{ |
|
640 |
+ |
List<Long> zReadList = (List<Long>)pFieldValue; |
|
641 |
+ |
for (Long zLong : zReadList) |
|
642 |
+ |
{ |
|
643 |
+ |
if ( !zExpected.remove( zLong ) ) |
|
644 |
+ |
{ |
|
645 |
+ |
fail( "Found value (" + zLong + "), not written" ); |
|
646 |
+ |
} |
|
647 |
+ |
} |
|
648 |
+ |
if ( !zExpected.isEmpty() ) |
|
649 |
+ |
{ |
|
650 |
+ |
fail( "Did NOT read: " + zExpected ); |
|
651 |
+ |
} |
|
652 |
+ |
} |
|
653 |
+ |
|
|
654 |
+ |
@SuppressWarnings("deprecation") |
|
655 |
+ |
private Date createDate( int pYear, int pMonth, int pDay, int pHour, int pMin, int pSec, int pMilliSecs ) |
|
656 |
+ |
{ |
|
657 |
+ |
Date zDate = new Date( pYear - 1900, pMonth - 1, pDay, pHour, pMin, pSec ); |
|
658 |
+ |
if ( pMilliSecs != 0 ) |
|
659 |
+ |
{ |
|
660 |
+ |
zDate = new Date( zDate.getTime() + pMilliSecs ); |
|
661 |
+ |
} |
|
662 |
+ |
return zDate; |
|
663 |
+ |
} |
|
664 |
+ |
|
|
665 |
+ |
@SuppressWarnings("deprecation") |
|
666 |
+ |
private String simpleDateToString( Date pDate ) |
|
667 |
+ |
{ |
|
668 |
+ |
int zYear = pDate.getYear() + 1900; |
|
669 |
+ |
int zMonth = pDate.getMonth() + 1; |
|
670 |
+ |
int zDay = pDate.getDate(); |
|
671 |
+ |
int zHour = pDate.getHours(); |
|
672 |
+ |
int zMin = pDate.getMinutes(); |
|
673 |
+ |
int zSec = pDate.getSeconds(); |
|
674 |
+ |
int zMilliSecs = (int)(pDate.getTime() - new Date( zYear - 1900, zMonth - 1, zDay, zHour, zMin, zSec ).getTime()); |
|
675 |
+ |
return "" + zYear + "/" + zMonth + "/" + zDay + "-" + zHour + ":" + zMin + ":" + zSec + "." + zMilliSecs; |
|
676 |
+ |
} |
|
677 |
+ |
|
|
678 |
+ |
private String createIndexKey( Object pFieldValue ) |
|
679 |
+ |
{ |
|
680 |
+ |
if ( pFieldValue == null ) |
|
681 |
+ |
{ |
|
682 |
+ |
return " "; |
|
683 |
+ |
} |
|
684 |
+ |
if ( pFieldValue instanceof String ) |
|
685 |
+ |
{ |
|
686 |
+ |
return pFieldValue + " "; |
|
687 |
+ |
} |
|
688 |
+ |
if ( pFieldValue instanceof Date ) |
|
689 |
+ |
{ |
|
690 |
+ |
return simpleDateToString( (Date)pFieldValue ); |
|
691 |
+ |
} |
|
692 |
+ |
return pFieldValue.toString(); |
|
693 |
+ |
} |
|
694 |
+ |
|
|
695 |
+ |
private Entity createIndexingEntity( String pKind, Object pFieldValue ) |
|
696 |
+ |
{ |
|
697 |
+ |
Entity zEntity = new Entity( pKind, createIndexKey( pFieldValue ), mGOD_Apollo ); |
|
698 |
+ |
zEntity.setProperty( "FieldValue", pFieldValue ); |
|
699 |
+ |
return zEntity; |
|
700 |
+ |
} |
|
701 |
+ |
|
|
702 |
+ |
private void validate( Entity pEntity, Object pExpectedFieldValue ) |
|
703 |
+ |
{ |
|
704 |
+ |
validate( pEntity, createIndexKey( pExpectedFieldValue ), pExpectedFieldValue ); |
|
705 |
+ |
} |
|
706 |
+ |
|
|
707 |
+ |
private void validate( Entity pEntity, String pExpectedKey, Object pExpectedFieldValue ) |
|
708 |
+ |
{ |
|
709 |
+ |
assertEquals( "Entity Key", pExpectedKey, pEntity.getKey().getName() ); |
|
710 |
+ |
Object zFieldValue = pEntity.getProperty( "FieldValue" ); |
|
711 |
+ |
if ( pExpectedFieldValue == null ) |
|
712 |
+ |
{ |
|
713 |
+ |
assertNull( "FieldValue", zFieldValue ); |
|
714 |
+ |
} |
|
715 |
+ |
else |
|
716 |
+ |
{ |
|
717 |
+ |
assertEquals( "Entity FieldValue", pExpectedFieldValue, zFieldValue ); |
|
718 |
+ |
assertEquals( "Entity FieldValue Class", pExpectedFieldValue.getClass(), zFieldValue.getClass() ); |
|
719 |
+ |
} |
|
720 |
+ |
} |
|
721 |
+ |
|
|
722 |
+ |
private Entity readAndValidate( Transaction pTransaction, Entity pEntity, String pName, long pCurrentVersion, long pCurrentChildren ) |
|
723 |
+ |
throws EntityNotFoundException |
|
724 |
+ |
{ |
|
725 |
+ |
validate( pEntity, pName, pCurrentVersion, pCurrentChildren ); |
|
726 |
+ |
|
|
727 |
+ |
return readAndValidate2( pTransaction, pEntity, pName, pCurrentVersion, pCurrentChildren ); |
|
728 |
+ |
} |
|
729 |
+ |
|
|
730 |
+ |
private void validate( Entity pEntity, String pName, long pCurrentVersion, long pCurrentChildren ) |
|
731 |
+ |
{ |
|
732 |
+ |
assertEquals( "Current Entity Version", pCurrentVersion, pEntity.getProperty( "Version" ) ); |
|
733 |
+ |
assertEquals( "Current Entity Name", pName, pEntity.getProperty( "Name" ) ); |
|
734 |
+ |
assertEquals( "Current Entity Children", pCurrentChildren, pEntity.getProperty( "Children" ) ); |
|
735 |
+ |
} |
|
736 |
+ |
|
|
737 |
+ |
private Entity readAndValidate2( Transaction pTransaction, Entity pEntity, String pName, long pCurrentVersion, long pCurrentChildren ) |
|
738 |
+ |
throws EntityNotFoundException |
|
739 |
+ |
{ |
|
740 |
+ |
Key zKey = pEntity.getKey(); |
|
741 |
+ |
|
|
742 |
+ |
return readAndValidate3( pTransaction, zKey, pName, pCurrentVersion, pCurrentChildren ); |
|
743 |
+ |
} |
|
744 |
+ |
|
|
745 |
+ |
private Entity readAndValidate3( Transaction pTransaction, Key zKey, String pName, long pCurrentVersion, long pCurrentChildren ) |
|
746 |
+ |
throws EntityNotFoundException |
|
747 |
+ |
{ |
|
748 |
+ |
assertEquals( "Key Kind", KIND, zKey.getKind() ); |
|
749 |
+ |
assertEquals( "Key Name (Our Key Value)", pName, zKey.getName() ); |
|
750 |
+ |
|
|
751 |
+ |
Entity zEntity = mDatastoreService.get( pTransaction, zKey ); |
|
752 |
+ |
|
|
753 |
+ |
if ( pTransaction == null ) |
|
754 |
+ |
{ |
|
755 |
+ |
Object zVersion = zEntity.getProperty( "Version" ); |
|
756 |
+ |
assertNotNull( "Read Entity Version", zVersion ); |
|
757 |
+ |
if ( !zVersion.equals( pCurrentVersion ) ) |
|
758 |
+ |
{ |
|
759 |
+ |
Transaction zTransaction = mDatastoreService.beginTransaction(); |
|
760 |
+ |
zEntity = mDatastoreService.get( zTransaction, zKey ); |
|
761 |
+ |
zTransaction.rollback(); |
|
762 |
+ |
} |
|
763 |
+ |
} |
|
764 |
+ |
|
|
765 |
+ |
assertEquals( "Read Entity Version", pCurrentVersion, zEntity.getProperty( "Version" ) ); |
|
766 |
+ |
assertEquals( "Read Entity Name", pName, zEntity.getProperty( "Name" ) ); |
|
767 |
+ |
assertEquals( "Read Entity Children", pCurrentChildren, zEntity.getProperty( "Children" ) ); |
767 |
768 |
|
|
768 |
|
- |
return zEntity; |
769 |
|
- |
} |
|
769 |
+ |
return zEntity; |
|
770 |
+ |
} |
770 |
771 |
|
} |