mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-30 22:11:07 +00:00 
			
		
		
		
	chore: collect coverage using GOCOVERDIR (#9004)
- run all unit tests and integration tests in sequence in the same job - upload the coverage data as an artifact to the run - only run via dispatch because it is very long - arguments are used to select which unit or integration tests to focus on Refs https://go.dev/blog/integration-test-coverage ### Testing - Run this workflow via workflow_dispatch (see https://codeberg.org/forgejo-integration/forgejo/actions/runs/11889) - Download the coverage information (see https://codeberg.org/forgejo-integration/forgejo/actions/runs/11889/artifacts/coverage) - Download the coverage information from an end-to-end cascade test (see https://code.forgejo.org/forgejo/end-to-end/actions/runs/3961) - Unzip them in a the `coverage/data` sub-directory at the root of the Forgejo source tree ```sh $ ls coverage/data actions coverage-actions.zip coverage-federation.zip coverage-tests.zip coverage-upgrade.zip federation tests upgrade ``` - Display the coverage percentage ``` $ make coverage-show-percentage ... forgejo.org/services/wiki/wiki_path.go:96: WebPathToGitPath 81.8% forgejo.org/services/wiki/wiki_path.go:113: GitPathToWebPath 90.0% forgejo.org/services/wiki/wiki_path.go:129: WebPathToUserTitle 71.4% forgejo.org/services/wiki/wiki_path.go:140: WebPathToURLPath 100.0% forgejo.org/services/wiki/wiki_path.go:144: WebPathFromRequest 100.0% forgejo.org/services/wiki/wiki_path.go:151: UserTitleToWebPath 80.0% forgejo.org/services/wiki/wiki_path.go:163: ToWikiPageMetaData 100.0% forgejo.org/tests/integration/api_repo_file_helpers.go:18: createFileInBranch 100.0% ... total: (statements) 63.9% ``` Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9004 Reviewed-by: jerger <jerger@noreply.codeberg.org> Co-authored-by: Earl Warren <contact@earl-warren.org> Co-committed-by: Earl Warren <contact@earl-warren.org>
This commit is contained in:
		
					parent
					
						
							
								ff03a4eff6
							
						
					
				
			
			
				commit
				
					
						7d3fcde71c
					
				
			
		
					 3 changed files with 171 additions and 24 deletions
				
			
		
							
								
								
									
										89
									
								
								.forgejo/workflows/coverage.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								.forgejo/workflows/coverage.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,89 @@ | |||
| name: coverage | ||||
| 
 | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|     inputs: | ||||
|       repository: | ||||
|         description: 'repository' | ||||
|         type: string | ||||
|       ref: | ||||
|         description: 'ref' | ||||
|         type: string | ||||
|       unit-tests-env: | ||||
|         description: 'COVERAGE_TEST_PACKAGES=forgejo.org/modules/actions' | ||||
|         type: string | ||||
|       integration-tests-env: | ||||
|         description: 'COVERAGE_TEST_ARGS=-run=TestAPIListRepoComments' | ||||
|         type: string | ||||
| 
 | ||||
| jobs: | ||||
|   all: | ||||
|     runs-on: docker | ||||
|     container: | ||||
|       image: 'data.forgejo.org/oci/ci:1' | ||||
|       options: --tmpfs /tmp:exec,noatime | ||||
|     services: | ||||
|       elasticsearch: | ||||
|         image: data.forgejo.org/oci/bitnami/elasticsearch:7 | ||||
|         options: --tmpfs /bitnami/elasticsearch/data | ||||
|         env: | ||||
|           discovery.type: single-node | ||||
|           ES_JAVA_OPTS: "-Xms512m -Xmx512m" | ||||
|       minio: | ||||
|         image: data.forgejo.org/oci/bitnami/minio:2024.8.17 | ||||
|         options: >- | ||||
|           --hostname gitea.minio --tmpfs /bitnami/minio/data:noatime | ||||
|         env: | ||||
|           MINIO_DOMAIN: minio | ||||
|           MINIO_ROOT_USER: 123456 | ||||
|           MINIO_ROOT_PASSWORD: 12345678 | ||||
|       mysql: | ||||
|         image: 'data.forgejo.org/oci/bitnami/mysql:8.4' | ||||
|         env: | ||||
|           ALLOW_EMPTY_PASSWORD: yes | ||||
|           MYSQL_DATABASE: testgitea | ||||
|           # | ||||
|           # See also https://codeberg.org/forgejo/forgejo/issues/976 | ||||
|           # | ||||
|           MYSQL_EXTRA_FLAGS: --innodb-adaptive-flushing=OFF --innodb-buffer-pool-size=4G --innodb-log-buffer-size=128M --innodb-flush-log-at-trx-commit=0 --innodb-flush-log-at-timeout=30 --innodb-flush-method=nosync --innodb-fsync-threshold=1000000000 --disable-log-bin | ||||
|         options: --tmpfs /bitnami/mysql/data:noatime | ||||
|       ldap: | ||||
|         image: data.forgejo.org/oci/test-openldap:latest | ||||
|       pgsql: | ||||
|         image: data.forgejo.org/oci/bitnami/postgresql:16 | ||||
|         env: | ||||
|           POSTGRESQL_DATABASE: test | ||||
|           POSTGRESQL_PASSWORD: postgres | ||||
|           POSTGRESQL_FSYNC: off | ||||
|           POSTGRESQL_EXTRA_FLAGS: -c full_page_writes=off | ||||
|         options: --tmpfs /bitnami/postgresql | ||||
|       cacher: | ||||
|         image: registry.redict.io/redict:7.3.0-scratch | ||||
|         options: --tmpfs /data:noatime | ||||
|     steps: | ||||
|       - uses: https://data.forgejo.org/actions/checkout@v4 | ||||
|         with: | ||||
|           repository: ${{ inputs.repository }} | ||||
|           ref: ${{ inputs.ref }} | ||||
|       - uses: ./.forgejo/workflows-composite/setup-env | ||||
|       - name: install git >= 2.42 | ||||
|         uses: ./.forgejo/workflows-composite/apt-install-from | ||||
|         with: | ||||
|           packages: git | ||||
|       - uses: ./.forgejo/workflows-composite/build-backend | ||||
|       - run: | | ||||
|           su forgejo -c '${{ inputs.unit-tests-env }} make coverage-run' | ||||
|           su forgejo -c '${{ inputs.integration-tests-env }} make coverage-run-pgsql' | ||||
|           su forgejo -c '${{ inputs.integration-tests-env }} make coverage-run-mysql' | ||||
|           su forgejo -c '${{ inputs.integration-tests-env }} make coverage-run-sqlite' | ||||
|           su forgejo -c 'make coverage-merge' | ||||
|         timeout-minutes: 180 | ||||
|         env: | ||||
|           TEST_ELASTICSEARCH_URL: http://elasticsearch:9200 | ||||
|           TEST_MINIO_ENDPOINT: minio:9000 | ||||
|           TEST_LDAP: 1 | ||||
|           TEST_REDIS_SERVER: cacher:6379 | ||||
|       - uses: https://code.forgejo.org/forgejo/upload-artifact@v4 | ||||
|         with: | ||||
|           name: coverage | ||||
|           path: ${{ forge.workspace }}/coverage/merged | ||||
							
								
								
									
										56
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										56
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -238,6 +238,9 @@ help: | |||
| 	@echo " - test-frontend-coverage           test frontend files and display code coverage" | ||||
| 	@echo " - test-backend                     test backend files" | ||||
| 	@echo " - test-remote-cacher               test backend files that use a remote cache" | ||||
| 	@echo " - coverage-run*                    test and collect coverages in the coverage/data directory" | ||||
| 	@echo " - coverage-show-html               display coverage-run results in an HTML page" | ||||
| 	@echo " - coverage-show-percent            display coverage-run per package coverage percentage" | ||||
| 	@echo " - test-e2e-sqlite[\#name.test.e2e] test end to end using playwright and sqlite" | ||||
| 	@echo " - webpack                          build webpack files" | ||||
| 	@echo " - svg                              build svg files" | ||||
|  | @ -556,16 +559,35 @@ test\#%: | |||
| 	@echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." | ||||
| 	@$(GOTEST) $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_TEST_PACKAGES) | ||||
| 
 | ||||
| .PHONY: coverage | ||||
| coverage: | ||||
| 	grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' coverage.out > coverage-bodged.out | ||||
| 	grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' integration.coverage.out > integration.coverage-bodged.out | ||||
| 	$(GO) run build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all | ||||
| coverage-merge: | ||||
| 	rm -fr coverage/merged ; mkdir -p coverage/merged | ||||
| 	$(GO) tool covdata merge -i `find coverage/data -name 'covmeta.*' | sed -e 's|/covmeta.*|,|' | tr -d '\n' | sed -e 's/,$$//'` -o coverage/merged | ||||
| 
 | ||||
| .PHONY: unit-test-coverage | ||||
| unit-test-coverage: | ||||
| 	@echo "Running unit-test-coverage $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." | ||||
| 	@$(GOTEST) $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_TEST_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 | ||||
| coverage-convert: coverage-merge | ||||
| 	$(GO) tool covdata textfmt -i=coverage/merged -o=coverage/textfmt.out | ||||
| 
 | ||||
| coverage-show-html: coverage-convert | ||||
| 	( cd coverage ; $(GO) tool cover -html=textfmt.out -o coverage.html ) | ||||
| 	xdg-open coverage/coverage.html | ||||
| 
 | ||||
| coverage-show-percentage: coverage-convert | ||||
| 	go tool cover -func=coverage/textfmt.out | ||||
| 
 | ||||
| coverage-run: | ||||
| 	contrib/coverage-helper.sh test_packages $(COVERAGE_TEST_PACKAGES) | ||||
| 
 | ||||
| coverage-run-%: generate-ini-% | ||||
|   # | ||||
|   # Migration tests go first | ||||
|   # | ||||
| 	$(MAKE) GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/$*.ini COVERAGE_TEST_ARGS= COVERAGE_TEST_PACKAGES=forgejo.org/tests/integration/migration-test coverage-run | ||||
| 	for pkg in $(MIGRATION_PACKAGES); do \
 | ||||
| 		$(MAKE) GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/$*.ini COVERAGE_TEST_DATABASE=$* COVERAGE_TEST_ARGS= COVERAGE_TEST_PACKAGES=$$pkg coverage-run ; \
 | ||||
| 	done | ||||
|   # | ||||
|   # All other integration tests follow | ||||
|   # | ||||
| 	$(MAKE) GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/$*.ini COVERAGE_TEST_DATABASE=$* COVERAGE_TEST_PACKAGES=forgejo.org/tests/integration coverage-run | ||||
| 
 | ||||
| .PHONY: tidy | ||||
| tidy: | ||||
|  | @ -685,7 +707,7 @@ test-e2e-mysql\#%: playwright e2e.mysql.test generate-ini-mysql | |||
| 	GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.mysql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e/$* | ||||
| 
 | ||||
| .PHONY: test-e2e-pgsql | ||||
| test-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql | ||||
| GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.initest-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql | ||||
| 	GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.pgsql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e | ||||
| 
 | ||||
| .PHONY: test-e2e-pgsql\#%
 | ||||
|  | @ -708,14 +730,6 @@ bench-mysql: integrations.mysql.test generate-ini-mysql | |||
| bench-pgsql: integrations.pgsql.test generate-ini-pgsql | ||||
| 	GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.cpuprofile=cpu.out -test.run DontRunTests -test.bench . | ||||
| 
 | ||||
| .PHONY: integration-test-coverage | ||||
| integration-test-coverage: integrations.cover.test generate-ini-mysql | ||||
| 	GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out | ||||
| 
 | ||||
| .PHONY: integration-test-coverage-sqlite | ||||
| integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sqlite | ||||
| 	GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out | ||||
| 
 | ||||
| integrations.mysql.test: git-check $(GO_SOURCES) | ||||
| 	$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -o integrations.mysql.test | ||||
| 
 | ||||
|  | @ -725,12 +739,6 @@ integrations.pgsql.test: git-check $(GO_SOURCES) | |||
| integrations.sqlite.test: git-check $(GO_SOURCES) | ||||
| 	$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -o integrations.sqlite.test -tags '$(TEST_TAGS)' | ||||
| 
 | ||||
| integrations.cover.test: git-check $(GO_SOURCES) | ||||
| 	$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.test | ||||
| 
 | ||||
| integrations.cover.sqlite.test: git-check $(GO_SOURCES) | ||||
| 	$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)' | ||||
| 
 | ||||
| .PHONY: migrations.mysql.test | ||||
| migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql | ||||
| 	$(GOTEST) $(GOTESTFLAGS) -c forgejo.org/tests/integration/migration-test -o migrations.mysql.test | ||||
|  |  | |||
							
								
								
									
										50
									
								
								contrib/coverage-helper.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								contrib/coverage-helper.sh
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,50 @@ | |||
| #!/bin/bash | ||||
| 
 | ||||
| set -e | ||||
| #set -x | ||||
| PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}:  ' | ||||
| 
 | ||||
| # | ||||
| # Those must be explicitly required and are excluded from the full list of packages because they | ||||
| # would interfere with the testing fixtures. | ||||
| # | ||||
| excluded+='forgejo.org/models/migrations|'                # must be run before database specific tests | ||||
| excluded+='forgejo.org/models/forgejo_migrations|'        # must be run before database specific tests | ||||
| excluded+='forgejo.org/tests/integration/migration-test|' # must be run before database specific tests | ||||
| excluded+='forgejo.org/tests|'                            # only tests, no coverage to get there | ||||
| excluded+='forgejo.org/tests/e2e|'                        # JavaScript is not in scope here and if it adds coverage it should not be counted | ||||
| excluded+='FAKETERMINATOR'                                # do not modify | ||||
| 
 | ||||
| : ${COVERAGEDIR:=$(pwd)/coverage/data} | ||||
| : ${GO:=$(go env GOROOT)/bin/go} | ||||
| 
 | ||||
| DEFAULT_TEST_PACKAGES=$($GO list ./... | grep -E -v "$excluded") | ||||
| 
 | ||||
| COVERED_PACKAGES=$($GO list ./...) | ||||
| COVERED_PACKAGES=$(echo $COVERED_PACKAGES | sed -e 's/ /,/g') | ||||
| 
 | ||||
| function run_test() { | ||||
|   local package="$1" | ||||
|   if echo "$package" | grep --quiet --fixed-string ".."; then | ||||
|     echo "$package contains a suspicious .." | ||||
|     return 1 | ||||
|   fi | ||||
| 
 | ||||
|   local coverage="$COVERAGEDIR/$COVERAGE_TEST_DATABASE/$package" | ||||
|   rm -fr $coverage | ||||
|   mkdir -p $coverage | ||||
| 
 | ||||
|   # | ||||
|   # -race cannot be used because it requires -covermode atomic which is | ||||
|   # different from the end-to-end tests and would cause issues wen merging | ||||
|   # | ||||
|   $GO test -timeout=20m -tags='sqlite sqlite_unlock_notify' -cover $package -coverpkg $COVERED_PACKAGES $COVERAGE_TEST_ARGS -args -test.gocoverdir=$coverage |& grep -v 'warning: no packages being tested depend on matches for pattern' | ||||
| } | ||||
| 
 | ||||
| function test_packages() { | ||||
|   for package in ${@:-$DEFAULT_TEST_PACKAGES}; do | ||||
|     run_test $package | ||||
|   done | ||||
| } | ||||
| 
 | ||||
| "$@" | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue