From 6b512ffd30802f6a9b7c4dd2bd2b3297731c716a Mon Sep 17 00:00:00 2001 From: Jonas Duri Date: Wed, 27 Jan 2021 21:02:43 +0100 Subject: [PATCH] Write some notes and improve some parts --- cmd/main.go | 8 +++++--- pkg/timeflake/timeflake.go | 1 + test/internal/utils/utils_test.go | 16 ++++++++++++++++ test/pkg/timeflake/timeflake_test.go | 25 +++++++++++++++++++++---- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 0944fe6..4241a35 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -9,6 +9,8 @@ import ( "github.com/gioni06/go-timeflake/pkg/timeflake" ) +// There will be a cli interface soon. +// Right now this is only used for development purpose only. func main() { f := timeflake.Random() @@ -22,21 +24,21 @@ func main() { g1 := timeflake.NewValues(f.Timestamp(), nil) h := timeflake.FromValues(g) - i := timeflake.FromValues(g1) + h1 := timeflake.FromValues(g1) c.Log() f.Log() d.Log() e.Log() h.Log() - i.Log() + h1.Log() fmt.Println("===Timeflake Comparison===") fmt.Printf("c == f => %v\n", reflect.DeepEqual(c, f)) fmt.Printf("f == d => %v\n", reflect.DeepEqual(f, d)) fmt.Printf("d == e => %v\n", reflect.DeepEqual(d, e)) fmt.Printf("e == h => %v\n", reflect.DeepEqual(e, h)) - fmt.Printf("h == i => %v (expect false)\n", reflect.DeepEqual(h, i)) + fmt.Printf("h == h1 => %v (expect false)\n", reflect.DeepEqual(h, h1)) } func init() { diff --git a/pkg/timeflake/timeflake.go b/pkg/timeflake/timeflake.go index 74c4877..ccec22a 100644 --- a/pkg/timeflake/timeflake.go +++ b/pkg/timeflake/timeflake.go @@ -91,6 +91,7 @@ func MaxTimeflake() *big.Int { if errMaxTimeflake != nil { fmt.Println("binary.Write failed:", errMaxTimeflake) } + return MaxTimeflake } diff --git a/test/internal/utils/utils_test.go b/test/internal/utils/utils_test.go index 9ae5dad..2b868c7 100644 --- a/test/internal/utils/utils_test.go +++ b/test/internal/utils/utils_test.go @@ -24,6 +24,14 @@ func TestBigIntToASCII(t *testing.T) { if res2 != "059aa2a89" { t.Errorf("expected '059aa2a89' got '%s'", res2) } + + + b3 := big.NewInt(0) + res3, _ := utils.BigIntToASCII(b3, alphabets.HEX, 5) + + if res3 != "0" { + t.Errorf("expected '0' got '%s'", res3) + } } func TestASCIIToBigInt(t *testing.T) { @@ -34,6 +42,14 @@ func TestASCIIToBigInt(t *testing.T) { if a.Cmp(b) != 0 { t.Error("failed") } + + b1 := utils.ASCIIToBigInt("0", alphabets.BASE62) + + a1 := big.NewInt(0) + + if a1.Cmp(b1) != 0 { + t.Error("failed") + } } func TestFillString(t *testing.T) { diff --git a/test/pkg/timeflake/timeflake_test.go b/test/pkg/timeflake/timeflake_test.go index 8231ec0..f50c030 100644 --- a/test/pkg/timeflake/timeflake_test.go +++ b/test/pkg/timeflake/timeflake_test.go @@ -11,10 +11,6 @@ import ( "github.com/gioni06/go-timeflake/pkg/timeflake" ) -func init() { - rand.Seed(time.Now().UnixNano()) -} - func bigFromString(s string, base int) (*big.Int, error) { buf := new(bytes.Buffer) var b = big.NewInt(0) @@ -29,6 +25,8 @@ func bigFromString(s string, base int) (*big.Int, error) { return b, nil } +// Run some sanity checks that ensure the overall correctness +// of the created Timeflakes. func TestTimeflake(t *testing.T) { now := (time.Now()).Unix() for range make([]int, 1000) { @@ -40,10 +38,12 @@ func TestTimeflake(t *testing.T) { isTimeflakeGTEZero := zero.Cmp(&f.Int) <= 0 isTimeflakeLTEMaxTimeflake := max.Cmp(&f.Int) >= 0 + // 0 < Timeflake integer value (big.Int) < MaxTimeflake if !(isTimeflakeGTEZero && isTimeflakeLTEMaxTimeflake) { t.Error("timeflake out of bounds") } + // Proof that Timeflakes are not capable of time travel into the future. Great! if !(now <= f.Timestamp()) { t.Error("timeflake timestamp is greater then expected") } @@ -59,6 +59,7 @@ func TestTimeflake(t *testing.T) { isTimeflakeGTEZero = zero.Cmp(r) <= 0 isTimeflakeLTEMaxTimeflake = max.Cmp(r) >= 0 + // 0 < Timeflake random bits < MaxRandom if !(isTimeflakeGTEZero && isTimeflakeLTEMaxTimeflake) { t.Error("timeflake random part out of bounds") } @@ -72,12 +73,24 @@ func TestTimeflake(t *testing.T) { isTimeflakeGTEZero = zero.Cmp(flakeTS) <= 0 isTimeflakeLTEMaxTimeflake = max.Cmp(flakeTS) >= 0 + // We know that a Timeflake can not travel into the future. + // This makes sure, that it can not travel past the boundaries of the Unix + // timestamp. + // @Todo - Check this line before January 19, 2038 if !(isTimeflakeGTEZero && isTimeflakeLTEMaxTimeflake) { t.Error("timeflake timestamp part out of bounds") } } } +// Test the randomness of created Timeflakes. +// This is achieved by creating 1.000,000 concurrent jobs that create +// Timeflakes. The base62 values are used as keys in a hashmap. +// If a key is already present, this test will fail. +// +// Test takes about 2.5sec on a recent MacBook. Don't hesitate to +// run a billion jobs, but don't forget to get yourself a cup of coffee +// before you start! func TestRandomnessOfTimeflakes(t *testing.T) { const numJobs = 1e6 jobs := make(chan int, numJobs) @@ -110,3 +123,7 @@ func TestRandomnessOfTimeflakes(t *testing.T) { } } } + +func init() { + rand.Seed(time.Now().UnixNano()) +}