001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.sample.petclinic;
018:
019: import java.util.Collection;
020: import java.util.Date;
021:
022: import javax.sql.DataSource;
023:
024: import junit.framework.TestCase;
025:
026: import org.compass.core.Compass;
027: import org.compass.core.CompassCallbackWithoutResult;
028: import org.compass.core.CompassDetachedHits;
029: import org.compass.core.CompassException;
030: import org.compass.core.CompassHits;
031: import org.compass.core.CompassSession;
032: import org.compass.core.CompassTemplate;
033: import org.compass.gps.ActiveMirrorGpsDevice;
034: import org.compass.gps.CompassGps;
035: import org.compass.gps.CompassGpsDevice;
036: import org.compass.sample.petclinic.util.EntityUtils;
037: import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
038: import org.springframework.context.ConfigurableApplicationContext;
039: import org.springframework.context.support.ClassPathXmlApplicationContext;
040: import org.springframework.jdbc.core.JdbcTemplate;
041: import org.springframework.transaction.PlatformTransactionManager;
042: import org.springframework.transaction.TransactionStatus;
043: import org.springframework.transaction.support.TransactionCallbackWithoutResult;
044: import org.springframework.transaction.support.TransactionTemplate;
045:
046: /**
047: * Base class for Clinic tests. Allows subclasses to specify context locations.
048: * <p/>
049: * This class extends AbstractTransactionalDataSourceSpringContextTests, one of
050: * the valuable test superclasses provided in the org.springframework.test
051: * package. This represents best practice for integration tests with Spring. The
052: * AbstractTransactionalDataSourceSpringContextTests superclass provides the
053: * following services:
054: * <li>Injects test dependencies, meaning that we don't need to perform
055: * application context lookups. See the setClinic() method. Injection uses
056: * autowiring by type.
057: * <li>Executes each test method in its own transaction, which is automatically
058: * rolled back by default. This means that even if tests insert or otherwise
059: * change database state, there is no need for a teardown or cleanup script.
060: * <li>Provides useful inherited protected fields, such as a JdbcTemplate that
061: * can be used to verify database state after test operations, or verify the
062: * results of queries performed by application code. An ApplicationContext is
063: * also inherited, and can be used for explicit lookup if necessary.
064: * <p/>
065: * The AbstractTransactionalDataSourceSpringContextTests and related classes are
066: * shipped in the spring-mock.jar.
067: *
068: * @author Ken Krebs
069: * @author Rod Johnson
070: * @see org.springframework.test.AbstractTransactionalDataSourceSpringContextTests
071: */
072: public abstract class AbstractClinicTests extends TestCase {
073:
074: private ConfigurableApplicationContext applicationContext;
075:
076: private JdbcTemplate jdbcTemplate;
077:
078: private TransactionTemplate transactionTemplate;
079:
080: public void setDataSource(DataSource dataSource) {
081: this .jdbcTemplate = new JdbcTemplate(dataSource);
082: }
083:
084: protected Clinic clinic;
085:
086: /**
087: * This method is provided to set the Clinic instance being tested by the
088: * Dependency Injection injection behaviour of the superclass from the
089: * org.springframework.test package.
090: *
091: * @param clinic clinic to test
092: */
093: public void setClinic(Clinic clinic) {
094: this .clinic = clinic;
095: }
096:
097: // <!-- COMPASS START
098: // Makes the tests run without a running HSQL instance
099:
100: protected CompassGps compassGps;
101:
102: protected CompassGpsDevice compassGpsDevice;
103:
104: protected CompassTemplate compassTemplate;
105:
106: protected Compass compass;
107:
108: public void setCompassGps(CompassGps compassGps) {
109: this .compassGps = compassGps;
110: // use read commited transaction isolation since we are performing the
111: // index operation and testing within the same transaction
112: //((SingleCompassGps) compassGps).setIndexTransactionIsolation(TransactionIsolation.READ_COMMITTED);
113: }
114:
115: public void setCompass(Compass compass) {
116: this .compass = compass;
117: this .compassTemplate = new CompassTemplate(compass);
118: }
119:
120: public void setCompassGpsDevice(CompassGpsDevice compassGpsDevice) {
121: this .compassGpsDevice = compassGpsDevice;
122: }
123:
124: public void setTransactionManager(
125: PlatformTransactionManager transactionManager) {
126: this .transactionTemplate = new TransactionTemplate(
127: transactionManager);
128: }
129:
130: protected abstract boolean hasClassMappings();
131:
132: protected abstract String[] getConfigLocations();
133:
134: /**
135: * If the gps device is active mirror type, perform the mirroring
136: */
137: protected void doPerformMirroringIfNeeded() {
138: if (compassGpsDevice instanceof ActiveMirrorGpsDevice) {
139: ((ActiveMirrorGpsDevice) compassGpsDevice)
140: .performMirroring();
141: }
142: }
143:
144: protected void setUp() throws Exception {
145: this .applicationContext = new ClassPathXmlApplicationContext(
146: getConfigLocations());
147: this .applicationContext.getBeanFactory()
148: .autowireBeanProperties(this ,
149: AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE,
150: true);
151: }
152:
153: protected void tearDown() throws Exception {
154: this .applicationContext.close();
155: }
156:
157: private void performIndex() {
158: compassGps.index();
159: }
160:
161: // COMPASS END -->
162:
163: public void testGetVets() {
164: transactionTemplate
165: .execute(new TransactionCallbackWithoutResult() {
166: protected void doInTransactionWithoutResult(
167: TransactionStatus transactionStatus) {
168: Collection vets = clinic.getVets();
169:
170: // Use the inherited JdbcTemplate (from
171: // AbstractTransactionalDataSourceSpringContextTests)
172: // to verify the results of the query
173: assertEquals(
174: "JDBC query must show the same number of vets",
175: jdbcTemplate
176: .queryForInt("SELECT COUNT(0) FROM VETS"),
177: vets.size());
178: Vet v1 = (Vet) EntityUtils.getById(vets,
179: Vet.class, 2);
180: assertEquals("Leary", v1.getLastName());
181: assertEquals(1, v1.getNrOfSpecialties());
182: assertEquals("radiology", ((Specialty) v1
183: .getSpecialties().get(0)).getName());
184: Vet v2 = (Vet) EntityUtils.getById(vets,
185: Vet.class, 3);
186: assertEquals("Douglas", v2.getLastName());
187: assertEquals(2, v2.getNrOfSpecialties());
188: assertEquals("dentistry", ((Specialty) v2
189: .getSpecialties().get(0)).getName());
190: assertEquals("surgery", ((Specialty) v2
191: .getSpecialties().get(1)).getName());
192: }
193: });
194: }
195:
196: public void testGetPetTypes() {
197: transactionTemplate
198: .execute(new TransactionCallbackWithoutResult() {
199: protected void doInTransactionWithoutResult(
200: TransactionStatus transactionStatus) {
201: Collection petTypes = clinic.getPetTypes();
202: assertEquals(
203: "JDBC query must show the same number of pet typess",
204: jdbcTemplate
205: .queryForInt("SELECT COUNT(0) FROM TYPES"),
206: petTypes.size());
207: PetType t1 = (PetType) EntityUtils.getById(
208: petTypes, PetType.class, 1);
209: assertEquals("cat", t1.getName());
210: PetType t4 = (PetType) EntityUtils.getById(
211: petTypes, PetType.class, 4);
212: assertEquals("snake", t4.getName());
213: }
214: });
215: }
216:
217: public void testFindOwners() {
218: Collection owners = this .clinic.findOwners("Davis");
219: assertEquals(2, owners.size());
220: owners = this .clinic.findOwners("Daviss");
221: assertEquals(0, owners.size());
222: }
223:
224: public void testLoadOwner() {
225: Owner o1 = this .clinic.loadOwner(1);
226: assertTrue(o1.getLastName().startsWith("Franklin"));
227: Owner o10 = this .clinic.loadOwner(10);
228: assertEquals("Carlos", o10.getFirstName());
229: }
230:
231: public void testInsertOwner() {
232: Collection owners = this .clinic.findOwners("Schultz");
233: int found = owners.size();
234: Owner owner = new Owner();
235: owner.setLastName("Schultz");
236: this .clinic.storeOwner(owner);
237: owners = this .clinic.findOwners("Schultz");
238: assertEquals(found + 1, owners.size());
239: }
240:
241: public void testUpdateOwner() throws Exception {
242: transactionTemplate
243: .execute(new TransactionCallbackWithoutResult() {
244: protected void doInTransactionWithoutResult(
245: TransactionStatus transactionStatus) {
246: Owner o1 = clinic.loadOwner(1);
247: String old = o1.getLastName();
248: o1.setLastName(old + "X");
249: clinic.storeOwner(o1);
250: o1 = clinic.loadOwner(1);
251: assertEquals(old + "X", o1.getLastName());
252: }
253: });
254: }
255:
256: public void testLoadPet() {
257: Collection types = this .clinic.getPetTypes();
258: Pet p7 = this .clinic.loadPet(7);
259: assertTrue(p7.getName().startsWith("Samantha"));
260: assertEquals(EntityUtils.getById(types, PetType.class, 1)
261: .getId(), p7.getType().getId());
262: assertEquals("Jean", p7.getOwner().getFirstName());
263: Pet p6 = this .clinic.loadPet(6);
264: assertEquals("George", p6.getName());
265: assertEquals(EntityUtils.getById(types, PetType.class, 4)
266: .getId(), p6.getType().getId());
267: assertEquals("Peter", p6.getOwner().getFirstName());
268: }
269:
270: public void testInsertPet() {
271: Owner o6 = this .clinic.loadOwner(6);
272: int found = o6.getPets().size();
273: Pet pet = new Pet();
274: pet.setName("bowser");
275: o6.addPet(pet);
276: Collection types = this .clinic.getPetTypes();
277: pet.setType((PetType) EntityUtils.getById(types, PetType.class,
278: 2));
279: pet.setBirthDate(new Date());
280: assertEquals(found + 1, o6.getPets().size());
281: this .clinic.storePet(pet);
282: o6 = this .clinic.loadOwner(6);
283: assertEquals(found + 1, o6.getPets().size());
284: }
285:
286: public void testUpdatePet() throws Exception {
287: Pet p7 = this .clinic.loadPet(7);
288: String old = p7.getName();
289: p7.setName(old + "X");
290: this .clinic.storePet(p7);
291: p7 = this .clinic.loadPet(7);
292: assertEquals(old + "X", p7.getName());
293: }
294:
295: public void testInsertVisit() {
296: Pet p7 = this .clinic.loadPet(7);
297: int found = p7.getVisits().size();
298: Visit visit = new Visit();
299: p7.addVisit(visit);
300: visit.setDescription("test");
301: this .clinic.storeVisit(visit);
302: assertEquals(found + 1, p7.getVisits().size());
303: }
304:
305: public void testCompassReindex() {
306: // reindex the database
307: performIndex();
308: // use sporadic data to test that we reindexed the db
309: compassTemplate.execute(new CompassCallbackWithoutResult() {
310: protected void doInCompassWithoutResult(
311: CompassSession session) throws CompassException {
312: CompassHits hits = session.find("Harold");
313: assertEquals(1, hits.getLength());
314: assertEquals("Harold", hits.resource(0).get(
315: Petclinic.MetaData.FirstName.Name));
316: if (hasClassMappings()) {
317: Owner owner = (Owner) hits.data(0);
318: assertEquals("Harold", owner.getFirstName());
319: assertEquals(1, owner.getPets().size());
320: Pet pet = (Pet) owner.getPets().get(0);
321: assertEquals("Iggy", pet.getName());
322: }
323: }
324: });
325:
326: compassTemplate.execute(new CompassCallbackWithoutResult() {
327: protected void doInCompassWithoutResult(
328: CompassSession session) throws CompassException {
329: CompassHits hits = session.find("Leo");
330: assertEquals(1, hits.getLength());
331: assertEquals("Leo", hits.resource(0).get(
332: Petclinic.MetaData.Name.Name));
333: if (hasClassMappings()) {
334: Pet pet = (Pet) hits.data(0);
335: assertEquals("Leo", pet.getName());
336: assertEquals("George", pet.getOwner()
337: .getFirstName());
338: }
339: }
340: });
341:
342: compassTemplate.execute(new CompassCallbackWithoutResult() {
343: protected void doInCompassWithoutResult(
344: CompassSession session) throws CompassException {
345: CompassHits hits = session.find("James");
346: assertEquals(1, hits.getLength());
347: assertEquals("James", hits.resource(0).get(
348: Petclinic.MetaData.FirstName.Name));
349: if (hasClassMappings()) {
350: Vet vet = (Vet) hits.data(0);
351: assertEquals("James", vet.getFirstName());
352: }
353: }
354: });
355:
356: compassTemplate.execute(new CompassCallbackWithoutResult() {
357: protected void doInCompassWithoutResult(
358: CompassSession session) throws CompassException {
359: if (hasClassMappings()) {
360: Pet samantha = (Pet) session.load(Pet.class,
361: new Integer(7));
362: assertEquals(2, samantha.getVisits().size());
363: }
364: }
365: });
366:
367: compassTemplate.execute(new CompassCallbackWithoutResult() {
368: protected void doInCompassWithoutResult(
369: CompassSession session) throws CompassException {
370: CompassHits hits = session.find("George");
371: assertEquals(2, hits.getLength());
372: if (hasClassMappings()) {
373: hits = session.find("radiology");
374: assertEquals(2, hits.length());
375: }
376: }
377: });
378: }
379:
380: public void testInsertOwnerCompassMirror() {
381: // reindex the database
382: performIndex();
383: // test that Schultz is not in compass
384: compassTemplate.execute(new CompassCallbackWithoutResult() {
385: protected void doInCompassWithoutResult(
386: CompassSession session) throws CompassException {
387: CompassHits hits = session.find("Schultz");
388: assertEquals(0, hits.getLength());
389: }
390: });
391: // do the orig spring test
392: Collection owners = this .clinic.findOwners("Schultz");
393: int found = owners.size();
394: Owner owner = new Owner();
395: owner.setLastName("Schultz");
396: this .clinic.storeOwner(owner);
397: owners = this .clinic.findOwners("Schultz");
398: assertEquals(found + 1, owners.size());
399: // test that Schultz is in compass as well
400: doPerformMirroringIfNeeded();
401: compassTemplate.execute(new CompassCallbackWithoutResult() {
402: protected void doInCompassWithoutResult(
403: CompassSession session) throws CompassException {
404: CompassHits hits = session.find("Schultz");
405: assertEquals(1, hits.getLength());
406: assertEquals("Schultz", hits.resource(0).get(
407: Petclinic.MetaData.LastName.Name));
408: if (hasClassMappings()) {
409: Owner owner = (Owner) hits.data(0);
410: assertEquals("Schultz", owner.getLastName());
411: }
412: }
413: });
414: }
415:
416: public void testUpdateOwnerCompassMirror() throws Exception {
417: // reindex the database
418: performIndex();
419: Owner o1 = this .clinic.loadOwner(1);
420: String old = o1.getLastName();
421: if (hasClassMappings()) {
422: // load the owner using compass
423: Owner oldCompassOwner = (Owner) compassTemplate.load(
424: Owner.class, new Integer(1));
425: // validate that it is the same as the db
426: assertEquals(old, oldCompassOwner.getLastName());
427: }
428: CompassDetachedHits hits = compassTemplate.findWithDetach(old
429: + "X");
430: assertEquals(0, hits.getLength());
431: // update and check db
432: o1.setLastName(old + "X");
433: this .clinic.storeOwner(o1);
434:
435: // we need to cause the ORM tool to flush it's data
436: // which it won't if we call the loadOwner method
437: // most ORM will flush as a result of a query on
438: // the object
439: // Note, that we do it since we want to test the change
440: // WITHIN the same transaction, usually, we won't check
441: // compass within the current transaction
442: this .clinic.findOwners("Test");
443:
444: o1 = this .clinic.loadOwner(1);
445: assertEquals(old + "X", o1.getLastName());
446: // check with compass
447: doPerformMirroringIfNeeded();
448: hits = compassTemplate.findWithDetach(old + "X");
449: assertEquals(1, hits.getLength());
450: if (hasClassMappings()) {
451: Owner newCompassOwner = (Owner) compassTemplate.load(
452: Owner.class, new Integer(1));
453: assertEquals(old + "X", newCompassOwner.getLastName());
454: }
455: }
456:
457: public void testInsertPetCompassMirror() {
458: // reindex the database
459: performIndex();
460: // test that browser is not in compass
461: compassTemplate.execute(new CompassCallbackWithoutResult() {
462: protected void doInCompassWithoutResult(
463: CompassSession session) throws CompassException {
464: CompassHits hits = session.find("bowser");
465: assertEquals(0, hits.getLength());
466: }
467: });
468:
469: Owner o6 = this .clinic.loadOwner(6);
470: int found = o6.getPets().size();
471: Pet pet = new Pet();
472: pet.setName("bowser");
473: o6.addPet(pet);
474: Collection types = this .clinic.getPetTypes();
475: pet.setType((PetType) EntityUtils.getById(types, PetType.class,
476: 2));
477: pet.setBirthDate(new Date());
478: assertEquals(found + 1, o6.getPets().size());
479: this .clinic.storePet(pet);
480: o6 = this .clinic.loadOwner(6);
481: assertEquals(found + 1, o6.getPets().size());
482:
483: // test that bowser is in compass as well
484: doPerformMirroringIfNeeded();
485: compassTemplate.execute(new CompassCallbackWithoutResult() {
486: protected void doInCompassWithoutResult(
487: CompassSession session) throws CompassException {
488: CompassHits hits = session.find("bowser");
489: assertEquals(1, hits.getLength());
490: assertEquals("bowser", hits.resource(0).get(
491: Petclinic.MetaData.Name.Name));
492: if (hasClassMappings()) {
493: Pet pet = (Pet) hits.data(0);
494: assertEquals("bowser", pet.getName());
495: }
496: }
497: });
498: }
499:
500: public void testUpdatePetCompassMirror() throws Exception {
501: // reindex the database
502: performIndex();
503:
504: Pet p7 = this .clinic.loadPet(7);
505: String old = p7.getName();
506:
507: // load the old pet
508: if (hasClassMappings()) {
509: Pet oldPet = (Pet) compassTemplate.load(Pet.class,
510: new Integer(7));
511: // check the same
512: assertEquals(old, oldPet.getName());
513: }
514: CompassDetachedHits hits = compassTemplate.findWithDetach(old
515: + "X");
516: assertEquals(0, hits.getLength());
517:
518: p7.setName(old + "X");
519: this .clinic.storePet(p7);
520: p7 = this .clinic.loadPet(7);
521: assertEquals(old + "X", p7.getName());
522:
523: // flush the database
524: this .clinic.getPets();
525:
526: // check the updae in compass
527: doPerformMirroringIfNeeded();
528: if (hasClassMappings()) {
529: Pet newPet = (Pet) compassTemplate.load(Pet.class,
530: new Integer(7));
531: assertEquals(old + "X", newPet.getName());
532: hits = compassTemplate.findWithDetach(old + "X");
533: assertEquals(1, hits.getLength()); // one pet (visits are accessed
534: // using OSEM)
535: } else {
536: hits = compassTemplate.findWithDetach(old + "X");
537: assertEquals(3, hits.getLength()); // one pet and two visits
538: }
539: }
540: }
|