Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutation testing #28

Closed
wants to merge 29 commits into from
Closed

Mutation testing #28

wants to merge 29 commits into from

Conversation

JekaMas
Copy link
Contributor

@JekaMas JekaMas commented Oct 6, 2022

Description

As far as consensus is extremely sensitive functionality, I believe we need a way to check our tests for usefulness and correctness. Code coverage, unfortunately, doesn't tell us about the quality of tests, either about usefulness. Even with high code coverage it's possible to write not very useful tests that always 'green', or tests that are 'green' if being executed in particular order.
For that reason the PR introduces changes:

  1. As far as we run tests with t.Parallel() it makes sense to use -race flag as well. At the moment tests do have data races that'd be great to fix in separate issues.
  2. To prevent incorrect global state the PR introduces -shuffle flag
  3. To check that tests are useful the PR adds mutation testing https://github.com/avito-tech/go-mutesting

Changes include

  • Bugfix (non-breaking change that solves an issue)
  • Hotfix (change that solves an urgent issue, and requires immediate attention)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (change that is not backwards-compatible and/or changes current functionality)

Checklist

  • I have assigned this PR to myself
  • I have added at least 1 reviewer
  • I have added the relevant labels
  • I have added sufficient documentation in code

Comments

This PR is for discussion about new tooling. At the moment data race tests and mutation tests are red. If we'd like to merge the PR, we should comment out this CI steps and make tasks to fix tests with race and a bunch of tasks to add/check tests with respect of mutation testing results.

A few examples of mutation testing:

 func (i *IBFT) handlePrepare(view *proto.View, quorum uint64) bool {
 	isValidPrepare := func(message *proto.Message) bool {
 		// Verify that the proposal hash is valid
@@ -799,7 +799,7 @@
 
 	if len(prepareMessages) < int(quorum)-1 {
 		//	quorum not reached, keep polling
-		return false
+
 	}
 
func (i *IBFT) handlePrepare(view *proto.View, quorum uint64) bool {
 	isValidPrepare := func(message *proto.Message) bool {
 		// Verify that the proposal hash is valid
@@ -852,7 +852,7 @@
 		case <-sub.SubCh:
 			if !i.handleCommit(view, quorum) {
 				//	quorum not reached, retry
-				continue
+
 			}
 

 func (i *IBFT) handleCommit(view *proto.View, quorum uint64) bool {
 	isValidCommit := func(message *proto.Message) bool {
 		var (
@@ -880,7 +880,7 @@
 	commitMessage
[result.txt](https://github.com/0xPolygon/go-ibft/files/9723038/result.txt)
s := i.messages.GetValidMessages(view, proto.MessageType_COMMIT, isValidCommit)
 	if len(commitMessages) < int(quorum) {
 		//	quorum not reached, keep polling
-		return false
+
 	}
 


 func (i *IBFT) runStates(ctx context.Context) {
 	var timeout error
 
@@ -594,7 +594,7 @@
 
 	//	is proposer
 	if !i.backend.IsProposer(msg.From, height, round) {
-		return false
+
 	}

 func (i *IBFT) runStates(ctx context.Context) {
 	var timeout error
 
@@ -615,7 +615,7 @@
 
 	//	proposal must be for round 0
 	if msg.View.Round != 0 {
-		return false
+
 	}
 
 func (i *IBFT) handlePrePrepare(view *proto.View) *proto.Message {
 	isValidPrePrepare := func(message *proto.Message) bool {
 		if view.Round == 0 {
@@ -772,7 +772,7 @@
 		case <-sub.SubCh:
 			if !i.handlePrepare(view, quorum) {
 				//	quorum of valid prepare messages not received, retry
-				continue
+
 			}
 

More results are in the file result.txt

@JekaMas JekaMas added the feature New functionality label Oct 6, 2022
@JekaMas JekaMas self-assigned this Oct 6, 2022
@JekaMas JekaMas marked this pull request as draft October 6, 2022 08:59
@codecov-commenter
Copy link

codecov-commenter commented Oct 6, 2022

Codecov Report

Merging #28 (da087ce) into main (3e9fecd) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##             main      #28   +/-   ##
=======================================
  Coverage   94.06%   94.06%           
=======================================
  Files           6        6           
  Lines        1314     1314           
=======================================
  Hits         1236     1236           
  Misses         57       57           
  Partials       21       21           
Impacted Files Coverage Δ
messages/event_manager.go 100.00% <ø> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Contributor

@vcastellm vcastellm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Let's discuss

.github/workflows/main.yml Outdated Show resolved Hide resolved
@zivkovicmilos
Copy link
Contributor

@JekaMas
I'll review this PR along with @dbrajovic when it's ready, but just one note since you're still working on it:
Please don't drop the consensus_test.go file, and move those tests to ibft_test.go 🙏

There is a specific reason why we kept the 2 separate, as ibft_test.go contains only unit tests, whereas consensus_test.go contains cluster tests

@JekaMas
Copy link
Contributor Author

JekaMas commented Oct 11, 2022

@JekaMas I'll review this PR along with @dbrajovic when it's ready, but just one note since you're still working on it: Please don't drop the consensus_test.go file, and move those tests to ibft_test.go 🙏

There is a specific reason why we kept the 2 separate, as ibft_test.go contains only unit tests, whereas consensus_test.go contains cluster tests

I with I could keep this files separated. I left a comment, why this is needed. Otherwise, mutations won't be performed versus consensus_test

@JekaMas JekaMas marked this pull request as ready for review October 11, 2022 14:14
@JekaMas JekaMas requested a review from vcastellm October 12, 2022 05:54
@zivkovicmilos
Copy link
Contributor

Hey @JekaMas,

Resolved the races in tests in the following PR which I'll merge out to main:
PR #29

I've included your test race workflow there, so when you pull in the changes after it gets merged, you'll have them running

- name: Mutating testing
run: make mut

# test-race:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makefile Outdated
lint:
golangci-lint run -E whitespace -E wsl -E wastedassign -E unconvert -E tparallel -E thelper -E stylecheck -E prealloc \
-E predeclared -E nlreturn -E misspell -E makezero -E lll -E importas -E ifshort -E gosec -E gofmt -E goconst \
-E forcetypeassert -E dogsled -E dupl -E errname -E errorlint -E nolintlint --timeout 2m

install:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about renaming this to install-mut, so it's more clear?

Makefile Outdated

mut:
go-mutesting --blacklist=".github/mut_blacklist" --config=".github/mut_config.yml" ./...
@echo MSI: `jq '.stats.msi' report.json`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Missing new line

@zivkovicmilos
Copy link
Contributor

@JekaMas
The comment just states that the files need to be joined up, and I can't find anything on the official docs about it.
Can you please explain the reasoning because I'm probably missing something?

@JekaMas
Copy link
Contributor Author

JekaMas commented Oct 13, 2022

@JekaMas The comment just states that the files need to be joined up, and I can't find anything on the official docs about it. Can you please explain the reasoning because I'm probably missing something?

Sure, it is from the mutation testing package readme https://github.com/avito-tech/go-mutesting

The targets of the mutation testing can be defined as arguments to the binary. Every target can be either a Go source file, a directory or a package. Directories and packages can also include the ... wildcard pattern which will search recursively for Go source files. Test source files with the suffix _test are excluded, since this would interfere with the testing process most of the time.

Also, I just tried it.

@zivkovicmilos
Copy link
Contributor

zivkovicmilos commented Oct 14, 2022

@JekaMas

Sure, it is from the mutation testing package readme https://github.com/avito-tech/go-mutesting
The targets of the mutation testing can be defined as arguments to the binary. Every target can be either a Go source file, a directory or a package. Directories and packages can also include the ... wildcard pattern which will search recursively for Go source files. Test source files with the suffix _test are excluded, since this would interfere with the testing process most of the time.
Also, I just tried it.

Isn't it possible to just give the directory / package for mutation, instead of a single test file? I've ran it with ./...

@JekaMas
Copy link
Contributor Author

JekaMas commented Oct 14, 2022

@JekaMas

Sure, it is from the mutation testing package readme https://github.com/avito-tech/go-mutesting
The targets of the mutation testing can be defined as arguments to the binary. Every target can be either a Go source file, a directory or a package. Directories and packages can also include the ... wildcard pattern which will search recursively for Go source files. Test source files with the suffix _test are excluded, since this would interfere with the testing process most of the time.
Also, I just tried it.

Isn't it possible to just give the directory / package for mutation, instead of a single test file? I've ran it with ./...

It is possible, although it'd run file by file:

  1. greb a file file.go
  2. perform a mutation
  3. run tests file_test.go
  4. mark the result

@JekaMas
Copy link
Contributor Author

JekaMas commented Oct 14, 2022

@zivkovicmilos Could you check the last changes? I tried a different approach with test files.

@zivkovicmilos
Copy link
Contributor

@JekaMas

@zivkovicmilos Could you check the last changes? I tried a different approach with test files.

I like this idea of having a test that will be the cornerstone for the cluster mutation tests 💯
It's much cleaner now

@JekaMas
Copy link
Contributor Author

JekaMas commented Nov 4, 2022

closed in favor of #38

@JekaMas JekaMas closed this Nov 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants