Search code examples
goflatbuffers

Flatbuffer mutate doesn't change bytes


I am running into a problem mutating a flatbuffer from bytes. According to the flatbuffer documentation (https://github.com/google/flatbuffers/blob/master/docs/source/Tutorial.md), you can mutate fixed size fields, such as an int32. And as you can see below, the generated golang TestMutate has a MutateServerId() function. My problem is that after I mutate it, the bytes don't seem to have changed.

Here is my flatbuffer table definition:

namespace foo;

table TestMutate {
    serverId:int32;
}

Here is a unit test I wrote:

func TestMutateFlatbuffer2(test *testing.T) {
    builder := flatbuffers.NewBuilder(1024)
    packageWalletStorageServicesRPC.TestMutateStart(builder)
    packageWalletStorageServicesRPC.TestMutateAddServerId(builder, 1)
    endMessage := packageWalletStorageServicesRPC.TestMutateEnd(builder)
    builder.Finish(endMessage)

    bytes := builder.FinishedBytes()
    testMutate := packageWalletStorageServicesRPC.GetRootAsTestMutate(bytes, 0)
    success := testMutate.MutateServerId(2)
    if !success {
        panic("Server id not mutated.")
    } else {
        logger.Logf(logger.INFO, "serverId mutated to:%d", testMutate.ServerId())
    }

    mutatedBytes := testMutate.Table().Bytes
    if string(mutatedBytes) == string(bytes) {
        panic("Bytes were not mutated.")
    }
}

Here is the output from the test.

=== RUN   TestMutateFlatbuffer2
2019/08/01 19:33:56.801926 foo_test.go:389   : [ I ]: serverId mutated to:2
--- FAIL: TestMutateFlatbuffer2 (0.00s)
panic: Bytes were not mutated. [recovered]
    panic: Bytes were not mutated.

Notice that it appears I've mutated the underlying structure, but when I get the bytes of the flatbuffer, they're not changed. Question 1: Am I getting the bytes the correct way? Question 2: If I'm getting them in the right way, why are they not changed since the call to mutate seemed to succeed?


Solution

  • Your test string(mutatedBytes) == string(bytes) fails because.. you are comparing the mutated buffer against itself. bytes refers to a buffer, that before your mutation contains a 1, and after it contains a 2. mutatedBytes points to the same buffer, and thus also contains a 2. The fact that testMutate.ServerId() returns 2 should tell you that the buffer got mutated succesfully, because there is no other way it could return 2 :) You'd have to make a (deep) copy of bytes before the mutation if you wanted this comparison to show that the buffers are different.