/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.rdf.model.test;
import org.apache.jena.rdf.model.Model ;
import org.apache.jena.rdf.model.test.helpers.TestingModelFactory ;
import org.junit.After;
import org.junit.Assert;
/**
* Test nesting concurrency.
*/
public class TestConcurrencyNesting extends AbstractModelTestBase
{
public static int MODEL1 = 0;
public static int MODEL2 = 1;
// Test suite to exercise the locking
long SLEEP = 100;
int threadCount = 0;
// Note : reuse the model across tests.
private Model[] workingModels;
private final int outerModel;
private final int innerModel;
boolean outerLock;
boolean innerLock;
boolean exceptionExpected;
/**
* Create a TestConcurrencyNesting fixture.
*
* @param modelFactory
* an instance of the TestingModelFactory
* @param model1Idx
* which model to use for outer model.
* @param model2Idx
* which model to use for inner model
* @param lock1
* lock type for outer model. Lock.READ or Lock.WRITE
* @param lock2
* lock type for inner model.
* @param exExpected
* true if an exception is expected.
* @param name
* The name of the test to run.
*/
public TestConcurrencyNesting( final TestingModelFactory modelFactory,
final Integer model1Idx, final Integer model2Idx,
final Boolean lock1, final Boolean lock2, final Boolean exExpected,
final String name )
{
super(modelFactory, name);
outerModel = model1Idx;
outerLock = lock1;
innerModel = model2Idx;
innerLock = lock2;
exceptionExpected = exExpected;
}
/**
* A human readable test name.
*/
@Override
public String getName()
{
return String.format("%s - %s outerLock:%s innerLock:%s", super
.getName(), (outerModel == innerModel) ? "same" : "different",
(outerLock), (innerLock));
}
@Override
public void setUp()
{
workingModels = new Model[2];
workingModels[TestConcurrencyNesting.MODEL1] = createModel();
workingModels[TestConcurrencyNesting.MODEL2] = createModel();
}
@Override
@After
public void tearDown()
{
workingModels[TestConcurrencyNesting.MODEL1].close();
workingModels[TestConcurrencyNesting.MODEL2].close();
}
public void testNesting()
{
boolean gotException = false;
try
{
workingModels[outerModel].enterCriticalSection(outerLock);
try
{
try
{
// Should fail if outerLock is READ and innerLock is WRITE
// and its on the same model, inner and outer.
workingModels[innerModel].enterCriticalSection(innerLock);
}
finally
{
workingModels[innerModel].leaveCriticalSection();
}
}
catch (final Exception ex)
{
gotException = true;
}
}
finally
{
workingModels[outerModel].leaveCriticalSection();
}
if (exceptionExpected)
{
Assert.assertTrue(getName()
+ " Failed to get expected lock promotion error",
gotException);
}
else
{
Assert.assertTrue(getName()
+ " Got unexpected lock promotion error", !gotException);
}
}
}