/** * OLAT - Online Learning and Training<br> * http://www.olat.org * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> * University of Zurich, Switzerland. * <hr> * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * This file has been modified by the OpenOLAT community. Changes are licensed * under the Apache 2.0 license as the original file. * <p> */ package org.olat.resource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.Assert; import org.junit.Test; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.test.OlatTestCase; import org.springframework.beans.factory.annotation.Autowired; /** * A <b>OLATResourceManagerTest </b> is used for SecurityResourceManager * testing. * * @author Andreas Ch. Kapp * */ public class OLATResourceManagerTest extends OlatTestCase { private static final OLog log = Tracing.createLoggerFor(OLATResourceManagerTest.class); @Autowired private DB dbInstance; @Autowired private OLATResourceManager rm; /** * Test creation/insert/update and deletion of a resource */ @Test public void testCreateInsertUpdateDeleteResource() { //create String resName = UUID.randomUUID().toString(); TestResourceable resource = new TestResourceable(8213649l, resName); OLATResource res = rm.createOLATResourceInstance( resource); Assert.assertNotNull(res); rm.saveOLATResource(res); Assert.assertEquals(new Long(8213649l), res.getResourceableId()); Assert.assertEquals(resName, res.getResourceableTypeName()); Assert.assertNotNull(res.getCreationDate()); Assert.assertNotNull(res.getKey()); dbInstance.commit(); } /** * Test find/persist of a resource */ @Test public void testFindOrPersistResourceable() { String resName = UUID.randomUUID().toString(); TestResourceable resource = new TestResourceable(8213650l, resName); //create by finding OLATResource ores1 = rm.findOrPersistResourceable(resource); Assert.assertNotNull(ores1); //only find OLATResource ores2 = rm.findOrPersistResourceable(resource); Assert.assertNotNull(ores2); Assert.assertEquals(ores1, ores2); } /** * Test type-only resource */ @Test public void testInsertTypeOnly() { TestResourceable resource = new TestResourceable(null, "typeonly"); OLATResource ores1 = rm.findOrPersistResourceable(resource); Assert.assertNotNull(ores1); Assert.assertNull(ores1.getResourceableId()); } /** * Test deletion of a resource */ @Test public void testDeleteResourceable() { String resName = UUID.randomUUID().toString(); TestResourceable resource = new TestResourceable(8213651l, resName); //delete on not persisted resourceable rm.deleteOLATResourceable(resource); //delete persisted resourceable OLATResource ores = rm.findOrPersistResourceable(resource); Assert.assertNotNull(ores); rm.deleteOLATResourceable(resource); dbInstance.commit(); OLATResource deletedRes = rm.findResourceable(8213651l, resName); Assert.assertNull(deletedRes); } @Test public void findResourceById() { String resName = UUID.randomUUID().toString(); TestResourceable resource = new TestResourceable(8213652l, resName); OLATResource ores = rm.findOrPersistResourceable(resource); dbInstance.commitAndCloseSession(); Assert.assertNotNull(ores); Assert.assertNotNull(ores.getKey()); //find by id OLATResource reloadedOres = rm.findResourceById(ores.getKey()); Assert.assertNotNull(reloadedOres); Assert.assertEquals(ores, reloadedOres); } @Test public void findResourceByTypes() { String resName1 = UUID.randomUUID().toString(); TestResourceable resource1 = new TestResourceable(8213653l, resName1); OLATResource ores1 = rm.findOrPersistResourceable(resource1); String resName2 = UUID.randomUUID().toString(); TestResourceable resource2 = new TestResourceable(8213654l, resName2); OLATResource ores2 = rm.findOrPersistResourceable(resource2); dbInstance.commitAndCloseSession(); Assert.assertNotNull(ores1); Assert.assertNotNull(ores2); //find by types List<String> types = new ArrayList<>(2); types.add(resName1); types.add(resName2); List<OLATResource> reloadedOres = rm.findResourceByTypes(types); Assert.assertNotNull(reloadedOres); Assert.assertEquals(2, reloadedOres.size()); Assert.assertTrue(reloadedOres.contains(ores1)); Assert.assertTrue(reloadedOres.contains(ores2)); } @Test public void findResourceable() { String resName = UUID.randomUUID().toString(); TestResourceable resource = new TestResourceable(8213655l, resName); OLATResource ores = rm.findOrPersistResourceable(resource); dbInstance.commitAndCloseSession(); Assert.assertNotNull(ores); Assert.assertNotNull(ores.getKey()); //find by id OLATResource reloadedOres = rm.findResourceable(8213655l, resName); Assert.assertNotNull(reloadedOres); Assert.assertEquals(ores, reloadedOres); } /** * Test find/persist of a resource */ @Test public void testConcurrentFindOrPersistResourceable() { final List<Exception> exceptionHolder = Collections.synchronizedList(new ArrayList<Exception>(1)); final List<OLATResource> statusList = Collections.synchronizedList(new ArrayList<OLATResource>(1)); final String resourceName = UUID.randomUUID().toString(); final CountDownLatch doneSignal = new CountDownLatch(2); Thread thread1 = new Thread(new Runnable() { public void run() { try { sleep(10); OLATResource resource = OLATResourceManager.getInstance().findOrPersistResourceable(new TestResourceable(123123999l, resourceName)); assertNotNull(resource); statusList.add(resource); log.info("testConcurrentFindOrPersistResourceable thread1 finished"); } catch (Exception ex) { exceptionHolder.add(ex);// no exception should happen } finally { DBFactory.getInstance().commitAndCloseSession(); doneSignal.countDown(); } }}); Thread thread2 = new Thread(new Runnable() { public void run() { try { sleep(10); OLATResource resource = OLATResourceManager.getInstance().findOrPersistResourceable(new TestResourceable(123123999l, resourceName)); assertNotNull(resource); statusList.add(resource); log.info("testConcurrentFindOrPersistResourceable thread2 finished"); } catch (Exception ex) { exceptionHolder.add(ex);// no exception should happen } finally { DBFactory.getInstance().commitAndCloseSession(); doneSignal.countDown(); } }}); thread1.start(); thread2.start(); try { boolean interrupt = doneSignal.await(10, TimeUnit.SECONDS); assertTrue("Test takes too long (more than 10s)", interrupt); } catch (InterruptedException e) { fail("" + e.getMessage()); } // if not -> they are in deadlock and the db did not detect it for (Exception exception : exceptionHolder) { log.error("exception: ", exception); } if (exceptionHolder.size() > 0) { assertTrue("It throws an exception in test => see sysout exception[0]=" + exceptionHolder.get(0).getMessage(), exceptionHolder.size() == 0); } assertEquals("Missing created OresResource in statusList",2, statusList.size()); assertEquals("Created OresResource has not same key",statusList.get(0).getKey(), statusList.get(1).getKey()); log.info("testConcurrentFindOrPersistResourceable finish successful"); } /** * Test resource for null values */ @Test public void testNULLVALUE() { NullTester ntester = new NullTester(); // Uncomment for testing: OLATResource or = null; try { or = rm.createOLATResourceInstance(ntester); } catch (RuntimeException re) { assertNull(or); } } /** * Resource with null value */ private static class NullTester implements OLATResourceable { @Override public Long getResourceableId() { return new Long(0); } @Override public String getResourceableTypeName() { return this.getClass().getName(); } } /////////////////////////////// // Inner class TestResourceable /////////////////////////////// private static class TestResourceable implements OLATResourceable { private final Long resId; private final String resName; public TestResourceable(Long resId, String resourceName) { this.resId = resId; this.resName = resourceName; } @Override public Long getResourceableId() { return resId; } @Override public String getResourceableTypeName() { return resName; } } }