/*
* 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.model.intest;
import com.evolveum.icf.dummy.resource.DummyAccount;
import com.evolveum.icf.dummy.resource.DummyResource;
import com.evolveum.icf.dummy.resource.DummySyncStyle;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.DummyResourceContoller;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.testng.annotations.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static com.evolveum.midpoint.test.IntegrationTestTools.getAttributeValue;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
/**
* Tests for MID-2436 (volatile attributes).
*
* @author mederly
*
*/
@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class TestVolatility extends AbstractInitializedModelIntegrationTest {
public static final File TEST_DIR = new File("src/test/resources/volatility");
protected static final File RESOURCE_DUMMY_HR_FILE = new File(TEST_DIR, "resource-dummy-hr.xml");
protected static final String RESOURCE_DUMMY_HR_OID = "10000000-0000-0000-0000-00000000f004";
protected static final String RESOURCE_DUMMY_HR_NAME = "hr";
protected static final File RESOURCE_DUMMY_VOLATILE_FILE = new File(TEST_DIR, "resource-dummy-volatile.xml");
protected static final String RESOURCE_DUMMY_VOLATILE_OID = "10000000-0000-0000-0000-00000000f104";
protected static final String RESOURCE_DUMMY_VOLATILE_NAME = "volatile";
protected static final File RESOURCE_DUMMY_MONSTERIZED_FILE = new File(TEST_DIR, "resource-dummy-monsterized.xml");
protected static final String RESOURCE_DUMMY_MONSTERIZED_OID = "67a954d2-f391-11e6-a1d7-078381fe0e6f";
protected static final String RESOURCE_DUMMY_MONSTERIZED_NAME = "monsterized";
protected static final String ACCOUNT_MANCOMB_DUMMY_USERNAME = "mancomb";
protected static final String ACCOUNT_GUYBRUSH_DUMMY_USERNAME = "guybrush"; //Guybrush Threepwood
protected static final String ACCOUNT_LARGO_DUMMY_USERNAME = "largo";
protected static final String TASK_LIVE_SYNC_DUMMY_HR_FILENAME = TEST_DIR + "/task-dummy-hr-livesync.xml";
protected static final String TASK_LIVE_SYNC_DUMMY_HR_OID = "10000000-0000-0000-5555-55550000f004";
protected static final File USER_TEMPLATE_FILE = new File(TEST_DIR, "user-template-import-hr.xml");
protected static final File USER_LARGO_WITH_ASSIGNMENT_FILE = new File(TEST_DIR, "user-largo-with-assignment.xml");
@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
super.initSystem(initTask, initResult);
assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL);
repoAddObjectFromFile(USER_TEMPLATE_FILE, initResult);
initDummyResource(RESOURCE_DUMMY_HR_NAME, RESOURCE_DUMMY_HR_FILE, RESOURCE_DUMMY_HR_OID, ctl -> {
ctl.getDummyResource().setSyncStyle(DummySyncStyle.SMART);
ctl.getDummyResource().populateWithDefaultSchema();
}, initTask, initResult);
initDummyResource(RESOURCE_DUMMY_VOLATILE_NAME, RESOURCE_DUMMY_VOLATILE_FILE, RESOURCE_DUMMY_VOLATILE_OID, initTask, initResult);
initDummyResource(RESOURCE_DUMMY_MONSTERIZED_NAME, RESOURCE_DUMMY_MONSTERIZED_FILE, RESOURCE_DUMMY_MONSTERIZED_OID, initTask, initResult);
}
@Test
public void test100ImportLiveSyncTaskDummyHr() throws Exception {
final String TEST_NAME = "test100ImportLiveSyncTaskDummyHr";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TestVolatility.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
/// WHEN
TestUtil.displayWhen(TEST_NAME);
importSyncTask();
// THEN
TestUtil.displayThen(TEST_NAME);
waitForSyncTaskStart();
}
@Test
public void test110AddDummyHrAccountMancomb() throws Exception {
final String TEST_NAME = "test110AddDummyHrAccountMancomb";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TestVolatility.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// Preconditions
//assertUsers(5);
DummyAccount account = new DummyAccount(ACCOUNT_MANCOMB_DUMMY_USERNAME);
account.setEnabled(true);
account.addAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Mancomb Seepgood");
/// WHEN
TestUtil.displayWhen(TEST_NAME);
getDummyResource(RESOURCE_DUMMY_HR_NAME).addAccount(account);
waitForSyncTaskNextRun();
// THEN
TestUtil.displayThen(TEST_NAME);
PrismObject<ShadowType> accountMancombHr = findAccountByUsername(ACCOUNT_MANCOMB_DUMMY_USERNAME,
getDummyResourceObject(RESOURCE_DUMMY_HR_NAME));
display("Account mancomb on HR", accountMancombHr);
assertNotNull("No mancomb HR account shadow", accountMancombHr);
assertEquals("Wrong resourceRef in mancomb HR account", RESOURCE_DUMMY_HR_OID,
accountMancombHr.asObjectable().getResourceRef().getOid());
assertShadowOperationalData(accountMancombHr, SynchronizationSituationType.LINKED, null);
PrismObject<ShadowType> accountMancombVolatileTarget = findAccountByUsername(ACCOUNT_MANCOMB_DUMMY_USERNAME,
getDummyResourceObject(RESOURCE_DUMMY_VOLATILE_NAME));
display("Account mancomb on target", accountMancombVolatileTarget);
assertNotNull("No mancomb target account shadow", accountMancombVolatileTarget);
assertEquals("Wrong resourceRef in mancomb target account", RESOURCE_DUMMY_VOLATILE_OID,
accountMancombVolatileTarget.asObjectable().getResourceRef().getOid());
assertShadowOperationalData(accountMancombVolatileTarget, SynchronizationSituationType.LINKED, null);
PrismObject<UserType> userMancomb = findUserByUsername(ACCOUNT_MANCOMB_DUMMY_USERNAME);
display("User mancomb", userMancomb);
assertNotNull("User mancomb was not created", userMancomb);
assertLinks(userMancomb, 2);
assertLinked(userMancomb, accountMancombHr);
assertLinked(userMancomb, accountMancombVolatileTarget);
String descriptionOnResource = getAttributeValue(accountMancombVolatileTarget.asObjectable(),
DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DESCRIPTION_QNAME);
String descriptionOfUser = userMancomb.asObjectable().getDescription();
String expectedDescription = "Description of " + ACCOUNT_MANCOMB_DUMMY_USERNAME;
assertEquals("Wrong description on resource account", expectedDescription, descriptionOnResource);
assertEquals("Wrong description in user record", expectedDescription, descriptionOfUser);
// assertUsers(6);
// notifications
notificationManager.setDisabled(true);
}
@Test
public void test120UpdateDummyHrAccountMancomb() throws Exception {
final String TEST_NAME = "test120UpdateDummyHrAccountMancomb";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TestVolatility.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
/// WHEN
TestUtil.displayWhen(TEST_NAME);
DummyAccount account = getDummyResource(RESOURCE_DUMMY_HR_NAME).getAccountByUsername(ACCOUNT_MANCOMB_DUMMY_USERNAME);
account.replaceAttributeValue(DummyAccount.ATTR_FULLNAME_NAME, "Sir Mancomb Seepgood");
display("Dummy HR resource", getDummyResource(RESOURCE_DUMMY_HR_NAME).debugDump());
// Make sure we have steady state
waitForSyncTaskNextRun();
// THEN
TestUtil.displayThen(TEST_NAME);
PrismObject<ShadowType> accountMancombHr = findAccountByUsername(ACCOUNT_MANCOMB_DUMMY_USERNAME,
getDummyResourceObject(RESOURCE_DUMMY_HR_NAME));
display("Account mancomb on HR", accountMancombHr);
assertNotNull("No mancomb HR account shadow", accountMancombHr);
assertEquals("Wrong resourceRef in mancomb HR account", RESOURCE_DUMMY_HR_OID,
accountMancombHr.asObjectable().getResourceRef().getOid());
assertEquals("Wrong name in mancomb HR account", "Sir Mancomb Seepgood",
getAttributeValue(accountMancombHr.asObjectable(),
DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_QNAME));
assertShadowOperationalData(accountMancombHr, SynchronizationSituationType.LINKED, null);
PrismObject<ShadowType> accountMancombVolatileTarget = findAccountByUsername(ACCOUNT_MANCOMB_DUMMY_USERNAME,
getDummyResourceObject(RESOURCE_DUMMY_VOLATILE_NAME));
display("Account mancomb on target", accountMancombVolatileTarget);
assertNotNull("No mancomb target account shadow", accountMancombVolatileTarget);
assertEquals("Wrong resourceRef in mancomb target account", RESOURCE_DUMMY_VOLATILE_OID,
accountMancombVolatileTarget.asObjectable().getResourceRef().getOid());
assertEquals("Wrong name in mancomb target account", "Sir Mancomb Seepgood",
getAttributeValue(accountMancombHr.asObjectable(),
DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_QNAME));
assertShadowOperationalData(accountMancombVolatileTarget, SynchronizationSituationType.LINKED, null);
PrismObject<UserType> userMancomb = findUserByUsername(ACCOUNT_MANCOMB_DUMMY_USERNAME);
display("User mancomb", userMancomb);
assertNotNull("User mancomb is not there", userMancomb);
assertLinks(userMancomb, 2);
assertEquals("Wrong name in mancomb user", "Sir Mancomb Seepgood",
userMancomb.asObjectable().getFullName().getOrig());
assertLinked(userMancomb, accountMancombHr);
assertLinked(userMancomb, accountMancombVolatileTarget);
String descriptionOnResource = getAttributeValue(accountMancombVolatileTarget.asObjectable(),
DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DESCRIPTION_QNAME);
String descriptionOfUser = userMancomb.asObjectable().getDescription();
String expectedDescription = "Updated description of " + ACCOUNT_MANCOMB_DUMMY_USERNAME;
assertEquals("Wrong description on resource account", expectedDescription, descriptionOnResource);
assertEquals("Wrong description in user record", expectedDescription, descriptionOfUser);
// notifications
notificationManager.setDisabled(true);
}
@Test
public void test200ModifyGuybrushAssignAccount() throws Exception {
final String TEST_NAME = "test200ModifyGuybrushAssignAccount";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TestVolatility.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// Preconditions
//assertUsers(5);
TestUtil.displayWhen(TEST_NAME);
Collection<ObjectDelta<? extends ObjectType>> deltas = new ArrayList<ObjectDelta<? extends ObjectType>>();
ObjectDelta<UserType> accountAssignmentUserDelta = createAccountAssignmentUserDelta(USER_GUYBRUSH_OID, RESOURCE_DUMMY_VOLATILE_OID, null, true);
deltas.add(accountAssignmentUserDelta);
// WHEN
modelService.executeChanges(deltas, null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
PrismObject<UserType> userGuybrush = findUserByUsername(ACCOUNT_GUYBRUSH_DUMMY_USERNAME);
display("User guybrush", userGuybrush);
assertNotNull("User guybrush is not there", userGuybrush);
assertLinks(userGuybrush, 1);
PrismObject<ShadowType> accountGuybrushVolatileTarget = findAccountByUsername(ACCOUNT_GUYBRUSH_DUMMY_USERNAME,
getDummyResourceObject(RESOURCE_DUMMY_VOLATILE_NAME));
display("Account guybrush on target", accountGuybrushVolatileTarget);
assertNotNull("No guybrush target account shadow", accountGuybrushVolatileTarget);
assertEquals("Wrong resourceRef in guybrush target account", RESOURCE_DUMMY_VOLATILE_OID,
accountGuybrushVolatileTarget.asObjectable().getResourceRef().getOid());
assertShadowOperationalData(accountGuybrushVolatileTarget, SynchronizationSituationType.LINKED, null);
assertLinked(userGuybrush, accountGuybrushVolatileTarget);
String descriptionOnResource = getAttributeValue(accountGuybrushVolatileTarget.asObjectable(),
DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DESCRIPTION_QNAME);
String descriptionOfUser = userGuybrush.asObjectable().getDescription();
String expectedDescription = "Description of " + ACCOUNT_GUYBRUSH_DUMMY_USERNAME;
assertEquals("Wrong description on resource account", expectedDescription, descriptionOnResource);
assertEquals("Wrong description in user record", expectedDescription, descriptionOfUser);
// assertUsers(6);
// notifications
notificationManager.setDisabled(true);
}
@Test
public void test300AddLargo() throws Exception {
final String TEST_NAME = "test300AddLargo";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TestVolatility.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// Preconditions
//assertUsers(5);
TestUtil.displayWhen(TEST_NAME);
PrismObject<UserType> user = PrismTestUtil.parseObject(USER_LARGO_WITH_ASSIGNMENT_FILE);
ObjectDelta<UserType> userDelta = ObjectDelta.createAddDelta(user);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta);
// WHEN
modelService.executeChanges(deltas, null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
PrismObject<UserType> userLargo = findUserByUsername(ACCOUNT_LARGO_DUMMY_USERNAME);
display("User largo", userLargo);
assertNotNull("User largo is not there", userLargo);
assertLinks(userLargo, 1);
PrismObject<ShadowType> accountLargoVolatileTarget = findAccountByUsername(ACCOUNT_LARGO_DUMMY_USERNAME,
getDummyResourceObject(RESOURCE_DUMMY_VOLATILE_NAME));
display("Account largo on target", accountLargoVolatileTarget);
assertNotNull("No largo target account shadow", accountLargoVolatileTarget);
assertEquals("Wrong resourceRef in largo target account", RESOURCE_DUMMY_VOLATILE_OID,
accountLargoVolatileTarget.asObjectable().getResourceRef().getOid());
assertShadowOperationalData(accountLargoVolatileTarget, SynchronizationSituationType.LINKED, null);
assertLinked(userLargo, accountLargoVolatileTarget);
String descriptionOnResource = getAttributeValue(accountLargoVolatileTarget.asObjectable(),
DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DESCRIPTION_QNAME);
String descriptionOfUser = userLargo.asObjectable().getDescription();
String expectedDescription = "Description of " + ACCOUNT_LARGO_DUMMY_USERNAME;
assertEquals("Wrong description on resource account", expectedDescription, descriptionOnResource);
assertEquals("Wrong description in user record", expectedDescription, descriptionOfUser);
// assertUsers(6);
// notifications
notificationManager.setDisabled(true);
}
/**
* MID-3727
*/
@Test
public void test400AddHerman() throws Exception {
final String TEST_NAME = "test400AddHerman";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TestVolatility.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
PrismObject<UserType> userBefore = PrismTestUtil.parseObject(USER_HERMAN_FILE);
AssignmentType assignmentType = createAccountAssignment(RESOURCE_DUMMY_MONSTERIZED_OID, null);
userBefore.asObjectable().getAssignment().add(assignmentType);
userBefore.asObjectable().getOrganization().add(createPolyStringType("foo"));
userBefore.asObjectable().getOrganization().add(createPolyStringType(DummyResource.VALUE_COOKIE));
userBefore.asObjectable().getOrganization().add(createPolyStringType("bar"));
display("User before", userBefore);
// WHEN
TestUtil.displayWhen(TEST_NAME);
addObject(userBefore, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> userAfter = getUser(USER_HERMAN_OID);
display("User after", userAfter);
assertNotNull("User not there", userAfter);
assertLinks(userAfter, 1);
DummyAccount dummyAccount = assertDummyAccount(RESOURCE_DUMMY_MONSTERIZED_NAME, USER_HERMAN_USERNAME);
display("Dummy account", dummyAccount);
assertDummyAccountAttribute(RESOURCE_DUMMY_MONSTERIZED_NAME, USER_HERMAN_USERNAME,
DummyAccount.ATTR_INTERESTS_NAME, "foo", "bar", DummyResource.VALUE_COOKIE);
}
/**
* Monsterized resource is volatile: Monster has eaten the cookie. But we still
* want the cookie to be in the values. The volatility=explosive should fix it.
* MID-3727
*/
@Test
public void test402ModifyHermanMonster() throws Exception {
final String TEST_NAME = "test402ModifyHermanMonster";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TestVolatility.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserAdd(USER_HERMAN_OID, UserType.F_ORGANIZATION, task, result,
createPolyString(DummyResource.VALUE_MONSTER));
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> userAfter = getUser(USER_HERMAN_OID);
display("User after", userAfter);
assertNotNull("User not there", userAfter);
assertLinks(userAfter, 1);
DummyAccount dummyAccount = assertDummyAccount(RESOURCE_DUMMY_MONSTERIZED_NAME, USER_HERMAN_USERNAME);
display("Dummy account", dummyAccount);
assertDummyAccountAttribute(RESOURCE_DUMMY_MONSTERIZED_NAME, USER_HERMAN_USERNAME,
DummyAccount.ATTR_INTERESTS_NAME,
"foo", "bar", DummyResource.VALUE_COOKIE, DummyResource.VALUE_MONSTER);
}
protected void importSyncTask() throws FileNotFoundException {
importObjectFromFile(TASK_LIVE_SYNC_DUMMY_HR_FILENAME);
}
protected void waitForSyncTaskStart() throws Exception {
waitForTaskStart(TASK_LIVE_SYNC_DUMMY_HR_OID, false, 10000);
}
protected void waitForSyncTaskNextRun() throws Exception {
waitForTaskNextRunAssertSuccess(TASK_LIVE_SYNC_DUMMY_HR_OID, false, 10000);
}
}