/* * 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.tuscany.sca.interfacedef.impl; import static org.junit.Assert.fail; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.interfacedef.Compatibility; import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException; import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.interfacedef.Operation; import org.junit.Before; import org.junit.Test; /** * TODO some tests commented out due to DataType.equals() needing to be strict * * @version $Rev$ $Date$ */ public class ContractCompatibilityTestCase { private InterfaceContractMapper mapper; @Before public void setUp() throws Exception { ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); mapper = utilities.getUtility(InterfaceContractMapper.class); } @Test public void testNoOperation() throws Exception { InterfaceContract source = new MockContract("FooContract"); InterfaceContract target = new MockContract("FooContract"); mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); } @Test public void testBasic() throws Exception { InterfaceContract source = new MockContract("FooContract"); Operation opSource1 = newOperation("op1"); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); Operation opSource2 = newOperation("op1"); Map targetOperations = new HashMap(); targetOperations.put("op1", opSource2); target.getInterface().getOperations().addAll(targetOperations.values()); mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); } @Test public void testBasicIncompatibleOperationNames() throws Exception { InterfaceContract source = new MockContract("FooContract"); Operation opSource1 = newOperation("op1"); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); Operation opSource2 = newOperation("op2"); Map targetOperations = new HashMap(); targetOperations.put("op2", opSource2); target.getInterface().getOperations().addAll(targetOperations.values()); try { mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); fail(); } catch (IncompatibleInterfaceContractException e) { // expected } } @Test public void testInputTypes() throws Exception { InterfaceContract source = new MockContract("FooContract"); List sourceInputTypes = new ArrayList(); sourceInputTypes.add(new DataTypeImpl(Object.class, Object.class)); DataType> inputType = new DataTypeImpl>(String.class, sourceInputTypes); Operation opSource1 = newOperation("op1"); opSource1.setInputType(inputType); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); List targetInputTypes = new ArrayList(); targetInputTypes.add(new DataTypeImpl(Object.class, Object.class)); DataType> targetInputType = new DataTypeImpl>(String.class, targetInputTypes); Operation opTarget = newOperation("op1"); opTarget.setInputType(targetInputType); Map targetOperations = new HashMap(); targetOperations.put("op1", opTarget); target.getInterface().getOperations().addAll(targetOperations.values()); mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); } @Test public void testIncompatibleInputTypes() throws Exception { InterfaceContract source = new MockContract("FooContract"); List sourceInputTypes = new ArrayList(); sourceInputTypes.add(new DataTypeImpl(Integer.class, Integer.class)); DataType> inputType = new DataTypeImpl>(String.class, sourceInputTypes); Operation opSource1 = newOperation("op1"); opSource1.setInputType(inputType); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); List targetInputTypes = new ArrayList(); targetInputTypes.add(new DataTypeImpl(String.class, String.class)); DataType> targetInputType = new DataTypeImpl>(String.class, targetInputTypes); Operation opTarget = newOperation("op1"); opTarget.setInputType(targetInputType); Map targetOperations = new HashMap(); targetOperations.put("op1", opTarget); target.getInterface().getOperations().addAll(targetOperations.values()); try { mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); fail(); } catch (IncompatibleInterfaceContractException e) { // expected } } /** * Verifies source input types can be super types of the target */ @Test public void testSourceSuperTypeInputCompatibility() throws Exception { // InterfaceContract source = new MockContract("FooContract"); // List sourceInputTypes = new ArrayList(); // sourceInputTypes.add(new DataTypeImpl(Object.class, // Object.class)); // DataType> inputType = new // DataTypeImpl>(String.class, sourceInputTypes); // Operation opSource1 = newOperationImpl("op1", inputType, null, null, // false, null); // Map sourceOperations = new HashMap(); // sourceOperations.put("op1", opSource1); // source.getInterface().getOperations().addAll(sourceOperations.values()); // // InterfaceContract target = new MockContract("FooContract"); // List targetInputTypes = new ArrayList(); // targetInputTypes.add(new DataTypeImpl(String.class, // String.class)); // DataType> targetInputType = // new DataTypeImpl>(String.class, targetInputTypes); // // Operation opTarget = newOperationImpl("op1", targetInputType, null, // null, false, null); // Map targetOperations = new HashMap(); // targetOperations.put("op1", opTarget); // target.getInterface().getOperations().addAll(targetOperations.values()); // wireService.checkCompatibility(source, target, false); } @Test public void testOutputTypes() throws Exception { InterfaceContract source = new MockContract("FooContract"); DataType sourceStringType = new DataTypeImpl(String.class, String.class); ArrayList sourceTypes = new ArrayList(); sourceTypes.add(sourceStringType); DataType sourceOutputType = new DataTypeImpl(Object[].class, sourceTypes); Operation opSource1 = newOperation("op1"); opSource1.setOutputType(sourceOutputType); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); DataType stringType = new DataTypeImpl(String.class, String.class); ArrayList types = new ArrayList(); types.add(stringType); DataType targetOutputType = new DataTypeImpl(Object[].class, types); Operation opTarget = newOperation("op1"); opTarget.setOutputType(targetOutputType); Map targetOperations = new HashMap(); targetOperations.put("op1", opTarget); target.getInterface().getOperations().addAll(targetOperations.values()); mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); } /** * Verifies a return type that is a supertype of of the target is compatible */ @Test public void testSupertypeOutputTypes() throws Exception { // InterfaceContract source = new MockContract("FooContract"); // DataType sourceOutputType = new DataTypeImpl(Object.class, // Object.class); // Operation opSource1 = newOperationImpl("op1", null, // sourceOutputType, null, false, null); // Map sourceOperations = new HashMap(); // sourceOperations.put("op1", opSource1); // source.getInterface().getOperations().addAll(sourceOperations.values()); // // InterfaceContract target = new MockContract("FooContract"); // DataType targetOutputType = new DataTypeImpl(String.class, // String.class); // Operation opTarget = newOperationImpl("op1", null, targetOutputType, // null, false, null); // Map targetOperations = new HashMap(); // targetOperations.put("op1", opTarget); // target.getInterface().getOperations().addAll(targetOperations.values()); // wireService.checkCompatibility(source, target, false); } @Test public void testIncompatibleOutputTypes() throws Exception { InterfaceContract source = new MockContract("FooContract"); DataType sourceType = new DataTypeImpl(String.class, String.class); ArrayList sourceTypes = new ArrayList(); sourceTypes.add(sourceType); DataType sourceOutputType = new DataTypeImpl(Object[].class, sourceTypes); Operation opSource1 = newOperation("op1"); opSource1.setOutputType(sourceOutputType); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); DataType targetType = new DataTypeImpl(Integer.class, Integer.class); ArrayList targetTypes = new ArrayList(); targetTypes.add(targetType); DataType targetOutputType = new DataTypeImpl(Object[].class, targetTypes); Operation opTarget = newOperation("op1"); opTarget.setOutputType(targetOutputType); Map targetOperations = new HashMap(); targetOperations.put("op1", opTarget); target.getInterface().getOperations().addAll(targetOperations.values()); try { mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); fail(); } catch (IncompatibleInterfaceContractException e) { // expected } } @Test public void testFaultTypes() throws Exception { InterfaceContract source = new MockContract("FooContract"); DataType sourceFaultType = new DataTypeImpl(String.class, String.class); List sourceFaultTypes = new ArrayList(); sourceFaultTypes.add(0, sourceFaultType); Operation opSource1 = newOperation("op1"); opSource1.setFaultTypes(sourceFaultTypes); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); DataType targetFaultType = new DataTypeImpl(String.class, String.class); List targetFaultTypes = new ArrayList(); targetFaultTypes.add(0, targetFaultType); Operation opTarget = newOperation("op1"); opTarget.setFaultTypes(targetFaultTypes); Map targetOperations = new HashMap(); targetOperations.put("op1", opTarget); target.getInterface().getOperations().addAll(targetOperations.values()); mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); } @Test public void testSourceFaultTargetNoFaultCompatibility() throws Exception { InterfaceContract source = new MockContract("FooContract"); DataType sourceFaultType = new DataTypeImpl(String.class, String.class); List sourceFaultTypes = new ArrayList(); sourceFaultTypes.add(0, sourceFaultType); Operation opSource1 = newOperation("op1"); opSource1.setFaultTypes(sourceFaultTypes); Map sourceOperations = new HashMap(); sourceOperations.put("op1", opSource1); source.getInterface().getOperations().addAll(sourceOperations.values()); InterfaceContract target = new MockContract("FooContract"); Operation opTarget = newOperation("op1"); Map targetOperations = new HashMap(); targetOperations.put("op1", opTarget); target.getInterface().getOperations().addAll(targetOperations.values()); mapper.checkCompatibility(source, target, Compatibility.SUBSET, false, false); } /** * Verifies a source's fault which is a supertype of the target's fault are * compatible * * @throws Exception */ @Test public void testFaultSuperTypes() throws Exception { // InterfaceContract source = new MockContract("FooContract"); // DataType sourceFaultType = new DataTypeImpl(Exception.class, // Exception.class); // List sourceFaultTypes = new ArrayList(); // sourceFaultTypes.add(0, sourceFaultType); // Operation opSource1 = newOperationImpl("op1", null, null, // sourceFaultTypes, false, null); // Map sourceOperations = new HashMap(); // sourceOperations.put("op1", opSource1); // source.getInterface().getOperations().addAll(sourceOperations.values()); // // InterfaceContract target = new MockContract("FooContract"); // DataType targetFaultType = new // DataTypeImpl(TuscanyException.class, TuscanyException.class); // List targetFaultTypes = new ArrayList(); // targetFaultTypes.add(0, targetFaultType); // // Operation opTarget = newOperationImpl("op1", null, null, // targetFaultTypes, false, null); // Map targetOperations = new HashMap(); // targetOperations.put("op1", opTarget); // target.getInterface().getOperations().addAll(targetOperations.values()); // wireService.checkCompatibility(source, target, false); } /** * Verifies a source's faults which are supertypes and a superset of the * target's faults are compatible */ @Test public void testFaultSuperTypesAndSuperset() throws Exception { // InterfaceContract source = new MockContract("FooContract"); // DataType sourceFaultType = new DataTypeImpl(Exception.class, // Exception.class); // DataType sourceFaultType2 = new // DataTypeImpl(RuntimeException.class, RuntimeException.class); // List sourceFaultTypes = new ArrayList(); // sourceFaultTypes.add(0, sourceFaultType); // sourceFaultTypes.add(1, sourceFaultType2); // Operation opSource1 = newOperationImpl("op1", null, null, // sourceFaultTypes, false, null); // Map sourceOperations = new HashMap(); // sourceOperations.put("op1", opSource1); // source.getInterface().getOperations().addAll(sourceOperations.values()); // // InterfaceContract target = new MockContract("FooContract"); // DataType targetFaultType = new // DataTypeImpl(TuscanyException.class, TuscanyException.class); // List targetFaultTypes = new ArrayList(); // targetFaultTypes.add(0, targetFaultType); // // Operation opTarget = newOperationImpl("op1", null, null, // targetFaultTypes, false, null); // Map targetOperations = new HashMap(); // targetOperations.put("op1", opTarget); // target.getInterface().getOperations().addAll(targetOperations.values()); // wireService.checkCompatibility(source, target, false); } private static class MockInterface extends InterfaceImpl { } private class MockContract extends InterfaceContractImpl { public MockContract() { } public MockContract(String interfaceClass) { Interface jInterface = new MockInterface(); setInterface(jInterface); } } private static Operation newOperation(String name) { Operation operation = new OperationImpl(); operation.setName(name); ArrayList outputTypes = new ArrayList(); outputTypes.add(new DataTypeImpl(Object.class, Object.class)); operation.setOutputType(new DataTypeImpl(Object[].class, outputTypes)); return operation; } }