/* * Copyright (c) 2010-2017 Evolveum * * Licensed 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 com.evolveum.midpoint.provisioning.impl.dummy; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertTrue; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; import org.testng.annotations.Test; import com.evolveum.icf.dummy.resource.BreakMode; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; /** * @author Radovan Semancik * */ @ContextConfiguration(locations = "classpath:ctx-provisioning-test-main.xml") @DirtiesContext public class TestDummyNegative extends AbstractDummyTest { private static final Trace LOGGER = TraceManager.getTrace(TestDummyNegative.class); private static final String ACCOUNT_ELAINE_RESOURCE_NOT_FOUND_FILENAME = TEST_DIR + "account-elaine-resource-not-found.xml"; @Test public void test110GetResourceBrokenSchemaNetwork() throws Exception { testGetResourceBrokenSchema(BreakMode.NETWORK, "test110GetResourceBrokenSchemaNetwork"); } @Test public void test111GetResourceBrokenSchemaGeneric() throws Exception { testGetResourceBrokenSchema(BreakMode.GENERIC, "test111GetResourceBrokenSchemaGeneric"); } @Test public void test112GetResourceBrokenSchemaIo() throws Exception { testGetResourceBrokenSchema(BreakMode.IO, "test112GetResourceBrokenSchemaIO"); } @Test public void test113GetResourceBrokenSchemaRuntime() throws Exception { testGetResourceBrokenSchema(BreakMode.RUNTIME, "test113GetResourceBrokenSchemaRuntime"); } public void testGetResourceBrokenSchema(BreakMode breakMode, String testName) throws Exception { TestUtil.displayTestTile(testName); // GIVEN OperationResult result = new OperationResult(TestDummyNegative.class.getName() + "."+testName); // precondition PrismObject<ResourceType> repoResource = repositoryService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, result); display("Repo resource (before)", repoResource); PrismContainer<Containerable> schema = repoResource.findContainer(ResourceType.F_SCHEMA); assertTrue("Schema found in resource before the test (precondition)", schema == null || schema.isEmpty()); dummyResource.setSchemaBreakMode(breakMode); try { // WHEN PrismObject<ResourceType> resource = provisioningService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, null, result); // THEN display("Resource with broken schema", resource); OperationResultType fetchResult = resource.asObjectable().getFetchResult(); result.computeStatus(); display("getObject result", result); assertEquals("Unexpected result of getObject operation", OperationResultStatus.PARTIAL_ERROR, result.getStatus()); assertNotNull("No fetch result", fetchResult); display("fetchResult", fetchResult); assertEquals("Unexpected result of fetchResult", OperationResultStatusType.PARTIAL_ERROR, fetchResult.getStatus()); } finally { dummyResource.setSchemaBreakMode(BreakMode.NONE); } } @Test public void test190GetResource() throws Exception { final String TEST_NAME = "test190GetResource"; TestUtil.displayTestTile(TEST_NAME); // GIVEN Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); dummyResource.setSchemaBreakMode(BreakMode.NONE); syncServiceMock.reset(); // WHEN TestUtil.displayWhen(TEST_NAME); PrismObject<ResourceType> resource = provisioningService.getObject(ResourceType.class, RESOURCE_DUMMY_OID, null, task, result); TestUtil.displayThen(TEST_NAME); assertSuccess(result); display("Resource after", resource); IntegrationTestTools.displayXml("Resource after (XML)", resource); assertHasSchema(resource, "dummy"); } @Test public void test200AddAccountNullAttributes() throws Exception { final String TEST_NAME = "test200AddAccountNullAttributes"; TestUtil.displayTestTile(TEST_NAME); // GIVEN Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); syncServiceMock.reset(); ShadowType accountType = parseObjectTypeFromFile(ACCOUNT_WILL_FILENAME, ShadowType.class); PrismObject<ShadowType> account = accountType.asPrismObject(); account.checkConsistence(); account.removeContainer(ShadowType.F_ATTRIBUTES); display("Adding shadow", account); try { // WHEN TestUtil.displayWhen(TEST_NAME); provisioningService.addObject(account, null, null, task, result); AssertJUnit.fail("The addObject operation was successful. But expecting an exception."); } catch (SchemaException e) { // This is expected display("Expected exception", e); } TestUtil.displayThen(TEST_NAME); syncServiceMock.assertNotifyFailureOnly(); } @Test public void test201AddAccountEmptyAttributes() throws Exception { TestUtil.displayTestTile("test201AddAccountEmptyAttributes"); // GIVEN Task task = taskManager.createTaskInstance(TestDummyNegative.class.getName() + ".test201AddAccountEmptyAttributes"); OperationResult result = new OperationResult(TestDummyNegative.class.getName() + ".test201AddAccountEmptyAttributes"); syncServiceMock.reset(); ShadowType accountType = parseObjectTypeFromFile(ACCOUNT_WILL_FILENAME, ShadowType.class); PrismObject<ShadowType> account = accountType.asPrismObject(); account.checkConsistence(); account.findContainer(ShadowType.F_ATTRIBUTES).getValue().clear(); display("Adding shadow", account); try { // WHEN provisioningService.addObject(account, null, null, task, result); AssertJUnit.fail("The addObject operation was successful. But expecting an exception."); } catch (SchemaException e) { // This is expected display("Expected exception", e); } syncServiceMock.assertNotifyFailureOnly(); } @Test public void test210AddAccountNoObjectclass() throws Exception { TestUtil.displayTestTile("test210AddAccountNoObjectclass"); // GIVEN Task task = taskManager.createTaskInstance(TestDummyNegative.class.getName() + ".test210AddAccountNoObjectclass"); OperationResult result = new OperationResult(TestDummyNegative.class.getName() + ".test210AddAccountNoObjectclass"); syncServiceMock.reset(); ShadowType accountType = parseObjectTypeFromFile(ACCOUNT_WILL_FILENAME, ShadowType.class); PrismObject<ShadowType> account = accountType.asPrismObject(); account.checkConsistence(); // IMPORTANT: deliberately violating the schema accountType.setObjectClass(null); accountType.setKind(null); display("Adding shadow", account); try { // WHEN provisioningService.addObject(account, null, null, task, result); AssertJUnit.fail("The addObject operation was successful. But expecting an exception."); } catch (SchemaException e) { // This is expected display("Expected exception", e); } syncServiceMock.assertNotifyFailureOnly(); } @Test public void test220AddAccountNoResourceRef() throws Exception { final String TEST_NAME = "test220AddAccountNoResourceRef"; TestUtil.displayTestTile(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyNegative.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); syncServiceMock.reset(); ShadowType accountType = parseObjectTypeFromFile(ACCOUNT_WILL_FILENAME, ShadowType.class); PrismObject<ShadowType> account = accountType.asPrismObject(); account.checkConsistence(); accountType.setResourceRef(null); display("Adding shadow", account); try { // WHEN provisioningService.addObject(account, null, null, task, result); AssertJUnit.fail("The addObject operation was successful. But expecting an exception."); } catch (SchemaException e) { // This is expected display("Expected exception", e); } //FIXME: not sure, if this check is needed..if the reosurce is not specified, provisioning probably will be not called. // syncServiceMock.assertNotifyFailureOnly(); } @Test public void test221DeleteAccountResourceNotFound() throws Exception { final String TEST_NAME = "test221DeleteAccountResourceNotFound"; TestUtil.displayTestTile(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyNegative.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); syncServiceMock.reset(); ShadowType accountType = parseObjectTypeFromFile(ACCOUNT_ELAINE_RESOURCE_NOT_FOUND_FILENAME, ShadowType.class); PrismObject<ShadowType> account = accountType.asPrismObject(); account.checkConsistence(); // accountType.setResourceRef(null); display("Adding shadow", account); try { // WHEN String oid = repositoryService.addObject(account, null, result); ProvisioningOperationOptions options = ProvisioningOperationOptions.createForce(true); provisioningService.deleteObject(ShadowType.class, oid, options, null, task, result); // AssertJUnit.fail("The addObject operation was successful. But expecting an exception."); } catch (SchemaException e) { // This is expected display("Expected exception", e); } //FIXME: is this really notify failure? the resource does not exist but shadow is deleted. maybe other case of notify? // syncServiceMock.assertNotifyFailureOnly(); } /** * Try to get an account when a shadow has been deleted (but the account exists). * Proper ObjectNotFoundException is expected, compensation should not run. */ @Test public void test230GetAccountDeletedShadow() throws Exception { final String TEST_NAME = "test230GetAccountDeletedShadow"; TestUtil.displayTestTile(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummyNegative.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject<ShadowType> account = PrismTestUtil.parseObject(ACCOUNT_MORGAN_FILE); String shadowOid = provisioningService.addObject(account, null, null, task, result); repositoryService.deleteObject(ShadowType.class, shadowOid, result); // reset task = taskManager.createTaskInstance(TestDummyNegative.class.getName() + "." + TEST_NAME); result = task.getResult(); syncServiceMock.reset(); try { // WHEN provisioningService.getObject(ShadowType.class, shadowOid, null, task, result); AssertJUnit.fail("Unexpected success"); } catch (ObjectNotFoundException e) { // this is expected display("Expected exception", e); result.computeStatus(); display("Result", result); TestUtil.assertFailure(result); } syncServiceMock.assertNoNotifyChange(); } }