Time consuming builds detection, including timed out suites time-consumer-detection 132/head
authorDmitriy Pavlov <dpavlov@apache.org>
Sat, 6 Jul 2019 12:20:47 +0000 (15:20 +0300)
committerDmitriy Pavlov <dpavlov@apache.org>
Sat, 6 Jul 2019 12:20:47 +0000 (15:20 +0300)
ignite-tc-helper-web/src/main/webapp/buildtime.html
tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/buildtime/BuildTimeService.java
tcbot-engine/src/main/java/org/apache/ignite/tcbot/engine/ui/BuildTimeResultUi.java
tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/build/FatBuildDao.java
tcbot-teamcity-ignited/src/main/java/org/apache/ignite/tcignited/buildtime/BuildTimeResult.java

index 2e1dcc4e9bbe760f4baffa552847618bacebe9ba..7090beb565636af2aa485b2bc8231ab21334f36e 100644 (file)
@@ -50,6 +50,7 @@ function loadAnalytics() {
         methods: {
             setBuildTimeStat(data) {
                 this.byBuildType = data.byBuildType;
+                this.timedOutByBuildType = data.timedOutByBuildType;
 
                 $("#loadStatus").html("");
             },
@@ -85,6 +86,7 @@ function loadData() {
 
 
 <div class="formgroup"  id="app">
+
     <v-app id="readyForReview">
         <!--<v-expansion-panel>-->
             <!--<v-expansion-panel-content-->
@@ -95,6 +97,7 @@ function loadData() {
                     <div>Build types longest avg.duration</div>
                 </template>
                 <v-card>
+                    <div>Longest average duration (more than 90 minutes)</div>
                     <v-data-table
                             :headers="headers"
                             :items="byBuildType"
@@ -111,6 +114,19 @@ function loadData() {
                             <td class="text-xs-right">{{ props.item.totalDuration }}</td>
                         </template>
                     </v-data-table>
+
+                    <div>Timed out suites average duration (more than 60 minutes)</div>
+                    <v-data-table
+                            :headers="headers"
+                            :items="timedOutByBuildType"
+                            class="elevation-1"
+                    >
+                        <template v-slot:items="props">
+                            <td class="text-xs-right">{{ props.item.buildType }}</td>
+                            <td class="text-xs-right">{{ props.item.averageDuration }}</td>
+                            <td class="text-xs-right">{{ props.item.totalDuration }}</td>
+                        </template>
+                    </v-data-table>
                 </v-card>
             <!--</v-expansion-panel-content>-->
         <!--</v-expansion-panel>-->
index 7001e35de7bce526ebafb31690b468c9af05561c..6e47757145668b20b9cf3e6a27ac25e7cffdd4f8 100644 (file)
@@ -76,26 +76,31 @@ public class BuildTimeService {
 
         BuildTimeResultUi resultUi = new BuildTimeResultUi();
 
-        long minDuration = Duration.ofMinutes(60).toMillis();
+        long minDuration = Duration.ofMinutes(90).toMillis();
+        long minDurationTimeout = Duration.ofMinutes(60).toMillis();
         int cntToInclude = 50;
-        BuildTimeResult  res = lastRes1d;
-        List<Map.Entry<Long, BuildTimeRecord>> entries = res.topByBuildTypes(availableServers, minDuration, cntToInclude);
+        BuildTimeResult res = lastRes1d;
 
-        entries.forEach(e -> {
-            BuildTimeRecordUi buildTimeRecordUi = new BuildTimeRecordUi();
-            Long key = e.getKey();
-            int btId = BuildTimeResult.cacheKeyToBuildType(key);
-            buildTimeRecordUi.buildType = compactor.getStringFromId(btId);
+        res.topByBuildTypes(availableServers, minDuration, cntToInclude)
+                .stream().map(this::convertToUi).forEach(e -> resultUi.byBuildType.add(e));
 
-            buildTimeRecordUi.averageDuration = TimeUtil.millisToDurationPrintable(e.getValue().avgDuration());
-            buildTimeRecordUi.totalDuration =  TimeUtil.millisToDurationPrintable(e.getValue().totalDuration());
-
-            resultUi.byBuildType.add(buildTimeRecordUi);
-        });
+        res.topTimeoutsByBuildTypes(availableServers, minDurationTimeout, cntToInclude)
+                .stream().map(this::convertToUi).forEach(e -> resultUi.timedOutByBuildType.add(e));
 
         return resultUi;
     }
 
+    public BuildTimeRecordUi convertToUi(Map.Entry<Long, BuildTimeRecord> e) {
+        BuildTimeRecordUi buildTimeRecordUi = new BuildTimeRecordUi();
+        Long key = e.getKey();
+        int btId = BuildTimeResult.cacheKeyToBuildType(key);
+        buildTimeRecordUi.buildType = compactor.getStringFromId(btId);
+
+        buildTimeRecordUi.averageDuration = TimeUtil.millisToDurationPrintable(e.getValue().avgDuration());
+        buildTimeRecordUi.totalDuration =  TimeUtil.millisToDurationPrintable(e.getValue().totalDuration());
+        return buildTimeRecordUi;
+    }
+
     @SuppressWarnings("WeakerAccess")
     @MonitoredTask(name = "Load Build Time Analytics")
     protected void loadAnalytics() {
index 5bcebc9f6d2394b8e5c812b13fec678b748917a3..295a141affc892c329765af37a4e7d3ee5bb5668 100644 (file)
@@ -25,4 +25,5 @@ import java.util.List;
 @SuppressWarnings({"WeakerAccess", "PublicField"})
 public class BuildTimeResultUi {
     public List<BuildTimeRecordUi> byBuildType = new ArrayList<>();
+    public List<BuildTimeRecordUi> timedOutByBuildType = new ArrayList<>();
 }
index d3ef1355bddc98e32c23ca25185f28693a470c60..5b4740d62dfd53463124c20867755ccc378c845c 100644 (file)
@@ -240,6 +240,7 @@ public class FatBuildDao {
     public BuildTimeResult loadBuildTimeResult(int ageDays, List<Long> idsToCheck) {
         int stateRunning = compactor.getStringId(BuildRef.STATE_RUNNING);
         Integer buildDurationId = compactor.getStringIdIfPresent(Statistics.BUILD_DURATION);
+        int timeoutProblemCode = compactor.getStringId(ProblemOccurrence.TC_EXECUTION_TIMEOUT);
 
         BuildTimeResult res = new BuildTimeResult();
 
@@ -258,7 +259,9 @@ public class FatBuildDao {
                             System.err.println("Running " + runningTime + " BT: " + buildTypeId);
 
                             int srvId = BuildRefDao.cacheKeyToSrvId(key);
-                            res.add(srvId, buildTypeId, runningTime);
+                            boolean hasTimeout = build.hasBuildProblemType(timeoutProblemCode);
+
+                            res.add(srvId, buildTypeId, runningTime, hasTimeout);
                         }
                     });
                 }
index 0a05e74ecaa05b2b4432b032e8a3c419ac58aa14..c5a68df4d6ae25f652b257676f4473fad8317904 100644 (file)
@@ -3,13 +3,18 @@ package org.apache.ignite.tcignited.buildtime;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 public class BuildTimeResult {
     private Map<Long, BuildTimeRecord> btByBuildType = new HashMap<>();
+    private Map<Long, BuildTimeRecord> timedOutByBuildType = new HashMap<>();
 
-    public void add(int srvId, int buildTypeId, long runningTime) {
-        btByBuildType.computeIfAbsent(buildTypeToCacheKey(srvId, buildTypeId), k->new BuildTimeRecord())
-                .addInvocation(runningTime);
+    public void add(int srvId, int buildTypeId, long runningTime, boolean hasTimeout) {
+        long cacheKey = buildTypeToCacheKey(srvId, buildTypeId);
+        btByBuildType.computeIfAbsent(cacheKey, k -> new BuildTimeRecord()).addInvocation(runningTime);
+
+        if (hasTimeout)
+            timedOutByBuildType.computeIfAbsent(cacheKey, k -> new BuildTimeRecord()).addInvocation(runningTime);
     }
 
     public static long buildTypeToCacheKey(long srvId, int btId) {
@@ -29,17 +34,32 @@ public class BuildTimeResult {
     public List<Map.Entry<Long, BuildTimeRecord>> topByBuildTypes(Set<Integer> availableServers,
                                                                   long minAvgDurationMs,
                                                                   int maxCnt) {
-        return btByBuildType.entrySet().stream()
-                .filter(e -> {
-                    Long key = e.getKey();
-                    int srvId = cacheKeyToSrvId(key);
-                    return availableServers.contains(srvId);
-                })
-                .filter(e -> e.getValue().avgDuration() > minAvgDurationMs)
+        return filtered(btByBuildType, availableServers, minAvgDurationMs)
+                .sorted(Comparator.comparing(
+                        (Function<Map.Entry<Long, BuildTimeRecord>, Long>) entry -> entry.getValue().avgDuration())
+                        .reversed())
+                .limit(maxCnt)
+                .collect(Collectors.toList());
+    }
+
+    public List<Map.Entry<Long, BuildTimeRecord>> topTimeoutsByBuildTypes(Set<Integer> availableServers,
+                                                                  long minAvgDurationMs,
+                                                                  int maxCnt) {
+        return filtered(timedOutByBuildType, availableServers, minAvgDurationMs)
                 .sorted(Comparator.comparing(
                         (Function<Map.Entry<Long, BuildTimeRecord>, Long>) entry -> entry.getValue().avgDuration())
                         .reversed())
                 .limit(maxCnt)
                 .collect(Collectors.toList());
     }
+
+    private Stream<Map.Entry<Long, BuildTimeRecord>> filtered(Map<Long, BuildTimeRecord> map, Set<Integer> availableServers, long minAvgDurationMs) {
+        return map.entrySet().stream()
+                .filter(e -> {
+                    Long key = e.getKey();
+                    int srvId = cacheKeyToSrvId(key);
+                    return availableServers.contains(srvId);
+                })
+                .filter(e -> e.getValue().avgDuration() > minAvgDurationMs);
+    }
 }