You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/04 21:51:59 UTC
[2/4] incubator-brooklyn git commit: brooklyn-utils-test-support: add
org.apache package prefix
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e06e79ab/utils/test-support/src/main/java/org/apache/brooklyn/test/PlatformTestSelectorListener.java
----------------------------------------------------------------------
diff --git a/utils/test-support/src/main/java/org/apache/brooklyn/test/PlatformTestSelectorListener.java b/utils/test-support/src/main/java/org/apache/brooklyn/test/PlatformTestSelectorListener.java
new file mode 100644
index 0000000..0282eee
--- /dev/null
+++ b/utils/test-support/src/main/java/org/apache/brooklyn/test/PlatformTestSelectorListener.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.test;
+
+import org.testng.IInvokedMethod;
+import org.testng.IInvokedMethodListener;
+import org.testng.ITestResult;
+import org.testng.SkipException;
+
+public class PlatformTestSelectorListener implements IInvokedMethodListener {
+ private static final String GROUP_UNIX = "UNIX";
+ private static final String GROUP_WINDOWS = "Windows";
+
+ public static boolean isWindows() {
+ return System.getProperty("os.name").startsWith("Windows");
+ }
+
+ @Override
+ public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
+ boolean isUnixTest = false;
+ boolean isWinTest = false;
+
+ String[] groups = method.getTestMethod().getGroups();
+ for (String group : groups) {
+ isUnixTest = isUnixTest || group.equalsIgnoreCase(GROUP_UNIX);
+ isWinTest = isWinTest || group.equalsIgnoreCase(GROUP_WINDOWS);
+ }
+
+ boolean isWinPlatform = isWindows();
+ if (isUnixTest || isWinTest) {
+ if (isWinPlatform && isUnixTest && !isWinTest) {
+ throw new SkipException("Skipping unix-specific test.");
+ } else if (!isWinPlatform && isWinTest && !isUnixTest) {
+ throw new SkipException("Skipping windows-specific test.");
+ }
+ }
+ }
+
+ @Override
+ public void afterInvocation(IInvokedMethod method, ITestResult testResult) {}
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e06e79ab/utils/test-support/src/main/java/org/apache/brooklyn/test/StatusListener.java
----------------------------------------------------------------------
diff --git a/utils/test-support/src/main/java/org/apache/brooklyn/test/StatusListener.java b/utils/test-support/src/main/java/org/apache/brooklyn/test/StatusListener.java
new file mode 100644
index 0000000..1803967
--- /dev/null
+++ b/utils/test-support/src/main/java/org/apache/brooklyn/test/StatusListener.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.test;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.IClass;
+import org.testng.ITestContext;
+import org.testng.ITestListener;
+import org.testng.ITestResult;
+
+/**
+ * adapted from the following class:
+ *
+ * @see org.jclouds.test.testng.UnitTestStatusListener
+ *
+ * normally not used, preferring instead LoggingVerboseReporter which prints out config info
+ */
+public class StatusListener implements ITestListener {
+
+ public static final Logger log = LoggerFactory.getLogger(StatusListener.class);
+
+ /**
+ * Holds test classes actually running in all threads.
+ */
+ private ThreadLocal<IClass> threadTestClass = new ThreadLocal<IClass>();
+ private ThreadLocal<Long> threadTestStart = new ThreadLocal<Long>();
+
+ private AtomicInteger failed = new AtomicInteger(0);
+ private AtomicInteger succeded = new AtomicInteger(0);
+ private AtomicInteger skipped = new AtomicInteger(0);
+
+ //TODO instead of system.out.println we should log -- *and* perhaps write to sysout if logger doesn't?
+ protected static void log(String msg) {
+ log.info(msg);
+ }
+
+ public void onTestStart(ITestResult res) {
+ log("Starting test " + getTestDesc(res));
+ threadTestClass.set(res.getTestClass());
+ threadTestStart.set(System.currentTimeMillis());
+ }
+
+ synchronized public void onTestSuccess(ITestResult arg0) {
+ log(getThreadId() + " Test " + getTestDesc(arg0) + " succeeded: " + (System.currentTimeMillis() - threadTestStart.get()) + "ms");
+ succeded.incrementAndGet();
+ printStatus();
+ }
+
+ synchronized public void onTestFailure(ITestResult arg0) {
+ log(getThreadId() + " Test " + getTestDesc(arg0) + " failed: "+arg0.getThrowable());
+ failed.incrementAndGet();
+ printStatus();
+ }
+
+ synchronized public void onTestSkipped(ITestResult arg0) {
+ System.out.println(getThreadId() + " Test " + getTestDesc(arg0) + " skipped.");
+ skipped.incrementAndGet();
+ printStatus();
+ }
+
+ public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
+ }
+
+ public void onStart(ITestContext arg0) {
+ }
+
+ public void onFinish(ITestContext arg0) {
+ }
+
+ private String getThreadId() {
+ return "[" + Thread.currentThread().getName() + "]";
+ }
+
+ private String getTestDesc(ITestResult res) {
+ return res.getMethod().getMethodName() + "(" + res.getTestClass().getName() + ")";
+ }
+
+ private void printStatus() {
+ log("Test suite progress: tests succeeded: " + succeded.get() + ", failed: " + failed.get() + ", skipped: " + skipped.get() + ".");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e06e79ab/utils/test-support/src/main/java/org/apache/brooklyn/test/TestResourceUnavailableException.java
----------------------------------------------------------------------
diff --git a/utils/test-support/src/main/java/org/apache/brooklyn/test/TestResourceUnavailableException.java b/utils/test-support/src/main/java/org/apache/brooklyn/test/TestResourceUnavailableException.java
new file mode 100644
index 0000000..c49a248
--- /dev/null
+++ b/utils/test-support/src/main/java/org/apache/brooklyn/test/TestResourceUnavailableException.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.test;
+
+import com.google.common.base.Throwables;
+import org.testng.SkipException;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Indicates that a test cannot be run as a necessary resource is not available.
+ *
+ * <p>This exception should be used by tests that need a particular test resource (i.e., a file that is conventionally
+ * in the <code>src/test/resources</code> folder, and that available as a classpath resource at runtime) is not
+ * available. It will cause TestNG to mark the test as "skipped" with a suitable message.</p>
+ *
+ * <p>Some tests require binary files (such as OSGi bundles) which under Apache conventions are not able to be
+ * distributed in our source code release. This exception allows such tests to become "optional" so that they do not
+ * cause test failures when running the tests on a source distribution.</p>
+ *
+ * <p>Note that the single-string constructors expect the string to be the simple name of the classpath resource that
+ * is not available. The exception message is then derived from this. The two-string constructors take both the
+ * resource name and an explicit exception message.</p>
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class TestResourceUnavailableException extends SkipException {
+
+ private final String resourceName;
+
+ /**
+ * Asserts that a resource is available on the classpath; otherwise, throws {@link TestResourceUnavailableException}
+ *
+ * Note that this will use the same classloader that was used to load this class.
+ *
+ * @param resourceName the classpath resource name, e.g.
+ * <code>/brooklyn/osgi/brooklyn-test-osgi-entities.jar</code>
+ */
+ public static void throwIfResourceUnavailable(Class<?> relativeToClass, String resourceName) {
+ checkNotNull(relativeToClass, relativeToClass);
+ checkNotNull(resourceName, "resourceName");
+ checkArgument(!resourceName.isEmpty(), "resourceName must not be empty");
+ InputStream resource = relativeToClass.getResourceAsStream(resourceName);
+ if (resource == null)
+ throw new TestResourceUnavailableException(resourceName);
+
+ // just make sure we clean up the resource
+ try {
+ resource.close();
+ } catch (IOException e) {
+ Throwables.propagate(e);
+ }
+ }
+
+ /**
+ * Instantiate an exception, giving the name of the unavailable resource.
+ *
+ * @param resourceName the name of the resource on the classpath, e.g.
+ * <code>/brooklyn/osgi/brooklyn-test-osgi-entities.jar</code>
+ */
+ public TestResourceUnavailableException(String resourceName) {
+ super(messageFromResourceName(resourceName));
+ this.resourceName = resourceName;
+ }
+
+ /**
+ * Instantiate an exception, giving the name of the unavailable resource.
+ *
+ * @param resourceName the name of the resource on the classpath, e.g.
+ * <code>/brooklyn/osgi/brooklyn-test-osgi-entities.jar</code>
+ * @param cause the underlying exception that caused this one
+ */
+ public TestResourceUnavailableException(String resourceName, Throwable cause) {
+ super(messageFromResourceName(resourceName), cause);
+ this.resourceName = resourceName;
+ }
+
+ /**
+ * Instantiate an exception, giving the name of the unavailable resource.
+ *
+ * @param resourceName the name of the resource on the classpath, e.g.
+ * <code>/brooklyn/osgi/brooklyn-test-osgi-entities.jar</code>
+ * @param skipMessage the message associated with the exception
+ */
+ public TestResourceUnavailableException(String resourceName, String skipMessage) {
+ super(skipMessage);
+ this.resourceName = resourceName;
+ }
+
+ /**
+ * Instantiate an exception, giving the name of the unavailable resource.
+ *
+ * @param resourceName the name of the resource on the classpath, e.g.
+ * <code>/brooklyn/osgi/brooklyn-test-osgi-entities.jar</code>
+ * @param skipMessage the message associated with the exception
+ * @param cause the underlying exception that caused this one
+ */
+ public TestResourceUnavailableException(String resourceName, String skipMessage, Throwable cause) {
+ super(skipMessage, cause);
+ this.resourceName = resourceName;
+ }
+
+ private static String messageFromResourceName(String resourceName) {
+ return String.format("Test resource '%s' not found; test skipped.", resourceName);
+ }
+
+ /**
+ * Get the name of the classpath resource that could not be loaded.
+ *
+ * @return the name of the classpath resource whose absence caused this exception.
+ */
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ @Override
+ public boolean isSkip() {
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e06e79ab/utils/test-support/src/main/java/org/apache/brooklyn/test/VerboseReporter.java
----------------------------------------------------------------------
diff --git a/utils/test-support/src/main/java/org/apache/brooklyn/test/VerboseReporter.java b/utils/test-support/src/main/java/org/apache/brooklyn/test/VerboseReporter.java
new file mode 100644
index 0000000..0ec78e1
--- /dev/null
+++ b/utils/test-support/src/main/java/org/apache/brooklyn/test/VerboseReporter.java
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.test;
+
+import java.util.List;
+
+import org.testng.ITestContext;
+import org.testng.ITestNGMethod;
+import org.testng.ITestResult;
+import org.testng.TestListenerAdapter;
+import org.testng.internal.ConstructorOrMethod;
+import org.testng.internal.Utils;
+
+/**
+ * Reporter printing out detailed messages about what TestNG
+ * is going to run and what is the status of what has been just run.
+ *
+ * To see messages from this reporter, either run Ant in verbose mode ('ant -v')
+ * or set verbose level to 5 or higher
+ *
+ * @author Lukas Jungmann
+ * @since 6.4
+ *
+ * THIS IS AN EXACT COPY OF THE CLASS IN org.testng.reporters
+ * EXCEPT FOR THIS COMMENT AND log(String) CHANGED TO BE PROTECTED
+ */
+public class VerboseReporter extends TestListenerAdapter {
+
+ /**
+ * Default prefix for messages printed out by this reporter
+ *
+ */
+ public static final String LISTENER_PREFIX = "[VerboseTestNG] ";
+ private String suiteName;
+ private final String prefix;
+
+ private enum Status {
+
+ SUCCESS(ITestResult.SUCCESS), FAILURE(ITestResult.FAILURE), SKIP(ITestResult.SKIP),
+ SUCCESS_PERCENTAGE_FAILURE(ITestResult.SUCCESS_PERCENTAGE_FAILURE), STARTED(ITestResult.STARTED);
+ private final int code;
+
+ private Status(int i) {
+ code = i;
+ }
+
+ @SuppressWarnings("unused")
+ public int getCode() {
+ return code;
+ }
+ }
+
+ /**
+ * Default constructor
+ */
+ public VerboseReporter() {
+ this(LISTENER_PREFIX);
+ }
+
+ /**
+ * Create VerboseReporter with custom prefix
+ *
+ * @param prefix prefix for messages printed out by this reporter
+ */
+ public VerboseReporter(String prefix) {
+ this.prefix = prefix;
+ }
+
+ @Override
+ public void beforeConfiguration(ITestResult tr) {
+ super.beforeConfiguration(tr);
+ logTestResult(Status.STARTED, tr, true);
+ }
+
+ @Override
+ public void onConfigurationFailure(ITestResult tr) {
+ super.onConfigurationFailure(tr);
+ logTestResult(Status.FAILURE, tr, true);
+ }
+
+ @Override
+ public void onConfigurationSkip(ITestResult tr) {
+ super.onConfigurationSkip(tr);
+ logTestResult(Status.SKIP, tr, true);
+ }
+
+ @Override
+ public void onConfigurationSuccess(ITestResult tr) {
+ super.onConfigurationSuccess(tr);
+ logTestResult(Status.SUCCESS, tr, true);
+ }
+
+ @Override
+ public void onTestStart(ITestResult tr) {
+ logTestResult(Status.STARTED, tr, false);
+ }
+
+ @Override
+ public void onTestFailure(ITestResult tr) {
+ super.onTestFailure(tr);
+ logTestResult(Status.FAILURE, tr, false);
+ }
+
+ @Override
+ public void onTestFailedButWithinSuccessPercentage(ITestResult tr) {
+ super.onTestFailedButWithinSuccessPercentage(tr);
+ logTestResult(Status.SUCCESS_PERCENTAGE_FAILURE, tr, false);
+ }
+
+ @Override
+ public void onTestSkipped(ITestResult tr) {
+ super.onTestSkipped(tr);
+ logTestResult(Status.SKIP, tr, false);
+ }
+
+ @Override
+ public void onTestSuccess(ITestResult tr) {
+ super.onTestSuccess(tr);
+ logTestResult(Status.SUCCESS, tr, false);
+ }
+
+ @Override
+ public void onStart(ITestContext ctx) {
+ suiteName = ctx.getName();//ctx.getSuite().getXmlSuite().getFileName();
+ log("RUNNING: Suite: \"" + suiteName + "\" containing \"" + ctx.getAllTestMethods().length + "\" Tests (config: " + ctx.getSuite().getXmlSuite().getFileName() + ")");
+ }
+
+ @Override
+ public void onFinish(ITestContext context) {
+ logResults();
+ suiteName = null;
+ }
+
+ private ITestNGMethod[] resultsToMethods(List<ITestResult> results) {
+ ITestNGMethod[] result = new ITestNGMethod[results.size()];
+ int i = 0;
+ for (ITestResult tr : results) {
+ result[i++] = tr.getMethod();
+ }
+ return result;
+ }
+
+ /**
+ * Print out test summary
+ */
+ private void logResults() {
+ //
+ // Log test summary
+ //
+ ITestNGMethod[] ft = resultsToMethods(getFailedTests());
+ StringBuilder sb = new StringBuilder("\n===============================================\n");
+ sb.append(" ").append(suiteName).append("\n");
+ sb.append(" Tests run: ").append(Utils.calculateInvokedMethodCount(getAllTestMethods()));
+ sb.append(", Failures: ").append(Utils.calculateInvokedMethodCount(ft));
+ sb.append(", Skips: ").append(Utils.calculateInvokedMethodCount(resultsToMethods(getSkippedTests())));
+ int confFailures = getConfigurationFailures().size();
+ int confSkips = getConfigurationSkips().size();
+ if (confFailures > 0 || confSkips > 0) {
+ sb.append("\n").append(" Configuration Failures: ").append(confFailures);
+ sb.append(", Skips: ").append(confSkips);
+ }
+ sb.append("\n===============================================");
+ log(sb.toString());
+ }
+
+ /**
+ * Log meaningful message for passed in arguments.
+ * Message itself is of form:
+ * $status: "$suiteName" - $methodDeclaration ($actualArguments) finished in $x ms ($run of $totalRuns)
+ *
+ * @param st status of passed in itr
+ * @param itr test result to be described
+ * @param isConfMethod is itr describing configuration method
+ */
+ private void logTestResult(Status st, ITestResult itr, boolean isConfMethod) {
+ StringBuilder sb = new StringBuilder();
+ String stackTrace = "";
+ switch (st) {
+ case STARTED:
+ sb.append("INVOKING");
+ break;
+ case SKIP:
+ sb.append("SKIPPED");
+ stackTrace = itr.getThrowable() != null
+ ? Utils.stackTrace(itr.getThrowable(), false)[0] : "";
+ break;
+ case FAILURE:
+ sb.append("FAILED");
+ stackTrace = itr.getThrowable() != null
+ ? Utils.stackTrace(itr.getThrowable(), false)[0] : "";
+ break;
+ case SUCCESS:
+ sb.append("PASSED");
+ break;
+ case SUCCESS_PERCENTAGE_FAILURE:
+ sb.append("PASSED with failures");
+ break;
+ default:
+ //not happen
+ throw new RuntimeException("Unsupported test status:" + itr.getStatus());
+ }
+ if (isConfMethod) {
+ sb.append(" CONFIGURATION: ");
+ } else {
+ sb.append(": ");
+ }
+ ITestNGMethod tm = itr.getMethod();
+ int identLevel = sb.length();
+ sb.append(getMethodDeclaration(tm));
+ Object[] params = itr.getParameters();
+ Class<?>[] paramTypes = tm.getConstructorOrMethod().getParameterTypes();
+ if (null != params && params.length > 0) {
+ // The error might be a data provider parameter mismatch, so make
+ // a special case here
+ if (params.length != paramTypes.length) {
+ sb.append("Wrong number of arguments were passed by the Data Provider: found ");
+ sb.append(params.length);
+ sb.append(" but expected ");
+ sb.append(paramTypes.length);
+ } else {
+ sb.append("(value(s): ");
+ for (int i = 0; i < params.length; i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+ sb.append(Utils.toString(params[i], paramTypes[i]));
+ }
+ sb.append(")");
+
+ }
+ }
+ if (Status.STARTED != st) {
+ sb.append(" finished in ");
+ sb.append(itr.getEndMillis() - itr.getStartMillis());
+ sb.append(" ms");
+ if (!Utils.isStringEmpty(tm.getDescription())) {
+ sb.append("\n");
+ for (int i = 0; i < identLevel; i++) {
+ sb.append(" ");
+ }
+ sb.append(tm.getDescription());
+ }
+ if (tm.getInvocationCount() > 1) {
+ sb.append(" (");
+ sb.append(tm.getCurrentInvocationCount());
+ sb.append(" of ");
+ sb.append(tm.getInvocationCount());
+ sb.append(")");
+ }
+ if (!Utils.isStringEmpty(stackTrace)) {
+ sb.append("\n").append(stackTrace.substring(0, stackTrace.lastIndexOf(System.getProperty("line.separator"))));
+ }
+ } else {
+ if (!isConfMethod && tm.getInvocationCount() > 1) {
+ sb.append(" success: ");
+ sb.append(tm.getSuccessPercentage());
+ sb.append("%");
+ }
+ }
+ log(sb.toString());
+ }
+
+ protected void log(String message) {
+ //prefix all output lines
+ System.out.println(message.replaceAll("(?m)^", prefix));
+ }
+
+ /**
+ *
+ * @param method method to be described
+ * @return FQN of a class + method declaration for a method passed in
+ * ie. test.triangle.CheckCount.testCheckCount(java.lang.String)
+ */
+ private String getMethodDeclaration(ITestNGMethod method) {
+ //see Utils.detailedMethodName
+ //perhaps should rather adopt the original method instead
+ ConstructorOrMethod m = method.getConstructorOrMethod();
+ StringBuilder buf = new StringBuilder();
+ buf.append("\"");
+ if (suiteName != null) {
+ buf.append(suiteName);
+ } else {
+ buf.append("UNKNOWN");
+ }
+ buf.append("\"");
+ buf.append(" - ");
+ if (method.isBeforeSuiteConfiguration()) {
+ buf.append("@BeforeSuite ");
+ } else if (method.isBeforeTestConfiguration()) {
+ buf.append("@BeforeTest ");
+ } else if (method.isBeforeClassConfiguration()) {
+ buf.append("@BeforeClass ");
+ } else if (method.isBeforeGroupsConfiguration()) {
+ buf.append("@BeforeGroups ");
+ } else if (method.isBeforeMethodConfiguration()) {
+ buf.append("@BeforeMethod ");
+ } else if (method.isAfterMethodConfiguration()) {
+ buf.append("@AfterMethod ");
+ } else if (method.isAfterGroupsConfiguration()) {
+ buf.append("@AfterGroups ");
+ } else if (method.isAfterClassConfiguration()) {
+ buf.append("@AfterClass ");
+ } else if (method.isAfterTestConfiguration()) {
+ buf.append("@AfterTest ");
+ } else if (method.isAfterSuiteConfiguration()) {
+ buf.append("@AfterSuite ");
+ }
+ buf.append(m.getDeclaringClass().getName());
+ buf.append(".");
+ buf.append(m.getName());
+ buf.append("(");
+ int i = 0;
+ for (Class<?> p : m.getParameterTypes()) {
+ if (i++ > 0) {
+ buf.append(", ");
+ }
+ buf.append(p.getName());
+ }
+ buf.append(")");
+ return buf.toString();
+ }
+
+ @Override
+ public String toString() {
+ return "VerboseReporter{" + "suiteName=" + suiteName + '}';
+ }
+}