2

I have a test that compares the equality of two pointers to instances of a struct (MyStruct). The pointers are stored within other structs (container1 and container2). Here's how I check the equality:

require.Equal(*container1.MyStruct, *container2.MyStruct)

the Equals() method is from the Testify library: https://github.com/stretchr/testify/blob/master/require/require_forward.go#L128

This test passes when I run it on my Mac. However, when I push my changes to our build server (Linux), the test fails. The error message is the standard Error: Not equal... message, but when I diff the expected and actual shown in the output, they're exactly the same!

I thought maybe Go is somehow comparing the addresses of the pointers rather than the contents, but the comment on require.Equal makes this seem unlikely:

// Pointer variable equality is determined based on the equality of the referenced values (as opposed to the memory addresses)

Any idea what's going on here? Does Go behave differently on Mac vs Linux?

I'm not able to post specifics here as it's an issue I'm seeing in a codebase I touch at work.

3
  • 2
    Are you 100% sure that you're running the exact same versions of Go in both environments? Have you tried using reflect.DeepEqual or assert.Equal? It might also be a dependency issue (your IDE may be referencing a local version of stretchr/require different that the one being obtained in your build server) Commented Aug 18, 2020 at 19:47
  • 3
    Please edit your question to include the relevant source code to reproduce the issue. Commented Aug 18, 2020 at 19:55
  • @A.Lorefice require.Equal and assert.Equal are using reflect.DeepEqual in their implementation as I remember. The only problem is when you try to compare struct which contains maps because they do not keep order. But it should work otherwise. Commented Aug 19, 2020 at 7:50

1 Answer 1

3

The problem is that there's a bug in the output of the Equal function's "expected... actual..." printing logic for structs when the struct contains a Time object. Here's a snippet from the error output: (I've removed the irrelevant fields of the struct):

        Error Trace:    my_test.go:388
                                    my_test.go:50
        Error:          Not equal:
                        expected: {
                          BuildStartDateUtc: 2020-08-17 22:43:05.330062876 +0000 UTC,
                          

                        actual  : {
                          BuildStartDateUtc: 2020-08-17 22:43:05.330062876 +0000 UTC,                            
                        }
                         

Fields look the same. However, if I compare MyStruct.BuildStartDateUtc directly, I get this:

expected: &time.Time{wall:0x389ccfe6, ext:63733398658, loc:(*time.Location)(0x101d4e0)}
actual : &time.Time{wall:0x389ccfe6, ext:63733398658, loc:(*time.Location)(nil)}

The "loc" field is missing in the actual. This is what's causing the comparision to fail, but since "loc" evidently is not included in the output when we compare a struct that contains a Time, we get a very confusing "expected... actual..." output where the actual/expected look exactly equal when they're not.

When I syncronized the Location of the Times being compared the test passed.

Looks like it might be related to this Testify issue: https://github.com/stretchr/testify/issues/984

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.