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

Tests for #206 #209

Merged
merged 6 commits into from
Aug 4, 2018
Merged

Conversation

liamsi
Copy link
Contributor

@liamsi liamsi commented Jul 19, 2018

  • compare to proto3 behaviour
  • simple tests for pointers to empty struct and nil pointer

The intended behaviour is achieved by your PR @jaekwon 👍 Currently, the test fails with:

TestProto3CompatPtrs: (Click to expand)
=== RUN   TestProto3CompatPtrs
--- FAIL: TestProto3CompatPtrs (0.00s)
	proto3_compat_test.go:126: 
			Error Trace:	proto3_compat_test.go:126
			Error:      	Not equal: 
			            	expected: []byte(nil)
			            	actual  : []byte{}
			            	
			            	Diff:
			            	--- Expected
			            	+++ Actual
			            	@@ -1,2 +1,3 @@
			            	-([]uint8) <nil>
			            	+([]uint8) {
			            	+}
			            	 
			Test:       	TestProto3CompatPtrs
	proto3_compat_test.go:128: []
	proto3_compat_test.go:140: [10 0]
FAIL

The problem here seems orthogonal to what we were trying to do in the initial PR: If we skip (nil-pointer case) in amino we end up with []byte(nil). In protobuf we end up with []byte{}.

This is fixed by e90abf1

- compare to proto3 behaviour
- test for pointers to empty struct and nil pointer

Signed-off-by: Liamsi <Liamsi@users.noreply.github.com>
- use []byte{} not []byte(nil)

Signed-off-by: Liamsi <Liamsi@users.noreply.github.com>
@liamsi liamsi changed the title WIP: tests for #206 Tests for #206 Jul 19, 2018
amino.go Outdated
@@ -197,7 +197,7 @@ func (cdc *Codec) MarshalBinaryBare(o interface{}) ([]byte, error) {

// Encode Amino:binary bytes.
var bz []byte
buf := new(bytes.Buffer)
buf := bytes.NewBuffer([]byte{})
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is necessary, fyi. From the docs,
"The zero value for Buffer is an empty buffer ready to use."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, it is ready to use but the returned bytes will differ from what go-protobuf returns ([]byte(nil) vs []byte{}). Alternatively, we can make the tests treat these cases as equal instead of modifying it here.

@jaekwon
Copy link
Contributor

jaekwon commented Jul 20, 2018

The test TestEncodeAminoDecodeProto should be cleaned up and either split into multiple tests or at least separated w/ t.Run(name, func(){}).

Maybe it makes sense to also fold the other test into the new framework...

I think the tests should ideally unmarshal as well and test for equality before and after... I noticed that we lack proper fuzz tests here in go-amino, so I modified the test cases there, but given how we missed this the first time (e.g. the new test cases would fail w/ the WriteEmpty changes before #206) and that the fuzz tests may still not be complete, I think we should also add unmarshal+and+test+for+equality here as well.

#206 (comment)

@liamsi
Copy link
Contributor Author

liamsi commented Aug 1, 2018

OK, I've split up the tests and removed the remaining one which didn't really test a separate concern / unit of code. We can still improve them. I would suggest to add table driven test (as you usually do). we But let's get this merged and tested and switch to table-driven tests in a separate PR?

I'll see why the EmptyStruct test fails while fuzzing (I think I know), run the fuzzer for a while, and we should be good to merge and create a release.

@liamsi
Copy link
Contributor Author

liamsi commented Aug 2, 2018

For the failing fuzzer test: In protobuf this (repeated field containing a nil would not even be encoded with error'ing:
https://github.com/golang/protobuf/blob/f5983d50c82d70eaa88c17080245cc871558081f/proto/table_marshal.go#L277-L279
as nil is not allowed in repeated fields (arrays / slices). For the sake of compatibility, I think we should disallow that in repeated fields, too.

Context (failing fuzzer test):

	Diff:
    			            	--- Expected
    			            	+++ Actual
    			            	@@ -117,4 +117,3 @@
    			            	   (*tests.EmptyStruct)(<nil>),
    			            	-  (*tests.EmptyStruct)({
    			            	-  })
    			            	+  (*tests.EmptyStruct)(<nil>)
    			            	  }
    			Test:       	TestCodecStruct/PointerSlicesStruct:binary

If we look at protobuf's behaviour here:

message EmptyMessage {}

// this will generate (part of) the same go-lang code as PointerSlicesStruct
message PtrSliceEmptyMsg {
    repeated EmptyMessage ptr = 1;
}

when trying to encode what causes the problem on amino's side:

psl := p3.PtrSliceEmptyMsg{Ptr: []*p3.EmptyMessage{nil, &p3.EmptyMessage{}}}
pb, err := proto.Marshal(&psl)
	Error Trace:	proto3_compat_test.go:187
			Error:      	Received unexpected error:
			            	proto: repeated field Ptr has nil element
			Test:       	TestEmptyMessageRoundtrip

@jaekwon jaekwon merged commit 6db2352 into tendermint:jae/writeemptyptr Aug 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants