requirements: Add a composite requirement
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Thu, 28 Apr 2016 16:23:25 +0000 (12:23 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Thu, 12 May 2016 21:18:32 +0000 (17:18 -0400)
This allows to group requirement together with one of the defined priority
level.

Change-Id: Ic88fe6c6d679f107244bd366d4d37816c9508b19
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/analysis/requirements/CompositeRequirementTest.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/analysis/requirements/TmfCompositeAnalysisRequirement.java [new file with mode: 0644]

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 (file)
index 0000000..5c1dfdc
--- /dev/null
@@ -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 (file)
index 0000000..d58bb95
--- /dev/null
@@ -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<TmfAnalysisRequirement> 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<TmfAnalysisRequirement> subRequirements, PriorityLevel level) {
+        super(Collections.EMPTY_SET, level);
+        fSubReqs = ImmutableList.copyOf(subRequirements);
+    }
+
+    @Override
+    public boolean test(ITmfTrace trace) {
+        Collection<TmfAnalysisRequirement> 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$
+        }
+    }
+
+}
This page took 0.027339 seconds and 5 git commands to generate.