From c750ceef37f99c162125787669f427087ff067c1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Genevi=C3=A8ve=20Bastien?= Date: Thu, 28 Apr 2016 12:23:25 -0400 Subject: [PATCH] requirements: Add a composite requirement MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This allows to group requirement together with one of the defined priority level. Change-Id: Ic88fe6c6d679f107244bd366d4d37816c9508b19 Signed-off-by: Geneviève Bastien --- .../CompositeRequirementTest.java | 171 ++++++++++++++++++ .../TmfCompositeAnalysisRequirement.java | 67 +++++++ 2 files changed, 238 insertions(+) create mode 100644 tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/CompositeRequirementTest.java create mode 100644 tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfCompositeAnalysisRequirement.java diff --git a/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/CompositeRequirementTest.java b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/CompositeRequirementTest.java new file mode 100644 index 0000000000..5c1dfdcec0 --- /dev/null +++ b/tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/CompositeRequirementTest.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2016 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.tests.analysis.requirements; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement.PriorityLevel; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.tests.stubs.trace.TmfTraceStub; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableSet; + +import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfCompositeAnalysisRequirement; + +/** + * Test the {@link TmfCompositeAnalysisRequirement} class + * + * @author Geneviève Bastien + */ +public class CompositeRequirementTest { + + private static final @NonNull TmfAnalysisRequirement FALSE_REQ1 = new TmfAnalysisRequirement(Collections.EMPTY_SET, PriorityLevel.MANDATORY) { + @Override + public boolean test(ITmfTrace trace) { + return false; + } + }; + + private static final @NonNull TmfAnalysisRequirement FALSE_REQ2 = new TmfAnalysisRequirement(Collections.EMPTY_SET, PriorityLevel.MANDATORY) { + @Override + public boolean test(ITmfTrace trace) { + return false; + } + }; + + private static final @NonNull TmfAnalysisRequirement TRUE_REQ1 = new TmfAnalysisRequirement(Collections.EMPTY_SET, PriorityLevel.MANDATORY) { + @Override + public boolean test(ITmfTrace trace) { + return true; + } + }; + + private static final @NonNull TmfAnalysisRequirement TRUE_REQ2 = new TmfAnalysisRequirement(Collections.EMPTY_SET, PriorityLevel.MANDATORY) { + @Override + public boolean test(ITmfTrace trace) { + return true; + } + }; + + private ITmfTrace fTrace; + + /** + * Setup a trace to be used in tests + */ + @Before + public void setupTrace() { + fTrace = new TmfTraceStub(); + } + + /** + * Test composite requirement with {@link PriorityLevel#MANDATORY} level + */ + @Test + public void testMandatory() { + ITmfTrace trace = fTrace; + assertNotNull(trace); + + TmfAnalysisRequirement req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1), PriorityLevel.MANDATORY); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1, TRUE_REQ2), PriorityLevel.MANDATORY); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1), PriorityLevel.MANDATORY); + assertFalse(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, TRUE_REQ1), PriorityLevel.MANDATORY); + assertFalse(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, FALSE_REQ2), PriorityLevel.MANDATORY); + assertFalse(req.test(trace)); + } + + /** + * Test composite requirement with {@link PriorityLevel#AT_LEAST_ONE} level + */ + @Test + public void testAtLeastOne() { + ITmfTrace trace = fTrace; + assertNotNull(trace); + + TmfAnalysisRequirement req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1), PriorityLevel.AT_LEAST_ONE); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1, TRUE_REQ2), PriorityLevel.AT_LEAST_ONE); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1), PriorityLevel.AT_LEAST_ONE); + assertFalse(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, TRUE_REQ1), PriorityLevel.AT_LEAST_ONE); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, FALSE_REQ2), PriorityLevel.AT_LEAST_ONE); + assertFalse(req.test(trace)); + } + + /** + * Test composite requirement with {@link PriorityLevel#ALL_OR_NOTHING} level + */ + @Test + public void testAllOrNothing() { + ITmfTrace trace = fTrace; + assertNotNull(trace); + + TmfAnalysisRequirement req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1), PriorityLevel.ALL_OR_NOTHING); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1, TRUE_REQ2), PriorityLevel.ALL_OR_NOTHING); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1), PriorityLevel.ALL_OR_NOTHING); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, TRUE_REQ1), PriorityLevel.ALL_OR_NOTHING); + assertFalse(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, FALSE_REQ2), PriorityLevel.ALL_OR_NOTHING); + assertTrue(req.test(trace)); + } + + /** + * Test composite requirement with {@link PriorityLevel#OPTIONAL} level + */ + @Test + public void testOptional() { + ITmfTrace trace = fTrace; + assertNotNull(trace); + + TmfAnalysisRequirement req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1), PriorityLevel.OPTIONAL); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(TRUE_REQ1, TRUE_REQ2), PriorityLevel.OPTIONAL); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1), PriorityLevel.OPTIONAL); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, TRUE_REQ1), PriorityLevel.OPTIONAL); + assertTrue(req.test(trace)); + + req = new TmfCompositeAnalysisRequirement(ImmutableSet.of(FALSE_REQ1, FALSE_REQ2), PriorityLevel.OPTIONAL); + assertTrue(req.test(trace)); + } + +} diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfCompositeAnalysisRequirement.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfCompositeAnalysisRequirement.java new file mode 100644 index 0000000000..d58bb95315 --- /dev/null +++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfCompositeAnalysisRequirement.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2016 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.tmf.core.analysis.requirements; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +import com.google.common.collect.ImmutableList; + +/** + * This class allows to group requirements together and implement their test for + * each level + * + * @author Geneviève Bastien + * @since 2.0 + */ +public class TmfCompositeAnalysisRequirement extends TmfAnalysisRequirement { + + private final Collection fSubReqs; + + /** + * Constructor with sub requirements + * + * @param subRequirements + * The collection of sub-requirements for this requirement + * @param level + * The level of this requirement + */ + public TmfCompositeAnalysisRequirement(Collection subRequirements, PriorityLevel level) { + super(Collections.EMPTY_SET, level); + fSubReqs = ImmutableList.copyOf(subRequirements); + } + + @Override + public boolean test(ITmfTrace trace) { + Collection subReqs = fSubReqs; + if (subReqs.isEmpty()) { + return true; + } + // Count the number of requirements testing to true + long count = subReqs.stream() + .filter(r -> r.test(trace)) + .count(); + switch (getPriorityLevel()) { + case ALL_OR_NOTHING: + return count == subReqs.size() || count == 0; + case AT_LEAST_ONE: + return count > 0; + case MANDATORY: + return count == subReqs.size(); + case OPTIONAL: + return true; + default: + throw new IllegalStateException("Composite requirement: Unknown value level"); //$NON-NLS-1$ + } + } + +} -- 2.34.1