github.com/tobyzxj/uuid@v0.0.0-20140223123307-aa0153c14395/uuid_test.go (about)

     1  // Copyright 2011 Google Inc.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package uuid
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"os"
    11  	"strings"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  type test struct {
    17  	in      string
    18  	version Version
    19  	variant Variant
    20  	isuuid  bool
    21  }
    22  
    23  var tests = []test{
    24  	{"f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, RFC4122, true},
    25  	{"f47ac10b-58cc-1372-8567-0e02b2c3d479", 1, RFC4122, true},
    26  	{"f47ac10b-58cc-2372-8567-0e02b2c3d479", 2, RFC4122, true},
    27  	{"f47ac10b-58cc-3372-8567-0e02b2c3d479", 3, RFC4122, true},
    28  	{"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true},
    29  	{"f47ac10b-58cc-5372-8567-0e02b2c3d479", 5, RFC4122, true},
    30  	{"f47ac10b-58cc-6372-8567-0e02b2c3d479", 6, RFC4122, true},
    31  	{"f47ac10b-58cc-7372-8567-0e02b2c3d479", 7, RFC4122, true},
    32  	{"f47ac10b-58cc-8372-8567-0e02b2c3d479", 8, RFC4122, true},
    33  	{"f47ac10b-58cc-9372-8567-0e02b2c3d479", 9, RFC4122, true},
    34  	{"f47ac10b-58cc-a372-8567-0e02b2c3d479", 10, RFC4122, true},
    35  	{"f47ac10b-58cc-b372-8567-0e02b2c3d479", 11, RFC4122, true},
    36  	{"f47ac10b-58cc-c372-8567-0e02b2c3d479", 12, RFC4122, true},
    37  	{"f47ac10b-58cc-d372-8567-0e02b2c3d479", 13, RFC4122, true},
    38  	{"f47ac10b-58cc-e372-8567-0e02b2c3d479", 14, RFC4122, true},
    39  	{"f47ac10b-58cc-f372-8567-0e02b2c3d479", 15, RFC4122, true},
    40  
    41  	{"urn:uuid:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
    42  	{"URN:UUID:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
    43  	{"f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true},
    44  	{"f47ac10b-58cc-4372-1567-0e02b2c3d479", 4, Reserved, true},
    45  	{"f47ac10b-58cc-4372-2567-0e02b2c3d479", 4, Reserved, true},
    46  	{"f47ac10b-58cc-4372-3567-0e02b2c3d479", 4, Reserved, true},
    47  	{"f47ac10b-58cc-4372-4567-0e02b2c3d479", 4, Reserved, true},
    48  	{"f47ac10b-58cc-4372-5567-0e02b2c3d479", 4, Reserved, true},
    49  	{"f47ac10b-58cc-4372-6567-0e02b2c3d479", 4, Reserved, true},
    50  	{"f47ac10b-58cc-4372-7567-0e02b2c3d479", 4, Reserved, true},
    51  	{"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true},
    52  	{"f47ac10b-58cc-4372-9567-0e02b2c3d479", 4, RFC4122, true},
    53  	{"f47ac10b-58cc-4372-a567-0e02b2c3d479", 4, RFC4122, true},
    54  	{"f47ac10b-58cc-4372-b567-0e02b2c3d479", 4, RFC4122, true},
    55  	{"f47ac10b-58cc-4372-c567-0e02b2c3d479", 4, Microsoft, true},
    56  	{"f47ac10b-58cc-4372-d567-0e02b2c3d479", 4, Microsoft, true},
    57  	{"f47ac10b-58cc-4372-e567-0e02b2c3d479", 4, Future, true},
    58  	{"f47ac10b-58cc-4372-f567-0e02b2c3d479", 4, Future, true},
    59  
    60  	{"f47ac10b158cc-5372-a567-0e02b2c3d479", 0, Invalid, false},
    61  	{"f47ac10b-58cc25372-a567-0e02b2c3d479", 0, Invalid, false},
    62  	{"f47ac10b-58cc-53723a567-0e02b2c3d479", 0, Invalid, false},
    63  	{"f47ac10b-58cc-5372-a56740e02b2c3d479", 0, Invalid, false},
    64  	{"f47ac10b-58cc-5372-a567-0e02-2c3d479", 0, Invalid, false},
    65  	{"g47ac10b-58cc-4372-a567-0e02b2c3d479", 0, Invalid, false},
    66  }
    67  
    68  var constants = []struct {
    69  	c    interface{}
    70  	name string
    71  }{
    72  	{Person, "Person"},
    73  	{Group, "Group"},
    74  	{Org, "Org"},
    75  	{Invalid, "Invalid"},
    76  	{RFC4122, "RFC4122"},
    77  	{Reserved, "Reserved"},
    78  	{Microsoft, "Microsoft"},
    79  	{Future, "Future"},
    80  	{Domain(17), "Domain17"},
    81  	{Variant(42), "BadVariant42"},
    82  }
    83  
    84  func testTest(t *testing.T, in string, tt test) {
    85  	uuid := Parse(in)
    86  	if ok := (uuid != nil); ok != tt.isuuid {
    87  		t.Errorf("Parse(%s) got %v expected %v\b", in, ok, tt.isuuid)
    88  	}
    89  	if uuid == nil {
    90  		return
    91  	}
    92  
    93  	if v := uuid.Variant(); v != tt.variant {
    94  		t.Errorf("Variant(%s) got %d expected %d\b", in, v, tt.variant)
    95  	}
    96  	if v, _ := uuid.Version(); v != tt.version {
    97  		t.Errorf("Version(%s) got %d expected %d\b", in, v, tt.version)
    98  	}
    99  }
   100  
   101  func TestUUID(t *testing.T) {
   102  	for _, tt := range tests {
   103  		testTest(t, tt.in, tt)
   104  		testTest(t, strings.ToUpper(tt.in), tt)
   105  	}
   106  }
   107  
   108  func TestConstants(t *testing.T) {
   109  	for x, tt := range constants {
   110  		v, ok := tt.c.(fmt.Stringer)
   111  		if !ok {
   112  			t.Errorf("%x: %v: not a stringer", x, v)
   113  		} else if s := v.String(); s != tt.name {
   114  			v, _ := tt.c.(int)
   115  			t.Errorf("%x: Constant %T:%d gives %q, expected %q\n", x, tt.c, v, s, tt.name)
   116  		}
   117  	}
   118  }
   119  
   120  func TestRandomUUID(t *testing.T) {
   121  	m := make(map[string]bool)
   122  	for x := 1; x < 32; x++ {
   123  		uuid := NewRandom()
   124  		s := uuid.String()
   125  		if m[s] {
   126  			t.Errorf("NewRandom returned duplicated UUID %s\n", s)
   127  		}
   128  		m[s] = true
   129  		if v, _ := uuid.Version(); v != 4 {
   130  			t.Errorf("Random UUID of version %s\n", v)
   131  		}
   132  		if uuid.Variant() != RFC4122 {
   133  			t.Errorf("Random UUID is variant %d\n", uuid.Variant())
   134  		}
   135  	}
   136  }
   137  
   138  func TestNew(t *testing.T) {
   139  	m := make(map[string]bool)
   140  	for x := 1; x < 32; x++ {
   141  		s := New()
   142  		if m[s] {
   143  			t.Errorf("New returned duplicated UUID %s\n", s)
   144  		}
   145  		m[s] = true
   146  		uuid := Parse(s)
   147  		if uuid == nil {
   148  			t.Errorf("New returned %q which does not decode\n", s)
   149  			continue
   150  		}
   151  		if v, _ := uuid.Version(); v != 4 {
   152  			t.Errorf("Random UUID of version %s\n", v)
   153  		}
   154  		if uuid.Variant() != RFC4122 {
   155  			t.Errorf("Random UUID is variant %d\n", uuid.Variant())
   156  		}
   157  	}
   158  }
   159  
   160  func clockSeq(t *testing.T, uuid UUID) int {
   161  	seq, ok := uuid.ClockSequence()
   162  	if !ok {
   163  		t.Fatalf("%s: invalid clock sequence\n", uuid)
   164  	}
   165  	return seq
   166  }
   167  
   168  func TestClockSeq(t *testing.T) {
   169  	// Fake time.Now for this test to return a monotonically advancing time; restore it at end.
   170  	defer func(orig func() time.Time) { timeNow = orig }(timeNow)
   171  	monTime := time.Now()
   172  	timeNow = func() time.Time {
   173  		monTime = monTime.Add(1 * time.Second)
   174  		return monTime
   175  	}
   176  
   177  	SetClockSequence(-1)
   178  	uuid1 := NewUUID()
   179  	uuid2 := NewUUID()
   180  
   181  	if clockSeq(t, uuid1) != clockSeq(t, uuid2) {
   182  		t.Errorf("clock sequence %d != %d\n", clockSeq(t, uuid1), clockSeq(t, uuid2))
   183  	}
   184  
   185  	SetClockSequence(-1)
   186  	uuid2 = NewUUID()
   187  
   188  	// Just on the very off chance we generated the same sequence
   189  	// two times we try again.
   190  	if clockSeq(t, uuid1) == clockSeq(t, uuid2) {
   191  		SetClockSequence(-1)
   192  		uuid2 = NewUUID()
   193  	}
   194  	if clockSeq(t, uuid1) == clockSeq(t, uuid2) {
   195  		t.Errorf("Duplicate clock sequence %d\n", clockSeq(t, uuid1))
   196  	}
   197  
   198  	SetClockSequence(0x1234)
   199  	uuid1 = NewUUID()
   200  	if seq := clockSeq(t, uuid1); seq != 0x1234 {
   201  		t.Errorf("%s: expected seq 0x1234 got 0x%04x\n", uuid1, seq)
   202  	}
   203  }
   204  
   205  func TestCoding(t *testing.T) {
   206  	text := "7d444840-9dc0-11d1-b245-5ffdce74fad2"
   207  	urn := "urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2"
   208  	data := UUID{
   209  		0x7d, 0x44, 0x48, 0x40,
   210  		0x9d, 0xc0,
   211  		0x11, 0xd1,
   212  		0xb2, 0x45,
   213  		0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2,
   214  	}
   215  	if v := data.String(); v != text {
   216  		t.Errorf("%x: encoded to %s, expected %s\n", data, v, text)
   217  	}
   218  	if v := data.URN(); v != urn {
   219  		t.Errorf("%x: urn is %s, expected %s\n", data, v, urn)
   220  	}
   221  
   222  	uuid := Parse(text)
   223  	if !Equal(uuid, data) {
   224  		t.Errorf("%s: decoded to %s, expected %s\n", text, uuid, data)
   225  	}
   226  }
   227  
   228  func TestVersion1(t *testing.T) {
   229  	uuid1 := NewUUID()
   230  	uuid2 := NewUUID()
   231  
   232  	if Equal(uuid1, uuid2) {
   233  		t.Errorf("%s:duplicate uuid\n", uuid1)
   234  	}
   235  	if v, _ := uuid1.Version(); v != 1 {
   236  		t.Errorf("%s: version %s expected 1\n", uuid1, v)
   237  	}
   238  	if v, _ := uuid2.Version(); v != 1 {
   239  		t.Errorf("%s: version %s expected 1\n", uuid2, v)
   240  	}
   241  	n1 := uuid1.NodeID()
   242  	n2 := uuid2.NodeID()
   243  	if !bytes.Equal(n1, n2) {
   244  		t.Errorf("Different nodes %x != %x\n", n1, n2)
   245  	}
   246  	t1, ok := uuid1.Time()
   247  	if !ok {
   248  		t.Errorf("%s: invalid time\n", uuid1)
   249  	}
   250  	t2, ok := uuid2.Time()
   251  	if !ok {
   252  		t.Errorf("%s: invalid time\n", uuid2)
   253  	}
   254  	q1, ok := uuid1.ClockSequence()
   255  	if !ok {
   256  		t.Errorf("%s: invalid clock sequence\n", uuid1)
   257  	}
   258  	q2, ok := uuid2.ClockSequence()
   259  	if !ok {
   260  		t.Errorf("%s: invalid clock sequence", uuid2)
   261  	}
   262  
   263  	switch {
   264  	case t1 == t2 && q1 == q2:
   265  		t.Errorf("time stopped\n")
   266  	case t1 > t2 && q1 == q2:
   267  		t.Errorf("time reversed\n")
   268  	case t1 < t2 && q1 != q2:
   269  		t.Errorf("clock sequence chaned unexpectedly\n")
   270  	}
   271  }
   272  
   273  func TestNodeAndTime(t *testing.T) {
   274  	// Time is February 5, 1998 12:30:23.136364800 AM GMT
   275  
   276  	uuid := Parse("7d444840-9dc0-11d1-b245-5ffdce74fad2")
   277  	node := []byte{0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2}
   278  
   279  	ts, ok := uuid.Time()
   280  	if ok {
   281  		c := time.Unix(ts.UnixTime())
   282  		want := time.Date(1998, 2, 5, 0, 30, 23, 136364800, time.UTC)
   283  		if !c.Equal(want) {
   284  			t.Errorf("Got time %v, want %v", c, want)
   285  		}
   286  	} else {
   287  		t.Errorf("%s: bad time\n", uuid)
   288  	}
   289  	if !bytes.Equal(node, uuid.NodeID()) {
   290  		t.Errorf("Expected node %v got %v\n", node, uuid.NodeID())
   291  	}
   292  }
   293  
   294  func TestMD5(t *testing.T) {
   295  	uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String()
   296  	want := "6fa459ea-ee8a-3ca4-894e-db77e160355e"
   297  	if uuid != want {
   298  		t.Errorf("MD5: got %q expected %q\n", uuid, want)
   299  	}
   300  }
   301  
   302  func TestSHA1(t *testing.T) {
   303  	uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String()
   304  	want := "886313e1-3b8a-5372-9b90-0c9aee199e5d"
   305  	if uuid != want {
   306  		t.Errorf("SHA1: got %q expected %q\n", uuid, want)
   307  	}
   308  }
   309  
   310  func TestNodeID(t *testing.T) {
   311  	nid := []byte{1, 2, 3, 4, 5, 6}
   312  	SetNodeInterface("")
   313  	s := NodeInterface()
   314  	if s == "" || s == "user" {
   315  		t.Errorf("NodeInterface %q after SetInteface\n", s)
   316  	}
   317  	node1 := NodeID()
   318  	if node1 == nil {
   319  		t.Errorf("NodeID nil after SetNodeInterface\n", s)
   320  	}
   321  	SetNodeID(nid)
   322  	s = NodeInterface()
   323  	if s != "user" {
   324  		t.Errorf("Expected NodeInterface %q got %q\n", "user", s)
   325  	}
   326  	node2 := NodeID()
   327  	if node2 == nil {
   328  		t.Errorf("NodeID nil after SetNodeID\n", s)
   329  	}
   330  	if bytes.Equal(node1, node2) {
   331  		t.Errorf("NodeID not changed after SetNodeID\n", s)
   332  	} else if !bytes.Equal(nid, node2) {
   333  		t.Errorf("NodeID is %x, expected %x\n", node2, nid)
   334  	}
   335  }
   336  
   337  func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) {
   338  	if uuid == nil {
   339  		t.Errorf("%s failed\n", name)
   340  		return
   341  	}
   342  	if v, _ := uuid.Version(); v != 2 {
   343  		t.Errorf("%s: %s: expected version 2, got %s\n", name, uuid, v)
   344  		return
   345  	}
   346  	if v, ok := uuid.Domain(); !ok || v != domain {
   347  		if !ok {
   348  			t.Errorf("%s: %d: Domain failed\n", name, uuid)
   349  		} else {
   350  			t.Errorf("%s: %s: expected domain %d, got %d\n", name, uuid, domain, v)
   351  		}
   352  	}
   353  	if v, ok := uuid.Id(); !ok || v != id {
   354  		if !ok {
   355  			t.Errorf("%s: %d: Id failed\n", name, uuid)
   356  		} else {
   357  			t.Errorf("%s: %s: expected id %d, got %d\n", name, uuid, id, v)
   358  		}
   359  	}
   360  }
   361  
   362  func TestDCE(t *testing.T) {
   363  	testDCE(t, "NewDCESecurity", NewDCESecurity(42, 12345678), 42, 12345678)
   364  	testDCE(t, "NewDCEPerson", NewDCEPerson(), Person, uint32(os.Getuid()))
   365  	testDCE(t, "NewDCEGroup", NewDCEGroup(), Group, uint32(os.Getgid()))
   366  }
   367  
   368  type badRand struct{}
   369  
   370  func (r badRand) Read(buf []byte) (int, error) {
   371  	for i, _ := range buf {
   372  		buf[i] = byte(i)
   373  	}
   374  	return len(buf), nil
   375  }
   376  
   377  func TestBadRand(t *testing.T) {
   378  	SetRand(badRand{})
   379  	uuid1 := New()
   380  	uuid2 := New()
   381  	if uuid1 != uuid2 {
   382  		t.Errorf("execpted duplicates, got %q and %q\n", uuid1, uuid2)
   383  	}
   384  	SetRand(nil)
   385  	uuid1 = New()
   386  	uuid2 = New()
   387  	if uuid1 == uuid2 {
   388  		t.Errorf("unexecpted duplicates, got %q\n", uuid1)
   389  	}
   390  }