|
| 1 | +// Copyright (C) MongoDB, Inc. 2022-present. |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 4 | +// not use this file except in compliance with the License. You may obtain |
| 5 | +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | + |
1 | 7 | package uuid
|
2 | 8 |
|
3 | 9 | import (
|
| 10 | + "sync" |
4 | 11 | "testing"
|
5 | 12 |
|
6 |
| - "github.com/stretchr/testify/assert" |
| 13 | + "github.com/stretchr/testify/require" |
7 | 14 | )
|
8 | 15 |
|
9 | 16 | func TestNew(t *testing.T) {
|
10 | 17 | m := make(map[UUID]bool)
|
11 |
| - for i := 1; i < 100; i++ { |
| 18 | + for i := 1; i < 1000000; i++ { |
12 | 19 | uuid, err := New()
|
13 |
| - assert.NoError(t, err, "New error") |
14 |
| - assert.False(t, m[uuid], "New returned a duplicate UUID %v", uuid) |
| 20 | + require.NoError(t, err, "New error") |
| 21 | + require.False(t, m[uuid], "New returned a duplicate UUID %v", uuid) |
15 | 22 | m[uuid] = true
|
16 | 23 | }
|
17 | 24 | }
|
| 25 | + |
| 26 | +// GODRIVER-2349 |
| 27 | +// Test that initializing many package-global UUID sources concurrently never leads to any duplicate |
| 28 | +// UUIDs being generated. |
| 29 | +func TestGlobalSource(t *testing.T) { |
| 30 | + // Create a slice of 1,000 sources and initialize them in 1,000 separate goroutines. The goal is |
| 31 | + // to emulate many separate Go driver processes starting at the same time and initializing the |
| 32 | + // uuid package at the same time. |
| 33 | + sources := make([]*source, 1000) |
| 34 | + var wg sync.WaitGroup |
| 35 | + for i := range sources { |
| 36 | + wg.Add(1) |
| 37 | + go func(i int) { |
| 38 | + defer wg.Done() |
| 39 | + sources[i] = newGlobalSource() |
| 40 | + }(i) |
| 41 | + } |
| 42 | + wg.Wait() |
| 43 | + |
| 44 | + // Read 1,000 UUIDs from each source and assert that there is never a duplicate value, either |
| 45 | + // from the same source or from separate sources. |
| 46 | + const iterations = 1000 |
| 47 | + uuids := make(map[UUID]bool, len(sources)*iterations) |
| 48 | + for i := 0; i < iterations; i++ { |
| 49 | + for j, s := range sources { |
| 50 | + uuid, err := s.new() |
| 51 | + require.NoError(t, err, "new() error") |
| 52 | + require.Falsef(t, uuids[uuid], "source %d returned a duplicate UUID on iteration %d: %v", j, i, uuid) |
| 53 | + uuids[uuid] = true |
| 54 | + } |
| 55 | + } |
| 56 | +} |
0 commit comments