testng icon indicating copy to clipboard operation
testng copied to clipboard

FileAlreadyExistsException when report is generated

Open JanVomlel opened this issue 2 years ago • 2 comments

TestNG Version

7.6.0 7.5 is ok

Expected behavior

Generate test reports without errors in console.

Actual behavior

> Task :libs:xxx:test
Jun 01, 2022 9:01:16 AM org.testng.log4testng.Logger error
SEVERE: D:\...\build\reports\tests\test\jquery-3.6.0.min.js
java.nio.file.FileAlreadyExistsException: D:\...\build\reports\tests\test\jquery-3.6.0.min.js
	at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:87)
	at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
	at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
	at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:236)
	at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:484)
	at java.base/java.nio.file.Files.newOutputStream(Files.java:228)
	at java.base/java.nio.file.Files.copy(Files.java:3160)
	at org.testng.reporters.jq.Main.generateReport(Main.java:93)
	at org.testng.TestNG.generateReports(TestNG.java:1134)
	at org.testng.TestNG.run(TestNG.java:1072)
	at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:141)
	at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:90)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

Is the issue reproducible on runner?

  • [ ] Shell
  • [ ] Maven
  • [x ] Gradle
  • [ ] Ant
  • [ ] Eclipse
  • [ ] IntelliJ
  • [ ] NetBeans

Test case sample

useTestNG() { useDefaultListeners = true }

JanVomlel avatar Jun 01 '22 07:06 JanVomlel

We are seeing this with egeria ( https://github.com/odpi/egeria ) under maven.

testng 7.5 works fine. 7.6.0 introduced the issue, which continues into 7.6.1

I was testing with

mvn --version    
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: /usr/local/Cellar/maven/3.8.6/libexec
Java version: 18.0.1.1, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk/18.0.1.1/libexec/openjdk.jdk/Contents/Home
Default locale: en_GB, platform encoding: UTF-8
OS name: "mac os x", version: "12.5", arch: "x86_64", family: "mac"

surefire plugin is 3.0.0-M7 (also occurs with M6/M5)

Example: /Users/jonesn/IdeaProjects/egeria/master/open-metadata-implementation/frameworks/open-connector-framework/target/surefire-reports/jquery-3.6.0.min.js

planetf1 avatar Jul 01 '22 10:07 planetf1

I am also observing this in both 7.6.0 and 7.6.1, as stated by OP 7.5 is ok

Ordiel avatar Jul 08 '22 18:07 Ordiel

Our company has the same issue. Yes it is somewhat "ignorable" but would be nice if this is not happening :D

codenox-vs avatar Oct 28 '22 15:10 codenox-vs

@codenox-vs Maybe your company wants to propose a fix?

juherr avatar Oct 30 '22 14:10 juherr

@codenox-vs @Ordiel @planetf1 @JanVomlel - Can one of you please help create and share a sample test project that can be used to reproduce the problem? For some reason I am not able to recreate it.

This is how my gradle build file looks like

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This is a general purpose Gradle build.
 * Learn more about Gradle by exploring our samples at https://docs.gradle.org/7.3.3/samples
 * This project uses @Incubating APIs which are subject to change.
 */

plugins {
    java
    idea
}

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(11))
    }
}

repositories {
    mavenCentral()
}

dependencies {
    // https://mvnrepository.com/artifact/org.testng/testng
    testImplementation("org.testng:testng:7.6.1")
}

tasks.test {
    testLogging.showStandardStreams = true
    useTestNG {
        useDefaultListeners = true
        val options = this as TestNGOptions
        options.suites("src/test/resources/testng.xml")
    }
    reports.html.required.set( false)
}

This is how my test case looks like

import org.testng.annotations.Test;

public class HelloWorld {

  @Test
  public void testMethod() {}

  @Test
  public void anotherTestMethod() {}

  @Test
  public void thirdTest() {}
}

This is how my suite file looks like

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Default Suite">
  <test thread-count="5" name="testng_playground" verbose="2">
    <classes>
      <class name="com.rationaleemotions.HelloWorld">
      </class>
    </classes>
  </test> <!-- testng_playground -->
</suite> <!-- Default Suite -->

And this is how my command output looks like

➜  test_example ./gradlew test      

> Task :test

Gradle Test Executor 4 STANDARD_ERROR
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Default Suite STANDARD_OUT
    PASSED: com.rationaleemotions.HelloWorld.thirdTest
    PASSED: com.rationaleemotions.HelloWorld.anotherTestMethod
    PASSED: com.rationaleemotions.HelloWorld.testMethod

    ===============================================
        testng_playground
        Tests run: 3, Failures: 0, Skips: 0
    ===============================================


BUILD SUCCESSFUL in 2s
3 actionable tasks: 2 executed, 1 up-to-date

krmahadevan avatar Oct 31 '22 04:10 krmahadevan

We see this too in all our projects

melloware avatar Nov 04 '22 18:11 melloware

We see this too in all our projects

@melloware how about sharing a sample project which I can use to reproduce the problem ?

krmahadevan avatar Nov 05 '22 01:11 krmahadevan

@krmahadevan the bug is right here:

https://github.com/cbeust/testng/blob/b484be19263ded600f47206396f51a3ac3f49710/testng-core/src/main/java/org/testng/reporters/jq/Main.java#L95

it needs to be...

Files.copy(cfgFilePath, strTarget, StandardCopyOption.REPLACE_EXISTING);

melloware avatar Nov 05 '22 13:11 melloware

@melloware - Thanks for pointing out the line of code. As I mentioned here I wasn't able to reproduce the problem with a standard Gradle project.

It would help if there's a reproducible so that we can add a test as well that would ensure that going forward the bug doesn't come up again.

Alternatively we would be more than glad to help merge a PR if you would like to raise one (especially since you have taken the effort to identify the line of code as well that is causing the problem).

krmahadevan avatar Nov 05 '22 13:11 krmahadevan

Ok I will do. One thing to note I have a feeling this is Windows bug are you running your example in Windows or some other Os?

If you look in the stack trace is definitely mentions WindowsFileSystem which has different locking than Linux.

melloware avatar Nov 05 '22 13:11 melloware

@melloware - Good catch! That could be the reason. I am running on a OSX machine which perhaps is why I couldn't reproduce it.

krmahadevan avatar Nov 05 '22 13:11 krmahadevan

Ok I will submit a PR.

melloware avatar Nov 05 '22 13:11 melloware

We have observed this issue on linux with eclipse. I'll see if I can provide a reproducer.

guillaumecle avatar Nov 05 '22 18:11 guillaumecle

PR submitted

melloware avatar Nov 06 '22 12:11 melloware

PR submitted

Thanks @melloware , I just started experiencing this issue on the latest version as well. Can't wait for the PR to be merged! Impacted environments: Linux, Windows: Gradle, Eclipse

speedythesnail avatar Nov 06 '22 18:11 speedythesnail

@krmahadevan the reason you were not able to reproduce is probably this warning

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Because the nop logger is used, the exception is not logged to the console (from there https://github.com/cbeust/testng/blob/master/testng-core/src/main/java/org/testng/reporters/jq/Main.java#L103) Adding a slf4j binding (like log4j-slf4j-impl) as a dependency should be enough to see the exception.

guillaumecle avatar Nov 07 '22 20:11 guillaumecle