You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dp...@apache.org on 2019/08/05 16:16:20 UTC

[ignite-teamcity-bot] branch master updated: IGNITE-11962: Fix detection of newly contributed tests: detect new tests only, filter out init errors (new Missing status was instroduced, new test requires 4missing&4failures) - Fixes #143.

This is an automated email from the ASF dual-hosted git repository.

dpavlov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-teamcity-bot.git


The following commit(s) were added to refs/heads/master by this push:
     new 9456568  IGNITE-11962: Fix detection of newly contributed tests: detect new tests only, filter out init errors (new Missing status was instroduced, new test requires 4missing&4failures) - Fixes #143.
9456568 is described below

commit 9456568d198d2587957388cb4716ff5dcabc8b31
Author: Dmitriy Pavlov <dp...@apache.org>
AuthorDate: Mon Aug 5 19:16:07 2019 +0300

    IGNITE-11962: Fix detection of newly contributed tests: detect new tests only, filter out init errors (new Missing status was instroduced, new test requires 4missing&4failures) - Fixes #143.
    
    Signed-off-by: Dmitriy Pavlov <dp...@apache.org>
---
 .../src/main/webapp/js/testfails-2.2.js            |  2 +
 .../ignite/tcbot/engine/issue/EventTemplate.java   | 30 ++++++--
 .../ignite/tcbot/engine/issue/EventTemplates.java  |  6 +-
 .../teamcity/ignited/runhist/InvocationData.java   | 37 ++++++++--
 .../teamcity/ignited/runhist/RunHistCompacted.java | 80 +++++++++++++---------
 .../ignite/tcignited/build/SuiteHistory.java       |  8 +--
 .../ignite/tcignited/history/IEventTemplate.java   |  4 +-
 .../apache/ignite/tcignited/history/RunStatus.java |  4 +-
 8 files changed, 118 insertions(+), 53 deletions(-)

diff --git a/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js b/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js
index 75ba7ac..e744146 100644
--- a/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js
+++ b/ignite-tc-helper-web/src/main/webapp/js/testfails-2.2.js
@@ -1032,6 +1032,8 @@ function drawLatestRunsBlock(state, len) {
         runColor = "grey";
     else if (state === 3)
         runColor = "black";
+    else if (state === 4)
+        runColor = "lightgrey";
 
     return "<span style='background-color: " + runColor + "; width:" + (len * 1) + "px; height:10px; display: inline-block;'></span>";
 }
\ No newline at end of file
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplate.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplate.java
index 9aad878..0298bc3 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplate.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplate.java
@@ -22,7 +22,11 @@ import org.apache.ignite.tcignited.history.IEventTemplate;
 public class EventTemplate implements IEventTemplate {
     private final int[] beforeEvent;
     private final int[] eventAndAfter;
-    private boolean shouldBeFirst;
+    private boolean includeMissing = false;
+    /**
+     * Event template eventAndAfter should be always first build in history of non-missed object.
+     */
+    private boolean shouldBeFirstNonMissing = false;
 
     public EventTemplate(int[] beforeEvent, int[] eventAndAfter) {
         this.beforeEvent = beforeEvent;
@@ -37,17 +41,29 @@ public class EventTemplate implements IEventTemplate {
         return eventAndAfter;
     }
 
-    public int cntEvents() {
-        return beforeEvent.length + eventAndAfter.length;
+    @Override
+    public boolean includeMissing() {
+        return includeMissing;
     }
 
-    public EventTemplate setShouldBeFirst(boolean shouldBeFirst) {
-        this.shouldBeFirst = shouldBeFirst;
+    @Override
+    public boolean shouldBeFirstNonMissing() {
+        return shouldBeFirstNonMissing;
+    }
+
+    EventTemplate includeMissing(boolean include) {
+        this.includeMissing = include;
 
         return this;
     }
 
-    public boolean shouldBeFirst() {
-        return shouldBeFirst;
+    public int cntEvents() {
+        return beforeEvent.length + eventAndAfter.length;
+    }
+
+    public EventTemplate onlyForFirstNonMissing(boolean shouldBeFirst) {
+        this.shouldBeFirstNonMissing = shouldBeFirst;
+
+        return this;
     }
 }
diff --git a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplates.java b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplates.java
index 5bd11b8..b979475 100644
--- a/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplates.java
+++ b/tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/issue/EventTemplates.java
@@ -24,10 +24,12 @@ import static org.apache.ignite.tcignited.history.RunStatus.RES_CRITICAL_FAILURE
 import static org.apache.ignite.tcignited.history.RunStatus.RES_FAILURE;
 import static org.apache.ignite.tcignited.history.RunStatus.RES_OK;
 import static org.apache.ignite.tcignited.history.RunStatus.RES_OK_OR_FAILURE;
+import static org.apache.ignite.tcignited.history.RunStatus.RES_MISSING;
 
 public class EventTemplates {
     private static final int OK = RES_OK.getCode();
     private static final int FAIL = RES_FAILURE.getCode();
+    private static final int MISSING = RES_MISSING.getCode();
 
     public static final EventTemplate newFailure = new EventTemplate(
             new int[]{OK, OK, OK, OK, OK},
@@ -40,9 +42,9 @@ public class EventTemplates {
     );
 
     public static final EventTemplate newContributedTestFailure = new EventTemplate(
-            new int[]{},
+            new int[]{MISSING, MISSING, MISSING, MISSING},
             new int[]{FAIL, FAIL, FAIL, FAIL}
-    ).setShouldBeFirst(true);
+    ).includeMissing(true).onlyForFirstNonMissing(true);
 
     public static final EventTemplate newFailureForFlakyTest = new EventTemplate(
             new int[]{OK, OK, OK, OK, OK},
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java
index f973c07..0e18020 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/InvocationData.java
@@ -18,15 +18,13 @@
 package org.apache.ignite.ci.teamcity.ignited.runhist;
 
 import com.google.common.base.MoreObjects;
+import org.apache.ignite.tcignited.history.RunStatus;
 
+import javax.annotation.Nonnull;
 import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import org.apache.ignite.tcignited.history.RunStatus;
-
-import javax.annotation.Nonnull;
-
 /**
  *
  */
@@ -39,6 +37,8 @@ public class InvocationData {
     public static final int OK = RunStatus.RES_OK.getCode();
     /** Ok. */
     public static final int CRITICAL_FAILURE = RunStatus.RES_CRITICAL_FAILURE.getCode();
+    /** Test is missing in suite run. */
+    public static final int MISSING = RunStatus.RES_MISSING.getCode();
 
     /** Invocations map from build ID to invocation data. */
     private final List<Invocation> invocationList = new ArrayList<>();
@@ -50,9 +50,9 @@ public class InvocationData {
     /**
      *
      */
-    public int notMutedRunsCount() {
+    public int notMutedAndNonMissingRunsCount() {
         return (int)
-            invocations()
+            invocations(true)
                 .filter(invocation -> invocation.status() != MUTED)
                 .count();
     }
@@ -62,7 +62,20 @@ public class InvocationData {
      */
     @Nonnull
     Stream<Invocation> invocations() {
-        return invocationList.stream();
+        return invocations(false);
+    }
+
+
+    /**
+     * @param skipMissing Skip missing (absent) invocations.
+     */
+    @Nonnull Stream<Invocation> invocations(boolean skipMissing) {
+        Stream<Invocation> stream = invocationList.stream();
+
+        if (skipMissing)
+            stream = stream.filter(invocation -> invocation.status() != MISSING);
+
+        return stream;
     }
 
     /**
@@ -118,4 +131,14 @@ public class InvocationData {
     public Set<Integer> buildIds() {
         return invocationList.stream().map(Invocation::buildId).collect(Collectors.toSet());
     }
+
+    public void registerMissing(Integer testId, Set<Integer> suiteBuildIds) {
+        Set<Integer> idsPresent = buildIds();
+        HashSet<Integer> toAdd = new HashSet<>(suiteBuildIds);
+        toAdd.removeAll(idsPresent);
+
+        toAdd.forEach(id -> {
+            add(new Invocation(id).withStatus(MISSING));
+        });
+    }
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java
index 722ff7a..97ca64c 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/ci/teamcity/ignited/runhist/RunHistCompacted.java
@@ -18,21 +18,21 @@
 package org.apache.ignite.ci.teamcity.ignited.runhist;
 
 import com.google.common.base.MoreObjects;
-import org.apache.ignite.tcbot.common.TcBotConst;
-import org.apache.ignite.tcignited.history.ChangesState;
-import org.apache.ignite.tcignited.history.IEventTemplate;
-import org.apache.ignite.tcignited.history.IRunHistory;
-import org.apache.ignite.tcignited.history.RunStatus;
-
-import javax.annotation.Nullable;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
+import javax.annotation.Nullable;
+import org.apache.ignite.tcbot.common.TcBotConst;
+import org.apache.ignite.tcignited.history.ChangesState;
+import org.apache.ignite.tcignited.history.IEventTemplate;
+import org.apache.ignite.tcignited.history.IRunHistory;
+import org.apache.ignite.tcignited.history.RunStatus;
 
 /**
- *
+ * In memory replacement of invocation history (RunHist/RunStat).
  */
 public class RunHistCompacted implements IRunHistory {
     /** Data. */
@@ -47,7 +47,7 @@ public class RunHistCompacted implements IRunHistory {
 
     /** {@inheritDoc} */
     @Override public int getRunsCount() {
-        return data.notMutedRunsCount();
+        return data.notMutedAndNonMissingRunsCount();
     }
 
     /** {@inheritDoc} */
@@ -80,12 +80,21 @@ public class RunHistCompacted implements IRunHistory {
         List<Invocation> latestRuns = data.invocations().collect(Collectors.toList());
 
         for (Invocation cur : latestRuns) {
-            if (prev != null && cur != null) {
+            if (cur == null)
+                continue;
+
+            if (cur.status() == InvocationData.MISSING)
+                continue;
+
+            //todo here all previous MISSING invocations status could be checked
+            // (using outside build history)
+            if (prev != null) {
                 if (prev.status() != cur.status()
                     && cur.changesState() == ChangesState.NONE
                     && prev.changesState() != ChangesState.UNKNOWN)
                     statusChange++;
             }
+
             prev = cur;
         }
         return statusChange;
@@ -101,8 +110,8 @@ public class RunHistCompacted implements IRunHistory {
         return data.criticalFailuresCount();
     }
 
-    @Override
-    public Set<Integer> buildIds() {
+    /** {@inheritDoc} */
+    @Override public Set<Integer> buildIds() {
         return data.buildIds();
     }
 
@@ -126,24 +135,29 @@ public class RunHistCompacted implements IRunHistory {
         assert centralEvtBuild < template.length;
         assert centralEvtBuild >= 0;
 
-        List<Invocation> histAsArr = data.invocations().collect(Collectors.toList());
+        boolean includeMissing = t.includeMissing();
+        List<Invocation> histAsArr = data.invocations(!includeMissing).collect(Collectors.toList());
 
         if (histAsArr.size() < template.length)
             return null;
 
         Integer detectedAt = null;
-        if (t.shouldBeFirst()) {
-            //todo detect somehow test is new (e.g. status absent for test history).
-            detectedAt = checkTemplateAtPos(template, centralEvtBuild, histAsArr, 0);
+
+        //startIgnite from the end to find most recent
+        for (int idx = histAsArr.size() - template.length; idx >= 0; idx--) {
+            detectedAt = checkTemplateAtPos(template, centralEvtBuild, histAsArr, idx);
+
+            if (detectedAt != null)
+                break;
         }
-        else {
-            //startIgnite from the end to find most recent
-            for (int idx = histAsArr.size() - template.length; idx >= 0; idx--) {
-                detectedAt = checkTemplateAtPos(template, centralEvtBuild, histAsArr, idx);
 
-                if (detectedAt != null)
-                    break;
-            }
+        if (detectedAt != null && t.shouldBeFirstNonMissing()) {
+            Optional<Invocation> first = data.invocations(true).findFirst();
+            if (!first.isPresent())
+                return null;
+
+            if (first.get().buildId() != detectedAt)
+                return null;
         }
 
         return detectedAt;
@@ -206,23 +220,27 @@ public class RunHistCompacted implements IRunHistory {
         data.sort();
     }
 
+    public void registerMissing(Integer testId, Set<Integer> buildIds) {
+        data.registerMissing(testId, buildIds);
+    }
+
     public RunHistCompacted filterSuiteInvByParms(Map<Integer, Integer> requireParameters) {
-        RunHistCompacted copy = new RunHistCompacted();
+        RunHistCompacted cp = new RunHistCompacted();
 
         data.invocations()
-                .filter(invocation -> invocation.containsParameterValue(requireParameters))
-                .forEach(invocation -> copy.data.add(invocation));
+            .filter(invocation -> invocation.containsParameterValue(requireParameters))
+            .forEach(invocation -> cp.data.add(invocation));
 
-        return copy;
+        return cp;
     }
 
     public RunHistCompacted filterByBuilds(Set<Integer> builds) {
-        RunHistCompacted copy = new RunHistCompacted();
+        RunHistCompacted cp = new RunHistCompacted();
 
         data.invocations()
-                .filter(invocation -> builds.contains(invocation.buildId()))
-                .forEach(invocation -> copy.data.add(invocation));
+            .filter(invocation -> builds.contains(invocation.buildId()))
+            .forEach(invocation -> cp.data.add(invocation));
 
-        return copy;
+        return cp;
     }
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
index 7d1b24f..fdca1d4 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/SuiteHistory.java
@@ -20,7 +20,6 @@ package org.apache.ignite.tcignited.build;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
-
 import org.apache.ignite.Ignite;
 import org.apache.ignite.ci.teamcity.ignited.runhist.Invocation;
 import org.apache.ignite.ci.teamcity.ignited.runhist.RunHistCompacted;
@@ -30,7 +29,7 @@ import org.apache.ignite.tcignited.history.ISuiteRunHistory;
 import org.apache.ignite.tcignited.history.SuiteInvocation;
 
 /**
- * Suite run history summary.
+ * Suite run history (in memory) summary with tests grouped by name.
  */
 public class SuiteHistory implements ISuiteRunHistory {
     /** Tests history: Test name ID->RunHistory */
@@ -46,8 +45,9 @@ public class SuiteHistory implements ISuiteRunHistory {
     private SuiteHistory() {}
 
     private void finalizeInvocations() {
-        //todo add missing status to tests
-        //  testsHistory.values().registerMissing(suiteHist.buildIds());
+        Set<Integer> presentBuilds = suiteHist.buildIds();
+
+        testsHistory.forEach((k, t) -> t.registerMissing(k, presentBuilds));
 
         suiteHist.sort();
         testsHistory.values().forEach(RunHistCompacted::sort);
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IEventTemplate.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IEventTemplate.java
index 85b5a6f..78b0edc 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IEventTemplate.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/IEventTemplate.java
@@ -24,5 +24,7 @@ public interface IEventTemplate {
 
     int[] eventAndAfter();
 
-    boolean shouldBeFirst();
+    boolean includeMissing();
+
+    boolean shouldBeFirstNonMissing();
 }
diff --git a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunStatus.java b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunStatus.java
index f468a9f..7f8171b 100644
--- a/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunStatus.java
+++ b/tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/history/RunStatus.java
@@ -34,7 +34,9 @@ public enum RunStatus {
     /** Result of test execution, muted failure found. */
     RES_MUTED_FAILURE(2),
     /** Result of suite: Critical failure, no results. */
-    RES_CRITICAL_FAILURE(3);
+    RES_CRITICAL_FAILURE(3),
+    /** Test is not present in current run */
+    RES_MISSING(4);
 
     /** Mapping of status int -> object. */
     private static Map<Integer, RunStatus> holder = Stream.of(values()).collect(Collectors.toMap(RunStatus::getCode, i -> i));