Skip to content

Commit c846209

Browse files
committed
add code coverage flag to the debug build and add docs for generating the coverage report
1 parent 804251e commit c846209

File tree

5 files changed

+228
-12
lines changed

5 files changed

+228
-12
lines changed

Diff for: .drone.star

+136-11
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,13 @@ def main(ctx):
452452
),
453453
)
454454

455+
test_pipelines.append(
456+
pipelineDependsOn(
457+
generateAndUploadCoverageReport(ctx),
458+
testPipelines(ctx),
459+
),
460+
)
461+
455462
pipelines = test_pipelines + build_release_pipelines
456463

457464
if ctx.build.event == "cron":
@@ -1041,7 +1048,8 @@ def localApiTestPipeline(ctx):
10411048
((wopiCollaborationService("fakeoffice") + wopiCollaborationService("collabora") + wopiCollaborationService("onlyoffice")) if params["collaborationServiceNeeded"] else []) +
10421049
(ocisHealthCheck("wopi", ["wopi-collabora:9304", "wopi-onlyoffice:9304", "wopi-fakeoffice:9304"]) if params["collaborationServiceNeeded"] else []) +
10431050
localApiTests(ctx, name, params["suites"], storage, params["extraEnvironment"], run_with_remote_php) +
1044-
logRequests(),
1051+
logRequests() +
1052+
(generateCoverageReportFromTest(ctx, name)),
10451053
"services": (emailService() if params["emailNeeded"] else []) +
10461054
(clamavService() if params["antivirusNeeded"] else []) +
10471055
((fakeOffice() + collaboraService() + onlyofficeService()) if params["collaborationServiceNeeded"] else []),
@@ -1056,6 +1064,49 @@ def localApiTestPipeline(ctx):
10561064
pipelines.append(pipeline)
10571065
return pipelines
10581066

1067+
def generateCoverageReportFromTest(ctx, name):
1068+
environment = {
1069+
"GOCOVERDIR": "reports",
1070+
}
1071+
1072+
return [
1073+
{
1074+
"name": "coverageReport-%s" % name,
1075+
"image": OC_CI_GOLANG,
1076+
"environment": environment,
1077+
"commands": [
1078+
"go tool covdata percent -i=$GOCOVERDIR -o=coverage-%s.out" % name,
1079+
],
1080+
},
1081+
{
1082+
"name": "coverage-locate",
1083+
"image": OC_UBUNTU,
1084+
"commands": [
1085+
"mkdir -p cache/acceptance/coverage/",
1086+
"mv coverage-%s.out cache/acceptance/coverage/" % name,
1087+
],
1088+
},
1089+
{
1090+
"name": "coverage-cache-1",
1091+
"image": PLUGINS_S3,
1092+
"settings": {
1093+
"endpoint": {
1094+
"from_secret": "cache_s3_server",
1095+
},
1096+
"bucket": "cache",
1097+
"source": "cache/acceptance/coverage/coverage-%s.out" % name,
1098+
"target": "%s/%s/coverage" % (ctx.repo.slug, ctx.build.commit + "-${DRONE_BUILD_NUMBER}"),
1099+
"path_style": True,
1100+
"access_key": {
1101+
"from_secret": "cache_s3_access_key",
1102+
},
1103+
"secret_key": {
1104+
"from_secret": "cache_s3_secret_key",
1105+
},
1106+
},
1107+
},
1108+
]
1109+
10591110
def localApiTests(ctx, name, suites, storage = "ocis", extra_environment = {}, with_remote_php = False):
10601111
test_dir = "%s/tests/acceptance" % dirs["base"]
10611112
expected_failures_file = "%s/expected-failures-localAPI-on-%s-storage.md" % (test_dir, storage.upper())
@@ -1137,7 +1188,7 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
11371188
"RenameFileIfCreateChildFileIsNotSupported",
11381189
]
11391190

1140-
ocis_bin = "ocis/bin/ocis"
1191+
ocis_bin = "ocis/bin/ocis-debug"
11411192
validatorTests = []
11421193
wopiServer = []
11431194
extra_server_environment = {}
@@ -1280,7 +1331,8 @@ def coreApiTests(ctx, part_number = 1, number_of_parts = 1, with_remote_php = Fa
12801331
],
12811332
},
12821333
] +
1283-
logRequests(),
1334+
logRequests() +
1335+
generateCoverageReportFromTest(ctx, part_number),
12841336
"services": redisForOCStorage(storage),
12851337
"depends_on": getPipelineNames(buildOcisBinaryForTesting(ctx)),
12861338
"trigger": {
@@ -2407,6 +2459,7 @@ def ocisServer(storage = "ocis", accounts_hash_difficulty = 4, volumes = [], dep
24072459
"WEB_DEBUG_ADDR": "0.0.0.0:9104",
24082460
"WEBDAV_DEBUG_ADDR": "0.0.0.0:9119",
24092461
"WEBFINGER_DEBUG_ADDR": "0.0.0.0:9279",
2462+
"GOCOVERDIR": "reports",
24102463
}
24112464

24122465
if deploy_type == "":
@@ -2450,7 +2503,7 @@ def ocisServer(storage = "ocis", accounts_hash_difficulty = 4, volumes = [], dep
24502503
for item in extra_server_environment:
24512504
environment[item] = extra_server_environment[item]
24522505

2453-
ocis_bin = "ocis/bin/ocis"
2506+
ocis_bin = "ocis/bin/ocis-debug"
24542507

24552508
wrapper_commands = [
24562509
"make -C %s build" % dirs["ocisWrapper"],
@@ -2469,18 +2522,21 @@ def ocisServer(storage = "ocis", accounts_hash_difficulty = 4, volumes = [], dep
24692522
"depends_on": depends_on,
24702523
}
24712524

2525+
commands = [
2526+
"mkdir -p $GOCOVERDIR",
2527+
"%s init --insecure true" % ocis_bin,
2528+
"cat $OCIS_CONFIG_DIR/ocis.yaml",
2529+
"cp tests/config/drone/app-registry.yaml /root/.ocis/config/app-registry.yaml",
2530+
] + (wrapper_commands)
2531+
24722532
return [
24732533
{
24742534
"name": container_name,
24752535
"image": OC_CI_GOLANG,
24762536
"detach": True,
24772537
"environment": environment,
24782538
"user": user,
2479-
"commands": [
2480-
"%s init --insecure true" % ocis_bin,
2481-
"cat $OCIS_CONFIG_DIR/ocis.yaml",
2482-
"cp tests/config/drone/app-registry.yaml /root/.ocis/config/app-registry.yaml",
2483-
] + (wrapper_commands),
2539+
"commands": commands,
24842540
"volumes": volumes,
24852541
"depends_on": depends_on,
24862542
},
@@ -2513,7 +2569,7 @@ def startOcisService(service = None, name = None, environment = {}, volumes = []
25132569
"detach": True,
25142570
"environment": environment,
25152571
"commands": [
2516-
"ocis/bin/ocis %s server" % service,
2572+
"ocis/bin/ocis-debug %s server" % service,
25172573
],
25182574
"volumes": volumes,
25192575
},
@@ -2539,7 +2595,7 @@ def build():
25392595
"name": "build",
25402596
"image": OC_CI_GOLANG,
25412597
"commands": [
2542-
"retry -t 3 'make -C ocis build'",
2598+
"retry -t 3 'make -C ocis build-debug'",
25432599
],
25442600
"environment": DRONE_HTTP_PROXY_ENV,
25452601
"volumes": [stepVolumeGo],
@@ -2744,6 +2800,75 @@ def genericCache(name, action, mounts, cache_path):
27442800
}
27452801
return step
27462802

2803+
def generateAndUploadCoverageReport(ctx):
2804+
cache_path = "%s/%s/%s" % ("cache", ctx.repo.slug, ctx.build.commit + "-${DRONE_BUILD_NUMBER}")
2805+
2806+
sonar_env = {
2807+
"SONAR_TOKEN": {
2808+
"from_secret": "sonarcloud_acceptance_tests",
2809+
},
2810+
}
2811+
2812+
if ctx.build.event == "pull_request":
2813+
sonar_env.update({
2814+
"SONAR_PULL_REQUEST_BASE": "%s" % (ctx.build.target),
2815+
"SONAR_PULL_REQUEST_BRANCH": "%s" % (ctx.build.source),
2816+
"SONAR_PULL_REQUEST_KEY": "%s" % (ctx.build.ref.replace("refs/pull/", "").split("/")[0]),
2817+
})
2818+
2819+
return {
2820+
"kind": "pipeline",
2821+
"type": "docker",
2822+
"name": "sonarcloud",
2823+
"platform": {
2824+
"os": "linux",
2825+
"arch": "amd64",
2826+
},
2827+
"steps": [
2828+
{
2829+
"name": "sync-from-cache",
2830+
"image": MINIO_MC,
2831+
"environment": MINIO_MC_ENV,
2832+
"commands": [
2833+
"mkdir -p results",
2834+
"mc alias set cache $MC_HOST $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY",
2835+
"mc mirror cache/$CACHE_BUCKET/%s/%s/coverage results/" % (ctx.repo.slug, ctx.build.commit + "-${DRONE_BUILD_NUMBER}"),
2836+
],
2837+
},
2838+
{
2839+
"name": "sonarcloud-properties",
2840+
"image": OC_UBUNTU,
2841+
"commands": [
2842+
"mv sonar-project.properties sonar-project.properties.skip",
2843+
"mv tests/acceptance/sonar-project.properties sonar-project.properties",
2844+
],
2845+
},
2846+
{
2847+
"name": "sonarcloud",
2848+
"image": SONARSOURCE_SONAR_SCANNER_CLI,
2849+
"environment": sonar_env,
2850+
},
2851+
{
2852+
"name": "purge-cache",
2853+
"image": MINIO_MC,
2854+
"environment": MINIO_MC_ENV,
2855+
"commands": [
2856+
"mc alias set cache $MC_HOST $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY",
2857+
"mc rm --recursive --force cache/$CACHE_BUCKET/%s/%s" % (ctx.repo.slug, ctx.build.commit + "-${DRONE_BUILD_NUMBER}"),
2858+
],
2859+
},
2860+
],
2861+
"trigger": {
2862+
"ref": [
2863+
"refs/heads/master",
2864+
],
2865+
"status": [
2866+
"success",
2867+
"failure",
2868+
],
2869+
},
2870+
}
2871+
27472872
def genericCachePurge(flush_path):
27482873
return {
27492874
"kind": "pipeline",

Diff for: .make/go.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ $(BIN)/$(EXECUTABLE): $(SOURCES)
102102
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $@ ./cmd/$(NAME)
103103

104104
$(BIN)/$(EXECUTABLE)-debug: $(SOURCES)
105-
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(DEBUG_LDFLAGS)' -gcflags '$(GCFLAGS)' -o $@ ./cmd/$(NAME)
105+
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(DEBUG_LDFLAGS)' -cover -gcflags '$(GCFLAGS)' -o $@ ./cmd/$(NAME)
106106

107107
.PHONY: watch
108108
watch: $(REFLEX)

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[![Build Status](https://drone.owncloud.com/api/badges/owncloud/ocis/status.svg)](https://drone.owncloud.com/owncloud/ocis)
66
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=owncloud_ocis&metric=security_rating)](https://sonarcloud.io/dashboard?id=owncloud_ocis)
77
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=owncloud_ocis&metric=coverage)](https://sonarcloud.io/dashboard?id=owncloud_ocis)
8+
[![Acceptance Test Coverage](https://sonarcloud.io/api/project_badges/measure?project=owncloud-1_ocis_acceptance-tests&metric=coverage)](https://sonarcloud.io/summary/new_code?id=owncloud-1_ocis_acceptance-tests)
89
[![Go Report](https://goreportcard.com/badge/github.com/owncloud/ocis)](https://goreportcard.com/report/github.com/owncloud/ocis)
910
[![Go Doc](https://godoc.org/github.com/owncloud/ocis?status.svg)](http://godoc.org/github.com/owncloud/ocis)
1011
[![oCIS docker image](https://img.shields.io/docker/v/owncloud/ocis?label=oCIS%20docker%20image&logo=docker&sort=semver)](https://hub.docker.com/r/owncloud/ocis)

Diff for: docs/ocis/development/testing.md

+36
Original file line numberDiff line numberDiff line change
@@ -585,3 +585,39 @@ The sample `fontsMap.json` file is located in `tests/config/drone/fontsMap.json`
585585
"defaultFont": "/path/to/ocis/tests/config/drone/NotoSans.ttf"
586586
}
587587
```
588+
589+
## Generating code coverag report by running acceptance test
590+
591+
To find out what oCIS code is covered by the API tests, first create a debug build of oCIS.
592+
593+
```shell
594+
make -c ocis build-debug
595+
```
596+
597+
oCIS should be served by the debug binary.
598+
599+
```shell
600+
ocis/bin/ocis-debug server
601+
```
602+
603+
Then define a folder to store the coverage report.
604+
605+
```shell
606+
export GOCOVERDIR=coveragedatafiles
607+
```
608+
609+
Running the tests will generate the coverage report inside the `coveragedatafiles` directory.
610+
611+
To view the report in human readable form, enter the following command or refer to the official [documentation](https://go.dev/doc/build-cover#working) for more formats.
612+
613+
```
614+
go tool covdata textfmt -i=coveragedatafiles -o=cov.txt
615+
```
616+
617+
You can also view the report in a web UI using the following command.
618+
619+
```
620+
go tool cover -html=cov.txt
621+
```
622+
623+
This command should open a browser with the code report.

Diff for: tests/acceptance/sonar-project.properties

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
sonar.projectKey=owncloud-1_ocis_acceptance-tests
2+
sonar.organization=owncloud-1
3+
sonar.projectVersion=7.1.1
4+
sonar.host.url=https://sonarcloud.io
5+
6+
# =====================================================
7+
# Meta-data for the project
8+
# =====================================================
9+
10+
sonar.links.homepage=https://github.com/owncloud/ocis
11+
sonar.links.ci=https://drone.owncloud.com/owncloud/ocis/
12+
sonar.links.scm=https://github.com/owncloud/ocis
13+
sonar.links.issue=https://github.com/owncloud/ocis/issues
14+
15+
# =====================================================
16+
# Properties that will be shared amongst all modules
17+
# =====================================================
18+
19+
# SQ standard properties
20+
sonar.sources=.
21+
22+
# Pull Requests
23+
sonar.pullrequest.provider=github
24+
sonar.pullrequest.github.repository=owncloud/ocis
25+
sonar.pullrequest.base=${env.SONAR_PULL_REQUEST_BASE}
26+
sonar.pullrequest.branch=${env.SONAR_PULL_REQUEST_BRANCH}
27+
sonar.pullrequest.key=${env.SONAR_PULL_REQUEST_KEY}
28+
29+
# Properties specific to language plugins:
30+
sonar.go.coverage.reportPaths=results/coverage-*.out
31+
32+
# Exclude files
33+
sonar.exclusions=**/third_party,docs/**,changelog/**,**/package.json,**/rollup.config.js,CHANGELOG.md,deployments/**,tests/**,vendor/**,vendor-bin/**,README.md,**/mocks/**,/protogen/**,**/*_gen.go
34+
sonar.coverage.exclusions=**/*_test.go,**mocks/**,/protogen/**,**/*_gen.go
35+
sonar.cpd.exclusions=**/defaultconfig.go,**/*_test.go,**/revaconfig/**,services/settings/pkg/store/defaults/defaults.go
36+
37+
# Rule exclusions
38+
sonar.issue.ignore.multicriteria=g1,g2
39+
40+
# Ignore "Define a constant instead of duplicating this literal" rule for tests
41+
sonar.issue.ignore.multicriteria.g1.ruleKey=go:S1192
42+
sonar.issue.ignore.multicriteria.g1.resourceKey=**/*_test.go
43+
44+
# Ignore "Rename function XXX to match the regular expression ^(_|[a-zA-Z0-9]+)$" rule for tests
45+
sonar.issue.ignore.multicriteria.g2.ruleKey=go:S100
46+
sonar.issue.ignore.multicriteria.g2.resourceKey=**/*_test.go
47+
48+
# Timeout for web requests
49+
#sonar.ws.timeout=60 is the default, but we need to increase it to deal with timeouts when loading defaults
50+
sonar.ws.timeout=120
51+
52+
#
53+
sonar.go.skipUnchanged=true
54+
sonar.scm.forceReloadAll=true

0 commit comments

Comments
 (0)