Beispiel #1
0
func testPipe2(t *testing.T, fileName string) {
	r, w := openPipe(t, fileName)

	c := 1024 * 128
	s := "Hello world!!"

	go func() {
		for i := 0; i < c; i++ {
			m := fmt.Sprintf("[%d]%s ", i, s)
			_, err := ioutils.WriteFull(w, []byte(m))
			assert.ErrorIsNil(t, err)
		}
		assert.ErrorIsNil(t, w.Close())
	}()

	time.Sleep(time.Millisecond * 100)

	buf := make([]byte, len(s)*c*2)
	n, err := ioutils.ReadFull(r, buf)
	assert.Must(t, errors.Equal(err, io.EOF))
	buf = buf[:n]
	for i := 0; i < c; i++ {
		m := fmt.Sprintf("[%d]%s ", i, s)
		assert.Must(t, len(buf) >= len(m))
		assert.Must(t, string(buf[:len(m)]) == m)
		buf = buf[len(m):]
	}
	assert.Must(t, len(buf) == 0)
	assert.ErrorIsNil(t, r.Close())
}
Beispiel #2
0
func hexStringToObject(t *testing.T, s string) interface{} {
	p, err := hex.DecodeString(strings.NewReplacer("\t", "", "\r", "", "\n", "", " ", "").Replace(s))
	assert.ErrorIsNil(t, err)
	o, err := DecodeDump(p)
	assert.ErrorIsNil(t, err)
	assert.Must(t, o != nil)
	return o
}
Beispiel #3
0
func TestWriteNil(t *testing.T) {
	r, w := Pipe()

	go func() {
		_, err := w.Write(nil)
		assert.ErrorIsNil(t, err)
		assert.ErrorIsNil(t, w.Close())
	}()

	buf := make([]byte, 4096)
	n, err := ioutils.ReadFull(r, buf)
	assert.Must(t, errors.Equal(err, io.EOF))
	assert.Must(t, n == 0)
	assert.ErrorIsNil(t, r.Close())
}
Beispiel #4
0
func TestEncodeHash(t *testing.T) {
	docheck := func(m map[string]string) {
		p, err := EncodeDump(toHash(m))
		assert.ErrorIsNil(t, err)
		o, err := DecodeDump(p)
		assert.ErrorIsNil(t, err)
		checkHash(t, o, m)
	}
	docheck(map[string]string{"": ""})
	docheck(map[string]string{"": "", "a": "", "b": "a", "c": "b", "d": "c"})
	hash := make(map[string]string)
	for i := 0; i < 65536; i++ {
		hash[strconv.Itoa(i)] = strconv.Itoa(i + 1)
	}
	docheck(hash)
}
Beispiel #5
0
func TestEncodeList(t *testing.T) {
	docheck := func(list ...string) {
		p, err := EncodeDump(toList(list...))
		assert.ErrorIsNil(t, err)
		o, err := DecodeDump(p)
		assert.ErrorIsNil(t, err)
		checkList(t, o, list)
	}
	docheck("")
	docheck("", "a", "b", "c", "d", "e")
	list := []string{}
	for i := 0; i < 65536; i++ {
		list = append(list, strconv.Itoa(i))
	}
	docheck(list...)
}
Beispiel #6
0
func TestEncodeSet(t *testing.T) {
	docheck := func(set ...string) {
		p, err := EncodeDump(toSet(set...))
		assert.ErrorIsNil(t, err)
		o, err := DecodeDump(p)
		assert.ErrorIsNil(t, err)
		checkSet(t, o, set)
	}
	docheck("")
	docheck("", "a", "b", "c")
	set := []string{}
	for i := 0; i < 65536; i++ {
		set = append(set, strconv.Itoa(i))
	}
	docheck(set...)
}
Beispiel #7
0
func getobj(t *testing.T, entries map[string]*BinEntry, key string) (*BinEntry, interface{}) {
	e := entries[key]
	assert.Must(t, e != nil)
	o, err := DecodeDump(e.Value)
	assert.ErrorIsNil(t, err)
	return e, o
}
Beispiel #8
0
func testPipe1(t *testing.T, fileName string) {
	r, w := openPipe(t, fileName)

	s := "Hello world!!"

	go func(data []byte) {
		_, err := ioutils.WriteFull(w, data)
		assert.ErrorIsNil(t, err)
		assert.ErrorIsNil(t, w.Close())
	}([]byte(s))

	buf := make([]byte, 64)
	n, err := ioutils.ReadFull(r, buf)
	assert.Must(t, errors.Equal(err, io.EOF))
	assert.Must(t, n == len(s))
	assert.Must(t, string(buf[:n]) == s)
	assert.ErrorIsNil(t, r.Close())
}
Beispiel #9
0
func TestEncodeString(t *testing.T) {
	docheck := func(text string) {
		p, err := EncodeDump(toString(text))
		assert.ErrorIsNil(t, err)
		o, err := DecodeDump(p)
		assert.ErrorIsNil(t, err)
		checkString(t, o, text)
	}
	docheck("hello world!!")
	docheck("2147483648")
	docheck("4294967296")
	docheck("")
	var b bytes.Buffer
	for i := 0; i < 1024; i++ {
		b.Write([]byte("01"))
	}
	docheck(b.String())
}
Beispiel #10
0
func testPipe3(t *testing.T, fileName string) {
	r, w := openPipe(t, fileName)

	c := make(chan int)

	size := 4096

	go func() {
		buf := make([]byte, size)
		for {
			n, err := r.Read(buf)
			if errors.Equal(err, io.EOF) {
				break
			}
			assert.ErrorIsNil(t, err)
			c <- n
		}
		assert.ErrorIsNil(t, r.Close())
		c <- 0
	}()

	go func() {
		buf := make([]byte, size)
		for i := 1; i < size; i++ {
			n, err := ioutils.WriteFull(w, buf[:i])
			assert.ErrorIsNil(t, err)
			assert.Must(t, n == i)
		}
		assert.ErrorIsNil(t, w.Close())
	}()

	sum := 0
	for i := 1; i < size; i++ {
		sum += i
	}
	for {
		n := <-c
		if n == 0 {
			break
		}
		sum -= n
	}
	assert.Must(t, sum == 0)
}
Beispiel #11
0
func TestEncodeZSet(t *testing.T) {
	docheck := func(m map[string]float64) {
		p, err := EncodeDump(toZSet(m))
		assert.ErrorIsNil(t, err)
		o, err := DecodeDump(p)
		assert.ErrorIsNil(t, err)
		checkZSet(t, o, m)
	}
	docheck(map[string]float64{"": 0})
	zset := make(map[string]float64)
	for i := -65535; i < 65536; i++ {
		zset[strconv.Itoa(i)] = float64(i)
	}
	docheck(zset)
	zset["inf"] = math.Inf(1)
	zset["-inf"] = math.Inf(-1)
	zset["nan"] = math.NaN()
	docheck(zset)
}
Beispiel #12
0
func delayClose(t *testing.T, closer Closer, c chan int, u pipeTest) {
	time.Sleep(time.Millisecond * 100)
	var err error
	if u.witherr {
		err = closer.CloseWithError(u.err)
	} else {
		err = closer.Close()
	}
	assert.ErrorIsNil(t, err)
	c <- 0
}
Beispiel #13
0
func openPipe(t *testing.T, fileName string) (Reader, Writer) {
	buffSize := bytesize.KB * 8
	fileSize := bytesize.MB * 32
	if fileName == "" {
		return PipeSize(buffSize)
	} else {
		f, err := OpenFile(fileName, false)
		assert.ErrorIsNil(t, err)
		return PipeFile(buffSize, fileSize, f)
	}
}
Beispiel #14
0
func TestPipeReadClose2(t *testing.T) {
	r, w := Pipe()
	c := make(chan int, 1)

	go delayClose(t, r, c, pipeTest{})

	n, err := r.Read(make([]byte, 64))
	<-c

	assert.Must(t, errors.Equal(err, io.ErrClosedPipe))
	assert.Must(t, n == 0)
	assert.ErrorIsNil(t, w.Close())
}
Beispiel #15
0
func DecodeHexRdb(t *testing.T, s string, n int) map[string]*BinEntry {
	p, err := hex.DecodeString(strings.NewReplacer("\t", "", "\r", "", "\n", "", " ", "").Replace(s))
	assert.ErrorIsNil(t, err)
	r := bytes.NewReader(p)
	l := NewLoader(r)
	assert.ErrorIsNil(t, l.Header())
	entries := make(map[string]*BinEntry)
	var i int = 0
	for {
		e, err := l.NextBinEntry()
		assert.ErrorIsNil(t, err)
		if e == nil {
			break
		}
		assert.Must(t, e.DB == 0)
		entries[string(e.Key)] = e
		i++
	}
	assert.ErrorIsNil(t, l.Footer())
	assert.Must(t, r.Len() == 0)
	assert.Must(t, len(entries) == i && i == n)
	return entries
}
Beispiel #16
0
func TestDecodeBulkBytes(t *testing.T) {
	test := "*2\r\n$4\r\nLLEN\r\n$6\r\nmylist\r\n"
	resp, err := DecodeFromBytes([]byte(test))
	assert.ErrorIsNil(t, err)
	x, ok := resp.(*Array)
	assert.Must(t, ok)
	assert.Must(t, len(x.Value) == 2)
	s1, ok := x.Value[0].(*BulkBytes)
	assert.Must(t, ok)
	assert.Must(t, bytes.Equal(s1.Value, []byte("LLEN")))
	s2, ok := x.Value[1].(*BulkBytes)
	assert.Must(t, ok)
	assert.Must(t, bytes.Equal(s2.Value, []byte("mylist")))
}
Beispiel #17
0
func TestWriteAfterWriterClose(t *testing.T) {
	r, w := Pipe()

	s := "hello"

	errs := make(chan error)

	go func() {
		_, err := ioutils.WriteFull(w, []byte(s))
		assert.ErrorIsNil(t, err)
		assert.ErrorIsNil(t, w.Close())
		_, err = w.Write([]byte("world"))
		errs <- err
	}()

	buf := make([]byte, 4096)
	n, err := ioutils.ReadFull(r, buf)
	assert.Must(t, errors.Equal(err, io.EOF))
	assert.Must(t, string(buf[:n]) == s)

	err = <-errs
	assert.Must(t, errors.Equal(err, io.ErrClosedPipe))
	assert.ErrorIsNil(t, r.Close())
}
Beispiel #18
0
func TestDecodeRequest(t *testing.T) {
	test := []string{
		"PING\r\n",
		"ECHO   abc\r\n",
		"*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",
		"\n",
	}
	for _, s := range test {
		_, err := DecodeRequestFromBytes([]byte(s))
		assert.ErrorIsNil(t, err)
	}

	invalidTest := []string{
		"+OK\r\n",
	}
	for _, s := range invalidTest {
		_, err := DecodeRequestFromBytes([]byte(s))
		assert.Must(t, err != nil)
	}
}
Beispiel #19
0
func TestDecoder(t *testing.T) {
	test := []string{
		"$6\r\nfoobar\r\n",
		"$0\r\n\r\n",
		"$-1\r\n",
		"*0\r\n",
		"*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",
		"*3\r\n:1\r\n:2\r\n:3\r\n",
		"*-1\r\n",
		"+OK\r\n",
		"-Error message\r\n",
		"*2\r\n$1\r\n0\r\n*0\r\n",
		"*3\r\n$4\r\nEVAL\r\n$31\r\nreturn {1,2,{3,'Hello World!'}}\r\n$1\r\n0\r\n",
		"\n",
	}
	for _, s := range test {
		_, err := DecodeFromBytes([]byte(s))
		assert.ErrorIsNil(t, err)
	}
}
Beispiel #20
0
func TestPipeWriteClose(t *testing.T) {
	for _, u := range pipeTests {
		r, w := Pipe()
		c := make(chan int, 1)

		if u.async {
			go delayClose(t, r, c, u)
		} else {
			delayClose(t, r, c, u)
		}
		<-c

		n, err := ioutils.WriteFull(w, []byte("hello, world"))
		expect := u.err
		if expect == nil {
			expect = io.ErrClosedPipe
		}
		assert.Must(t, errors.Equal(err, expect))
		assert.Must(t, n == 0)
		assert.ErrorIsNil(t, w.Close())
	}
}
Beispiel #21
0
func TestPipeReadClose(t *testing.T) {
	for _, u := range pipeTests {
		r, w := Pipe()
		c := make(chan int, 1)

		if u.async {
			go delayClose(t, w, c, u)
		} else {
			delayClose(t, w, c, u)
		}

		buf := make([]byte, 64)
		n, err := r.Read(buf)
		<-c

		expect := u.err
		if expect == nil {
			expect = io.EOF
		}
		assert.Must(t, errors.Equal(err, expect))
		assert.Must(t, n == 0)
		assert.ErrorIsNil(t, r.Close())
	}
}
Beispiel #22
0
func testPipe4(t *testing.T, fileName string) {
	r, w := openPipe(t, fileName)

	key := []byte("spinlock aes-128")

	block := aes.BlockSize
	count := 1024 * 1024 * 128 / block

	go func() {
		buf := make([]byte, count*block)
		m, err := aes.NewCipher(key)
		assert.ErrorIsNil(t, err)
		for i := 0; i < len(buf); i++ {
			buf[i] = byte(i)
		}

		e := cipher.NewCBCEncrypter(m, make([]byte, block))
		e.CryptBlocks(buf, buf)

		n, err := ioutils.WriteFull(w, buf)
		assert.ErrorIsNil(t, err)
		assert.ErrorIsNil(t, w.Close())
		assert.Must(t, n == len(buf))
	}()

	buf := make([]byte, count*block)
	m, err := aes.NewCipher(key)
	assert.ErrorIsNil(t, err)

	_, err = ioutils.ReadFull(r, buf)
	assert.ErrorIsNil(t, err)

	e := cipher.NewCBCDecrypter(m, make([]byte, block))
	e.CryptBlocks(buf, buf)

	for i := 0; i < len(buf); i++ {
		assert.Must(t, buf[i] == byte(i))
	}
	_, err = ioutils.ReadFull(r, buf)
	assert.Must(t, errors.Equal(err, io.EOF))
	assert.ErrorIsNil(t, r.Close())
}
Beispiel #23
0
func TestEncodeRdb(t *testing.T) {
	objs := make([]struct {
		db       uint32
		expireat uint64
		key      []byte
		obj      interface{}
		typ      string
	}, 128)
	var b bytes.Buffer
	enc := NewEncoder(&b)
	assert.ErrorIsNil(t, enc.EncodeHeader())
	for i := 0; i < len(objs); i++ {
		db := uint32(i + 32)
		expireat := uint64(i)
		key := []byte(strconv.Itoa(i))
		var obj interface{}
		var typ string
		switch i % 5 {
		case 0:
			s := strconv.Itoa(i)
			obj = s
			typ = "string"
			assert.ErrorIsNil(t, enc.EncodeObject(db, key, expireat, toString(s)))
		case 1:
			list := []string{}
			for j := 0; j < 32; j++ {
				list = append(list, fmt.Sprintf("l%d_%d", i, rand.Int()))
			}
			obj = list
			typ = "list"
			assert.ErrorIsNil(t, enc.EncodeObject(db, key, expireat, toList(list...)))
		case 2:
			hash := make(map[string]string)
			for j := 0; j < 32; j++ {
				hash[strconv.Itoa(j)] = fmt.Sprintf("h%d_%d", i, rand.Int())
			}
			obj = hash
			typ = "hash"
			assert.ErrorIsNil(t, enc.EncodeObject(db, key, expireat, toHash(hash)))
		case 3:
			zset := make(map[string]float64)
			for j := 0; j < 32; j++ {
				zset[strconv.Itoa(j)] = rand.Float64()
			}
			obj = zset
			typ = "zset"
			assert.ErrorIsNil(t, enc.EncodeObject(db, key, expireat, toZSet(zset)))
		case 4:
			set := []string{}
			for j := 0; j < 32; j++ {
				set = append(set, fmt.Sprintf("s%d_%d", i, rand.Int()))
			}
			obj = set
			typ = "set"
			assert.ErrorIsNil(t, enc.EncodeObject(db, key, expireat, toSet(set...)))
		}
		objs[i].db = db
		objs[i].expireat = expireat
		objs[i].key = key
		objs[i].obj = obj
		objs[i].typ = typ
	}
	assert.ErrorIsNil(t, enc.EncodeFooter())
	rdb := b.Bytes()
	var c atomic2.Int64
	l := NewLoader(ioutils.NewCountReader(bytes.NewReader(rdb), &c))
	assert.ErrorIsNil(t, l.Header())
	var i int = 0
	for {
		e, err := l.NextBinEntry()
		assert.ErrorIsNil(t, err)
		if e == nil {
			break
		}
		assert.Must(t, objs[i].db == e.DB)
		assert.Must(t, objs[i].expireat == e.ExpireAt)
		assert.Must(t, bytes.Equal(objs[i].key, e.Key))
		o, err := DecodeDump(e.Value)
		assert.ErrorIsNil(t, err)
		switch objs[i].typ {
		case "string":
			checkString(t, o, objs[i].obj.(string))
		case "list":
			checkList(t, o, objs[i].obj.([]string))
		case "hash":
			checkHash(t, o, objs[i].obj.(map[string]string))
		case "zset":
			checkZSet(t, o, objs[i].obj.(map[string]float64))
		case "set":
			checkSet(t, o, objs[i].obj.([]string))
		}
		i++
	}
	assert.Must(t, i == len(objs))
	assert.ErrorIsNil(t, l.Footer())
	assert.Must(t, c.Get() == int64(len(rdb)))
}
Beispiel #24
0
func testEncodeAndCheck(t *testing.T, resp Resp, expect []byte) {
	b, err := EncodeToBytes(resp)
	assert.ErrorIsNil(t, err)
	assert.Must(t, bytes.Equal(b, expect))
}