Remove TestBundleDiag constructor
[odlparent.git] / bundles-test-lib / src / main / java / org / opendaylight / odlparent / bundlestest / lib / TestBundleDiag.java
1 /*
2  * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.odlparent.bundlestest.lib;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.util.concurrent.TimeUnit;
13 import java.util.function.BiConsumer;
14 import org.awaitility.Awaitility;
15 import org.awaitility.core.ConditionTimeoutException;
16 import org.opendaylight.odlparent.bundles.diag.DiagProvider;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 /**
21  * Utility to verify bundle diagnostic state.
22  *
23  * @author Michael Vorburger.ch, based on guidance from Christian Schneider
24  */
25 public class TestBundleDiag {
26     private static final Logger LOG = LoggerFactory.getLogger(TestBundleDiag.class);
27
28     private final DiagProvider diagProvider;
29
30     public TestBundleDiag(final DiagProvider diagProvider) {
31         this.diagProvider = requireNonNull(diagProvider);
32     }
33
34     /**
35      * Does something similar to Karaf's "diag" CLI command, and throws a {@link SystemStateFailureException} if
36      * anything including bundle wiring is not OK.
37      *
38      * <p>The implementation is based on Karaf's BundleService, and not the BundleStateService, because each Karaf
39      * supported DI system (such as Blueprint and Declarative Services, see String constants in BundleStateService),
40      * will have a separate BundleStateService.  The BundleService however will contain the combined status of all
41      * BundleStateServices.
42      *
43      * @param timeout maximum time to wait for bundles to settle
44      * @param timeoutUnit time unit of timeout
45      * @throws SystemStateFailureException if all bundles do not settle within the timeout period
46      */
47     public void checkBundleDiagInfos(final long timeout, final TimeUnit timeoutUnit)
48             throws SystemStateFailureException {
49         checkBundleDiagInfos(timeout, timeoutUnit, (timeInfo, bundleDiagInfos) ->
50             LOG.info("checkBundleDiagInfos: Elapsed time {}s, remaining time {}s, {}",
51                 timeInfo.elapsedTimeInMS() / 1000, timeInfo.remainingTimeInMS() / 1000,
52                 bundleDiagInfos.getFullDiagnosticText()));
53     }
54
55     public void checkBundleDiagInfos(final long timeout, final TimeUnit timeoutUnit,
56             final BiConsumer<TimeInfo, BundleDiagInfos> awaitingListener) throws SystemStateFailureException {
57         LOG.info("checkBundleDiagInfos() started...");
58         try {
59             Awaitility.await("checkBundleDiagInfos")
60                 .pollDelay(0, TimeUnit.MILLISECONDS)
61                 .pollInterval(1, TimeUnit.SECONDS)
62                 .atMost(timeout, timeoutUnit)
63                     .conditionEvaluationListener(condition -> awaitingListener.accept(
64                         new TimeInfo(condition.getElapsedTimeInMS(), condition.getRemainingTimeInMS()),
65                         (BundleDiagInfosImpl) condition.getValue()))
66                     .until(
67                         () -> BundleDiagInfosImpl.ofDiag(diagProvider.currentDiag()),
68                         new BundleServiceSummaryMatcher());
69
70             // If we're here then either BundleServiceSummaryMatcher quit because of Active, Failure or Stopping..
71             final var diag = diagProvider.currentDiag();
72             final var bundleInfos = BundleDiagInfosImpl.ofDiag(diag);
73             final var systemState = bundleInfos.getSystemState();
74             if (systemState.equals(SystemState.Failure) || systemState.equals(SystemState.Stopping)) {
75                 LOG.error("""
76                     diag failure; BundleService reports bundle(s) which failed or are already stopping (details in \
77                     following INFO and ERROR log messages...)""");
78                 diag.logState(LOG);
79                 throw new SystemStateFailureException("diag failed; some bundles failed to start", bundleInfos);
80
81             } else {
82                 // Inform the developer of the green SystemState.Active
83                 LOG.info("diag successful; system state active ({})", bundleInfos.getFullDiagnosticText());
84             }
85
86         } catch (ConditionTimeoutException e) {
87             // If this happens then it got stuck waiting in SystemState.Booting,
88             // typically due to bundles still in BundleState GracePeriod or Waiting
89             LOG.error("""
90                 diag failure; BundleService reports bundle(s) which are still not active (details in following INFO \
91                 and ERROR log messages...)""");
92             final var diag = diagProvider.currentDiag();
93             diag.logState(LOG);
94             throw new SystemStateFailureException("diag timeout; some bundles are still not active:",
95                 BundleDiagInfosImpl.ofDiag(diag), e);
96         }
97     }
98 }