I have a nodejs project written in coffeescript which I use the sonar javascript plugin to analyse.
I have all my source in a folder called "src" and tests in a folder called "test".
The test files have the same names as the source files.
When I run tests
- the coffescript is compiled to javascript and copied to "lib/src" and "lib/test"
- the javascript is then instrumented for coverage and copied to "lib-cov/lib/src" and "lib-cov/lib/test" (actually only the src is instrumented, the tests are just copied again to maintain relative paths)
After running the tests on the instrumented code I get 2 reports "reports/lcov.info" and "reports/TEST-all.xml"
This works on one of my projects but in another I get duplicate resource errors from 2 of the source files (I cannot figure out what's special about them)
The "sonar-project.properties" looks like this:
sonar.projectKey=ddm:ddm-server
sonar.projectName=D4A Dependency Manager Server
sonar.projectVersion=1.0
sonar.sources=lib/src
sonar.exclusions=index.js
sonar.language=js
sonar.javascript.jstestdriver.reportsPath=reports
sonar.javascript.lcov.reportPath=reports/lcov.info
The files in the "lib/src" directory are (there are no subdirectories):
- Archive.js
- Get.js
- index.js
- Library.js
- Post.js
- Registry.js
- Version.js
Only "Archive.js" and "Post.js" cause a problem
and result in the following error:
ERROR: Caused by: Duplicate source for resource: org.sonar.api.resources.File@16d828ef[key=Archive.js,dir=<null>,filename=Archive.js,language=JavaScript]
If I exclude "Archive.js" and "Post.js" everything works fine - Is there something special about these names?
FYI: the complete output from the sonar runner in Jenkins is:
[DDM_SERVER_CONTINUOUS_BUILD_AND_TEST] $ /home/jenkins/tools/hudson.plugins.sonar.SonarRunnerInstallation/Sonar_Runner_2.3/sonar-runner-2.3/bin/sonar-runner -Dsonar.jdbc.driver=com.mysql.jdbc.Driver -Dsonar.jdbc.url=jdbc:mysql://sonar.lgcoreapps.com:3306/sonar?autoReconnect=true&useUnicode=true&characterEncoding=utf8 ******** ******** -Dsonar.host.url=http://sonar.lgcoreapps.com ******** ******** -Dsonar.projectBaseDir=<http://jenkins.lgcoreapps.com/job/DDM_SERVER_CONTINUOUS_BUILD_AND_TEST/ws/> -Dsonar.exclusions=index.js
SonarQube Runner 2.3
Java 1.7.0_09-icedtea Oracle Corporation (64-bit)
Linux 2.6.32-358.el6.x86_64 amd64
INFO: Runner configuration file: /home/jenkins/tools/hudson.plugins.sonar.SonarRunnerInstallation/Sonar_Runner_2.3/sonar-runner-2.3/conf/sonar-runner.properties
INFO: Project configuration file: <http://jenkins.lgcoreapps.com/job/DDM_SERVER_CONTINUOUS_BUILD_AND_TEST/ws/sonar-project.properties>
INFO: Default locale: "en_US", source code encoding: "US-ASCII" (analysis is platform dependent)
INFO: Work directory: <http://jenkins.lgcoreapps.com/job/DDM_SERVER_CONTINUOUS_BUILD_AND_TEST/ws/.sonar>
INFO: SonarQube Server 3.5.1
13:46:58.260 INFO - Load batch settings
13:46:58.349 INFO - User cache: /home/jenkins/.sonar/cache
13:46:58.351 INFO - Install plugins
13:46:59.109 INFO - ------------- Executing Project Scan
13:46:59.750 INFO - Install JDBC driver
13:46:59.754 INFO - Apply project exclusions
13:46:59.758 INFO - Create JDBC datasource for jdbc:mysql://sonar.lgcoreapps.com:3306/sonar?autoReconnect=true&useUnicode=true&characterEncoding=utf8
13:47:00.110 INFO - Initializing Hibernate
13:47:03.520 INFO - ------------- Inspecting D4A Dependency Manager Server
13:47:03.525 INFO - Load module settings
13:47:04.145 INFO - Quality profile : [name=Sonar way,language=js]
13:47:04.171 INFO - Excluded sources:
13:47:04.172 INFO - index.js
13:47:04.172 INFO - Excluded tests:
13:47:04.172 INFO - **/package-info.java
13:47:04.203 INFO - Configure Maven plugins
13:47:04.309 INFO - Compare to previous analysis (2014-02-07)
13:47:04.335 INFO - Compare over 5 days (2014-02-02, analysis of 2014-02-07 12:04:17.0)
13:47:04.352 INFO - Compare over 30 days (2014-01-08, analysis of 2014-02-07 12:04:17.0)
13:47:04.654 INFO - Base dir: <http://jenkins.lgcoreapps.com/job/DDM_SERVER_CONTINUOUS_BUILD_AND_TEST/ws/>
13:47:04.654 INFO - Working dir: <http://jenkins.lgcoreapps.com/job/DDM_SERVER_CONTINUOUS_BUILD_AND_TEST/ws/.sonar>
13:47:04.654 INFO - Source dirs: <http://jenkins.lgcoreapps.com/job/DDM_SERVER_CONTINUOUS_BUILD_AND_TEST/ws/lib/src>
13:47:04.654 INFO - Source encoding: US-ASCII, default locale: en_US
13:47:04.676 INFO - Sensor JavaScriptSourceImporter...
13:47:04.797 INFO - Sensor JavaScriptSourceImporter done: 121 ms
13:47:04.797 INFO - Sensor JavaScriptSquidSensor...
13:47:05.858 INFO - Sensor JavaScriptSquidSensor done: 1061 ms
13:47:05.858 INFO - Sensor LCOVSensor...
13:47:05.859 INFO - Analysing <http://jenkins.lgcoreapps.com/job/DDM_SERVER_CONTINUOUS_BUILD_AND_TEST/ws/reports/lcov.info>
13:47:05.902 INFO - Sensor LCOVSensor done: 44 ms
13:47:05.903 INFO - Sensor JsTestDriverSensor...
INFO: ------------------------------------------------------------------------
INFO: EXECUTION FAILURE
INFO: ------------------------------------------------------------------------
Total time: 8.617s
Final Memory: 9M/28M
INFO: ------------------------------------------------------------------------
ERROR: Error during Sonar runner execution
ERROR: Unable to execute Sonar
ERROR: Caused by: Duplicate source for resource: org.sonar.api.resources.File@563e2119[key=Archive.js,dir=<null>,filename=Archive.js,language=JavaScript]
ERROR:
ERROR: To see the full stack trace of the errors, re-run SonarQube Runner with the -e switch.
ERROR: Re-run SonarQube Runner using the -X switch to enable full debug logging.
Build step 'Invoke Standalone Sonar Analysis' marked build as failure
EDIT: After confirming that the analysis completes ok when not submitting the test report , here is the TEST-all.xml from the reports directory in case it also provides a clue
<testsuite name="Mocha Tests" tests="36" failures="0" errors="0" skipped="0" timestamp="Fri, 07 Feb 2014 10:23:12 GMT" time="1.073">
<testcase classname="Archive" name="should respond with 404 Not Found if pathInfo is not "/" or """ time="0.005"/>
<testcase classname="Archive when the archive does not exist" name="should respond with 404 not Found" time="0.002"/>
<testcase classname="Archive when the archive exists" name="should respond with the archive" time="0.004"/>
<testcase classname="Get with an empty repository" name="should respond with an empty list of libraries" time="0.003"/>
<testcase classname="Get with a single library in the repository" name="should respond with a single entry list of libraries" time="0.002"/>
<testcase classname="Get with a multiple libraries in the repository" name="should respond with a list of libraries" time="0.004"/>
<testcase classname="Get with a multiple libraries in the repository" name="should prepend the root path to library paths correctly" time="0.001"/>
<testcase classname="Get with a multiple libraries in the repository" name="should pass requests with pathInfo not equal to "/" or "" to a Library instance" time="0.001"/>
<testcase classname="Library with an empty repository" name="should respond with 404 not Found" time="0.003"/>
<testcase classname="Library with an empty library (no versions)" name="should respond with an empty list of versions" time="0.003"/>
<testcase classname="Library with a single version" name="should respond with a single entry list of versions" time="0.002"/>
<testcase classname="Library with multiple versions" name="should respond with a list of versions" time="0.002"/>
<testcase classname="Library with multiple versions" name="should prepend the root path to library paths correctly" time="0.002"/>
<testcase classname="Library with multiple versions" name="should pass requests with pathInfo not equal to "/" or "" to a Version instance" time="0.001"/>
<testcase classname="Post" name="should respond with 400 Bad Request if the name is not specified" time="0.001"/>
<testcase classname="Post" name="should respond with 400 Bad Request if the version is not specified" time="0.001"/>
<testcase classname="Post" name="should respond with 415 Unsupported Media Type if the content-type is not application/octet-stream" time="0.001"/>
<testcase classname="Post" name="should respond with a new resource on success and write the archive and dependencies to the file system" time="0.015"/>
<testcase classname="Post" name="should respond with 400 Bad Request if dependencies are specified in an invalid format" time="0.005"/>
<testcase classname="Post" name="should add the dependencies to the new resource if present in the headers" time="0.015"/>
<testcase classname="Post" name="should prepend the root path to library paths correctly" time="0.011"/>
<testcase classname="Post" name="should respond with 405 Method Not Allowed if pathInfo is not "/" or """ time="0.001"/>
<testcase classname="Registry GET" name="should be handled by an instance of Get" time="0.001"/>
<testcase classname="Registry POST" name="should be handled by an instance of Post" time="0"/>
<testcase classname="Registry UNKNOWN" name="should respond with 405 Method Not Allowed" time="0"/>
<testcase classname="Version when the version does not exist" name="should respond with 404 not Found" time="0.003"/>
<testcase classname="Version when the version exists" name="should respond with the version details and an empty list of dependencies" time="0.002"/>
<testcase classname="Version when the version exists" name="should pass requests with pathInfo equal to "/archive" to an Archive instance" time="0.001"/>
<testcase classname="Version when the version exists" name="should respond with 404 Not Found if pathInfo is not "/" or "" or "/archive"" time="0"/>
<testcase classname="Version when the version exists with a dependencies.json file" name="should respond with the list of dependencies" time="0.005"/>
<testcase classname="Version when the version exists with a dependencies.json file" name="should prepend the root path to library paths correctly" time="0.004"/>
<testcase classname="index with an empty repository GET "/"" name="should return an empty list of libraries" time="0.022"/>
<testcase classname="index with an empty repository after posting a library to "/" GET "/"" name="should respond with a single entry list of libraries" time="0.005"/>
<testcase classname="index with an empty repository after posting a library to "/" GET "/library"" name="should respond with a single entry list of versions" time="0.005"/>
<testcase classname="index with an empty repository after posting a library to "/" GET "/library/0.0.0"" name="should respond with the library resource" time="0.009"/>
<testcase classname="index with an empty repository after posting a library to "/" GET "/library/0.0.0/archive"" name="should respond with the library archive" time="0.006"/>
</testsuite>