github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/feed/lookup/lookup_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:44</date>
    10  //</624450119214829568>
    11  
    12  
    13  package lookup_test
    14  
    15  import (
    16  	"fmt"
    17  	"math/rand"
    18  	"testing"
    19  
    20  	"github.com/ethereum/go-ethereum/swarm/log"
    21  	"github.com/ethereum/go-ethereum/swarm/storage/feed/lookup"
    22  )
    23  
    24  type Data struct {
    25  	Payload uint64
    26  	Time    uint64
    27  }
    28  
    29  type Store map[lookup.EpochID]*Data
    30  
    31  func write(store Store, epoch lookup.Epoch, value *Data) {
    32  	log.Debug("Write: %d-%d, value='%d'\n", epoch.Base(), epoch.Level, value.Payload)
    33  	store[epoch.ID()] = value
    34  }
    35  
    36  func update(store Store, last lookup.Epoch, now uint64, value *Data) lookup.Epoch {
    37  	epoch := lookup.GetNextEpoch(last, now)
    38  
    39  	write(store, epoch, value)
    40  
    41  	return epoch
    42  }
    43  
    44  const Day = 60 * 60 * 24
    45  const Year = Day * 365
    46  const Month = Day * 30
    47  
    48  func makeReadFunc(store Store, counter *int) lookup.ReadFunc {
    49  	return func(epoch lookup.Epoch, now uint64) (interface{}, error) {
    50  		*counter++
    51  		data := store[epoch.ID()]
    52  		var valueStr string
    53  		if data != nil {
    54  			valueStr = fmt.Sprintf("%d", data.Payload)
    55  		}
    56  		log.Debug("Read: %d-%d, value='%s'\n", epoch.Base(), epoch.Level, valueStr)
    57  		if data != nil && data.Time <= now {
    58  			return data, nil
    59  		}
    60  		return nil, nil
    61  	}
    62  }
    63  
    64  func TestLookup(t *testing.T) {
    65  
    66  	store := make(Store)
    67  	readCount := 0
    68  	readFunc := makeReadFunc(store, &readCount)
    69  
    70  //3年前12个月每月更新一次,然后沉默两年。
    71  	now := uint64(1533799046)
    72  	var epoch lookup.Epoch
    73  
    74  	var lastData *Data
    75  	for i := uint64(0); i < 12; i++ {
    76  		t := uint64(now - Year*3 + i*Month)
    77  		data := Data{
    78  Payload: t, //我们的“有效载荷”将是时间戳本身。
    79  			Time:    t,
    80  		}
    81  		epoch = update(store, epoch, t, &data)
    82  		lastData = &data
    83  	}
    84  
    85  //尝试获取最后一个值
    86  
    87  	value, err := lookup.Lookup(now, lookup.NoClue, readFunc)
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	readCountWithoutHint := readCount
    93  
    94  	if value != lastData {
    95  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", lastData, value)
    96  	}
    97  
    98  //重置下次测试的读取计数
    99  	readCount = 0
   100  //提供提示以加快查找速度。特别是,我们给出了最后一次更新的确切位置
   101  	value, err = lookup.Lookup(now, epoch, readFunc)
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  
   106  	if value != lastData {
   107  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", lastData, value)
   108  	}
   109  
   110  	if readCount > readCountWithoutHint {
   111  		t.Fatalf("Expected lookup to complete with fewer or same reads than %d since we provided a hint. Did %d reads.", readCountWithoutHint, readCount)
   112  	}
   113  
   114  //尝试获取中间值
   115  //如果我们在现在-年*3+6*月内寻找一个值,我们应该得到这个值
   116  //因为“有效载荷”是时间戳本身,所以我们可以检查它。
   117  
   118  	expectedTime := now - Year*3 + 6*Month
   119  
   120  	value, err = lookup.Lookup(expectedTime, lookup.NoClue, readFunc)
   121  	if err != nil {
   122  		t.Fatal(err)
   123  	}
   124  
   125  	data, ok := value.(*Data)
   126  
   127  	if !ok {
   128  		t.Fatal("Expected value to contain data")
   129  	}
   130  
   131  	if data.Time != expectedTime {
   132  		t.Fatalf("Expected value timestamp to be %d, got %d", data.Time, expectedTime)
   133  	}
   134  
   135  }
   136  
   137  func TestOneUpdateAt0(t *testing.T) {
   138  
   139  	store := make(Store)
   140  	readCount := 0
   141  
   142  	readFunc := makeReadFunc(store, &readCount)
   143  	now := uint64(1533903729)
   144  
   145  	var epoch lookup.Epoch
   146  	data := Data{
   147  		Payload: 79,
   148  		Time:    0,
   149  	}
   150  	update(store, epoch, 0, &data)
   151  
   152  	value, err := lookup.Lookup(now, lookup.NoClue, readFunc)
   153  	if err != nil {
   154  		t.Fatal(err)
   155  	}
   156  	if value != &data {
   157  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", data, value)
   158  	}
   159  }
   160  
   161  //测试即使给出错误提示也会找到更新
   162  func TestBadHint(t *testing.T) {
   163  
   164  	store := make(Store)
   165  	readCount := 0
   166  
   167  	readFunc := makeReadFunc(store, &readCount)
   168  	now := uint64(1533903729)
   169  
   170  	var epoch lookup.Epoch
   171  	data := Data{
   172  		Payload: 79,
   173  		Time:    0,
   174  	}
   175  
   176  //更新t=1200
   177  	update(store, epoch, 1200, &data)
   178  
   179  //想出一些邪恶的暗示
   180  	badHint := lookup.Epoch{
   181  		Level: 18,
   182  		Time:  1200000000,
   183  	}
   184  
   185  	value, err := lookup.Lookup(now, badHint, readFunc)
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  	if value != &data {
   190  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", data, value)
   191  	}
   192  }
   193  
   194  func TestLookupFail(t *testing.T) {
   195  
   196  	store := make(Store)
   197  	readCount := 0
   198  
   199  	readFunc := makeReadFunc(store, &readCount)
   200  	now := uint64(1533903729)
   201  
   202  //不要写任何东西,试着抬头看看。
   203  //我们在测试我们不会陷入循环
   204  
   205  	value, err := lookup.Lookup(now, lookup.NoClue, readFunc)
   206  	if err != nil {
   207  		t.Fatal(err)
   208  	}
   209  	if value != nil {
   210  		t.Fatal("Expected value to be nil, since the update should've failed")
   211  	}
   212  
   213  	expectedReads := now/(1<<lookup.HighestLevel) + 1
   214  	if uint64(readCount) != expectedReads {
   215  		t.Fatalf("Expected lookup to fail after %d reads. Did %d reads.", expectedReads, readCount)
   216  	}
   217  }
   218  
   219  func TestHighFreqUpdates(t *testing.T) {
   220  
   221  	store := make(Store)
   222  	readCount := 0
   223  
   224  	readFunc := makeReadFunc(store, &readCount)
   225  	now := uint64(1533903729)
   226  
   227  //在过去的1000秒内,每秒写一次更新
   228  	var epoch lookup.Epoch
   229  
   230  	var lastData *Data
   231  	for i := uint64(0); i <= 994; i++ {
   232  		T := uint64(now - 1000 + i)
   233  		data := Data{
   234  Payload: T, //我们的“有效载荷”将是时间戳本身。
   235  			Time:    T,
   236  		}
   237  		epoch = update(store, epoch, T, &data)
   238  		lastData = &data
   239  	}
   240  
   241  	value, err := lookup.Lookup(lastData.Time, lookup.NoClue, readFunc)
   242  	if err != nil {
   243  		t.Fatal(err)
   244  	}
   245  
   246  	if value != lastData {
   247  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", lastData, value)
   248  	}
   249  
   250  	readCountWithoutHint := readCount
   251  //重置下次测试的读取计数
   252  	readCount = 0
   253  //提供提示以加快查找速度。特别是,我们给出了最后一次更新的确切位置
   254  	value, err = lookup.Lookup(now, epoch, readFunc)
   255  	if err != nil {
   256  		t.Fatal(err)
   257  	}
   258  
   259  	if value != lastData {
   260  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", lastData, value)
   261  	}
   262  
   263  	if readCount > readCountWithoutHint {
   264  		t.Fatalf("Expected lookup to complete with fewer or equal reads than %d since we provided a hint. Did %d reads.", readCountWithoutHint, readCount)
   265  	}
   266  
   267  	for i := uint64(0); i <= 994; i++ {
   268  T := uint64(now - 1000 + i) //最近1000秒每秒钟更新一次
   269  		value, err := lookup.Lookup(T, lookup.NoClue, readFunc)
   270  		if err != nil {
   271  			t.Fatal(err)
   272  		}
   273  		data, _ := value.(*Data)
   274  		if data == nil {
   275  			t.Fatalf("Expected lookup to return %d, got nil", T)
   276  		}
   277  		if data.Payload != T {
   278  			t.Fatalf("Expected lookup to return %d, got %d", T, data.Time)
   279  		}
   280  	}
   281  }
   282  
   283  func TestSparseUpdates(t *testing.T) {
   284  
   285  	store := make(Store)
   286  	readCount := 0
   287  	readFunc := makeReadFunc(store, &readCount)
   288  
   289  //从1970年1月1日开始每5年写3次更新,然后沉默
   290  
   291  	now := uint64(1533799046)
   292  	var epoch lookup.Epoch
   293  
   294  	var lastData *Data
   295  	for i := uint64(0); i < 5; i++ {
   296  T := uint64(Year * 5 * i) //从1970年1月1日开始每5年写3次更新,然后沉默
   297  		data := Data{
   298  Payload: T, //我们的“有效载荷”将是时间戳本身。
   299  			Time:    T,
   300  		}
   301  		epoch = update(store, epoch, T, &data)
   302  		lastData = &data
   303  	}
   304  
   305  //尝试获取最后一个值
   306  
   307  	value, err := lookup.Lookup(now, lookup.NoClue, readFunc)
   308  	if err != nil {
   309  		t.Fatal(err)
   310  	}
   311  
   312  	readCountWithoutHint := readCount
   313  
   314  	if value != lastData {
   315  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", lastData, value)
   316  	}
   317  
   318  //重置下次测试的读取计数
   319  	readCount = 0
   320  //提供提示以加快查找速度。特别是,我们给出了最后一次更新的确切位置
   321  	value, err = lookup.Lookup(now, epoch, readFunc)
   322  	if err != nil {
   323  		t.Fatal(err)
   324  	}
   325  
   326  	if value != lastData {
   327  		t.Fatalf("Expected lookup to return the last written value: %v. Got %v", lastData, value)
   328  	}
   329  
   330  	if readCount > readCountWithoutHint {
   331  		t.Fatalf("Expected lookup to complete with fewer reads than %d since we provided a hint. Did %d reads.", readCountWithoutHint, readCount)
   332  	}
   333  
   334  }
   335  
   336  //TESTG将保存预煮的测试结果
   337  //字段被缩写为减小以下文本的大小
   338  type testG struct {
   339  e lookup.Epoch //最后的
   340  n uint64       //下一级
   341  x uint8        //预期结果
   342  }
   343  
   344  //测试用例
   345  var testGetNextLevelCases []testG = []testG{{e: lookup.Epoch{Time: 989875233, Level: 12}, n: 989875233, x: 11}, {e: lookup.Epoch{Time: 995807650, Level: 18}, n: 995598156, x: 19}, {e: lookup.Epoch{Time: 969167082, Level: 0}, n: 968990357, x: 18}, {e: lookup.Epoch{Time: 993087628, Level: 14}, n: 992987044, x: 20}, {e: lookup.Epoch{Time: 963364631, Level: 20}, n: 963364630, x: 19}, {e: lookup.Epoch{Time: 963497510, Level: 16}, n: 963370732, x: 18}, {e: lookup.Epoch{Time: 955421349, Level: 22}, n: 955421348, x: 21}, {e: lookup.Epoch{Time: 968220379, Level: 15}, n: 968220378, x: 14}, {e: lookup.Epoch{Time: 939129014, Level: 6}, n: 939128771, x: 11}, {e: lookup.Epoch{Time: 907847903, Level: 6}, n: 907791833, x: 18}, {e: lookup.Epoch{Time: 910835564, Level: 15}, n: 910835564, x: 14}, {e: lookup.Epoch{Time: 913578333, Level: 22}, n: 881808431, x: 25}, {e: lookup.Epoch{Time: 895818460, Level: 3}, n: 895818132, x: 9}, {e: lookup.Epoch{Time: 903843025, Level: 24}, n: 895609561, x: 23}, {e: lookup.Epoch{Time: 877889433, Level: 13}, n: 877877093, x: 15}, {e: lookup.Epoch{Time: 901450396, Level: 10}, n: 901450058, x: 9}, {e: lookup.Epoch{Time: 925179910, Level: 3}, n: 925168393, x: 16}, {e: lookup.Epoch{Time: 913485477, Level: 21}, n: 913485476, x: 20}, {e: lookup.Epoch{Time: 924462991, Level: 18}, n: 924462990, x: 17}, {e: lookup.Epoch{Time: 941175128, Level: 13}, n: 941175127, x: 12}, {e: lookup.Epoch{Time: 920126583, Level: 3}, n: 920100782, x: 19}, {e: lookup.Epoch{Time: 932403200, Level: 9}, n: 932279891, x: 17}, {e: lookup.Epoch{Time: 948284931, Level: 2}, n: 948284921, x: 9}, {e: lookup.Epoch{Time: 953540997, Level: 7}, n: 950547986, x: 22}, {e: lookup.Epoch{Time: 926639837, Level: 18}, n: 918608882, x: 24}, {e: lookup.Epoch{Time: 954637598, Level: 1}, n: 954578761, x: 17}, {e: lookup.Epoch{Time: 943482981, Level: 10}, n: 942924151, x: 19}, {e: lookup.Epoch{Time: 963580771, Level: 7}, n: 963580771, x: 6}, {e: lookup.Epoch{Time: 993744930, Level: 7}, n: 993690858, x: 16}, {e: lookup.Epoch{Time: 1018890213, Level: 12}, n: 1018890212, x: 11}, {e: lookup.Epoch{Time: 1030309411, Level: 2}, n: 1030309227, x: 9}, {e: lookup.Epoch{Time: 1063204997, Level: 20}, n: 1063204996, x: 19}, {e: lookup.Epoch{Time: 1094340832, Level: 6}, n: 1094340633, x: 7}, {e: lookup.Epoch{Time: 1077880597, Level: 10}, n: 1075914292, x: 20}, {e: lookup.Epoch{Time: 1051114957, Level: 18}, n: 1051114957, x: 17}, {e: lookup.Epoch{Time: 1045649701, Level: 22}, n: 1045649700, x: 21}, {e: lookup.Epoch{Time: 1066198885, Level: 14}, n: 1066198884, x: 13}, {e: lookup.Epoch{Time: 1053231952, Level: 1}, n: 1053210845, x: 16}, {e: lookup.Epoch{Time: 1068763404, Level: 14}, n: 1068675428, x: 18}, {e: lookup.Epoch{Time: 1039042173, Level: 15}, n: 1038973110, x: 17}, {e: lookup.Epoch{Time: 1050747636, Level: 6}, n: 1050747364, x: 9}, {e: lookup.Epoch{Time: 1030034434, Level: 23}, n: 1030034433, x: 22}, {e: lookup.Epoch{Time: 1003783425, Level: 18}, n: 1003783424, x: 17}, {e: lookup.Epoch{Time: 988163976, Level: 15}, n: 988084064, x: 17}, {e: lookup.Epoch{Time: 1007222377, Level: 15}, n: 1007222377, x: 14}, {e: lookup.Epoch{Time: 1001211375, Level: 13}, n: 1001208178, x: 14}, {e: lookup.Epoch{Time: 997623199, Level: 8}, n: 997623198, x: 7}, {e: lookup.Epoch{Time: 1026283830, Level: 10}, n: 1006681704, x: 24}, {e: lookup.Epoch{Time: 1019421907, Level: 20}, n: 1019421906, x: 19}, {e: lookup.Epoch{Time: 1043154306, Level: 16}, n: 1043108343, x: 16}, {e: lookup.Epoch{Time: 1075643767, Level: 17}, n: 1075325898, x: 18}, {e: lookup.Epoch{Time: 1043726309, Level: 20}, n: 1043726308, x: 19}, {e: lookup.Epoch{Time: 1056415324, Level: 17}, n: 1056415324, x: 16}, {e: lookup.Epoch{Time: 1088650219, Level: 13}, n: 1088650218, x: 12}, {e: lookup.Epoch{Time: 1088551662, Level: 7}, n: 1088543355, x: 13}, {e: lookup.Epoch{Time: 1069667265, Level: 6}, n: 1069667075, x: 7}, {e: lookup.Epoch{Time: 1079145970, Level: 18}, n: 1079145969, x: 17}, {e: lookup.Epoch{Time: 1083338876, Level: 7}, n: 1083338875, x: 6}, {e: lookup.Epoch{Time: 1051581086, Level: 4}, n: 1051568869, x: 14}, {e: lookup.Epoch{Time: 1028430882, Level: 4}, n: 1028430864, x: 5}, {e: lookup.Epoch{Time: 1057356462, Level: 1}, n: 1057356417, x: 5}, {e: lookup.Epoch{Time: 1033104266, Level: 0}, n: 1033097479, x: 13}, {e: lookup.Epoch{Time: 1031391367, Level: 11}, n: 1031387304, x: 14}, {e: lookup.Epoch{Time: 1049781164, Level: 15}, n: 1049781163, x: 14}, {e: lookup.Epoch{Time: 1027271628, Level: 12}, n: 1027271627, x: 11}, {e: lookup.Epoch{Time: 1057270560, Level: 23}, n: 1057270560, x: 22}, {e: lookup.Epoch{Time: 1047501317, Level: 15}, n: 1047501317, x: 14}, {e: lookup.Epoch{Time: 1058349035, Level: 11}, n: 1045175573, x: 24}, {e: lookup.Epoch{Time: 1057396147, Level: 20}, n: 1057396147, x: 19}, {e: lookup.Epoch{Time: 1048906375, Level: 18}, n: 1039616919, x: 25}, {e: lookup.Epoch{Time: 1074294831, Level: 20}, n: 1074294831, x: 19}, {e: lookup.Epoch{Time: 1088946052, Level: 1}, n: 1088917364, x: 14}, {e: lookup.Epoch{Time: 1112337595, Level: 17}, n: 1111008110, x: 22}, {e: lookup.Epoch{Time: 1099990284, Level: 5}, n: 1099968370, x: 15}, {e: lookup.Epoch{Time: 1087036441, Level: 16}, n: 1053967855, x: 25}, {e: lookup.Epoch{Time: 1069225185, Level: 8}, n: 1069224660, x: 10}, {e: lookup.Epoch{Time: 1057505479, Level: 9}, n: 1057505170, x: 14}, {e: lookup.Epoch{Time: 1072381377, Level: 12}, n: 1065950959, x: 22}, {e: lookup.Epoch{Time: 1093887139, Level: 8}, n: 1093863305, x: 14}, {e: lookup.Epoch{Time: 1082366510, Level: 24}, n: 1082366510, x: 23}, {e: lookup.Epoch{Time: 1103231132, Level: 14}, n: 1102292201, x: 22}, {e: lookup.Epoch{Time: 1094502355, Level: 3}, n: 1094324652, x: 18}, {e: lookup.Epoch{Time: 1068488344, Level: 12}, n: 1067577330, x: 19}, {e: lookup.Epoch{Time: 1050278233, Level: 12}, n: 1050278232, x: 11}, {e: lookup.Epoch{Time: 1047660768, Level: 5}, n: 1047652137, x: 17}, {e: lookup.Epoch{Time: 1060116167, Level: 11}, n: 1060114091, x: 12}, {e: lookup.Epoch{Time: 1068149392, Level: 21}, n: 1052074801, x: 24}, {e: lookup.Epoch{Time: 1081934120, Level: 6}, n: 1081933847, x: 8}, {e: lookup.Epoch{Time: 1107943693, Level: 16}, n: 1107096139, x: 25}, {e: lookup.Epoch{Time: 1131571649, Level: 9}, n: 1131570428, x: 11}, {e: lookup.Epoch{Time: 1123139367, Level: 0}, n: 1122912198, x: 20}, {e: lookup.Epoch{Time: 1121144423, Level: 6}, n: 1120568289, x: 20}, {e: lookup.Epoch{Time: 1089932411, Level: 17}, n: 1089932410, x: 16}, {e: lookup.Epoch{Time: 1104899012, Level: 22}, n: 1098978789, x: 22}, {e: lookup.Epoch{Time: 1094588059, Level: 21}, n: 1094588059, x: 20}, {e: lookup.Epoch{Time: 1114987438, Level: 24}, n: 1114987437, x: 23}, {e: lookup.Epoch{Time: 1084186305, Level: 7}, n: 1084186241, x: 6}, {e: lookup.Epoch{Time: 1058827111, Level: 8}, n: 1058826504, x: 9}, {e: lookup.Epoch{Time: 1090679810, Level: 12}, n: 1090616539, x: 17}, {e: lookup.Epoch{Time: 1084299475, Level: 23}, n: 1084299475, x: 22}}
   346  
   347  func TestGetNextLevel(t *testing.T) {
   348  
   349  //首先,测试知名案例
   350  	last := lookup.Epoch{
   351  		Time:  1533799046,
   352  		Level: 5,
   353  	}
   354  
   355  	level := lookup.GetNextLevel(last, last.Time)
   356  	expected := uint8(4)
   357  	if level != expected {
   358  		t.Fatalf("Expected GetNextLevel to return %d for same-time updates at a nonzero level, got %d", expected, level)
   359  	}
   360  
   361  	level = lookup.GetNextLevel(last, last.Time+(1<<lookup.HighestLevel)+3000)
   362  	expected = lookup.HighestLevel
   363  	if level != expected {
   364  		t.Fatalf("Expected GetNextLevel to return %d for updates set 2^lookup.HighestLevel seconds away, got %d", expected, level)
   365  	}
   366  
   367  	level = lookup.GetNextLevel(last, last.Time+(1<<last.Level))
   368  	expected = last.Level
   369  	if level != expected {
   370  		t.Fatalf("Expected GetNextLevel to return %d for updates set 2^last.Level seconds away, got %d", expected, level)
   371  	}
   372  
   373  	last.Level = 0
   374  	level = lookup.GetNextLevel(last, last.Time)
   375  	expected = 0
   376  	if level != expected {
   377  		t.Fatalf("Expected GetNextLevel to return %d for same-time updates at a zero level, got %d", expected, level)
   378  	}
   379  
   380  //进行一批100次煮熟试验
   381  	for _, s := range testGetNextLevelCases {
   382  		level := lookup.GetNextLevel(s.e, s.n)
   383  		if level != s.x {
   384  			t.Fatalf("Expected GetNextLevel to return %d for last=%s when now=%d, got %d", s.x, s.e.String(), s.n, level)
   385  		}
   386  	}
   387  
   388  }
   389  
   390  //CookGetNextletvelTests用于生成确定性
   391  //testGetNextLevel的一组事例,从而“冻结”其当前行为
   392  func CookGetNextLevelTests(t *testing.T) {
   393  	st := ""
   394  	var last lookup.Epoch
   395  	last.Time = 1000000000
   396  	var now uint64
   397  	var expected uint8
   398  	for i := 0; i < 100; i++ {
   399  		last.Time += uint64(rand.Intn(1<<26)) - (1 << 25)
   400  		last.Level = uint8(rand.Intn(25))
   401  		v := last.Level + uint8(rand.Intn(lookup.HighestLevel))
   402  		if v > lookup.HighestLevel {
   403  			v = 0
   404  		}
   405  		now = last.Time + uint64(rand.Intn(1<<v+1)) - (1 << v)
   406  		expected = lookup.GetNextLevel(last, now)
   407  		st = fmt.Sprintf("%s,testG{e:lookup.Epoch{Time:%d, Level:%d}, n:%d, x:%d}", st, last.Time, last.Level, now, expected)
   408  	}
   409  	fmt.Println(st)
   410  }
   411