github.com/ld86/docker@v1.7.1-rc3/pkg/truncindex/truncindex_test.go (about)

     1  package truncindex
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  
     7  	"github.com/docker/docker/pkg/stringid"
     8  )
     9  
    10  // Test the behavior of TruncIndex, an index for querying IDs from a non-conflicting prefix.
    11  func TestTruncIndex(t *testing.T) {
    12  	ids := []string{}
    13  	index := NewTruncIndex(ids)
    14  	// Get on an empty index
    15  	if _, err := index.Get("foobar"); err == nil {
    16  		t.Fatal("Get on an empty index should return an error")
    17  	}
    18  
    19  	// Spaces should be illegal in an id
    20  	if err := index.Add("I have a space"); err == nil {
    21  		t.Fatalf("Adding an id with ' ' should return an error")
    22  	}
    23  
    24  	id := "99b36c2c326ccc11e726eee6ee78a0baf166ef96"
    25  	// Add an id
    26  	if err := index.Add(id); err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	// Add an empty id (should fail)
    31  	if err := index.Add(""); err == nil {
    32  		t.Fatalf("Adding an empty id should return an error")
    33  	}
    34  
    35  	// Get a non-existing id
    36  	assertIndexGet(t, index, "abracadabra", "", true)
    37  	// Get an empty id
    38  	assertIndexGet(t, index, "", "", true)
    39  	// Get the exact id
    40  	assertIndexGet(t, index, id, id, false)
    41  	// The first letter should match
    42  	assertIndexGet(t, index, id[:1], id, false)
    43  	// The first half should match
    44  	assertIndexGet(t, index, id[:len(id)/2], id, false)
    45  	// The second half should NOT match
    46  	assertIndexGet(t, index, id[len(id)/2:], "", true)
    47  
    48  	id2 := id[:6] + "blabla"
    49  	// Add an id
    50  	if err := index.Add(id2); err != nil {
    51  		t.Fatal(err)
    52  	}
    53  	// Both exact IDs should work
    54  	assertIndexGet(t, index, id, id, false)
    55  	assertIndexGet(t, index, id2, id2, false)
    56  
    57  	// 6 characters or less should conflict
    58  	assertIndexGet(t, index, id[:6], "", true)
    59  	assertIndexGet(t, index, id[:4], "", true)
    60  	assertIndexGet(t, index, id[:1], "", true)
    61  
    62  	// An ambiguous id prefix should return an error
    63  	if _, err := index.Get(id[:4]); err == nil {
    64  		t.Fatal("An ambiguous id prefix should return an error")
    65  	}
    66  
    67  	// 7 characters should NOT conflict
    68  	assertIndexGet(t, index, id[:7], id, false)
    69  	assertIndexGet(t, index, id2[:7], id2, false)
    70  
    71  	// Deleting a non-existing id should return an error
    72  	if err := index.Delete("non-existing"); err == nil {
    73  		t.Fatalf("Deleting a non-existing id should return an error")
    74  	}
    75  
    76  	// Deleting an empty id should return an error
    77  	if err := index.Delete(""); err == nil {
    78  		t.Fatal("Deleting an empty id should return an error")
    79  	}
    80  
    81  	// Deleting id2 should remove conflicts
    82  	if err := index.Delete(id2); err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	// id2 should no longer work
    86  	assertIndexGet(t, index, id2, "", true)
    87  	assertIndexGet(t, index, id2[:7], "", true)
    88  	assertIndexGet(t, index, id2[:11], "", true)
    89  
    90  	// conflicts between id and id2 should be gone
    91  	assertIndexGet(t, index, id[:6], id, false)
    92  	assertIndexGet(t, index, id[:4], id, false)
    93  	assertIndexGet(t, index, id[:1], id, false)
    94  
    95  	// non-conflicting substrings should still not conflict
    96  	assertIndexGet(t, index, id[:7], id, false)
    97  	assertIndexGet(t, index, id[:15], id, false)
    98  	assertIndexGet(t, index, id, id, false)
    99  }
   100  
   101  func assertIndexGet(t *testing.T, index *TruncIndex, input, expectedResult string, expectError bool) {
   102  	if result, err := index.Get(input); err != nil && !expectError {
   103  		t.Fatalf("Unexpected error getting '%s': %s", input, err)
   104  	} else if err == nil && expectError {
   105  		t.Fatalf("Getting '%s' should return an error, not '%s'", input, result)
   106  	} else if result != expectedResult {
   107  		t.Fatalf("Getting '%s' returned '%s' instead of '%s'", input, result, expectedResult)
   108  	}
   109  }
   110  
   111  func BenchmarkTruncIndexAdd100(b *testing.B) {
   112  	var testSet []string
   113  	for i := 0; i < 100; i++ {
   114  		testSet = append(testSet, stringid.GenerateRandomID())
   115  	}
   116  	b.ResetTimer()
   117  	for i := 0; i < b.N; i++ {
   118  		index := NewTruncIndex([]string{})
   119  		for _, id := range testSet {
   120  			if err := index.Add(id); err != nil {
   121  				b.Fatal(err)
   122  			}
   123  		}
   124  	}
   125  }
   126  
   127  func BenchmarkTruncIndexAdd250(b *testing.B) {
   128  	var testSet []string
   129  	for i := 0; i < 250; i++ {
   130  		testSet = append(testSet, stringid.GenerateRandomID())
   131  	}
   132  	b.ResetTimer()
   133  	for i := 0; i < b.N; i++ {
   134  		index := NewTruncIndex([]string{})
   135  		for _, id := range testSet {
   136  			if err := index.Add(id); err != nil {
   137  				b.Fatal(err)
   138  			}
   139  		}
   140  	}
   141  }
   142  
   143  func BenchmarkTruncIndexAdd500(b *testing.B) {
   144  	var testSet []string
   145  	for i := 0; i < 500; i++ {
   146  		testSet = append(testSet, stringid.GenerateRandomID())
   147  	}
   148  	b.ResetTimer()
   149  	for i := 0; i < b.N; i++ {
   150  		index := NewTruncIndex([]string{})
   151  		for _, id := range testSet {
   152  			if err := index.Add(id); err != nil {
   153  				b.Fatal(err)
   154  			}
   155  		}
   156  	}
   157  }
   158  
   159  func BenchmarkTruncIndexGet100(b *testing.B) {
   160  	var testSet []string
   161  	var testKeys []string
   162  	for i := 0; i < 100; i++ {
   163  		testSet = append(testSet, stringid.GenerateRandomID())
   164  	}
   165  	index := NewTruncIndex([]string{})
   166  	for _, id := range testSet {
   167  		if err := index.Add(id); err != nil {
   168  			b.Fatal(err)
   169  		}
   170  		l := rand.Intn(12) + 12
   171  		testKeys = append(testKeys, id[:l])
   172  	}
   173  	b.ResetTimer()
   174  	for i := 0; i < b.N; i++ {
   175  		for _, id := range testKeys {
   176  			if res, err := index.Get(id); err != nil {
   177  				b.Fatal(res, err)
   178  			}
   179  		}
   180  	}
   181  }
   182  
   183  func BenchmarkTruncIndexGet250(b *testing.B) {
   184  	var testSet []string
   185  	var testKeys []string
   186  	for i := 0; i < 250; i++ {
   187  		testSet = append(testSet, stringid.GenerateRandomID())
   188  	}
   189  	index := NewTruncIndex([]string{})
   190  	for _, id := range testSet {
   191  		if err := index.Add(id); err != nil {
   192  			b.Fatal(err)
   193  		}
   194  		l := rand.Intn(12) + 12
   195  		testKeys = append(testKeys, id[:l])
   196  	}
   197  	b.ResetTimer()
   198  	for i := 0; i < b.N; i++ {
   199  		for _, id := range testKeys {
   200  			if res, err := index.Get(id); err != nil {
   201  				b.Fatal(res, err)
   202  			}
   203  		}
   204  	}
   205  }
   206  
   207  func BenchmarkTruncIndexGet500(b *testing.B) {
   208  	var testSet []string
   209  	var testKeys []string
   210  	for i := 0; i < 500; i++ {
   211  		testSet = append(testSet, stringid.GenerateRandomID())
   212  	}
   213  	index := NewTruncIndex([]string{})
   214  	for _, id := range testSet {
   215  		if err := index.Add(id); err != nil {
   216  			b.Fatal(err)
   217  		}
   218  		l := rand.Intn(12) + 12
   219  		testKeys = append(testKeys, id[:l])
   220  	}
   221  	b.ResetTimer()
   222  	for i := 0; i < b.N; i++ {
   223  		for _, id := range testKeys {
   224  			if res, err := index.Get(id); err != nil {
   225  				b.Fatal(res, err)
   226  			}
   227  		}
   228  	}
   229  }
   230  
   231  func BenchmarkTruncIndexDelete100(b *testing.B) {
   232  	var testSet []string
   233  	for i := 0; i < 100; i++ {
   234  		testSet = append(testSet, stringid.GenerateRandomID())
   235  	}
   236  	b.ResetTimer()
   237  	for i := 0; i < b.N; i++ {
   238  		b.StopTimer()
   239  		index := NewTruncIndex([]string{})
   240  		for _, id := range testSet {
   241  			if err := index.Add(id); err != nil {
   242  				b.Fatal(err)
   243  			}
   244  		}
   245  		b.StartTimer()
   246  		for _, id := range testSet {
   247  			if err := index.Delete(id); err != nil {
   248  				b.Fatal(err)
   249  			}
   250  		}
   251  	}
   252  }
   253  
   254  func BenchmarkTruncIndexDelete250(b *testing.B) {
   255  	var testSet []string
   256  	for i := 0; i < 250; i++ {
   257  		testSet = append(testSet, stringid.GenerateRandomID())
   258  	}
   259  	b.ResetTimer()
   260  	for i := 0; i < b.N; i++ {
   261  		b.StopTimer()
   262  		index := NewTruncIndex([]string{})
   263  		for _, id := range testSet {
   264  			if err := index.Add(id); err != nil {
   265  				b.Fatal(err)
   266  			}
   267  		}
   268  		b.StartTimer()
   269  		for _, id := range testSet {
   270  			if err := index.Delete(id); err != nil {
   271  				b.Fatal(err)
   272  			}
   273  		}
   274  	}
   275  }
   276  
   277  func BenchmarkTruncIndexDelete500(b *testing.B) {
   278  	var testSet []string
   279  	for i := 0; i < 500; i++ {
   280  		testSet = append(testSet, stringid.GenerateRandomID())
   281  	}
   282  	b.ResetTimer()
   283  	for i := 0; i < b.N; i++ {
   284  		b.StopTimer()
   285  		index := NewTruncIndex([]string{})
   286  		for _, id := range testSet {
   287  			if err := index.Add(id); err != nil {
   288  				b.Fatal(err)
   289  			}
   290  		}
   291  		b.StartTimer()
   292  		for _, id := range testSet {
   293  			if err := index.Delete(id); err != nil {
   294  				b.Fatal(err)
   295  			}
   296  		}
   297  	}
   298  }
   299  
   300  func BenchmarkTruncIndexNew100(b *testing.B) {
   301  	var testSet []string
   302  	for i := 0; i < 100; i++ {
   303  		testSet = append(testSet, stringid.GenerateRandomID())
   304  	}
   305  	b.ResetTimer()
   306  	for i := 0; i < b.N; i++ {
   307  		NewTruncIndex(testSet)
   308  	}
   309  }
   310  
   311  func BenchmarkTruncIndexNew250(b *testing.B) {
   312  	var testSet []string
   313  	for i := 0; i < 250; i++ {
   314  		testSet = append(testSet, stringid.GenerateRandomID())
   315  	}
   316  	b.ResetTimer()
   317  	for i := 0; i < b.N; i++ {
   318  		NewTruncIndex(testSet)
   319  	}
   320  }
   321  
   322  func BenchmarkTruncIndexNew500(b *testing.B) {
   323  	var testSet []string
   324  	for i := 0; i < 500; i++ {
   325  		testSet = append(testSet, stringid.GenerateRandomID())
   326  	}
   327  	b.ResetTimer()
   328  	for i := 0; i < b.N; i++ {
   329  		NewTruncIndex(testSet)
   330  	}
   331  }
   332  
   333  func BenchmarkTruncIndexAddGet100(b *testing.B) {
   334  	var testSet []string
   335  	var testKeys []string
   336  	for i := 0; i < 500; i++ {
   337  		id := stringid.GenerateRandomID()
   338  		testSet = append(testSet, id)
   339  		l := rand.Intn(12) + 12
   340  		testKeys = append(testKeys, id[:l])
   341  	}
   342  	b.ResetTimer()
   343  	for i := 0; i < b.N; i++ {
   344  		index := NewTruncIndex([]string{})
   345  		for _, id := range testSet {
   346  			if err := index.Add(id); err != nil {
   347  				b.Fatal(err)
   348  			}
   349  		}
   350  		for _, id := range testKeys {
   351  			if res, err := index.Get(id); err != nil {
   352  				b.Fatal(res, err)
   353  			}
   354  		}
   355  	}
   356  }
   357  
   358  func BenchmarkTruncIndexAddGet250(b *testing.B) {
   359  	var testSet []string
   360  	var testKeys []string
   361  	for i := 0; i < 500; i++ {
   362  		id := stringid.GenerateRandomID()
   363  		testSet = append(testSet, id)
   364  		l := rand.Intn(12) + 12
   365  		testKeys = append(testKeys, id[:l])
   366  	}
   367  	b.ResetTimer()
   368  	for i := 0; i < b.N; i++ {
   369  		index := NewTruncIndex([]string{})
   370  		for _, id := range testSet {
   371  			if err := index.Add(id); err != nil {
   372  				b.Fatal(err)
   373  			}
   374  		}
   375  		for _, id := range testKeys {
   376  			if res, err := index.Get(id); err != nil {
   377  				b.Fatal(res, err)
   378  			}
   379  		}
   380  	}
   381  }
   382  
   383  func BenchmarkTruncIndexAddGet500(b *testing.B) {
   384  	var testSet []string
   385  	var testKeys []string
   386  	for i := 0; i < 500; i++ {
   387  		id := stringid.GenerateRandomID()
   388  		testSet = append(testSet, id)
   389  		l := rand.Intn(12) + 12
   390  		testKeys = append(testKeys, id[:l])
   391  	}
   392  	b.ResetTimer()
   393  	for i := 0; i < b.N; i++ {
   394  		index := NewTruncIndex([]string{})
   395  		for _, id := range testSet {
   396  			if err := index.Add(id); err != nil {
   397  				b.Fatal(err)
   398  			}
   399  		}
   400  		for _, id := range testKeys {
   401  			if res, err := index.Get(id); err != nil {
   402  				b.Fatal(res, err)
   403  			}
   404  		}
   405  	}
   406  }