package wire import ( "bytes" "fmt" "testing" ) const arch64 = uint64(^uint(0)) == ^uint64(0) // Returns true of overflow or underflow func checkIntSpill(i int64) bool { return i == (int64)((int)(i)) } // Returns true of overflow or underflow func checkUintSpill(i uint64) bool { return i == (uint64)((uint)(i)) } func TestVarint(t *testing.T) { check := func(i64 int64, s string) { i := int(i64) // Test with WriteVarint { buf := new(bytes.Buffer) n, err := new(int), new(error) WriteVarint(i, buf, n, err) bufBytes := buf.Bytes() // Read before consuming below. i_ := ReadVarint(buf, n, err) if i != i_ { fmt.Println(bufBytes) t.Fatalf("Encoded %v and got %v", i, i_) } if s != "" { if bufHex := fmt.Sprintf("%X", bufBytes); bufHex != s { t.Fatalf("Encoded %v, expected %v", bufHex, s) } } } // Test with PutVarint { buf := make([]byte, 100, 100) n1, err := PutVarint(buf, i) if err != nil { t.Errorf("Unexpected error in PutVarint %v (encoding %v)", err.Error(), i) } if s != "" { if n1 != len(s)/2 { t.Errorf("Unexpected PutVarint length %v, expected %v (encoding %v)", n1, len(s)/2, i) } if bufHex := fmt.Sprintf("%X", buf[:n1]); bufHex != s { t.Errorf("Got %v, expected %v (encoding %v)", bufHex, s, i) } } i2, n2, err := GetVarint(buf) if err != nil { t.Errorf("Unexpected error in GetVarint %v (encoding %v)", err.Error(), i) } if s != "" { if n2 != len(s)/2 { t.Errorf("Unexpected GetVarint length %v, expected %v (encoding %v)", n2, len(s)/2, i) } } else { if n1 != n2 { t.Errorf("Unmatched Put/Get lengths. %v vs %v (encoding %v)", n1, n2, i) } } if i != i2 { t.Errorf("Put/Get expected %v, got %v (encoding %v)", i, i2, i) } } } // 123457 is some prime. var i int64 for i = -(2 << 33); i < (2 << 33); i += 123457 { if !arch64 && checkIntSpill(i) { continue } check(i, "") } // Near zero check(-1, "F101") check(0, "00") check(1, "0101") // Positives check(1<<31-1, "047FFFFFFF") if arch64 { check(1<<32-1, "04FFFFFFFF") check(1<<32+0, "050100000000") check(1<<32+1, "050100000001") check(1<<53-1, "071FFFFFFFFFFFFF") } // Negatives check(-1<<31+1, "F47FFFFFFF") if arch64 { check(-1<<32+1, "F4FFFFFFFF") check(-1<<32-0, "F50100000000") check(-1<<32-1, "F50100000001") check(-1<<53+1, "F71FFFFFFFFFFFFF") } } func TestUvarint(t *testing.T) { check := func(i64 uint64, s string) { i := uint(i64) // Test with WriteUvarint { buf := new(bytes.Buffer) n, err := new(int), new(error) WriteUvarint(i, buf, n, err) bufBytes := buf.Bytes() i_ := ReadUvarint(buf, n, err) if i != i_ { fmt.Println(buf.Bytes()) t.Fatalf("Encoded %v and got %v", i, i_) } if s != "" { if bufHex := fmt.Sprintf("%X", bufBytes); bufHex != s { t.Fatalf("Encoded %v, expected %v", bufHex, s) } } } // Test with PutUvarint { buf := make([]byte, 100, 100) n1, err := PutUvarint(buf, i) if err != nil { t.Errorf("Unexpected error in PutUvarint %v (encoding %v)", err.Error(), i) } if s != "" { if n1 != len(s)/2 { t.Errorf("Unexpected PutUvarint length %v, expected %v (encoding %v)", n1, len(s)/2, i) } if bufHex := fmt.Sprintf("%X", buf[:n1]); bufHex != s { t.Errorf("Got %v, expected %v (encoding %v)", bufHex, s, i) } } i2, n2, err := GetUvarint(buf) if err != nil { t.Errorf("Unexpected error in GetUvarint %v (encoding %v)", err.Error(), i) } if s != "" { if n2 != len(s)/2 { t.Errorf("Unexpected GetUvarint length %v, expected %v (encoding %v)", n2, len(s)/2, i) } } else { if n1 != n2 { t.Errorf("Unmatched Put/Get lengths. %v vs %v (encoding %v)", n1, n2, i) } } if i != i2 { t.Errorf("Put/Get expected %v, got %v (encoding %v)", i, i2, i) } } } // 123457 is some prime. var i uint64 for i = 0; i < (2 << 33); i += 123457 { if !arch64 && checkUintSpill(i) { continue } check(i, "") } check(1, "0101") check(1<<31-1, "047FFFFFFF") check(1<<32-1, "04FFFFFFFF") if arch64 { check(1<<32-1, "04FFFFFFFF") check(1<<32+0, "050100000000") check(1<<32+1, "050100000001") check(1<<53-1, "071FFFFFFFFFFFFF") } }