Skip to content

Commit

Permalink
Add first link-related tests (MID-6109)
Browse files Browse the repository at this point in the history
Created experimental midpoint.findAssignee/findAssignees methods
to make inter-object links navigation easier.

Also introduced experimental AbstractEmptyModelIntegrationTest.

Cleaning up display() calls when asserters are created. (We decided
to call display() automatically only when creating asserters in known
contexts like "before" and "after" some operation.)
  • Loading branch information
mederly committed Apr 24, 2020
1 parent a5685a1 commit 4845cac
Show file tree
Hide file tree
Showing 21 changed files with 622 additions and 136 deletions.
Expand Up @@ -158,10 +158,10 @@ private boolean isThresholdTriggered(CollectionStats stats, PrismObject<ObjectCo

WaterMarkType highWaterMark = policyThreshold.getHighWaterMark();
if (highWaterMark != null) {
Integer warterMarkCount = highWaterMark.getCount();
if (warterMarkCount != null) {
if (stats.getObjectCount() > warterMarkCount) {
LOGGER.trace("Rule NOT triggered on {} because high watermark count exceeded (watermark: {}, actual: {})", collection, warterMarkCount, stats.getObjectCount());
Integer waterMarkCount = highWaterMark.getCount();
if (waterMarkCount != null) {
if (stats.getObjectCount() > waterMarkCount) {
LOGGER.trace("Rule NOT triggered on {} because high watermark count exceeded (watermark: {}, actual: {})", collection, waterMarkCount, stats.getObjectCount());
return false;
}
}
Expand All @@ -178,16 +178,16 @@ private boolean isThresholdTriggered(CollectionStats stats, PrismObject<ObjectCo
}
}

WaterMarkType lowhWaterMark = policyThreshold.getLowWaterMark();
if (lowhWaterMark != null) {
Integer warterMarkCount = lowhWaterMark.getCount();
if (warterMarkCount != null) {
if (stats.getObjectCount() < warterMarkCount) {
LOGGER.trace("Rule NOT triggered on {} because low watermark count not reached (watermark: {}, actual: {})", collection, warterMarkCount, stats.getObjectCount());
WaterMarkType lowWaterMark = policyThreshold.getLowWaterMark();
if (lowWaterMark != null) {
Integer waterMarkCount = lowWaterMark.getCount();
if (waterMarkCount != null) {
if (stats.getObjectCount() < waterMarkCount) {
LOGGER.trace("Rule NOT triggered on {} because low watermark count not reached (watermark: {}, actual: {})", collection, waterMarkCount, stats.getObjectCount());
return false;
}
}
Float waterMarkPercentage = lowhWaterMark.getPercentage();
Float waterMarkPercentage = lowWaterMark.getPercentage();
if (waterMarkPercentage != null) {
Float percentage = stats.computePercentage();
if (percentage == null) {
Expand Down Expand Up @@ -243,10 +243,9 @@ public void compileObjectCollectionView(CompiledObjectCollectionView existingVie

// TODO: support more cases
if (QNameUtil.match(ArchetypeType.COMPLEX_TYPE, collectionRefType)) {
RefFilter filter = null;
filter = (RefFilter) prismContext.queryFor(AssignmentHolderType.class)
.item(AssignmentHolderType.F_ARCHETYPE_REF).ref(collectionRef.getOid())
.buildFilter();
RefFilter filter = (RefFilter) prismContext.queryFor(AssignmentHolderType.class)
.item(AssignmentHolderType.F_ARCHETYPE_REF).ref(collectionRef.getOid())
.buildFilter();
filter.setTargetTypeNullAsAny(true);
filter.setRelationNullAsAny(true);
existingView.setFilter(filter);
Expand Down
Expand Up @@ -23,6 +23,7 @@
import com.evolveum.midpoint.model.impl.expr.triggerSetter.OptimizingTriggerCreatorImpl;
import com.evolveum.midpoint.model.impl.expr.triggerSetter.TriggerCreatorGlobalState;
import com.evolveum.midpoint.model.impl.lens.LensContext;
import com.evolveum.midpoint.model.impl.lens.LensFocusContext;
import com.evolveum.midpoint.model.impl.lens.LensProjectionContext;
import com.evolveum.midpoint.model.api.context.SynchronizationIntent;
import com.evolveum.midpoint.model.impl.messaging.MessageWrapper;
Expand Down Expand Up @@ -58,6 +59,7 @@
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.Holder;
import com.evolveum.midpoint.util.LocalizableMessage;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.Producer;
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.midpoint.util.exception.*;
Expand Down Expand Up @@ -2016,4 +2018,50 @@ public <T> ResourceAttributeDefinition<T> getAttributeDefinition(PrismObject<Res
String attributeName) throws SchemaException {
return getAttributeDefinition(resource, new QName(objectClassName), new QName(attributeName));
}

@Experimental
public <T extends AssignmentHolderType> T findAssignee(Class<T> type) throws CommunicationException, ObjectNotFoundException,
SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
return MiscUtil.extractSingleton(findAssignees(type), () -> new IllegalStateException("More than one assignee found"));
}

@Experimental
public <T extends AssignmentHolderType> List<T> findAssignees(Class<T> type) throws CommunicationException,
ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException,
ExpressionEvaluationException {
ObjectQuery query = prismContext.queryFor(type)
.item(AssignmentHolderType.F_ROLE_MEMBERSHIP_REF)
.ref(getFocusObjectReference().asReferenceValue().clone())
.build();
return searchObjects(type, query, null);
}

@Experimental
@NotNull
private ObjectReferenceType getFocusObjectReference() {
ObjectType focusObject = getFocusObjectAny();
String oid = focusObject.getOid();
if (oid == null) {
throw new IllegalStateException("No OID in focus object");
}
return ObjectTypeUtil.createObjectRef(focusObject, prismContext);
}

@Experimental
@NotNull
private <T extends ObjectType> T getFocusObjectAny() {
LensContext<T> lensContext = (LensContext<T>) getModelContext();
if (lensContext == null) {
throw new IllegalStateException("No model context present. Are you calling this method within model operation?");
}
LensFocusContext<T> focusContext = lensContext.getFocusContext();
if (focusContext == null) {
throw new IllegalStateException("No focus context present");
}
PrismObject<T> object = focusContext.getObjectAny();
if (object == null) {
throw new IllegalStateException("No old, current, nor new object in focus context");
}
return object.asObjectable();
}
}
Expand Up @@ -208,9 +208,10 @@ public boolean partialExecute(String componentName, ProjectorProcessor processor

private boolean shouldExecute(String componentName, ProjectorProcessor processor, LensContext<?> context, LensProjectionContext projectionContext) throws SchemaException {
ProcessorExecution processorExecution = processor.getClass().getAnnotation(ProcessorExecution.class);
return processorExecution == null || focusPresenceAndTypeCheckPasses(componentName, context, processorExecution)
&& focusDeletionCheckPasses(componentName, context.getFocusContext(), processorExecution)
&& projectionDeletionCheckPasses(componentName, projectionContext, processorExecution);
return processorExecution == null ||
focusPresenceAndTypeCheckPasses(componentName, context, processorExecution)
&& focusDeletionCheckPasses(componentName, context.getFocusContext(), processorExecution)
&& projectionDeletionCheckPasses(componentName, projectionContext, processorExecution);
}

private boolean focusPresenceAndTypeCheckPasses(String componentName, LensContext<?> context,
Expand Down
Expand Up @@ -9,22 +9,17 @@
import static org.testng.AssertJUnit.assertNotNull;

import com.evolveum.midpoint.model.api.context.EvaluatedAssignmentTarget;
import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest;
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismReferenceValue;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.delta.ReferenceDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.schema.PrismSchema;
import com.evolveum.midpoint.provisioning.ucf.impl.builtin.ManualConnectorInstance;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.internals.InternalsConfig;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.DummyResourceContoller;
import com.evolveum.midpoint.test.IntegrationTestTools;
import com.evolveum.midpoint.test.util.TestUtil;
Expand All @@ -36,24 +31,20 @@
import org.testng.AssertJUnit;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegrationTest {
public class AbstractConfiguredModelIntegrationTest extends AbstractEmptyModelIntegrationTest {

public static final File SYSTEM_CONFIGURATION_FILE = new File(COMMON_DIR, "system-configuration.xml");
public static final String SYSTEM_CONFIGURATION_OID = SystemObjectsType.SYSTEM_CONFIGURATION.value();

protected static final int NUMBER_OF_GLOBAL_POLICY_RULES = 7;

public static final File USER_ADMINISTRATOR_FILE = new File(COMMON_DIR, "user-administrator.xml");
protected static final String USER_ADMINISTRATOR_OID = "00000000-0000-0000-0000-000000000002";

protected static final String USER_TEMPLATE_FILENAME = COMMON_DIR + "/user-template.xml";
protected static final String USER_TEMPLATE_OID = "10000000-0000-0000-0000-000000000002";

Expand Down Expand Up @@ -179,9 +170,6 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra
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";

public static final File ROLE_SUPERUSER_FILE = new File(COMMON_DIR, "role-superuser.xml");
protected static final String ROLE_SUPERUSER_OID = "00000000-0000-0000-0000-000000000004";

protected static final File ROLE_PIRATE_FILE = new File(COMMON_DIR, "role-pirate.xml");
protected static final String ROLE_PIRATE_OID = "12345678-d34d-b33f-f00d-555555556666";
protected static final String ROLE_PIRATE_NAME = "Pirate";
Expand Down Expand Up @@ -552,39 +540,7 @@ public AbstractConfiguredModelIntegrationTest() {
super();
}

@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
logger.trace("initSystem");

// We want logging config from logback-test.xml and not from system config object (unless suppressed)
InternalsConfig.setAvoidLoggingChange(isAvoidLoggingChange());
super.initSystem(initTask, initResult);

modelService.postInit(initResult);
ManualConnectorInstance.setRandomDelayRange(0);

// System Configuration
PrismObject<SystemConfigurationType> configuration;
try {
File systemConfigurationFile = getSystemConfigurationFile();
if (systemConfigurationFile != null) {
configuration = repoAddObjectFromFile(systemConfigurationFile, initResult);
} else {
configuration = addSystemConfigurationObject(initResult);
}
} catch (ObjectAlreadyExistsException e) {
throw new ObjectAlreadyExistsException("System configuration already exists in repository;" +
"looks like the previous test haven't cleaned it up", e);
}
if (configuration != null) {
relationRegistry.applyRelationsConfiguration(configuration.asObjectable());
}

// Users
userAdministrator = repoAddObjectFromFile(USER_ADMINISTRATOR_FILE, UserType.class, initResult);
repoAddObjectFromFile(ROLE_SUPERUSER_FILE, initResult);
login(userAdministrator);
}
// initSystem is the same as in the superclass

protected int getNumberOfUsers() {
return 1; // Administrator
Expand All @@ -598,12 +554,6 @@ protected File getSystemConfigurationFile() {
return SYSTEM_CONFIGURATION_FILE;
}

// to be used in very specific cases only (it is invoked when getSystemConfigurationFile returns null).
protected PrismObject<SystemConfigurationType> addSystemConfigurationObject(OperationResult initResult) throws IOException, CommonException,
EncryptionException {
return null;
}

protected PrismObject<UserType> getDefaultActor() {
return userAdministrator;
}
Expand Down
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2020 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.model.intest;

import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.provisioning.ucf.impl.builtin.ManualConnectorInstance;
import com.evolveum.midpoint.schema.internals.InternalsConfig;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

import java.io.File;
import java.io.IOException;

/**
* Creates empty but functional environment for model integration tests - but without all the configured objects
* in {@link AbstractConfiguredModelIntegrationTest}.
*
* Creates a repo with:
* - empty system configuration
* - administrator user (from common dir)
* - superuser role (from common dir)
*/
@Experimental
public abstract class AbstractEmptyModelIntegrationTest extends AbstractModelIntegrationTest {

private static final File SYSTEM_CONFIGURATION_EMPTY_FILE = new File(COMMON_DIR, "system-configuration-empty.xml");

static final File USER_ADMINISTRATOR_FILE = new File(COMMON_DIR, "user-administrator.xml");
protected static final String USER_ADMINISTRATOR_OID = "00000000-0000-0000-0000-000000000002";

static final File ROLE_SUPERUSER_FILE = new File(COMMON_DIR, "role-superuser.xml");
protected static final String ROLE_SUPERUSER_OID = "00000000-0000-0000-0000-000000000004";

protected PrismObject<UserType> userAdministrator;

@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
logger.trace("initSystem");

// We want logging config from logback-test.xml and not from system config object (unless suppressed)
InternalsConfig.setAvoidLoggingChange(isAvoidLoggingChange());
super.initSystem(initTask, initResult);

modelService.postInit(initResult);
ManualConnectorInstance.setRandomDelayRange(0);

// System Configuration
PrismObject<SystemConfigurationType> configuration;
try {
File systemConfigurationFile = getSystemConfigurationFile();
if (systemConfigurationFile != null) {
configuration = repoAddObjectFromFile(systemConfigurationFile, initResult);
} else {
configuration = addSystemConfigurationObject(initResult);
}
} catch (ObjectAlreadyExistsException e) {
throw new ObjectAlreadyExistsException("System configuration already exists in repository;" +
"looks like the previous test haven't cleaned it up", e);
}
if (configuration != null) {
relationRegistry.applyRelationsConfiguration(configuration.asObjectable());
}

// Users
userAdministrator = repoAddObjectFromFile(USER_ADMINISTRATOR_FILE, UserType.class, initResult);
repoAddObjectFromFile(ROLE_SUPERUSER_FILE, initResult);
login(userAdministrator);
}

protected File getSystemConfigurationFile() {
return SYSTEM_CONFIGURATION_EMPTY_FILE;
}

// to be used in very specific cases only (it is invoked when getSystemConfigurationFile returns null).
protected PrismObject<SystemConfigurationType> addSystemConfigurationObject(OperationResult initResult)
throws IOException, CommonException, EncryptionException {
return null;
}
}

0 comments on commit 4845cac

Please sign in to comment.