001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.entity.test;
019:
020: import java.sql.Timestamp;
021: import java.util.ArrayList;
022: import java.util.Iterator;
023: import java.util.LinkedList;
024: import java.util.List;
025: import java.util.Map;
026: import java.lang.Thread;
027:
028: import junit.framework.TestCase;
029:
030: import org.ofbiz.base.util.Debug;
031: import org.ofbiz.base.util.UtilDateTime;
032: import org.ofbiz.base.util.UtilMisc;
033: import org.ofbiz.entity.GenericDelegator;
034: import org.ofbiz.entity.GenericEntity;
035: import org.ofbiz.entity.GenericEntityException;
036: import org.ofbiz.entity.GenericPK;
037: import org.ofbiz.entity.GenericValue;
038: import org.ofbiz.entity.condition.EntityCondition;
039: import org.ofbiz.entity.condition.EntityConditionList;
040: import org.ofbiz.entity.condition.EntityExpr;
041: import org.ofbiz.entity.condition.EntityOperator;
042: import org.ofbiz.entity.util.EntityFindOptions;
043: import org.ofbiz.entity.util.EntityListIterator;
044: import org.ofbiz.entity.transaction.GenericTransactionException;
045: import org.ofbiz.entity.transaction.TransactionUtil;
046:
047: public class EntityTestSuite extends TestCase {
048:
049: public static final String module = EntityTestSuite.class.getName();
050: public static final String DELEGATOR_NAME = "test";
051: public GenericDelegator delegator = null;
052: /*
053: * This sets how many values to insert when trying to create a large number of values. 10,000 causes HSQL to crash but is ok
054: * with Derby. Going up to 100,000 causes problems all around because Java List seems to be capped at about 65,000 values.
055: *
056: * NOTE: setting this lower so that the general tests don't take so long to run; to really push it can increase this number.
057: */
058: public static final long TEST_COUNT = 1000;
059:
060: public EntityTestSuite(String name) {
061: super (name);
062: }
063:
064: final static private int _level1max = 3; // number of TestingNode entities to create
065:
066: protected void setUp() throws Exception {
067: this .delegator = GenericDelegator
068: .getGenericDelegator(DELEGATOR_NAME);
069: }
070:
071: /*
072: * Tests storing values with the delegator's .create, .makeValue, and .storeAll methods
073: */
074: public void testMakeValue() throws Exception {
075: try {
076: // This method call directly stores a new value into the entity engine
077: delegator.create("TestingType", UtilMisc.toMap(
078: "testingTypeId", "TEST-1", "description",
079: "Testing Type #1"));
080:
081: // This sequence creates the GenericValue entities first, puts them in a List, then calls the delegator to store them all
082: List newValues = new LinkedList();
083:
084: newValues.add(delegator.makeValue("TestingType", UtilMisc
085: .toMap("testingTypeId", "TEST-2", "description",
086: "Testing Type #2")));
087: newValues.add(delegator.makeValue("TestingType", UtilMisc
088: .toMap("testingTypeId", "TEST-3", "description",
089: "Testing Type #3")));
090: newValues.add(delegator.makeValue("TestingType", UtilMisc
091: .toMap("testingTypeId", "TEST-4", "description",
092: "Testing Type #4")));
093: delegator.storeAll(newValues);
094:
095: // finds a List of newly created values. the second parameter specifies the fields to order results by.
096: List newlyCreatedValues = delegator.findAll("TestingType",
097: UtilMisc.toList("testingTypeId"));
098: TestCase.assertEquals("4 TestingTypes found", 4,
099: newlyCreatedValues.size());
100: } catch (GenericEntityException ex) {
101: TestCase.fail(ex.getMessage());
102: }
103: }
104:
105: /*
106: * Tests updating entities by doing a GenericValue .put(key, value) and .store()
107: */
108: public void testUpdateValue() throws Exception {
109: try {
110:
111: // retrieve a sample GenericValue, make sure it's correct
112: GenericValue testValue = delegator.findByPrimaryKey(
113: "TestingType", UtilMisc.toMap("testingTypeId",
114: "TEST-1"));
115: TestCase.assertEquals(
116: "Retrieved value has the correct description",
117: testValue.getString("description"),
118: "Testing Type #1");
119:
120: // now update and store it
121: testValue.put("description", "New Testing Type #1");
122: testValue.store();
123:
124: // now retrieve it again and make sure that the updated value is correct
125: testValue = delegator.findByPrimaryKey("TestingType",
126: UtilMisc.toMap("testingTypeId", "TEST-1"));
127: TestCase.assertEquals(
128: "Retrieved value has the correct description",
129: testValue.getString("description"),
130: "New Testing Type #1");
131:
132: } catch (GenericEntityException ex) {
133: TestCase.fail(ex.getMessage());
134: }
135: }
136:
137: /*
138: * Tests storing data with the delegator's .create method. Also tests .findCountByCondition and .getNextSeqId
139: */
140: public void testCreateTree() throws Exception {
141: try {
142: // get how many child nodes did we have before creating the tree
143: EntityCondition isChild = new EntityExpr(
144: "primaryParentNodeId", EntityOperator.NOT_EQUAL,
145: GenericEntity.NULL_FIELD);
146: long alreadyStored = delegator.findCountByCondition(
147: "TestingNode", isChild, null);
148:
149: //
150: // The tree has a root, the root has level1max children.
151: //
152:
153: // create the root
154: GenericValue root = delegator.create("TestingNode",
155: UtilMisc.toMap("testingNodeId", delegator
156: .getNextSeqId("testingNode"),
157: "primaryParentNodeId",
158: GenericEntity.NULL_FIELD, "description",
159: "root"));
160: int level1;
161: for (level1 = 0; level1 < _level1max; level1++) {
162: String nextSeqId = delegator
163: .getNextSeqId("testingNode");
164: GenericValue v = delegator.create("TestingNode",
165: UtilMisc.toMap("testingNodeId", nextSeqId,
166: "primaryParentNodeId", (String) root
167: .get("testingNodeId"),
168: "description", "node-level #1"));
169: }
170:
171: long created = level1;
172: long newlyStored = delegator.findCountByCondition(
173: "TestingNode", isChild, null);
174:
175: // Normally, newlyStored = alreadyStored + created
176: TestCase.assertEquals("Created/Stored Nodes", newlyStored,
177: created + alreadyStored);
178: } catch (GenericEntityException e) {
179: Debug.logInfo(e.getMessage(), module);
180: }
181: }
182:
183: /*
184: * More tests of storing data with .storeAll. Also prepares data for testing view-entities (see below.)
185: */
186: public void testAddMembersToTree() throws Exception {
187: // get the level1 nodes
188: EntityCondition isLevel1 = new EntityExpr(
189: "primaryParentNodeId", EntityOperator.NOT_EQUAL,
190: GenericEntity.NULL_FIELD);
191: List nodeLevel1 = delegator.findByCondition("TestingNode",
192: isLevel1, null, null);
193:
194: List newValues = new LinkedList();
195: Timestamp now = UtilDateTime.nowTimestamp();
196:
197: Iterator nodeIterator = nodeLevel1.iterator();
198: while (nodeIterator.hasNext()) {
199: GenericValue node = (GenericValue) nodeIterator.next();
200: GenericValue testing = delegator.makeValue("Testing",
201: UtilMisc.toMap("testingId", delegator
202: .getNextSeqId("Testing"), "testingTypeId",
203: "TEST-1"));
204: testing.put("testingName", "leaf-#"
205: + node.getString("testingNodeId"));
206: testing.put("description", "level1 leaf");
207: testing.put("comments", "No-comments");
208: testing.put("testingSize", new Long(10));
209: testing.put("testingDate", now);
210:
211: newValues.add(testing);
212: GenericValue member = delegator.makeValue(
213: "TestingNodeMember", UtilMisc.toMap(
214: "testingNodeId", node.get("testingNodeId"),
215: "testingId", testing.get("testingId")));
216:
217: member.put("fromDate", now);
218: member.put("thruDate", UtilDateTime.getNextDayStart(now));
219:
220: newValues.add(member);
221: }
222: int n = delegator.storeAll(newValues);
223: TestCase.assertEquals("Created/Stored Nodes", n, newValues
224: .size());
225: }
226:
227: /*
228: * Tests findByCondition and tests searching on a view-entity
229: */
230: public void testCountViews() throws Exception {
231: EntityCondition isNodeWithMember = new EntityExpr("testingId",
232: EntityOperator.NOT_EQUAL, GenericEntity.NULL_FIELD);
233: List nodeWithMembers = delegator.findByCondition(
234: "TestingNodeAndMember", isNodeWithMember, null, null);
235:
236: Iterator it;
237: it = nodeWithMembers.iterator();
238:
239: while (it.hasNext()) {
240: GenericValue v = (GenericValue) it.next();
241: Map fields = v.getAllFields();
242: Debug.logInfo("--------------------------", module);
243: // For values of a map
244: for (Iterator it1 = fields.keySet().iterator(); it1
245: .hasNext();) {
246: Object field = it1.next();
247: Object value = fields.get(field);
248: Debug.logInfo(field.toString()
249: + " = "
250: + ((value == null) ? "[null]" : value
251: .toString()), module);
252: }
253: }
254: long testingcount = delegator.findCountByCondition("Testing",
255: null, null);
256: TestCase
257: .assertEquals(
258: "Number of views should equal number of created entities in the test.",
259: nodeWithMembers.size(), testingcount);
260: }
261:
262: /*
263: * Tests findByCondition and a find by distinct
264: */
265: public void testFindDistinct() throws Exception {
266: List exprList = UtilMisc.toList(new EntityExpr("testingSize",
267: EntityOperator.EQUALS, new Long(10)), new EntityExpr(
268: "comments", EntityOperator.EQUALS, "No-comments"));
269: EntityConditionList condition = new EntityConditionList(
270: exprList, EntityOperator.AND);
271:
272: EntityFindOptions findOptions = new EntityFindOptions();
273: findOptions.setDistinct(true);
274:
275: List testingSize10 = delegator.findByCondition("Testing",
276: condition, null, UtilMisc.toList("testingSize",
277: "comments"), null, findOptions);
278: Debug.logInfo("testingSize10 is " + testingSize10.size(),
279: module);
280:
281: TestCase
282: .assertEquals(
283: "There should only be 1 result found by findDistinct()",
284: testingSize10.size(), 1);
285: }
286:
287: /*
288: * Tests a findByCondition using not like
289: */
290: public void testNotLike() throws Exception {
291: EntityCondition cond = new EntityExpr("description",
292: EntityOperator.NOT_LIKE, "root%");
293: List nodes = delegator.findByCondition("TestingNode", cond,
294: null, null);
295: TestCase.assertTrue("Found nodes", nodes != null);
296:
297: Iterator i = nodes.iterator();
298: while (i.hasNext()) {
299: GenericValue product = (GenericValue) i.next();
300: String nodeId = product.getString("description");
301: Debug.logInfo("Testing name - " + nodeId, module);
302: TestCase.assertTrue("No nodes starting w/ root", !nodeId
303: .startsWith("root"));
304: }
305: }
306:
307: /*
308: * Tests foreign key integrity by trying to remove an entity which has foreign-key dependencies. Should cause an exception.
309: */
310: public void testForeignKeyCreate() throws Exception {
311: try {
312: delegator.create("Testing", UtilMisc.toMap("testingId",
313: delegator.getNextSeqId("Testing"), "testingTypeId",
314: "NO-SUCH-KEY"));
315: } catch (GenericEntityException e) {
316: Debug.logInfo(e.toString(), module);
317: return;
318: }
319: TestCase
320: .fail("Foreign key referential integrity is not observed for create (INSERT)");
321: }
322:
323: /*
324: * Tests foreign key integrity by trying to remove an entity which has foreign-key dependencies. Should cause an exception.
325: */
326: public void testForeignKeyRemove() throws Exception {
327: try {
328: EntityCondition isLevel1 = new EntityExpr("description",
329: EntityOperator.EQUALS, "node-level #1");
330: delegator.removeByCondition("TestingNode", isLevel1);
331: } catch (GenericEntityException e) {
332: Debug.logInfo(e.toString(), module);
333: return;
334: }
335: TestCase
336: .fail("Foreign key referential integrity is not observed for remove (DELETE)");
337: }
338:
339: /*
340: * Tests the .getRelatedOne method and removeAll for removing entities
341: */
342: public void testRemoveNodeMemberAndTesting() throws Exception {
343: //
344: // Find the testing entities tru the node member and build a list of them
345: //
346: List values = delegator.findAll("TestingNodeMember");
347: Iterator i = values.iterator();
348:
349: ArrayList testings = new ArrayList();
350:
351: while (i.hasNext()) {
352: GenericValue nodeMember = (GenericValue) i.next();
353: testings.add(nodeMember.getRelatedOne("Testing"));
354: }
355: // and remove the nodeMember afterwards
356: delegator.removeAll(values);
357: values = delegator.findAll("TestingNodeMember");
358: TestCase.assertTrue("No more Node Member entities", values
359: .size() == 0);
360:
361: delegator.removeAll(testings);
362: values = delegator.findAll("Testing");
363: TestCase.assertTrue("No more Testing entities",
364: values.size() == 0);
365: }
366:
367: /*
368: * Tests the storeByCondition operation
369: */
370: public void testStoreByCondition() throws Exception {
371: // change the description of all the level1 nodes
372: EntityCondition isLevel1 = new EntityExpr("description",
373: EntityOperator.EQUALS, "node-level #1");
374: Map fieldsToSet = UtilMisc.toMap("description",
375: "node-level #1 (updated)");
376: int n = 0;
377: try {
378: delegator.storeByCondition("TestingNode", fieldsToSet,
379: isLevel1);
380: List updatedNodes = delegator.findByAnd("TestingNode",
381: fieldsToSet);
382: n = updatedNodes.size();
383: } catch (GenericEntityException e) {
384: TestCase.fail("testStoreByCondition threw an exception");
385: }
386:
387: TestCase.assertTrue("testStoreByCondition updated nodes > 0",
388: n > 0);
389: }
390:
391: /*
392: * Tests the .removeByCondition method for removing entities directly
393: */
394: public void testRemoveByCondition() throws Exception {
395: //
396: // remove all the level1 nodes by using a condition on the description field
397: //
398: EntityCondition isLevel1 = new EntityExpr("description",
399: EntityOperator.EQUALS, "node-level #1 (updated)");
400: int n = 0;
401:
402: try {
403: n = delegator.removeByCondition("TestingNode", isLevel1);
404: } catch (GenericEntityException e) {
405: TestCase.fail("testRemoveByCondition threw an exception");
406: }
407:
408: TestCase.assertTrue("testRemoveByCondition nodes > 0", n > 0);
409: }
410:
411: /*
412: * Test the .removeByPrimaryKey by using findByCondition and then retrieving the GenericPk from a GenericValue
413: */
414: public void testRemoveByPK() throws Exception {
415: //
416: // Find all the root nodes,
417: // delete them their primary key
418: //
419: EntityCondition isRoot = new EntityExpr("primaryParentNodeId",
420: EntityOperator.EQUALS, GenericEntity.NULL_FIELD);
421: List rootValues = delegator.findByCondition("TestingNode",
422: isRoot, UtilMisc.toList("testingNodeId"), null);
423:
424: Iterator it = rootValues.iterator();
425: while (it.hasNext()) {
426: GenericPK pk = ((GenericValue) it.next()).getPrimaryKey();
427: int del = delegator.removeByPrimaryKey(pk);
428: TestCase.assertEquals("Removing Root by primary key", del,
429: 1);
430: }
431:
432: // no more TestingNode should be in the data base anymore.
433:
434: List testingNodes = delegator.findAll("TestingNode");
435: TestCase.assertEquals(
436: "No more TestingNode after removing the roots",
437: testingNodes.size(), 0);
438: }
439:
440: /*
441: * Tests the .removeAll method only.
442: */
443: public void testRemoveType() throws Exception {
444: List values = delegator.findAll("TestingType");
445: delegator.removeAll(values);
446:
447: // now make sure there are no more of these
448: values = delegator.findAll("TestingType");
449: TestCase.assertEquals("No more TestingTypes after remove all",
450: values.size(), 0);
451: }
452:
453: /*
454: * This test will create a large number of unique items and add them to the delegator at once
455: */
456: public void testCreateManyAndStoreAtOnce() throws Exception {
457: try {
458: List newValues = new LinkedList();
459: for (int i = 0; i < TEST_COUNT; i++) {
460: newValues.add(delegator.makeValue("Testing", UtilMisc
461: .toMap("testingId", getTestId("T1-", i))));
462: }
463: delegator.storeAll(newValues);
464: List newlyCreatedValues = delegator.findAll("Testing",
465: UtilMisc.toList("testingId"));
466: TestCase.assertEquals("Test to create " + TEST_COUNT
467: + " and store all at once", TEST_COUNT,
468: newlyCreatedValues.size());
469: } catch (GenericEntityException e) {
470: assertTrue("GenericEntityException:" + e.toString(), false);
471: return;
472: } finally {
473: List newlyCreatedValues = delegator.findAll("Testing",
474: UtilMisc.toList("testingId"));
475: delegator.removeAll(newlyCreatedValues);
476: }
477: }
478:
479: /*
480: * This test will create a large number of unique items and add them to the delegator at once
481: */
482: public void testCreateManyAndStoreOneAtATime() throws Exception {
483: try {
484: for (int i = 0; i < TEST_COUNT; i++) {
485: delegator.create(delegator
486: .makeValue("Testing", UtilMisc.toMap(
487: "testingId", getTestId("T2-", i))));
488: }
489: List newlyCreatedValues = delegator.findAll("Testing",
490: UtilMisc.toList("testingId"));
491: TestCase.assertEquals("Test to create " + TEST_COUNT
492: + " and store one at a time: ", TEST_COUNT,
493: newlyCreatedValues.size());
494: } catch (GenericEntityException e) {
495: assertTrue("GenericEntityException:" + e.toString(), false);
496: return;
497: }
498: }
499:
500: /*
501: * This test will use the large number of unique items from above and test the EntityListIterator looping through the list
502: */
503: public void testEntityListIterator() throws Exception {
504: try {
505: EntityListIterator iterator = delegator
506: .findListIteratorByCondition("Testing",
507: new EntityExpr("testingId",
508: EntityOperator.LIKE, "T2-%"), null,
509: null);
510: assertTrue("Test if EntityListIterator was created: ",
511: iterator != null);
512:
513: int i = 0;
514: GenericValue item = (GenericValue) iterator.next();
515: while (item != null) {
516: assertTrue(
517: "Testing if iterated data matches test data (row "
518: + i + "): ", item
519: .getString("testingId").equals(
520: getTestId("T2-", i)));
521: item = (GenericValue) iterator.next();
522: i++;
523: }
524: assertTrue("Test if EntitlyListIterator iterates exactly "
525: + TEST_COUNT + " times: ", i == TEST_COUNT);
526: iterator.close();
527: } catch (GenericEntityException e) {
528: assertTrue("GenericEntityException:" + e.toString(), false);
529: return;
530: } finally {
531: List entitiesToRemove = delegator.findByCondition(
532: "Testing", new EntityExpr("testingId",
533: EntityOperator.LIKE, "T2-%"), null, null);
534: delegator.removeAll(entitiesToRemove);
535: }
536: }
537:
538: /*
539: * This test will verify transaction rollbacks using TransactionUtil.
540: */
541: public void testTransactionUtilRollback() throws Exception {
542: try {
543: GenericValue testValue = delegator.makeValue("Testing",
544: UtilMisc.toMap("testingId", "rollback-test"));
545: boolean transBegin = TransactionUtil.begin();
546: delegator.create(testValue);
547: TransactionUtil.rollback(transBegin, null, null);
548: GenericValue testValueOut = delegator.findByPrimaryKey(
549: "Testing", UtilMisc.toMap("testingId",
550: "rollback-test"));
551: assertEquals(
552: "Test that transaction rollback removes value: ",
553: testValueOut, null);
554: } catch (GenericEntityException e) {
555: assertTrue("GenericEntityException:" + e.toString(), false);
556: return;
557: }
558: }
559:
560: /*
561: * This test will verify that a transaction which takes longer than the pre-set timeout are rolled back.
562: */
563: public void testTransactionUtilMoreThanTimeout() throws Exception {
564: try {
565: GenericValue testValue = delegator.makeValue("Testing",
566: UtilMisc.toMap("testingId", "timeout-test"));
567: boolean transBegin = TransactionUtil.begin(10); // timeout set to 10 seconds
568: delegator.create(testValue);
569: Thread.sleep(20 * 1000);
570: TransactionUtil.commit(transBegin);
571: assertTrue(false);
572: } catch (GenericTransactionException e) {
573: assertTrue(true);
574: } catch (GenericEntityException e) {
575: assertTrue("Other GenericEntityException encountered:"
576: + e.toString(), false);
577: return;
578: } finally {
579: delegator.removeByAnd("Testing", UtilMisc.toMap(
580: "testingId", "timeout-test"));
581: }
582: }
583:
584: /*
585: * This test will verify that the same transaction transaction which takes less time than timeout will be committed.
586: */
587: public void testTransactionUtilLessThanTimeout() throws Exception {
588: try {
589: GenericValue testValue = delegator.makeValue("Testing",
590: UtilMisc.toMap("testingId", "timeout-test"));
591: boolean transBegin = TransactionUtil.begin();
592: TransactionUtil.setTransactionTimeout(20); // now set timeout to 20 seconds
593: delegator.create(testValue);
594: Thread.sleep(10 * 1000);
595: TransactionUtil.commit(transBegin);
596: assertTrue(true);
597: } catch (GenericTransactionException e) {
598: assertTrue(
599: "Transaction error when testing transaction less than timeout "
600: + e.toString(), false);
601: } catch (GenericEntityException e) {
602: assertTrue("Other GenericEntityException encountered:"
603: + e.toString(), false);
604: return;
605: } finally {
606: delegator.removeByAnd("Testing", UtilMisc.toMap(
607: "testingId", "timeout-test"));
608: }
609: }
610:
611: /*
612: * This will test setting a blob field to null by creating a TestBlob entity whose blob field is not set
613: */
614: public void testSetNullBlob() throws Exception {
615: try {
616: delegator.create("TestBlob", UtilMisc.toMap("testBlobId",
617: "null-blob"));
618: } catch (GenericEntityException ex) {
619: assertTrue("GenericEntityException:" + ex.toString(), false);
620: return;
621: } finally {
622: List allTestBlobs = delegator.findAll("TestBlob");
623: delegator.removeAll(allTestBlobs);
624: }
625: }
626:
627: /*
628: * Tests setting a byte value into a blob data type using the GenericValue .setBytes method
629: */
630: public void testBlobCreate() throws Exception {
631: try {
632: byte[] b = new byte[1];
633: b[0] = (byte) 0x01;
634: GenericValue testingBlob = delegator.makeValue("TestBlob",
635: UtilMisc.toMap("testBlobId", "byte-blob"));
636: testingBlob.setBytes("testBlobField", b);
637: testingBlob.create();
638:
639: TestCase.assertTrue(
640: "Blob with byte value successfully created...",
641: true);
642: } catch (Exception ex) {
643: TestCase.fail(ex.getMessage());
644: } finally {
645: // Remove all our newly inserted values.
646: List values = delegator.findAll("TestBlob");
647: delegator.removeAll(values);
648: }
649: }
650:
651: /*
652: * This creates an string id from a number
653: */
654: private String getTestId(String strTestBase, int iNum) {
655: StringBuffer strBufTemp = new StringBuffer(strTestBase);
656: if (iNum < 10000) {
657: strBufTemp.append("0");
658: }
659: if (iNum < 1000) {
660: strBufTemp.append("0");
661: }
662: if (iNum < 100) {
663: strBufTemp.append("0");
664: }
665: if (iNum < 10) {
666: strBufTemp.append("0");
667: }
668: strBufTemp.append(iNum);
669: return strBufTemp.toString();
670: }
671:
672: }
|