gouuid

Golang patch uuid works only in debug


I need to patch the uuid.New() function in my tests but I faced the following problem: the patching works only in debug mode. Here is some example of code which I wrote trying to fix the problem:

    generatedID := uuid.New()

    logrus.SetLevel(logrus.DebugLevel)
    logrus.Debugf("reference ID: %+v", generatedID)

    uuidPatch, err := mpatch.PatchMethod(uuid.New, func() uuid.UUID { return generatedID })
    if err != nil {
        logrus.Fatalf("failed to patch uuid.New: %v", err)
    }

    for i := 0; i < 5; i++ {
        id := uuid.New() 
        logrus.Debugf("%d. new ID: %+v", i+1, id)
    }

    uuidPatch.Unpatch()
    id := uuid.New()
    logrus.Debugf("new ID after unpatch: %+v", id)

so I need to get the same result of function uuid.New untill it will be inpatched. But here is the result of this code:

DEBU[0000] reference ID: 9dbb4f56-efa3-40c0-a624-2f676649c3c3 
DEBU[0000] 1. new ID: fb4f55f2-0a6d-4ed9-b97e-b72576b70806 
DEBU[0000] 2. new ID: be784352-b860-4cf0-ae52-5175c987fb60 
DEBU[0000] 3. new ID: 1cf5a6af-3c3b-4acd-8f8d-53ec05cd07b3 
DEBU[0000] 4. new ID: 2f1f3db7-4c8c-4724-9af1-1f4d3403685a 
DEBU[0000] 5. new ID: 38a85a73-735c-41f6-9e44-075f2a0c7562 
DEBU[0000] new ID after unpatch: fcc5d8c8-735d-4001-8aed-66305492b2f3 

As you can see, uuids are always new, even before unpatch.

But here is the result if I run in debug mode:

time="2025-04-18T16:25:45+03:00" level=debug msg="reference ID: 26a3853c-3f0a-4c69-a5e5-904f57d77931"
time="2025-04-18T16:25:45+03:00" level=debug msg="1. new ID: 26a3853c-3f0a-4c69-a5e5-904f57d77931"
time="2025-04-18T16:25:45+03:00" level=debug msg="2. new ID: 26a3853c-3f0a-4c69-a5e5-904f57d77931"
time="2025-04-18T16:25:45+03:00" level=debug msg="3. new ID: 26a3853c-3f0a-4c69-a5e5-904f57d77931"
time="2025-04-18T16:25:45+03:00" level=debug msg="4. new ID: 26a3853c-3f0a-4c69-a5e5-904f57d77931"
time="2025-04-18T16:25:45+03:00" level=debug msg="5. new ID: 26a3853c-3f0a-4c69-a5e5-904f57d77931"
time="2025-04-18T16:25:45+03:00" level=debug msg="new ID after unpatch: b4cb3cb8-43ce-4bd8-b9b2-97cfd13e94af"

Here I got the correct behavior: uuids are equal untill unpatch.

So I'd like to know what happens and how to solve it.

P.S. working with time.Now is correct: it changes the result of function to the specified date.


Solution

  • To cite from https://github.com/undefinedlabs/go-mpatch:

    Limitations
    Target functions could be inlined, making those functions unpatcheables. You can use //go:noinline directive or build with the gcflags=-l to disable inlining at compiler level.

    Inlining is typically not done when compiled with debug mode, since it makes debugging harder. This could explain the difference you see. In this case a fix would be to follow the instructions from the documentation to make sure that the relevant functions to not get inlined.