diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 47036541..54f1bd7f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -107,7 +107,6 @@ jobs: body: ${{ steps.readChangelogEntry.outputs.changes }} - name: Checkout develop branch - if: ${{ github.ref }} == 'master' uses: actions/checkout@v4 with: ref: 'develop' @@ -115,7 +114,6 @@ jobs: - name: Merge release branch into develop id: mergeIntoDevelop - if: ${{ github.ref }} == 'master' run: | git merge -m 'Merge master branch into develop after a release' origin/master git status | (! grep -Fq 'both modified:') || git status | grep -F 'both modified:' \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f2e58b..3796345d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog ## [Unreleased] +### Changed +- Client version updated on [5.4.1](https://github.com/reportportal/client-java/releases/tag/5.4.1), by @HardNorth +- Replace "jsr305" annotations with "jakarta.annotation-api", by @HardNorth +- Switch on use of `Instant` class instead of `Date` to get more timestamp precision, by @HardNorth ## [5.5.2] ### Changed diff --git a/build.gradle b/build.gradle index 440a3280..408aac38 100644 --- a/build.gradle +++ b/build.gradle @@ -39,12 +39,13 @@ repositories { } dependencies { - api 'com.epam.reportportal:client-java:5.3.17' + api 'com.epam.reportportal:client-java:5.4.1' compileOnly "org.testng:testng:${testng_version}" implementation 'org.slf4j:slf4j-api:2.0.7' + implementation 'org.apache.commons:commons-lang3:3.18.0' - testImplementation 'com.epam.reportportal:agent-java-test-utils:0.0.13' + testImplementation 'com.epam.reportportal:agent-java-test-utils:0.1.0' testImplementation "org.testng:testng:${testng_version}" testImplementation("org.junit.platform:junit-platform-runner:${junit5_runner_version}") { @@ -58,9 +59,9 @@ dependencies { testImplementation 'org.hamcrest:hamcrest-core:2.2' testImplementation "org.mockito:mockito-core:${mockito_version}" testImplementation "org.mockito:mockito-junit-jupiter:${mockito_version}" - testImplementation 'ch.qos.logback:logback-classic:1.4.14' + testImplementation 'ch.qos.logback:logback-classic:1.5.18' - testImplementation 'com.epam.reportportal:logger-java-logback:5.2.3' + testImplementation 'com.epam.reportportal:logger-java-logback:5.4.0' testImplementation 'commons-io:commons-io:2.17.0' testImplementation 'com.ibm.icu:icu4j:67.1' diff --git a/gradle.properties b/gradle.properties index 69947cd3..fc04988d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=5.5.3-SNAPSHOT +version=5.6.0-SNAPSHOT description=TestNG integration for ReportPortal junit5_version=5.6.3 junit5_runner_version=1.6.3 diff --git a/src/main/java/com/epam/reportportal/testng/ReportPortalTestNGListener.java b/src/main/java/com/epam/reportportal/testng/ReportPortalTestNGListener.java index 5680f5d7..48b77f7c 100644 --- a/src/main/java/com/epam/reportportal/testng/ReportPortalTestNGListener.java +++ b/src/main/java/com/epam/reportportal/testng/ReportPortalTestNGListener.java @@ -28,8 +28,7 @@ public class ReportPortalTestNGListener extends BaseTestNGListener { /* static instance with lazy init */ - public static final Supplier SERVICE = - new MemoizingSupplier<>(() -> new TestNGService(ReportPortal.builder().build())); + public static final Supplier SERVICE = new MemoizingSupplier<>(() -> new TestNGService(ReportPortal.builder().build())); public ReportPortalTestNGListener() { super(SERVICE.get()); diff --git a/src/main/java/com/epam/reportportal/testng/TestNGService.java b/src/main/java/com/epam/reportportal/testng/TestNGService.java index 2f7f7721..1c00767d 100644 --- a/src/main/java/com/epam/reportportal/testng/TestNGService.java +++ b/src/main/java/com/epam/reportportal/testng/TestNGService.java @@ -32,6 +32,8 @@ import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; import io.reactivex.Maybe; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.testng.*; @@ -43,11 +45,10 @@ import org.testng.xml.XmlClass; import org.testng.xml.XmlTest; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.time.Instant; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; @@ -68,14 +69,16 @@ * TestNG service implements operations for interaction ReportPortal */ public class TestNGService implements ITestNGService { - private static final Set BEFORE_METHODS = Stream.of(TestMethodType.BEFORE_TEST, + private static final Set BEFORE_METHODS = Stream.of( + TestMethodType.BEFORE_TEST, TestMethodType.BEFORE_SUITE, TestMethodType.BEFORE_GROUPS, TestMethodType.BEFORE_CLASS, TestMethodType.BEFORE_METHOD ).collect(Collectors.toSet()); private static final String AGENT_PROPERTIES_FILE = "agent.properties"; - private static final Set TESTNG_INVOKERS = Stream.of("org.testng.internal.TestInvoker", + private static final Set TESTNG_INVOKERS = Stream.of( + "org.testng.internal.TestInvoker", "org.testng.internal.invokers.TestInvoker" ).collect(Collectors.toSet()); private static final Predicate IS_RETRY_ELEMENT = e -> TESTNG_INVOKERS.contains(e.getClassName()) @@ -103,7 +106,7 @@ public class TestNGService implements ITestNGService { private static Thread getShutdownHook(final Supplier launch) { return new Thread(() -> { FinishExecutionRQ rq = new FinishExecutionRQ(); - rq.setEndTime(Calendar.getInstance().getTime()); + rq.setEndTime(Instant.now()); launch.get().finish(rq); }); } @@ -113,7 +116,7 @@ public TestNGService(@Nonnull final ReportPortal reportPortal) { //this reads property, so we want to //init ReportPortal object each time Launch object is going to be created StartLaunchRQ startRq = buildStartLaunchRq(reportPortal.getParameters()); - startRq.setStartTime(Calendar.getInstance().getTime()); + startRq.setStartTime(Instant.now()); Launch newLaunch = reportPortal.newLaunch(startRq); shutDownHook = getShutdownHook(() -> newLaunch); Runtime.getRuntime().addShutdownHook(shutDownHook); @@ -263,7 +266,7 @@ protected StartTestItemRQ buildStartConfigurationRq(@Nonnull ITestResult testRes rq.setName(createConfigurationName(testResult)); rq.setCodeRef(testResult.getMethod().getQualifiedName()); rq.setDescription(createConfigurationDescription(testResult)); - rq.setStartTime(new Date(testResult.getStartMillis())); + rq.setStartTime(Instant.ofEpochMilli(testResult.getStartMillis())); rq.setType(type == null ? null : type.toString()); boolean retry = isRetry(testResult); if (retry) { @@ -323,7 +326,7 @@ protected StartTestItemRQ buildStartStepRq(final @Nonnull ITestResult testResult rq.setAttributes(createStepAttributes(testResult)); rq.setDescription(createStepDescription(testResult)); rq.setParameters(createStepParameters(testResult)); - rq.setStartTime(new Date(testResult.getStartMillis())); + rq.setStartTime(Instant.ofEpochMilli(testResult.getStartMillis())); rq.setType(type.toString()); boolean retry = isRetry(testResult); if (retry) { @@ -379,7 +382,8 @@ public void startTestMethod(@Nonnull ITestResult testResult) { */ @Nullable private String getLogMessage(@Nonnull ITestResult testResult) { - String error = ofNullable(testResult.getThrowable()).map(t -> String.format(DESCRIPTION_ERROR_FORMAT, + String error = ofNullable(testResult.getThrowable()).map(t -> String.format( + DESCRIPTION_ERROR_FORMAT, getStackTrace(t, new Throwable()) )).orElse(null); if (error == null) { @@ -399,7 +403,7 @@ private String getLogMessage(@Nonnull ITestResult testResult) { @Nonnull protected FinishTestItemRQ buildFinishTestMethodRq(@Nonnull ItemStatus status, @Nonnull ITestResult testResult) { FinishTestItemRQ rq = new FinishTestItemRQ(); - rq.setEndTime(new Date(testResult.getEndMillis())); + rq.setEndTime(Instant.ofEpochMilli(testResult.getEndMillis())); rq.setStatus(status.name()); if (!testResult.isSuccess() && ItemStatus.SKIPPED != status) { rq.setDescription(getLogMessage(testResult)); @@ -507,8 +511,8 @@ public void finishTestMethod(ItemStatus status, ITestResult testResult) { if (ItemStatus.FAILED == status && (TestMethodType.BEFORE_METHOD == type || TestMethodType.BEFORE_CLASS == type)) { SKIPPED_STATUS_TRACKER.put(instance, Boolean.TRUE); } - if (status == ItemStatus.SKIPPED && rq.getIssue() == null - && (SKIPPED_STATUS_TRACKER.containsKey(instance) || (TestMethodType.BEFORE_METHOD == type && getAttribute(testResult, RP_RETRY) != null))) { + if (status == ItemStatus.SKIPPED && rq.getIssue() == null && (SKIPPED_STATUS_TRACKER.containsKey(instance) || ( + TestMethodType.BEFORE_METHOD == type && getAttribute(testResult, RP_RETRY) != null))) { rq.setIssue(Launch.NOT_ISSUE); } if (ItemStatus.SKIPPED == status && BEFORE_METHODS.contains(type) && testResult.getThrowable() != null) { @@ -533,7 +537,7 @@ public void sendReportPortalMsg(final ITestResult result) { rq.setLevel("ERROR"); rq.setMessage(ofNullable(result.getThrowable()).map(t -> getStackTrace(result.getThrowable(), new Throwable())) .orElse("Test has failed without exception")); - rq.setLogTime(Calendar.getInstance().getTime()); + rq.setLogTime(Instant.now()); return rq; }); } @@ -548,7 +552,7 @@ public void sendReportPortalMsg(final ITestResult result) { protected StartTestItemRQ buildStartSuiteRq(ISuite suite) { StartTestItemRQ rq = new StartTestItemRQ(); rq.setName(suite.getName()); - rq.setStartTime(Calendar.getInstance().getTime()); + rq.setStartTime(Instant.now()); rq.setType("SUITE"); return rq; } @@ -568,7 +572,7 @@ protected StartTestItemRQ buildStartTestItemRq(@Nonnull ITestContext testContext .ifPresent(xmlClasses -> xmlClasses.forEach(xmlClass -> ofNullable(xmlClass.getSupportClass()).map(c -> c.getAnnotation( Attributes.class)).ifPresent(a -> attributes.addAll(AttributeParser.retrieveAttributes(a))))); rq.setName(testContext.getName()); - rq.setStartTime(testContext.getStartDate()); + rq.setStartTime(ofNullable(testContext.getStartDate()).map(java.util.Date::toInstant).orElseGet(Instant::now)); rq.setType("TEST"); return rq; } @@ -583,7 +587,7 @@ protected StartTestItemRQ buildStartTestItemRq(@Nonnull ITestContext testContext protected StartLaunchRQ buildStartLaunchRq(ListenerParameters parameters) { StartLaunchRQ rq = new StartLaunchRQ(); rq.setName(parameters.getLaunchName()); - rq.setStartTime(Calendar.getInstance().getTime()); + rq.setStartTime(Instant.now()); Set attributes = new HashSet<>(parameters.getAttributes()); rq.setAttributes(attributes); rq.setMode(parameters.getLaunchRunningMode()); @@ -615,7 +619,7 @@ protected StartLaunchRQ buildStartLaunchRq(ListenerParameters parameters) { @Nonnull protected FinishExecutionRQ buildFinishLaunchRq(ListenerParameters parameters) { FinishExecutionRQ rq = new FinishExecutionRQ(); - rq.setEndTime(Calendar.getInstance().getTime()); + rq.setEndTime(Instant.now()); return rq; } @@ -629,7 +633,7 @@ protected FinishExecutionRQ buildFinishLaunchRq(ListenerParameters parameters) { @Nonnull protected FinishTestItemRQ buildFinishTestSuiteRq(ISuite suite) { /* 'real' end time */ - Date now = Calendar.getInstance().getTime(); + Instant now = Instant.now(); FinishTestItemRQ rq = new FinishTestItemRQ(); rq.setEndTime(now); return rq; @@ -644,7 +648,7 @@ protected FinishTestItemRQ buildFinishTestSuiteRq(ISuite suite) { @Nonnull protected FinishTestItemRQ buildFinishTestRq(ITestContext testContext) { FinishTestItemRQ rq = new FinishTestItemRQ(); - rq.setEndTime(testContext.getEndDate()); + rq.setEndTime(ofNullable(testContext.getEndDate()).map(java.util.Date::toInstant).orElse(null)); return rq; } @@ -776,10 +780,16 @@ private TestCaseIdEntry getTestCaseId(@Nonnull String codeRef, @Nonnull ITestRes Method method = getMethod(testResult); Object instance = testResult.getInstance(); List parameters = ofNullable(testResult.getParameters()).map(Arrays::asList).orElse(null); - TestCaseIdEntry id = getMethodAnnotation(TestCaseId.class, + TestCaseIdEntry id = getMethodAnnotation( + TestCaseId.class, testResult - ).flatMap(a -> ofNullable(method).map(m -> TestCaseIdUtils.getTestCaseId(a, m, codeRef, parameters, instance))) - .orElse(TestCaseIdUtils.getTestCaseId(codeRef, parameters)); + ).flatMap(a -> ofNullable(method).map(m -> TestCaseIdUtils.getTestCaseId( + a, + m, + codeRef, + parameters, + instance + ))).orElse(TestCaseIdUtils.getTestCaseId(codeRef, parameters)); return id == null ? null : id.getId().endsWith("[]") ? new TestCaseIdEntry(id.getId().substring(0, id.getId().length() - 2)) : id; } diff --git a/src/main/java/com/epam/reportportal/testng/util/ItemTreeUtils.java b/src/main/java/com/epam/reportportal/testng/util/ItemTreeUtils.java index 82ed71de..6eed791f 100644 --- a/src/main/java/com/epam/reportportal/testng/util/ItemTreeUtils.java +++ b/src/main/java/com/epam/reportportal/testng/util/ItemTreeUtils.java @@ -67,7 +67,8 @@ public static Optional retrieveLeaf(ITestContext test } public static Optional retrieveLeaf(ITestResult testResult, TestItemTree testItemTree) { - Optional testClassLeaf = retrieveLeaf(testResult.getTestContext(), + Optional testClassLeaf = retrieveLeaf( + testResult.getTestContext(), testResult.getTestClass(), testItemTree ); diff --git a/src/main/java/com/epam/reportportal/testng/util/internal/LimitedSizeConcurrentHashMap.java b/src/main/java/com/epam/reportportal/testng/util/internal/LimitedSizeConcurrentHashMap.java index 5d24162b..de4d3c38 100644 --- a/src/main/java/com/epam/reportportal/testng/util/internal/LimitedSizeConcurrentHashMap.java +++ b/src/main/java/com/epam/reportportal/testng/util/internal/LimitedSizeConcurrentHashMap.java @@ -1,6 +1,7 @@ package com.epam.reportportal.testng.util.internal; -import javax.annotation.Nonnull; +import jakarta.annotation.Nonnull; + import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; diff --git a/src/test/java/com/epam/reportportal/testng/BuildStepTest.java b/src/test/java/com/epam/reportportal/testng/BuildStepTest.java index df575ff4..2f4c60d5 100644 --- a/src/test/java/com/epam/reportportal/testng/BuildStepTest.java +++ b/src/test/java/com/epam/reportportal/testng/BuildStepTest.java @@ -16,11 +16,7 @@ package com.epam.reportportal.testng; -import com.epam.reportportal.annotations.Description; -import com.epam.reportportal.annotations.DisplayName; -import com.epam.reportportal.annotations.ParameterKey; -import com.epam.reportportal.annotations.TestCaseId; -import com.epam.reportportal.annotations.TestCaseIdKey; +import com.epam.reportportal.annotations.*; import com.epam.reportportal.listeners.ItemStatus; import com.epam.reportportal.service.Launch; import com.epam.reportportal.utils.MemoizingSupplier; @@ -37,7 +33,11 @@ import org.testng.internal.ConstructorOrMethod; import java.lang.reflect.Method; -import java.util.*; +import java.time.Instant; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Iterator; +import java.util.Optional; import static com.epam.reportportal.testng.Constants.*; import static org.hamcrest.MatcherAssert.assertThat; @@ -45,7 +45,7 @@ import static org.hamcrest.Matchers.nullValue; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; /** * @author Pavel Bortnik @@ -195,7 +195,7 @@ public void testStartTime() { instance.setTimeInMillis(DEFAULT_TIME); when(testResult.getStartMillis()).thenReturn(instance.getTimeInMillis()); StartTestItemRQ rq = testNGService.buildStartStepRq(testResult); - assertThat("Incorrect start time", rq.getStartTime(), is(instance.getTime())); + assertThat("Incorrect start time", rq.getStartTime(), is(Instant.ofEpochMilli(instance.getTimeInMillis()))); } @Test @@ -231,7 +231,7 @@ public void testBuildFinishRQ() { when(testResult.getEndMillis()).thenReturn(DEFAULT_TIME); when(testResult.isSuccess()).thenReturn(true); FinishTestItemRQ rq = testNGService.buildFinishTestMethodRq(ItemStatus.PASSED, testResult); - assertThat("Incorrect end time", rq.getEndTime().getTime(), is(DEFAULT_TIME)); + assertThat("Incorrect end time", rq.getEndTime(), is(Instant.ofEpochMilli(DEFAULT_TIME))); assertThat("Incorrect status", rq.getStatus(), is(ItemStatus.PASSED.name())); assertThat("Incorrect issue", rq.getIssue(), nullValue()); } @@ -247,7 +247,7 @@ public void testStartConfigurationRq() { assertThat("Incorrect method name", rq.getName(), is(DEFAULT_NAME)); assertThat("Incorrect method description", rq.getDescription(), is(DEFAULT_DESCRIPTION)); - assertThat("Incorrect start time", rq.getStartTime(), is(new Date(DEFAULT_TIME))); + assertThat("Incorrect start time", rq.getStartTime(), is(Instant.ofEpochMilli(DEFAULT_TIME))); assertThat("Incorrect test method type", rq.getType(), is(TestMethodType.BEFORE_TEST.name())); } @@ -339,7 +339,7 @@ public void testCaseId_fromAnnotationParametrized() { assertEquals(expectedParam, request.getTestCaseId()); } - private Method getTestMethodsExampleByName(String methodName){ + private Method getTestMethodsExampleByName(String methodName) { Optional methodOptional = Arrays.stream(TestMethodsExamples.class.getDeclaredMethods()) .filter(it -> it.getName().equals(methodName)) .findFirst(); diff --git a/src/test/java/com/epam/reportportal/testng/BuildTestTest.java b/src/test/java/com/epam/reportportal/testng/BuildTestTest.java index 984b0e00..fc62c7ab 100644 --- a/src/test/java/com/epam/reportportal/testng/BuildTestTest.java +++ b/src/test/java/com/epam/reportportal/testng/BuildTestTest.java @@ -18,18 +18,19 @@ import com.epam.reportportal.listeners.ListenerParameters; import com.epam.reportportal.service.Launch; +import com.epam.reportportal.utils.MemoizingSupplier; import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; import com.epam.ta.reportportal.ws.model.StartTestItemRQ; import com.epam.ta.reportportal.ws.model.attribute.ItemAttributeResource; import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; import org.hamcrest.Matchers; -import com.epam.reportportal.utils.MemoizingSupplier; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; -import org.testng.*; +import org.testng.ISuite; +import org.testng.ITestContext; import java.util.*; import java.util.regex.Pattern; @@ -149,7 +150,7 @@ public void testStartTestRq() { StartTestItemRQ rq = testNGService.buildStartTestItemRq(testContext); assertThat("Incorrect test item type", rq.getType(), is("TEST")); assertThat("Incorrect test item name", rq.getName(), is(DEFAULT_NAME)); - assertThat("Incorrect suite start time", rq.getStartTime(), is(instance.getTime())); + assertThat("Incorrect suite start time", rq.getStartTime(), is(instance.getTime().toInstant())); } @Test @@ -158,7 +159,7 @@ public void testFinishTestRqPassed() { when(testContext.getEndDate()).thenReturn(endTime); FinishTestItemRQ rq = testNGService.buildFinishTestRq(testContext); - assertThat("Incorrect end time", rq.getEndTime(), is(endTime)); + assertThat("Incorrect end time", rq.getEndTime(), is(endTime.toInstant())); } private ListenerParameters defaultListenerParameters() { diff --git a/src/test/java/com/epam/reportportal/testng/CallbackReportingUnitTest.java b/src/test/java/com/epam/reportportal/testng/CallbackReportingUnitTest.java index 91b8bebd..8708a03b 100644 --- a/src/test/java/com/epam/reportportal/testng/CallbackReportingUnitTest.java +++ b/src/test/java/com/epam/reportportal/testng/CallbackReportingUnitTest.java @@ -12,7 +12,6 @@ import org.mockito.Mock; import org.testng.ISuite; - import static com.epam.reportportal.testng.TestNGService.ITEM_TREE; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; diff --git a/src/test/java/com/epam/reportportal/testng/FailedBeforeAfterTest.java b/src/test/java/com/epam/reportportal/testng/FailedBeforeAfterTest.java index df4d0470..18185ca9 100644 --- a/src/test/java/com/epam/reportportal/testng/FailedBeforeAfterTest.java +++ b/src/test/java/com/epam/reportportal/testng/FailedBeforeAfterTest.java @@ -39,7 +39,8 @@ import java.util.stream.IntStream; import java.util.stream.Stream; -import static com.epam.reportportal.testng.integration.util.TestUtils.*; +import static com.epam.reportportal.testng.integration.util.TestUtils.mockLaunch; +import static com.epam.reportportal.testng.integration.util.TestUtils.namedUuid; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.mockito.ArgumentMatchers.any; @@ -61,11 +62,13 @@ public static void initLaunch(Launch launch) { private final Maybe suitedUuid = Maybe.just(namedUuid("suite")); private final Maybe testClassUuid = Maybe.just(namedUuid("class")); - private final List> testMethodUuidList = Arrays.asList(Maybe.just(namedUuid("before")), + private final List> testMethodUuidList = Arrays.asList( + Maybe.just(namedUuid("before")), Maybe.just(namedUuid("test")), Maybe.just(namedUuid("after")) ); - private final List finishUuidOrder = Stream.concat(testMethodUuidList.stream().map(Maybe::blockingGet), + private final List finishUuidOrder = Stream.concat( + testMethodUuidList.stream().map(Maybe::blockingGet), Stream.of(testClassUuid.blockingGet(), suitedUuid.blockingGet()) ) .collect(Collectors.toList()); @@ -75,7 +78,8 @@ public static void initLaunch(Launch launch) { @BeforeEach public void setupMock() { - mockLaunch(launch, + mockLaunch( + launch, Maybe.just("launchUuid"), suitedUuid, testClassUuid, @@ -195,7 +199,8 @@ public void agent_should_report_skipped_parametrized_tests_in_case_of_failed_bef verify(launch, times(8)).finishTestItem(finishUuidCapture.capture(), finishItemCapture.capture()); List finishUuids = finishUuidCapture.getAllValues().stream().map(Maybe::blockingGet).collect(Collectors.toList()); - assertThat(finishUuids, + assertThat( + finishUuids, equalTo(Stream.concat(testMethodUuidList.stream().map(Maybe::blockingGet), finishUuidOrder.stream()) .collect(Collectors.toList())) ); diff --git a/src/test/java/com/epam/reportportal/testng/IssueReportingTest.java b/src/test/java/com/epam/reportportal/testng/IssueReportingTest.java index 17fac0a1..4dd1bc1a 100644 --- a/src/test/java/com/epam/reportportal/testng/IssueReportingTest.java +++ b/src/test/java/com/epam/reportportal/testng/IssueReportingTest.java @@ -86,7 +86,8 @@ public void initMocks() { when(launch.startTestItem(any(), any())).thenAnswer((Answer>) invocation -> CommonUtils.createMaybeUuid()); when(launch.startTestItem(same(suiteMaybe), any())).thenAnswer((Answer>) invocation -> stepIds.poll()); when(launch.startTestItem(same(stepOneMaybe), any())).thenAnswer((Answer>) invocation -> stepIds.poll()); - when(launch.finishTestItem(any(), + when(launch.finishTestItem( + any(), any() )).thenAnswer((Answer>) invocation -> Maybe.just(new OperationCompletionRS("OK"))); TestReportPortalListener.initLaunch(launch); diff --git a/src/test/java/com/epam/reportportal/testng/NestedStepTest.java b/src/test/java/com/epam/reportportal/testng/NestedStepTest.java index 69d6774c..cfef1315 100644 --- a/src/test/java/com/epam/reportportal/testng/NestedStepTest.java +++ b/src/test/java/com/epam/reportportal/testng/NestedStepTest.java @@ -38,7 +38,8 @@ public class NestedStepTest { private final String testClassId = namedId("class_"); private final String testMethodId = namedId("test_"); private final List stepIdList = Stream.generate(() -> namedId("step_")).limit(2).collect(Collectors.toList()); - private final List> testStepIdOrder = Arrays.asList(Pair.of(testMethodId, stepIdList.get(0)), + private final List> testStepIdOrder = Arrays.asList( + Pair.of(testMethodId, stepIdList.get(0)), Pair.of(stepIdList.get(0), stepIdList.get(1)) ); diff --git a/src/test/java/com/epam/reportportal/testng/RetryTest.java b/src/test/java/com/epam/reportportal/testng/RetryTest.java index a25c249d..1eb81ee4 100644 --- a/src/test/java/com/epam/reportportal/testng/RetryTest.java +++ b/src/test/java/com/epam/reportportal/testng/RetryTest.java @@ -42,13 +42,15 @@ public static void initLaunch(Launch launch) { private final Maybe suitedUuid = Maybe.just(namedUuid("suite")); private final Maybe testClassUuid = Maybe.just(namedUuid("class")); - private final List> testUuidList = Stream.concat(Stream.concat( - Stream.generate(() -> Maybe.just(namedUuid("before1"))).limit(3), - Stream.generate(() -> Maybe.just(namedUuid("before2"))).limit(3) - ), Stream.concat( - Stream.generate(() -> Maybe.just(namedUuid("test"))).limit(3), - Stream.generate(() -> Maybe.just(namedUuid("after"))).limit(3) - )).collect(Collectors.toList()); + private final List> testUuidList = Stream.concat( + Stream.concat( + Stream.generate(() -> Maybe.just(namedUuid("before1"))).limit(3), + Stream.generate(() -> Maybe.just(namedUuid("before2"))).limit(3) + ), Stream.concat( + Stream.generate(() -> Maybe.just(namedUuid("test"))).limit(3), + Stream.generate(() -> Maybe.just(namedUuid("after"))).limit(3) + ) + ).collect(Collectors.toList()); private final List finishMethodUuidOrder = Stream.of( // BASIC CASE diff --git a/src/test/java/com/epam/reportportal/testng/TestCaseIdTest.java b/src/test/java/com/epam/reportportal/testng/TestCaseIdTest.java index 9a24423d..57590695 100644 --- a/src/test/java/com/epam/reportportal/testng/TestCaseIdTest.java +++ b/src/test/java/com/epam/reportportal/testng/TestCaseIdTest.java @@ -23,8 +23,8 @@ import static com.epam.reportportal.testng.integration.util.TestUtils.extractRequests; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.mockito.Mockito.any; import static org.mockito.Mockito.*; +import static org.mockito.Mockito.any; /** * @author Ihar Kahadouski @@ -138,7 +138,8 @@ public void testCaseIdFromAnnotationValueParametrized() { @Test public void verify_test_case_id_parameterized_no_marked_parameters() { - TestUtils.runTests(Collections.singletonList(TestReportPortalListener.class), + TestUtils.runTests( + Collections.singletonList(TestReportPortalListener.class), TestCaseIdFromAnnotationValueParametrizedNoParam.class ); @@ -158,7 +159,8 @@ public void verify_test_case_id_parameterized_no_marked_parameters() { @Test public void verify_test_case_id_not_parameterized_no_marked_parameters() { String testCaseId = TestCaseIdFromAnnotationValueNotParametrizedNoParam.TEST_CASE_ID; - TestUtils.runTests(Collections.singletonList(TestReportPortalListener.class), + TestUtils.runTests( + Collections.singletonList(TestReportPortalListener.class), TestCaseIdFromAnnotationValueNotParametrizedNoParam.class ); @@ -189,7 +191,8 @@ void test_verify_test_case_id_supports_templating_with_self_reference() { .filter(rq -> ItemType.STEP.name().equals(rq.getType())) .collect(Collectors.toList()); assertThat(stepRequests, hasSize(1)); - assertThat(stepRequests.get(0).getTestCaseId(), + assertThat( + stepRequests.get(0).getTestCaseId(), equalTo(TestCaseIdTemplateTest.TEST_CASE_ID_VALUE.replace("{this.FIELD}", TestCaseIdTemplateTest.FIELD)) ); } diff --git a/src/test/java/com/epam/reportportal/testng/TestDescriptionFailedTest.java b/src/test/java/com/epam/reportportal/testng/TestDescriptionFailedTest.java index 798fc6c2..551b9340 100644 --- a/src/test/java/com/epam/reportportal/testng/TestDescriptionFailedTest.java +++ b/src/test/java/com/epam/reportportal/testng/TestDescriptionFailedTest.java @@ -1,22 +1,5 @@ package com.epam.reportportal.testng; -import static com.epam.reportportal.testng.TestNGService.DESCRIPTION_ERROR_FORMAT; -import static com.epam.reportportal.testng.integration.feature.description.DescriptionFailedTest.ASSERT_ERROR; -import static com.epam.reportportal.testng.integration.feature.description.DescriptionFailedTest.NO_SUCH_ELEMENT_EXCEPTION; -import static com.epam.reportportal.testng.integration.feature.description.DescriptionFailedTest.TEST_DESCRIPTION; -import static com.epam.reportportal.testng.integration.util.TestUtils.mockLaunch; -import static com.epam.reportportal.testng.integration.util.TestUtils.mockLogging; -import static com.epam.reportportal.testng.integration.util.TestUtils.namedUuid; -import static com.epam.reportportal.testng.integration.util.TestUtils.runTests; -import static com.epam.reportportal.testng.integration.util.TestUtils.standardParameters; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.startsWith; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - import com.epam.reportportal.listeners.ItemStatus; import com.epam.reportportal.listeners.ListenerParameters; import com.epam.reportportal.service.Launch; @@ -27,92 +10,111 @@ import com.epam.reportportal.utils.formatting.MarkdownUtils; import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; -import java.util.Calendar; -import java.util.Collections; -import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import java.time.Instant; +import java.util.Collections; +import java.util.List; + +import static com.epam.reportportal.testng.TestNGService.DESCRIPTION_ERROR_FORMAT; +import static com.epam.reportportal.testng.integration.feature.description.DescriptionFailedTest.*; +import static com.epam.reportportal.testng.integration.util.TestUtils.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.startsWith; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class TestDescriptionFailedTest { - public static class TestListener extends BaseTestNGListener { - public static final ThreadLocal REPORT_PORTAL_THREAD_LOCAL = new ThreadLocal<>(); - - public TestListener() { - super(new TestNGService(new MemoizingSupplier<>(() -> getLaunch(REPORT_PORTAL_THREAD_LOCAL.get().getParameters())))); - } - - public static void initReportPortal(ReportPortal reportPortal) { - REPORT_PORTAL_THREAD_LOCAL.set(reportPortal); - } - - private static Launch getLaunch(ListenerParameters parameters) { - - ReportPortal reportPortal = REPORT_PORTAL_THREAD_LOCAL.get(); - StartLaunchRQ rq = new StartLaunchRQ(); - rq.setName(parameters.getLaunchName()); - rq.setStartTime(Calendar.getInstance().getTime()); - rq.setMode(parameters.getLaunchRunningMode()); - rq.setStartTime(Calendar.getInstance().getTime()); - - return reportPortal.newLaunch(rq); - - } - } - - private final String suitedUuid = namedUuid("suite"); - private final String testClassUuid = namedUuid("class"); - private final String assertionError = "java.lang.AssertionError: " + ASSERT_ERROR; - private final String noSuchElementException = "java.util.NoSuchElementException: " + NO_SUCH_ELEMENT_EXCEPTION; - private final String testDescriptionTestAssertErrorMessage = MarkdownUtils.asTwoParts(TEST_DESCRIPTION, String.format(DESCRIPTION_ERROR_FORMAT, assertionError)); - private final String testDescriptionTestExceptionMessage = MarkdownUtils.asTwoParts(TEST_DESCRIPTION, String.format(DESCRIPTION_ERROR_FORMAT, noSuchElementException)); - private final String testWithoutDescriptionTestAssertErrorMessage = String.format(DESCRIPTION_ERROR_FORMAT, assertionError).trim(); - private final String testWithoutDescriptionTestExceptionMessage = String.format(DESCRIPTION_ERROR_FORMAT, noSuchElementException).trim(); - - @Mock - private ReportPortalClient client; - - @BeforeEach - public void initMocks() { - mockLaunch(client, namedUuid("launchUuid"), suitedUuid, testClassUuid, "test"); - mockLogging(client); - ReportPortal reportPortal = ReportPortal.create(client, standardParameters()); - TestListener.initReportPortal(reportPortal); - } - - @Test - public void verify_description_in_case_of_test_exceptions() { - runTests(Collections.singletonList(TestDescriptionFailedTest.TestListener.class), DescriptionFailedTest.class); - - verify(client, times(1)).startLaunch(any()); // Start launch - verify(client, times(1)).startTestItem(any()); // Start parent suites - verify(client, times(1)).startTestItem(same(suitedUuid), any()); // Start test class - - ArgumentCaptor finishUuidCapture = ArgumentCaptor.forClass(String.class); - ArgumentCaptor finishItemCapture = ArgumentCaptor.forClass(FinishTestItemRQ.class); - verify(client, times(7)).finishTestItem(finishUuidCapture.capture(), finishItemCapture.capture()); - - List finishItems = finishItemCapture.getAllValues(); - FinishTestItemRQ testDescriptionTestAssertError = finishItems.get(0); - FinishTestItemRQ testDescriptionTestException = finishItems.get(1); - FinishTestItemRQ testWithDescriptionAnnotationTestException = finishItems.get(2); - FinishTestItemRQ testWithoutDescriptionTestAssertError = finishItems.get(3); - FinishTestItemRQ testWithoutDescriptionTestException = finishItems.get(4); - - assertThat(testDescriptionTestAssertError.getStatus(), equalTo(ItemStatus.FAILED.name())); - assertThat(testDescriptionTestException.getStatus(), equalTo(ItemStatus.FAILED.name())); - assertThat(testWithoutDescriptionTestAssertError.getStatus(), equalTo(ItemStatus.FAILED.name())); - assertThat(testWithoutDescriptionTestException.getStatus(), equalTo(ItemStatus.FAILED.name())); - assertThat(testWithDescriptionAnnotationTestException.getStatus(), equalTo(ItemStatus.FAILED.name())); - - assertThat(testDescriptionTestAssertError.getDescription(), startsWith(testDescriptionTestAssertErrorMessage)); - assertThat(testDescriptionTestException.getDescription(), startsWith(testDescriptionTestExceptionMessage)); - assertThat(testWithoutDescriptionTestAssertError.getDescription(), startsWith(testWithoutDescriptionTestAssertErrorMessage)); - assertThat(testWithoutDescriptionTestException.getDescription(), startsWith(testWithoutDescriptionTestExceptionMessage)); - assertThat(testWithDescriptionAnnotationTestException.getDescription(), startsWith(testDescriptionTestExceptionMessage)); - } + public static class TestListener extends BaseTestNGListener { + public static final ThreadLocal REPORT_PORTAL_THREAD_LOCAL = new ThreadLocal<>(); + + public TestListener() { + super(new TestNGService(new MemoizingSupplier<>(() -> getLaunch(REPORT_PORTAL_THREAD_LOCAL.get().getParameters())))); + } + + public static void initReportPortal(ReportPortal reportPortal) { + REPORT_PORTAL_THREAD_LOCAL.set(reportPortal); + } + + private static Launch getLaunch(ListenerParameters parameters) { + + ReportPortal reportPortal = REPORT_PORTAL_THREAD_LOCAL.get(); + StartLaunchRQ rq = new StartLaunchRQ(); + rq.setName(parameters.getLaunchName()); + rq.setStartTime(Instant.now()); + rq.setMode(parameters.getLaunchRunningMode()); + rq.setStartTime(Instant.now()); + + return reportPortal.newLaunch(rq); + + } + } + + private final String suitedUuid = namedUuid("suite"); + private final String testClassUuid = namedUuid("class"); + private final String assertionError = "java.lang.AssertionError: " + ASSERT_ERROR; + private final String noSuchElementException = "java.util.NoSuchElementException: " + NO_SUCH_ELEMENT_EXCEPTION; + private final String testDescriptionTestAssertErrorMessage = MarkdownUtils.asTwoParts( + TEST_DESCRIPTION, + String.format(DESCRIPTION_ERROR_FORMAT, assertionError) + ); + private final String testDescriptionTestExceptionMessage = MarkdownUtils.asTwoParts( + TEST_DESCRIPTION, + String.format(DESCRIPTION_ERROR_FORMAT, noSuchElementException) + ); + private final String testWithoutDescriptionTestAssertErrorMessage = String.format(DESCRIPTION_ERROR_FORMAT, assertionError).trim(); + private final String testWithoutDescriptionTestExceptionMessage = String.format(DESCRIPTION_ERROR_FORMAT, noSuchElementException) + .trim(); + + @Mock + private ReportPortalClient client; + + @BeforeEach + public void initMocks() { + mockLaunch(client, namedUuid("launchUuid"), suitedUuid, testClassUuid, "test"); + mockLogging(client); + ReportPortal reportPortal = ReportPortal.create(client, standardParameters()); + TestListener.initReportPortal(reportPortal); + } + + @Test + public void verify_description_in_case_of_test_exceptions() { + runTests(Collections.singletonList(TestDescriptionFailedTest.TestListener.class), DescriptionFailedTest.class); + + verify(client, times(1)).startLaunch(any()); // Start launch + verify(client, times(1)).startTestItem(any()); // Start parent suites + verify(client, times(1)).startTestItem(same(suitedUuid), any()); // Start test class + + ArgumentCaptor finishUuidCapture = ArgumentCaptor.forClass(String.class); + ArgumentCaptor finishItemCapture = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(client, times(7)).finishTestItem(finishUuidCapture.capture(), finishItemCapture.capture()); + + List finishItems = finishItemCapture.getAllValues(); + FinishTestItemRQ testDescriptionTestAssertError = finishItems.get(0); + FinishTestItemRQ testDescriptionTestException = finishItems.get(1); + FinishTestItemRQ testWithDescriptionAnnotationTestException = finishItems.get(2); + FinishTestItemRQ testWithoutDescriptionTestAssertError = finishItems.get(3); + FinishTestItemRQ testWithoutDescriptionTestException = finishItems.get(4); + + assertThat(testDescriptionTestAssertError.getStatus(), equalTo(ItemStatus.FAILED.name())); + assertThat(testDescriptionTestException.getStatus(), equalTo(ItemStatus.FAILED.name())); + assertThat(testWithoutDescriptionTestAssertError.getStatus(), equalTo(ItemStatus.FAILED.name())); + assertThat(testWithoutDescriptionTestException.getStatus(), equalTo(ItemStatus.FAILED.name())); + assertThat(testWithDescriptionAnnotationTestException.getStatus(), equalTo(ItemStatus.FAILED.name())); + + assertThat(testDescriptionTestAssertError.getDescription(), startsWith(testDescriptionTestAssertErrorMessage)); + assertThat(testDescriptionTestException.getDescription(), startsWith(testDescriptionTestExceptionMessage)); + assertThat(testWithoutDescriptionTestAssertError.getDescription(), startsWith(testWithoutDescriptionTestAssertErrorMessage)); + assertThat(testWithoutDescriptionTestException.getDescription(), startsWith(testWithoutDescriptionTestExceptionMessage)); + assertThat(testWithDescriptionAnnotationTestException.getDescription(), startsWith(testDescriptionTestExceptionMessage)); + } } diff --git a/src/test/java/com/epam/reportportal/testng/TestLaunchFinishShutdownHook.java b/src/test/java/com/epam/reportportal/testng/TestLaunchFinishShutdownHook.java index ceed8189..a9cc7800 100644 --- a/src/test/java/com/epam/reportportal/testng/TestLaunchFinishShutdownHook.java +++ b/src/test/java/com/epam/reportportal/testng/TestLaunchFinishShutdownHook.java @@ -31,7 +31,7 @@ public void test_shutdown_hook_finishes_launch_on_java_machine_exit(final Class< SocketUtils.ServerCallable serverCallable = new SocketUtils.ServerCallable( ss, Collections.emptyMap(), - Arrays.asList("files/launch_start_response.txt", "files/launch_finish_response.txt") + Arrays.asList("files/info_response_microseconds.txt", "files/launch_start_response.txt", "files/launch_finish_response.txt") ); Callable clientCallable = () -> ProcessUtils.buildProcess( true, @@ -41,7 +41,7 @@ public void test_shutdown_hook_finishes_launch_on_java_machine_exit(final Class< ); Pair, Process> startResult = SocketUtils.executeServerCallable(serverCallable, clientCallable, 20); assertThat(startResult.getValue(), notNullValue()); - assertThat("First request is a launch start", startResult.getKey().get(0), startsWith("POST /api/v2/test-project/launch")); + assertThat("Second request is a launch start", startResult.getKey().get(1), startsWith("POST /api/v2/test-project/launch")); Callable clientCallableResult = () -> { try { @@ -55,12 +55,14 @@ public void test_shutdown_hook_finishes_launch_on_java_machine_exit(final Class< return -2; } }; - Integer finishResult = CommonUtils.testExecutor().submit(clientCallableResult).get(35, TimeUnit.SECONDS); - assertThat( - "Second request is a launch finish", - startResult.getKey().get(1), - startsWith("PUT /api/v2/test-project/launch/b7a79414-287c-452d-b157-c32fe6cb1c72/finish") - ); - assertThat("Exit code should be '0'", finishResult, equalTo(0)); + try (CommonUtils.ExecutorService executor = CommonUtils.testExecutor()) { + Integer finishResult = executor.submit(clientCallableResult).get(35, TimeUnit.SECONDS); + assertThat( + "Second request is a launch finish", + startResult.getKey().get(2), + startsWith("PUT /api/v2/test-project/launch/b7a79414-287c-452d-b157-c32fe6cb1c72/finish") + ); + assertThat("Exit code should be '0'", finishResult, equalTo(0)); + } } } diff --git a/src/test/java/com/epam/reportportal/testng/bug/TestSkipExceptionOnBeforeClassTest.java b/src/test/java/com/epam/reportportal/testng/bug/TestSkipExceptionOnBeforeClassTest.java index 78fa6c79..4e004310 100644 --- a/src/test/java/com/epam/reportportal/testng/bug/TestSkipExceptionOnBeforeClassTest.java +++ b/src/test/java/com/epam/reportportal/testng/bug/TestSkipExceptionOnBeforeClassTest.java @@ -29,14 +29,15 @@ import com.epam.ta.reportportal.ws.model.FinishTestItemRQ; import com.epam.ta.reportportal.ws.model.StartTestItemRQ; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; +import io.reactivex.Maybe; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import java.time.Instant; import java.util.Arrays; -import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -47,97 +48,107 @@ import static org.hamcrest.Matchers.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class TestSkipExceptionOnBeforeClassTest { - public static class TestListener extends BaseTestNGListener { - public static final ThreadLocal REPORT_PORTAL_THREAD_LOCAL = new ThreadLocal<>(); - - public TestListener() { - super(new TestNGService(new MemoizingSupplier<>(() -> getLaunch(REPORT_PORTAL_THREAD_LOCAL.get().getParameters())))); - } - - public static void initReportPortal(ReportPortal reportPortal) { - REPORT_PORTAL_THREAD_LOCAL.set(reportPortal); - } - - private static Launch getLaunch(ListenerParameters parameters) { - - ReportPortal reportPortal = REPORT_PORTAL_THREAD_LOCAL.get(); - StartLaunchRQ rq = new StartLaunchRQ(); - rq.setName(parameters.getLaunchName()); - rq.setStartTime(Calendar.getInstance().getTime()); - rq.setMode(parameters.getLaunchRunningMode()); - rq.setStartTime(Calendar.getInstance().getTime()); - - return reportPortal.newLaunch(rq); - - } - } - - private final String suitedUuid = namedUuid("suite"); - private final String testClassUuid = namedUuid("class"); - private final List testUuidList = - Arrays.asList(namedUuid("beforeClass"), namedUuid("beforeMethod"), namedUuid("test"), - namedUuid("afterMethod"), namedUuid("afterClass")); - - private final List finishUuidOrder = - Stream.concat(testUuidList.stream(), Stream.of(testClassUuid, suitedUuid)).collect(Collectors.toList()); - - - @Mock - private ReportPortalClient client; - - @BeforeEach - public void initMocks() { - mockLaunch(client, namedUuid("launchUuid"), suitedUuid, testClassUuid, testUuidList); - mockLogging(client); - ReportPortal reportPortal = ReportPortal.create(client, standardParameters()); - TestListener.initReportPortal(reportPortal); - } - - @Test - public void verify_step_integrity_in_case_of_before_class_failed_with_skip_exception() { - runTests(Collections.singletonList(TestListener.class), SkipExceptionOnBeforeClassTest.class); - - verify(client, times(1)).startLaunch(any()); // Start launch - verify(client, times(1)).startTestItem(any()); // Start parent suites - verify(client, times(1)).startTestItem(same(suitedUuid), any()); // Start test class - - ArgumentCaptor startTestCapture = ArgumentCaptor.forClass(StartTestItemRQ.class); - verify(client, times(5)).startTestItem(same(testClassUuid), startTestCapture.capture()); - List startItems = startTestCapture.getAllValues(); - - assertThat(startItems.get(0).getType(), equalTo(ItemType.BEFORE_CLASS.name())); - assertThat(startItems.get(1).getType(), equalTo(ItemType.BEFORE_METHOD.name())); - assertThat(startItems.get(2).getType(), equalTo(ItemType.STEP.name())); - assertThat(startItems.get(3).getType(), equalTo(ItemType.AFTER_METHOD.name())); - assertThat(startItems.get(4).getType(), equalTo(ItemType.AFTER_CLASS.name())); - - ArgumentCaptor finishUuidCapture = ArgumentCaptor.forClass(String.class); - ArgumentCaptor finishItemCapture = ArgumentCaptor.forClass(FinishTestItemRQ.class); - verify(client, times(finishUuidOrder.size())).finishTestItem(finishUuidCapture.capture(), finishItemCapture.capture()); - List finishUuids = finishUuidCapture.getAllValues(); - assertThat(finishUuids, containsInAnyOrder(finishUuidOrder.toArray(new String[0]))); - - List finishItems = finishItemCapture.getAllValues(); - - FinishTestItemRQ beforeClassFinish = finishItems.get(0); - assertThat(beforeClassFinish.getStatus(), equalTo(ItemStatus.SKIPPED.name())); - assertThat(beforeClassFinish.getIssue(), nullValue()); - - finishItems.subList(1, finishItems.size() - 2).forEach(finishTestItemRQ -> { - assertThat(finishTestItemRQ.getStatus(), equalTo(ItemStatus.SKIPPED.name())); - assertThat(finishTestItemRQ.getIssue(), notNullValue()); - assertThat(finishTestItemRQ.getIssue().getIssueType(), equalTo(Launch.NOT_ISSUE.getIssueType())); - }); - - finishItems.subList(finishItems.size() - 2, finishItems.size()).forEach(finishTestItemRQ -> { - assertThat(finishTestItemRQ.getStatus(), nullValue()); - assertThat(finishTestItemRQ.getIssue(), nullValue()); - }); - } + public static class TestListener extends BaseTestNGListener { + public static final ThreadLocal REPORT_PORTAL_THREAD_LOCAL = new ThreadLocal<>(); + + public TestListener() { + super(new TestNGService(new MemoizingSupplier<>(() -> getLaunch(REPORT_PORTAL_THREAD_LOCAL.get().getParameters())))); + } + + public static void initReportPortal(ReportPortal reportPortal) { + REPORT_PORTAL_THREAD_LOCAL.set(reportPortal); + } + + private static Launch getLaunch(ListenerParameters parameters) { + + ReportPortal reportPortal = REPORT_PORTAL_THREAD_LOCAL.get(); + StartLaunchRQ rq = new StartLaunchRQ(); + rq.setName(parameters.getLaunchName()); + rq.setStartTime(Instant.now()); + rq.setMode(parameters.getLaunchRunningMode()); + rq.setStartTime(Instant.now()); + + return reportPortal.newLaunch(rq); + + } + } + + private final String suitedUuid = namedUuid("suite"); + private final String testClassUuid = namedUuid("class"); + private final List testUuidList = Arrays.asList( + namedUuid("beforeClass"), + namedUuid("beforeMethod"), + namedUuid("test"), + namedUuid("afterMethod"), + namedUuid("afterClass") + ); + + private final List finishUuidOrder = Stream.concat(testUuidList.stream(), Stream.of(testClassUuid, suitedUuid)) + .collect(Collectors.toList()); + + @Mock + private ReportPortalClient client; + + @BeforeEach + public void initMocks() { + mockLaunch(client, namedUuid("launchUuid"), suitedUuid, testClassUuid, testUuidList); + mockLogging(client); + when(client.getApiInfo()).thenReturn(Maybe.just(testApiInfo())); + ReportPortal reportPortal = ReportPortal.create(client, standardParameters()); + TestListener.initReportPortal(reportPortal); + } + + @Test + public void verify_step_integrity_in_case_of_before_class_failed_with_skip_exception() { + runTests(Collections.singletonList(TestListener.class), SkipExceptionOnBeforeClassTest.class); + + verify(client, times(1)).startLaunch(any()); // Start launch + verify(client, times(1)).startTestItem(any()); // Start parent suites + verify(client, times(1)).startTestItem(same(suitedUuid), any()); // Start test class + + ArgumentCaptor startTestCapture = ArgumentCaptor.forClass(StartTestItemRQ.class); + verify(client, times(5)).startTestItem(same(testClassUuid), startTestCapture.capture()); + List startItems = startTestCapture.getAllValues(); + + List types = startItems.stream().map(StartTestItemRQ::getType).collect(Collectors.toList()); + // It passes too fast to preserve order + assertThat( + types, + containsInAnyOrder( + ItemType.BEFORE_CLASS.name(), + ItemType.BEFORE_METHOD.name(), + ItemType.STEP.name(), + ItemType.AFTER_METHOD.name(), + ItemType.AFTER_CLASS.name() + ) + ); + + ArgumentCaptor finishUuidCapture = ArgumentCaptor.forClass(String.class); + ArgumentCaptor finishItemCapture = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(client, times(finishUuidOrder.size())).finishTestItem(finishUuidCapture.capture(), finishItemCapture.capture()); + List finishUuids = finishUuidCapture.getAllValues(); + assertThat(finishUuids, containsInAnyOrder(finishUuidOrder.toArray(new String[0]))); + + List finishItems = finishItemCapture.getAllValues(); + + FinishTestItemRQ beforeClassFinish = finishItems.get(0); + assertThat(beforeClassFinish.getStatus(), equalTo(ItemStatus.SKIPPED.name())); + assertThat(beforeClassFinish.getIssue(), nullValue()); + + finishItems.subList(1, finishItems.size() - 2).forEach(finishTestItemRQ -> { + assertThat(finishTestItemRQ.getStatus(), equalTo(ItemStatus.SKIPPED.name())); + assertThat(finishTestItemRQ.getIssue(), notNullValue()); + assertThat(finishTestItemRQ.getIssue().getIssueType(), equalTo(Launch.NOT_ISSUE.getIssueType())); + }); + + finishItems.subList(finishItems.size() - 2, finishItems.size()).forEach(finishTestItemRQ -> { + assertThat(finishTestItemRQ.getStatus(), nullValue()); + assertThat(finishTestItemRQ.getIssue(), nullValue()); + }); + } } diff --git a/src/test/java/com/epam/reportportal/testng/bug/TestWithFailedRetryAndDependentMethods.java b/src/test/java/com/epam/reportportal/testng/bug/TestWithFailedRetryAndDependentMethods.java index 1a2d4f54..d7316c89 100644 --- a/src/test/java/com/epam/reportportal/testng/bug/TestWithFailedRetryAndDependentMethods.java +++ b/src/test/java/com/epam/reportportal/testng/bug/TestWithFailedRetryAndDependentMethods.java @@ -18,8 +18,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import java.time.Instant; import java.util.Arrays; -import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -52,9 +52,9 @@ private static Launch getLaunch(ListenerParameters parameters) { ReportPortal reportPortal = REPORT_PORTAL_THREAD_LOCAL.get(); StartLaunchRQ rq = new StartLaunchRQ(); rq.setName(parameters.getLaunchName()); - rq.setStartTime(Calendar.getInstance().getTime()); + rq.setStartTime(Instant.now()); rq.setMode(parameters.getLaunchRunningMode()); - rq.setStartTime(Calendar.getInstance().getTime()); + rq.setStartTime(Instant.now()); return reportPortal.newLaunch(rq); @@ -65,8 +65,8 @@ private static Launch getLaunch(ListenerParameters parameters) { private final String testClassUuid = namedUuid("class"); private final List testUuidList = Arrays.asList(namedUuid("test1"), namedUuid("test1"), namedUuid("test2"), namedUuid("test3")); - private final List finishUuidOrder = - Stream.concat(testUuidList.stream(), Stream.of(testClassUuid, suitedUuid)).collect(Collectors.toList()); + private final List finishUuidOrder = Stream.concat(testUuidList.stream(), Stream.of(testClassUuid, suitedUuid)) + .collect(Collectors.toList()); @Mock private ReportPortalClient client; diff --git a/src/test/java/com/epam/reportportal/testng/bug/TestWithRetryWithStepsAndDependentMethodTest.java b/src/test/java/com/epam/reportportal/testng/bug/TestWithRetryWithStepsAndDependentMethodTest.java index 0e527f3c..a5dfcef3 100644 --- a/src/test/java/com/epam/reportportal/testng/bug/TestWithRetryWithStepsAndDependentMethodTest.java +++ b/src/test/java/com/epam/reportportal/testng/bug/TestWithRetryWithStepsAndDependentMethodTest.java @@ -20,8 +20,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import java.time.Instant; import java.util.Arrays; -import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -54,9 +54,9 @@ private static Launch getLaunch(ListenerParameters parameters) { ReportPortal reportPortal = REPORT_PORTAL_THREAD_LOCAL.get(); StartLaunchRQ rq = new StartLaunchRQ(); rq.setName(parameters.getLaunchName()); - rq.setStartTime(Calendar.getInstance().getTime()); + rq.setStartTime(Instant.now()); rq.setMode(parameters.getLaunchRunningMode()); - rq.setStartTime(Calendar.getInstance().getTime()); + rq.setStartTime(Instant.now()); return reportPortal.newLaunch(rq); diff --git a/src/test/java/com/epam/reportportal/testng/integration/bug/SkipExceptionOnBeforeClassTest.java b/src/test/java/com/epam/reportportal/testng/integration/bug/SkipExceptionOnBeforeClassTest.java index 87d53f17..4bd0f677 100644 --- a/src/test/java/com/epam/reportportal/testng/integration/bug/SkipExceptionOnBeforeClassTest.java +++ b/src/test/java/com/epam/reportportal/testng/integration/bug/SkipExceptionOnBeforeClassTest.java @@ -20,30 +20,30 @@ import org.testng.annotations.*; public class SkipExceptionOnBeforeClassTest { - public static final String SKIP_EXCEPTION = "Just skip the test!"; - - @BeforeClass - public void beforeClass() { - throw new SkipException(SKIP_EXCEPTION); - } - - @BeforeMethod - public void beforeMethod() { - // should just be skipped - } - - @Test - public void theTest() { - // should just be skipped - } - - @AfterMethod - public void afterMethod() { - // should just be skipped - } - - @AfterClass - public void afterClass() { - // should just be skipped - } + public static final String SKIP_EXCEPTION = "Just skip the test!"; + + @BeforeClass + public void beforeClass() { + throw new SkipException(SKIP_EXCEPTION); + } + + @BeforeMethod + public void beforeMethod() { + // should just be skipped + } + + @Test + public void theTest() { + // should just be skipped + } + + @AfterMethod + public void afterMethod() { + // should just be skipped + } + + @AfterClass + public void afterClass() { + // should just be skipped + } } diff --git a/src/test/java/com/epam/reportportal/testng/integration/feature/callback/CallbackReportingTest.java b/src/test/java/com/epam/reportportal/testng/integration/feature/callback/CallbackReportingTest.java index 325145b4..b2a35379 100644 --- a/src/test/java/com/epam/reportportal/testng/integration/feature/callback/CallbackReportingTest.java +++ b/src/test/java/com/epam/reportportal/testng/integration/feature/callback/CallbackReportingTest.java @@ -9,7 +9,7 @@ import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; -import java.util.Calendar; +import java.time.Instant; import static com.epam.reportportal.testng.TestNGService.ITEM_TREE; import static java.util.Optional.ofNullable; @@ -49,19 +49,22 @@ private void sendFinishRequest(TestItemTree.TestItemLeaf testResultLeaf, String FinishTestItemRQ finishTestItemRQ = new FinishTestItemRQ(); finishTestItemRQ.setDescription(description); finishTestItemRQ.setStatus(status); - finishTestItemRQ.setEndTime(Calendar.getInstance().getTime()); + finishTestItemRQ.setEndTime(Instant.now()); //noinspection ResultOfMethodCallIgnored - ofNullable(Launch.currentLaunch()).ifPresent(l -> - ItemTreeReporter.finishItem(l.getClient(), finishTestItemRQ, ITEM_TREE.getLaunchId(), testResultLeaf) - .cache() - .blockingGet()); + ofNullable(Launch.currentLaunch()).ifPresent(l -> ItemTreeReporter.finishItem( + l.getClient(), + finishTestItemRQ, + ITEM_TREE.getLaunchId(), + testResultLeaf + ).cache().blockingGet()); } private void attachLog(TestItemTree.TestItemLeaf testItemLeaf) { - ofNullable(Launch.currentLaunch()).ifPresent(l -> ItemTreeReporter.sendLog(l.getClient(), + ofNullable(Launch.currentLaunch()).ifPresent(l -> ItemTreeReporter.sendLog( + l.getClient(), "ERROR", "Error message", - Calendar.getInstance().getTime(), + Instant.now(), ITEM_TREE.getLaunchId(), testItemLeaf )); diff --git a/src/test/java/com/epam/reportportal/testng/integration/feature/description/DescriptionFailedTest.java b/src/test/java/com/epam/reportportal/testng/integration/feature/description/DescriptionFailedTest.java index 0ff8d188..b933e243 100644 --- a/src/test/java/com/epam/reportportal/testng/integration/feature/description/DescriptionFailedTest.java +++ b/src/test/java/com/epam/reportportal/testng/integration/feature/description/DescriptionFailedTest.java @@ -1,47 +1,48 @@ package com.epam.reportportal.testng.integration.feature.description; import com.epam.reportportal.annotations.Description; -import java.util.NoSuchElementException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; import org.testng.annotations.Test; +import java.util.NoSuchElementException; + public class DescriptionFailedTest { - private static final Logger LOGGER = LoggerFactory.getLogger(DescriptionFailedTest.class); - - public static final String TEST_DESCRIPTION = "My test description"; - public static final String ASSERT_ERROR = "Assert Error"; - public static final String NO_SUCH_ELEMENT_EXCEPTION = "No Such Element Exception"; - - @Test(description = TEST_DESCRIPTION) - public void testDescriptionTestAssertError() { - LOGGER.info("Inside 'testDescriptionTestAssertError' method"); - Assert.fail(ASSERT_ERROR); - } - - @Test - public void testWithoutDescriptionTestAssertError() { - LOGGER.info("Inside 'testWithoutDescriptionTestAssertError' method"); - Assert.fail(ASSERT_ERROR); - } - - @Test(description = TEST_DESCRIPTION) - public void testDescriptionTestException() { - LOGGER.info("Inside 'testDescriptionTestException' method"); - throw new NoSuchElementException(NO_SUCH_ELEMENT_EXCEPTION); - } - - @Test - public void testWithoutDescriptionTestException() { - LOGGER.info("Inside 'testWithoutDescriptionTestException' method"); - throw new NoSuchElementException(NO_SUCH_ELEMENT_EXCEPTION); - } - - @Test - @Description(TEST_DESCRIPTION) - public void testWithDescriptionAnnotationTestException() { - LOGGER.info("Inside 'testWithoutDescriptionTestException' method"); - throw new NoSuchElementException(NO_SUCH_ELEMENT_EXCEPTION); - } + private static final Logger LOGGER = LoggerFactory.getLogger(DescriptionFailedTest.class); + + public static final String TEST_DESCRIPTION = "My test description"; + public static final String ASSERT_ERROR = "Assert Error"; + public static final String NO_SUCH_ELEMENT_EXCEPTION = "No Such Element Exception"; + + @Test(description = TEST_DESCRIPTION) + public void testDescriptionTestAssertError() { + LOGGER.info("Inside 'testDescriptionTestAssertError' method"); + Assert.fail(ASSERT_ERROR); + } + + @Test + public void testWithoutDescriptionTestAssertError() { + LOGGER.info("Inside 'testWithoutDescriptionTestAssertError' method"); + Assert.fail(ASSERT_ERROR); + } + + @Test(description = TEST_DESCRIPTION) + public void testDescriptionTestException() { + LOGGER.info("Inside 'testDescriptionTestException' method"); + throw new NoSuchElementException(NO_SUCH_ELEMENT_EXCEPTION); + } + + @Test + public void testWithoutDescriptionTestException() { + LOGGER.info("Inside 'testWithoutDescriptionTestException' method"); + throw new NoSuchElementException(NO_SUCH_ELEMENT_EXCEPTION); + } + + @Test + @Description(TEST_DESCRIPTION) + public void testWithDescriptionAnnotationTestException() { + LOGGER.info("Inside 'testWithoutDescriptionTestException' method"); + throw new NoSuchElementException(NO_SUCH_ELEMENT_EXCEPTION); + } } diff --git a/src/test/java/com/epam/reportportal/testng/integration/feature/skipped/BeforeClassFailedTest.java b/src/test/java/com/epam/reportportal/testng/integration/feature/skipped/BeforeClassFailedTest.java index a03c47d9..cee6b1ac 100644 --- a/src/test/java/com/epam/reportportal/testng/integration/feature/skipped/BeforeClassFailedTest.java +++ b/src/test/java/com/epam/reportportal/testng/integration/feature/skipped/BeforeClassFailedTest.java @@ -2,7 +2,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.testng.annotations.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; public class BeforeClassFailedTest { private static final Logger LOGGER = LoggerFactory.getLogger(BeforeClassFailedTest.class); diff --git a/src/test/java/com/epam/reportportal/testng/integration/util/TestUtils.java b/src/test/java/com/epam/reportportal/testng/integration/util/TestUtils.java index b0c36894..b3687c9a 100644 --- a/src/test/java/com/epam/reportportal/testng/integration/util/TestUtils.java +++ b/src/test/java/com/epam/reportportal/testng/integration/util/TestUtils.java @@ -2,13 +2,14 @@ import com.epam.reportportal.listeners.ListenerParameters; import com.epam.reportportal.service.Launch; +import com.epam.reportportal.service.LaunchImpl; import com.epam.reportportal.service.ReportPortalClient; import com.epam.reportportal.util.test.CommonUtils; +import com.epam.ta.reportportal.ws.model.ApiInfo; import com.epam.ta.reportportal.ws.model.BatchSaveOperatingRS; import com.epam.ta.reportportal.ws.model.OperationCompletionRS; import com.epam.ta.reportportal.ws.model.StartTestItemRQ; import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS; -import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS; import io.reactivex.Maybe; import org.apache.commons.lang3.tuple.Pair; @@ -18,7 +19,6 @@ import org.testng.TestNG; import java.util.*; -import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; import static org.mockito.ArgumentMatchers.*; @@ -56,26 +56,6 @@ public static List extractRequests(ArgumentCaptor methodType.equalsIgnoreCase(it.getType())).collect(Collectors.toList()); } - /** - * Generates a unique ID shorter than UUID based on current time in milliseconds and thread ID. - * - * @return a unique ID string - */ - public static String generateUniqueId() { - return System.currentTimeMillis() + "-" + Thread.currentThread().getId() + "-" + ThreadLocalRandom.current().nextInt(9999); - } - - public static StartTestItemRQ standardStartStepRequest() { - StartTestItemRQ rq = new StartTestItemRQ(); - rq.setStartTime(Calendar.getInstance().getTime()); - String id = generateUniqueId(); - rq.setName("Step_" + id); - rq.setDescription("Test step description"); - rq.setUniqueId(id); - rq.setType("STEP"); - return rq; - } - public static void mockLaunch(Launch launch, Maybe launchUuid, Maybe suiteUuid, Maybe testClassUuid, Collection> testMethodUuidList) { mockLaunch(launch, standardParameters(), launchUuid, suiteUuid, testClassUuid, testMethodUuidList); @@ -160,7 +140,8 @@ public static void mockNestedSteps(final ReportPortalClient client, final List

[] other = responses.subList(1, responses.size()).toArray(new Maybe[0]); when(client.startTestItem(same(k), any())).thenReturn(first, other); }); - parentNestedPairs.forEach(p -> when(client.finishTestItem(same(p.getValue()), + parentNestedPairs.forEach(p -> when(client.finishTestItem( + same(p.getValue()), any() )).thenAnswer((Answer>) invocation -> Maybe.just(new OperationCompletionRS()))); } @@ -181,11 +162,11 @@ public static ListenerParameters standardParameters() { return result; } - public static StartLaunchRQ launchRQ(ListenerParameters parameters) { - StartLaunchRQ result = new StartLaunchRQ(); - result.setName(parameters.getLaunchName()); - result.setStartTime(Calendar.getInstance().getTime()); - result.setMode(parameters.getLaunchRunningMode()); - return result; + public static ApiInfo testApiInfo() { + ApiInfo apiInfo = new ApiInfo(); + ApiInfo.Build build = new ApiInfo.Build(); + apiInfo.setBuild(build); + build.setVersion(LaunchImpl.MICROSECONDS_MIN_VERSION); + return apiInfo; } } diff --git a/src/test/resources/files/info_response_microseconds.txt b/src/test/resources/files/info_response_microseconds.txt new file mode 100644 index 00000000..5df886b2 --- /dev/null +++ b/src/test/resources/files/info_response_microseconds.txt @@ -0,0 +1,11 @@ +HTTP/1.1 200 OK +Cache-Control: no-cache, no-store, max-age=0, must-revalidate +Content-Type: application/json +Expires: 0 +Pragma: no-cache +X-Content-Type-Options: nosniff +X-Frame-Options: DENY +X-Xss-Protection: 1; mode=block +Content-Length: 30 + +{"build":{"version":"5.13.2"}} \ No newline at end of file