Skip to content

Commit

Permalink
Make more model-intest tests pass
Browse files Browse the repository at this point in the history
1. A lot of tests were adapted to the new repo shadows handling.
2. Application of new classification to in-memory shadows
was fixed in ClassificationHelper. Application of the same
info to in-repo shadows in shadow updater was removed (causes
problems in shadows simulation mode).
3. ProvisioningOperationContext is now correctly set for
propagation operations.
4. Loot (in piracy extension for dummy resource) is now long,
not int. Some intests put java timestamps there.
5. Other minor fixes in provisioning-impl.

Work in progress.

Related to MID-2119 (shadow caching).
  • Loading branch information
mederly committed Dec 23, 2023
1 parent 4ac0632 commit 69d67f2
Show file tree
Hide file tree
Showing 34 changed files with 450 additions and 354 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,10 @@ default Collection<? extends QName> getNamesOfAttributesWithInboundExpressions()
return ((ResourceAttributeDefinition<T>) findAttributeDefinitionRequired(attrName))
.instantiateFromRealValues(List.of(realValues));
}

default @NotNull Collection<ItemName> getAllAttributesNames() {
return getAttributeDefinitions(ResourceAttributeDefinition.class).stream()
.map(ItemDefinition::getItemName)
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

import org.jetbrains.annotations.VisibleForTesting;

/**
* An alternative representation of a {@link ResourceAttributeDefinition} that describes a normalization-aware resource attribute:
* one that has both original and normalized values. Such attributes are to be stored in the repository, to facilitate
Expand Down Expand Up @@ -525,10 +527,14 @@ private T toNormalizationAwarePolyStringValue(
"Cannot convert from %s to %s".formatted(plainRealValue.getClass(), getTypeClass()));
}
//noinspection unchecked
return (T) new PolyString(
oldStringValue,
polyNormalizer.normalizeString(oldStringValue),
new PolyStringTranslationType().key("dummy")); // only to serialize the string in full; TODO remove eventually
return (T) wrap(oldStringValue, polyNormalizer.normalizeString(oldStringValue));
}

@VisibleForTesting
public static PolyString wrap(String orig, String norm) {
// The lang is only to serialize the string in full; TODO remove eventually MID-2119
return new PolyString(
orig, norm, new PolyStringTranslationType().key("dummy"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected void checkDefinition(@NotNull PrismPropertyDefinition<T> def) {
Preconditions.checkArgument(
def instanceof ResourceAttributeDefinition,
"Definition should be %s not %s" ,
ResourceAttributeContainerDefinition.class.getSimpleName(), definition.getClass().getName());
ResourceAttributeDefinition.class.getSimpleName(), definition.getClass().getName());
}

@Override
Expand Down Expand Up @@ -187,6 +187,11 @@ private <T2> PrismPropertyValue<T2> convertAndNormalize(
} else if (oldRealValue instanceof RawType raw) {
return new PrismPropertyValueImpl<>(
raw.getParsedRealValue(newJavaType));
} else if (Long.class.equals(newJavaType) && oldRealValue instanceof Integer integer) {
// FIXME temporary hack MID-2119 (loot was int, but needed to carry long values ... so we made it long,
// but this code is here to avoid crashing on int values)
//noinspection unchecked
return (PrismPropertyValue<T2>) new PrismPropertyValueImpl<>(integer.longValue());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@

package com.evolveum.midpoint.model.impl.lens.projector.focus;

import static com.evolveum.midpoint.model.impl.lens.LensUtil.setMappingTarget;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateMappingEvaluationPhaseType.BEFORE_ASSIGNMENTS;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;

import com.evolveum.midpoint.schema.config.*;

import jakarta.xml.bind.JAXBElement;
import javax.xml.datatype.XMLGregorianCalendar;

import org.jetbrains.annotations.NotNull;
Expand All @@ -41,6 +36,7 @@
import com.evolveum.midpoint.prism.path.PathKeyedMap;
import com.evolveum.midpoint.prism.path.UniformItemPath;
import com.evolveum.midpoint.prism.util.ObjectDeltaObject;
import com.evolveum.midpoint.schema.config.*;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
Expand Down Expand Up @@ -418,27 +414,6 @@ private ObjectTemplateMappingConfigItem getOrCreateItemSelectionMapping(
return selectionMapping.setTargetIfMissing(ref);
}

private void setDefaultStrong(ObjectTemplateMappingType mapping) {
if (mapping.getStrength() == null) {
mapping.setStrength(MappingStrengthType.STRONG);
}
}

private void setDefaultRelativityAbsolute(ObjectTemplateMappingType mapping) {
ExpressionType expression = mapping.getExpression();
if (expression == null) {
return;
}
for (JAXBElement<?> evaluator : expression.getExpressionEvaluator()) {
Object evaluatorValue = evaluator.getValue();
if (evaluatorValue instanceof TransformExpressionEvaluatorType transform) {
if (transform.getRelativityMode() == null) {
transform.setRelativityMode(TransformExpressionRelativityModeType.ABSOLUTE);
}
}
}
}

private ObjectTemplateMappingConfigItem getAuthoritativeSourceMapping(MultiSourceDataHandlingConfigItem handlingCI) {
var mapping = handlingCI.getDefaultAuthoritativeSource();
if (mapping != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public void test020ModifyLootAbsolute() throws Exception {
setDebugListener();

DummyAccount dummyAccount = getDummyResource().getAccountByUsername(ACCOUNT_JACK_DUMMY_USERNAME);
dummyAccount.addAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 999);
dummyAccount.addAttributeValue(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOOT_NAME, 999L);

ResourceObjectShadowChangeDescription change = new ResourceObjectShadowChangeDescription();
PrismObject<ShadowType> accountShadowJack = provisioningService.getObject(ShadowType.class, accountShadowJackDummyOid, null, task, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.test.TestObject;
import com.evolveum.midpoint.test.TestObject;

import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
Expand Down Expand Up @@ -157,14 +156,12 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractEmptyModelIn
protected static final String RESOURCE_DUMMY_SCHEMALESS_FILENAME = COMMON_DIR + "/resource-dummy-schemaless-no-schema.xml";
protected static final String RESOURCE_DUMMY_SCHEMALESS_OID = "ef2bc95b-76e0-59e2-86d6-9999dddd0000";
protected static final String RESOURCE_DUMMY_SCHEMALESS_NAME = "schemaless";
protected static final String RESOURCE_DUMMY_SCHEMALESS_NAMESPACE = MidPointConstants.NS_RI;

// Upcase resource turns all names to upper case. It is also caseInsensitive resource
protected static final File RESOURCE_DUMMY_UPCASE_FILE = new File(COMMON_DIR, "resource-dummy-upcase.xml");
protected static final String RESOURCE_DUMMY_UPCASE_OID = "10000000-0000-0000-0000-000000001204";
protected static final String RESOURCE_DUMMY_UPCASE_NAME = "upcase";
protected static final String RESOURCE_DUMMY_UPCASE_NAMESPACE = MidPointConstants.NS_RI;
protected static final QName RESOURCE_DUMMY_UPCASE_ASSOCIATION_GROUP_QNAME = new QName(RESOURCE_DUMMY_UPCASE_NAMESPACE, "group");
protected static final QName RESOURCE_DUMMY_UPCASE_ASSOCIATION_GROUP_QNAME = new QName(MidPointConstants.NS_RI, "group");

protected static final String RESOURCE_DUMMY_FAKE_FILENAME = COMMON_DIR + "/resource-dummy-fake.xml";
protected static final String RESOURCE_DUMMY_FAKE_OID = "10000000-0000-0000-0000-00000000000f";
Expand Down Expand Up @@ -395,7 +392,6 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractEmptyModelIn

public static final File GROUP_SHADOW_JOKER_DUMMY_UPCASE_FILE = new File(COMMON_DIR, "group-shadow-dummy-upcase-joker.xml");
public static final String GROUP_SHADOW_JOKER_DUMMY_UPCASE_OID = "bc2a1d98-9ca4-11e4-a600-001e8c717e5b";
public static final String GROUP_SHADOW_JOKER_DUMMY_UPCASE_NAME = "joker";
public static final String GROUP_JOKER_DUMMY_UPCASE_NAME = "JOKER";

public static final String DUMMY_ORG_TOP_NAME = DummyResourceContoller.ORG_TOP_NAME;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,31 @@
*/
package com.evolveum.midpoint.model.intest;

import static org.testng.AssertJUnit.assertEquals;

import static com.evolveum.midpoint.schema.constants.SchemaConstants.*;
import static com.evolveum.midpoint.test.IntegrationTestTools.toRepoPoly;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.datatype.XMLGregorianCalendar;

import org.springframework.beans.factory.annotation.Autowired;
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 com.evolveum.icf.dummy.resource.DummyGroup;
import com.evolveum.midpoint.prism.PrismConstants;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.match.MatchingRule;
import com.evolveum.midpoint.prism.match.MatchingRuleRegistry;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.util.PrismAsserts;
import com.evolveum.midpoint.schema.SearchResultList;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.internals.InternalCounters;
import com.evolveum.midpoint.schema.internals.InternalMonitor;
import com.evolveum.midpoint.schema.internals.InternalOperationClasses;
Expand All @@ -32,22 +45,6 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.springframework.beans.factory.annotation.Autowired;
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 javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import static com.evolveum.midpoint.schema.constants.SchemaConstants.*;

import static org.testng.AssertJUnit.assertEquals;

/**
* Test various case ignore and case transformation scenarios.
*
Expand Down Expand Up @@ -87,7 +84,8 @@ public class TestCaseIgnore extends AbstractInitializedModelIntegrationTest {
public void initSystem(Task initTask, OperationResult initResult)
throws Exception {
super.initSystem(initTask, initResult);
caseIgnoreMatchingRule = matchingRuleRegistry.getMatchingRule(PrismConstants.STRING_IGNORE_CASE_MATCHING_RULE_NAME, DOMUtil.XSD_STRING);
caseIgnoreMatchingRule =
matchingRuleRegistry.getMatchingRule(PrismConstants.STRING_IGNORE_CASE_MATCHING_RULE_NAME, DOMUtil.XSD_STRING);
preTestCleanup(AssignmentPolicyEnforcementType.FULL);

repoAddObjectFromFile(ROLE_X_FILE, initResult);
Expand Down Expand Up @@ -167,7 +165,7 @@ public void test133SearchAccountShadows() throws Exception {
rememberCounter(InternalCounters.SHADOW_FETCH_OPERATION_COUNT);

// WHEN
when();
when();
SearchResultList<PrismObject<ShadowType>> foundShadows = modelService.searchObjects(ShadowType.class, query, null, task, result);

// THEN
Expand All @@ -187,14 +185,16 @@ public void test133SearchAccountShadows() throws Exception {
accountOid = getSingleLinkOid(userJack);

// Check shadow
var accountShadow = getShadowRepo(accountOid);
display("Repo shadow", accountShadow);
assertAccountShadowRepo(accountShadow, accountOid, ACCOUNT_JACK_DUMMY_UPCASE_NAME, resourceDummyUpcaseType, caseIgnoreMatchingRule);
var repoShadow = getShadowRepo(accountOid);
display("Repo shadow", repoShadow);
assertAccountShadowRepo(repoShadow, accountOid, ACCOUNT_JACK_DUMMY_UPCASE_NAME,
resourceDummyUpcaseType, caseIgnoreMatchingRule);

// Check account
PrismObject<ShadowType> accountModel = modelService.getObject(ShadowType.class, accountOid, null, task, result);
display("Model shadow", accountModel);
assertAccountShadowModel(accountModel, accountOid, ACCOUNT_JACK_DUMMY_UPCASE_NAME, resourceDummyUpcaseType, caseIgnoreMatchingRule);
assertAccountShadowModel(accountModel, accountOid, ACCOUNT_JACK_DUMMY_UPCASE_NAME,
resourceDummyUpcaseType, caseIgnoreMatchingRule);

// Check account in dummy resource
assertDummyAccount(RESOURCE_DUMMY_UPCASE_NAME, ACCOUNT_JACK_DUMMY_UPCASE_NAME, "Jack Sparrow", true);
Expand Down Expand Up @@ -410,13 +410,12 @@ public void test161JackAssignRoleJoker() throws Exception {
display("User jack before", userBefore);

// WHEN
when();
when();
assignRole(USER_JACK_OID, ROLE_JOKER_OID, task, result);

// THEN
then();
result.computeStatus();
TestUtil.assertSuccess(result);
then();
assertSuccess(result);

// Make sure this is repository so we do not destroy the "evidence" yet.
PrismObject<UserType> userJack = repositoryService.getObject(UserType.class, USER_JACK_OID, null, result);
Expand Down Expand Up @@ -688,14 +687,14 @@ public void test200GuybrushAssignRoleFools() throws Exception {
PrismObject<ShadowType> groupFoolsRepoShadow = repositoryService.getObject(ShadowType.class, shadowRef.getOid(), null, result);
display("group fools repo shadow", groupFoolsRepoShadow);

PrismAsserts.assertPropertyValue(groupFoolsRepoShadow, ICFS_NAME_PATH, GROUP_DUMMY_FOOLS_NAME.toLowerCase());
PrismAsserts.assertPropertyValue(groupFoolsRepoShadow, ICFS_UID_PATH, GROUP_DUMMY_FOOLS_NAME.toLowerCase());
PrismAsserts.assertPropertyValue(groupFoolsRepoShadow, ICFS_NAME_PATH, toRepoPoly(GROUP_DUMMY_FOOLS_NAME));
PrismAsserts.assertPropertyValue(groupFoolsRepoShadow, ICFS_UID_PATH, toRepoPoly(GROUP_DUMMY_FOOLS_NAME));
assertShadowKindIntent(groupFoolsRepoShadow, ShadowKindType.ENTITLEMENT, INTENT_DUMMY_GROUP);

assertShadows(6);

}

@SuppressWarnings("SameParameterValue")
private void preTestCleanup(AssignmentPolicyEnforcementType enforcementPolicy) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException {
assumeAssignmentPolicy(enforcementPolicy);
dummyAuditService.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,9 @@ public void test100JackAssignAccountDummyConflicting() throws Exception {
account.addAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Jack Sparrow");
account.addAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, "Tortuga");
getDummyResource().addAccount(account);
repoAddObject(createShadow(getDummyResourceObject(), ACCOUNT_JACK_DUMMY_USERNAME), result);
repoAddObject(
createRepoShadow(getDummyResourceObject(), ACCOUNT_JACK_DUMMY_USERNAME).getPrismObject(),
result);

ObjectDelta<UserType> accountAssignmentUserDelta = createAccountAssignmentUserDelta(USER_JACK_OID, RESOURCE_DUMMY_OID, null, true);

Expand Down Expand Up @@ -284,7 +286,9 @@ public void test200JackAssignAccountDummyPinkConflicting() throws Exception {
account.addAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Jack Pinky");
account.addAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, "Red Sea");
getDummyResource(RESOURCE_DUMMY_PINK_NAME).addAccount(account);
repoAddObject(createShadow(getDummyResourceObject(RESOURCE_DUMMY_PINK_NAME), ACCOUNT_JACK_DUMMY_USERNAME), result);
repoAddObject(
createRepoShadow(getDummyResourceObject(RESOURCE_DUMMY_PINK_NAME), ACCOUNT_JACK_DUMMY_USERNAME).getPrismObject(),
result);

// assignment with weapon := 'pistol' (test for
Collection<ItemDelta<?, ?>> modifications = new ArrayList<>();
Expand Down Expand Up @@ -480,7 +484,9 @@ public void test230ScroogeAddAccountDummyConflictingNoShadow() throws Exception
getDummyResource(RESOURCE_DUMMY_PINK_NAME).addAccount(account);

PrismObject<UserType> userScrooge = createUser("scrooge", "Scrooge McDuck", true);
PrismObject<ShadowType> newPinkyShadow = createShadow(getDummyResourceType(RESOURCE_DUMMY_PINK_NAME).asPrismObject(), null, null);
PrismObject<ShadowType> newPinkyShadow =
createShadow(getDummyResourceType(RESOURCE_DUMMY_PINK_NAME).asPrismObject(), null, null)
.getPrismObject();
ObjectReferenceType linkRef = new ObjectReferenceType();
linkRef.asReferenceValue().setObject(newPinkyShadow);
userScrooge.asObjectable().getLinkRef().add(linkRef);
Expand Down Expand Up @@ -522,7 +528,8 @@ public void test235HackerAddAccountDummyEternalConflict() throws Exception {
dummyAuditService.clear();

PrismObject<UserType> userJoeHacker = createUser("hacker", "Joe Hacker", true);
PrismObject<ShadowType> newPinkyShadow = createShadow(getDummyResourceObject(RESOURCE_DUMMY_PINK_NAME), null, null);
PrismObject<ShadowType> newPinkyShadow =
createShadow(getDummyResourceObject(RESOURCE_DUMMY_PINK_NAME), null, null).getPrismObject();
ObjectReferenceType linkRef = new ObjectReferenceType();
linkRef.asReferenceValue().setObject(newPinkyShadow);
userJoeHacker.asObjectable().getLinkRef().add(linkRef);
Expand Down Expand Up @@ -1033,7 +1040,9 @@ public void test300JackAssignAccountDummyVioletConflicting() throws Exception {
account.addAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, "Jack Violet");
account.addAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME, "Sea of Lavender");
getDummyResource(RESOURCE_DUMMY_VIOLET_NAME).addAccount(account);
repoAddObject(createShadow(getDummyResourceObject(RESOURCE_DUMMY_VIOLET_NAME), ACCOUNT_JACK_DUMMY_USERNAME), result);
repoAddObject(
createRepoShadow(getDummyResourceObject(RESOURCE_DUMMY_VIOLET_NAME), ACCOUNT_JACK_DUMMY_USERNAME).getPrismObject(),
result);

Collection<ObjectDelta<? extends ObjectType>> deltas = new ArrayList<>();
ObjectDelta<UserType> accountAssignmentUserDelta = createAccountAssignmentUserDelta(USER_JACK_OID, RESOURCE_DUMMY_VIOLET_OID, null, true);
Expand Down

0 comments on commit 69d67f2

Please sign in to comment.