Golang: Failed to find test file for package

Hello, after several weeks and multiple tries, and some posts here and issues on jira that are closed, but don’t provide any solution or cause of the problem, I am hereby writing this post which would probably be similar to others already open (but currently without a solution).

Environment

golang version: 1.19
golang modules: yes
sonar-scanner:
     INFO: SonarScanner 4.7.0.2747
     INFO: Java 11.0.14.1 Eclipse Adoptium (64-bit)
     INFO: Mac OS X 13.2 x86_64

Project Tree (redacted in names)

[projectRoot]
├── golangci-report.xml
├── myproject
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   ├── main_test.go
│   ├── cmd
│   │   ├── [...]
│   ├── pkg
│   │   └── myproject
│   │       ├── airgap.go
│   │       ├── airgap_test.go
│   │       ├── deploy.go
│   │       ├── deploy_test.go
│   │       ├── diff.go
│   │       ├── diff_test.go
│   │       ├── generate.go
│   │       ├── generate_test.go
│   │       ├── subver
│   │       │   ├── subver.go
│   │       │   └── subver_test.go
│   │       ├── validate.go
│   │       ├── validate_test.go
│   └── vendor
│       ├── [...]
├── scripts
│   └── sonarcloud-scan.sh
├── sonar-project.properties

sonar-project.properties

# =====================================================
#   Standard properties
# =====================================================
sonar.organization=ORG_NAME
sonar.projectKey=ORG_NAME_myproject
sonar.projectName=myproject
sonar.projectVersion=1.0

sonar.projectBaseDir=${env.SONAR_RUN_WORKSPACE}
sonar.sourceEncoding=UTF-8

# Defines the initial scope of analysis for non-test code
sonar.sources=.
# Defines the initial scope of analysis for test code 
sonar.tests=.

sonar.inclusions=myproject/*.go,myproject/pkg/myproject/**/*.go,myproject/cmd/**/*.go
sonar.exclusions=myproject/out/,myproject/scripts/,myproject/vendor/,myproject/pkg/myproject/embeddedtemplates.go

sonar.test.inclusions=**/*_test.go
sonar.test.exclusions=myproject/vendor/,myproject/out/,myproject/scripts/

# =====================================================
#   Meta-data for the project
# =====================================================
sonar.links.homepage=https://github.com/ORG_NAME/myproject
sonar.links.issue=https://github.com/ORG_NAME/myproject/issues

# =====================================================
#   Properties specific to Go
# =====================================================
sonar.go.tests.reportPaths=myproject/go-test-report.out
sonar.go.coverage.reportPaths=myproject/coverage.out
sonar.go.golangci-lint.reportPaths=myproject/golangci-report.xml

sonarcloud-scan.sh

#!/usr/bin/env bash

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# changing dir to project root
cd "$SCRIPTDIR/.." || exit

SONAR_RUN_WORKSPACE=$(pwd)
export SONAR_RUN_WORKSPACE

if [[ "$1" == "TEST" ]]; then
    cd myproject

    echo "$(date +%T.00000) GO TEST START ==================================="
    go test \
        -v \
        -cover \
        -covermode=count \
        -mod=vendor \
        -coverprofile=coverage.out \
        -json \
        ./... > go-test-report.out
    
    go tool cover -func="coverage.out" > coverage-summary.out
    echo "$(date +%T.00000) TEST END     ==================================="

    echo "$(date +%T.00000) GOLANGCI-LINT START ==================================="
    golangci-lint run ./...
    echo "$(date +%T.00000) GOLANGCI-LINT END   ==================================="

    cd ..
fi

# PR Analysis
echo "$(date +%T.00000) SCAN 1 START"
sonar-scanner -X \
    -Dsonar.host.url='https://sonarcloud.io' -Dsonar.login='PROJECT_TOKEN' -Dsonar.analysis.repository='ORG_NAME/myproject' \
    -Dsonar.analysis.prNumber=2305 \
    -Dsonar.analysis.sha1=$(git rev-parse HEAD) \
    -Dsonar.pullrequest.base=master \
    -Dsonar.pullrequest.branch="$(git rev-parse --abbrev-ref HEAD)" \
    -Dsonar.pullrequest.key=2305 \
    -Dsonar.pullrequest.provider=github \
    -Dsonar.pullrequest.github.repository='ORG_NAME/myproject'

echo "$(date +%T.00000) SCAN 2 START"
# Branch Analysis
sonar-scanner \
    -Dsonar.host.url='https://sonarcloud.io' -Dsonar.login='PROJECT_TOKEN' -Dsonar.analysis.repository='ORG_NAME/myproject' \
    -Dsonar.analysis.sha1=$(git rev-parse HEAD) \
    -Dsonar.branch.name="$(git rev-parse --abbrev-ref HEAD)"

echo "$(date +%T.00000) SCANS END"

exit 0

The Error

Given this context, my error lines are the following ones:

15:19:16.378 INFO: Sensor Go Unit Test Report [go]
15:19:16.406 WARN: Failed to find test file for package github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/ and test TestCompare
15:19:16.410 WARN: Failed to find test file for package /Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver and test TestCompare
15:19:16.411 WARN: Failed to find test file for package /Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/ and test TestCompare
15:19:16.412 WARN: Failed to find test file for package ./myproject/pkg/myproject/subver/ and test TestCompare
15:19:16.415 WARN: Failed to find test file for package pkg/myproject/subver/ and test TestCompare
15:19:16.416 WARN: Failed to find test file for package myproject and test TestDefaultKubeconfig
[...]

I have tried to use different paths in the go-test-report.out generated by go test, but any seems to work.

{"Time":"2023-02-01T11:07:20.157369+01:00","Action":"run","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Test":"TestCompare"}
{"Time":"2023-02-01T11:07:20.157534+01:00","Action":"output","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Test":"TestCompare","Output":"=== RUN   TestCompare\n"}
{"Time":"2023-02-01T11:07:20.157555+01:00","Action":"output","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Test":"TestCompare","Output":"--- PASS: TestCompare (0.00s)\n"}
{"Time":"2023-02-01T11:07:20.157564+01:00","Action":"pass","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Test":"TestCompare","Elapsed":0}
{"Time":"2023-02-01T11:07:20.157572+01:00","Action":"output","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Output":"PASS\n"}
{"Time":"2023-02-01T11:07:20.157657+01:00","Action":"output","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Output":"coverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158183+01:00","Action":"output","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Output":"ok  \tmyproject/pkg/myproject/subver\t0.119s\tcoverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158204+01:00","Action":"pass","Package":"github.com/ORG_NAME/myproject/myproject/pkg/myproject/subver/","Elapsed":0.12}

{"Time":"2023-02-01T11:07:20.157369+01:00","Action":"run","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Test":"TestCompare"}
{"Time":"2023-02-01T11:07:20.157534+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Test":"TestCompare","Output":"=== RUN   TestCompare\n"}
{"Time":"2023-02-01T11:07:20.157555+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Test":"TestCompare","Output":"--- PASS: TestCompare (0.00s)\n"}
{"Time":"2023-02-01T11:07:20.157564+01:00","Action":"pass","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Test":"TestCompare","Elapsed":0}
{"Time":"2023-02-01T11:07:20.157572+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Output":"PASS\n"}
{"Time":"2023-02-01T11:07:20.157657+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Output":"coverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158183+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Output":"ok  \tmyproject/pkg/myproject/subver\t0.119s\tcoverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158204+01:00","Action":"pass","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver","Elapsed":0.12}

{"Time":"2023-02-01T11:07:20.157369+01:00","Action":"run","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Test":"TestCompare"}
{"Time":"2023-02-01T11:07:20.157534+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Test":"TestCompare","Output":"=== RUN   TestCompare\n"}
{"Time":"2023-02-01T11:07:20.157555+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Test":"TestCompare","Output":"--- PASS: TestCompare (0.00s)\n"}
{"Time":"2023-02-01T11:07:20.157564+01:00","Action":"pass","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Test":"TestCompare","Elapsed":0}
{"Time":"2023-02-01T11:07:20.157572+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Output":"PASS\n"}
{"Time":"2023-02-01T11:07:20.157657+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Output":"coverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158183+01:00","Action":"output","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Output":"ok  \tmyproject/pkg/myproject/subver\t0.119s\tcoverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158204+01:00","Action":"pass","Package":"/Users/martin.deluca/_projects/ORG_NAME/myproject/pkg/myproject/subver/","Elapsed":0.12}

{"Time":"2023-02-01T11:07:20.157369+01:00","Action":"run","Package":"./myproject/pkg/myproject/subver/","Test":"TestCompare"}
{"Time":"2023-02-01T11:07:20.157534+01:00","Action":"output","Package":"./myproject/pkg/myproject/subver/","Test":"TestCompare","Output":"=== RUN   TestCompare\n"}
{"Time":"2023-02-01T11:07:20.157555+01:00","Action":"output","Package":"./myproject/pkg/myproject/subver/","Test":"TestCompare","Output":"--- PASS: TestCompare (0.00s)\n"}
{"Time":"2023-02-01T11:07:20.157564+01:00","Action":"pass","Package":"./myproject/pkg/myproject/subver/","Test":"TestCompare","Elapsed":0}
{"Time":"2023-02-01T11:07:20.157572+01:00","Action":"output","Package":"./myproject/pkg/myproject/subver/","Output":"PASS\n"}
{"Time":"2023-02-01T11:07:20.157657+01:00","Action":"output","Package":"./myproject/pkg/myproject/subver/","Output":"coverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158183+01:00","Action":"output","Package":"./myproject/pkg/myproject/subver/","Output":"ok  \tmyproject/pkg/myproject/subver\t0.119s\tcoverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158204+01:00","Action":"pass","Package":"./myproject/pkg/myproject/subver/","Elapsed":0.12}

{"Time":"2023-02-01T11:07:20.157369+01:00","Action":"run","Package":"pkg/myproject/subver/","Test":"TestCompare"}
{"Time":"2023-02-01T11:07:20.157534+01:00","Action":"output","Package":"pkg/myproject/subver/","Test":"TestCompare","Output":"=== RUN   TestCompare\n"}
{"Time":"2023-02-01T11:07:20.157555+01:00","Action":"output","Package":"pkg/myproject/subver/","Test":"TestCompare","Output":"--- PASS: TestCompare (0.00s)\n"}
{"Time":"2023-02-01T11:07:20.157564+01:00","Action":"pass","Package":"pkg/myproject/subver/","Test":"TestCompare","Elapsed":0}
{"Time":"2023-02-01T11:07:20.157572+01:00","Action":"output","Package":"pkg/myproject/subver/","Output":"PASS\n"}
{"Time":"2023-02-01T11:07:20.157657+01:00","Action":"output","Package":"pkg/myproject/subver/","Output":"coverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158183+01:00","Action":"output","Package":"pkg/myproject/subver/","Output":"ok  \tmyproject/pkg/myproject/subver\t0.119s\tcoverage: 86.4% of statements\n"}
{"Time":"2023-02-01T11:07:20.158204+01:00","Action":"pass","Package":"pkg/myproject/subver/","Elapsed":0.12}

Which is the format expected by that sonar sensor to make it work?

Anyone has any suggestion?

Hi @Hammond95,

From what I can see in the logs, the problem is in the “Package” property. Have you tried setting it as a relative path?
Can you please send me a go test code snippet that is causing this error?
Thank you!

All the best,

Irina

Hi Irina,
yes that was also my conclusion, and as you can see on my previous comment I’ve tried to manually change the output and format of Package but none of those changes did work.

Could you point me out to the right docs or give me a working example of the property to change in sonar-project.properties?

BR,
Martin

Hi Irina, I’ve not heard back from you…
do you have any idea to help me solve this?

BR,
Martin

is it fixed ?

i am facing the same issue… SonarScanner 5.0.1.3006, sonarqube 10.5.1

Hello @Mohit_Chaudhary and @farruda,

I’ve been investigating the issue, and it seems to be caused by a wrong resolution of the test files caused by the use of relative paths in the GoTestSensor.

I’ve created SONARSLANG-647 to fix the issue and better investigate how the test report generation works in Go. It is not very clear to me how the Package field is populated or whether there is a way to customize it.

As a temporary workaround, you can modify the test report file to specify the absolute path for each Package entry.

For example, change

{"Time":"2024-05-16T17:08:34.308686+02:00","Action":"run","Package":"go_project_1","Test":"Test1"}

to

{"Time":"2024-05-16T17:08:34.308686+02:00","Action":"run","Package":"/absolute/path/to/go_project_1","Test":"Test1"}

Please let me know if the workaround works since it may help to understand if there are more cases to cover.

Cheers,
Angelo