コード例 #1
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func TestWriteAfterWriterClose(t *testing.T) {
	r, w := New()

	s := "hello"

	errs := make(chan error)

	go func() {
		n, err := w.Write([]byte(s))
		assert.MustNoError(err)
		assert.Must(n == len(s))
		assert.MustNoError(w.Close())
		_, err = w.Write([]byte("world"))
		errs <- err
	}()

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

	err = <-errs
	assert.Must(errors.Equal(err, io.ErrClosedPipe))
	assert.MustNoError(r.Close())
}
コード例 #2
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func testPipe2(t *testing.T, fileName string) {
	r, w, f := openPipe(t, fileName)
	defer f.Close()

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

	go func() {
		for i := 0; i < c; i++ {
			m := fmt.Sprintf("[%d]%s ", i, s)
			n, err := w.Write([]byte(m))
			assert.MustNoError(err)
			assert.Must(n == len(m))
		}
		assert.MustNoError(w.Close())
	}()

	time.Sleep(time.Millisecond * 10)

	buf := make([]byte, len(s)*c*2)
	n, err := io.ReadFull(r, buf)
	assert.Must(errors.Equal(err, io.EOF))
	buf = buf[:n]
	for i := 0; i < c; i++ {
		m := fmt.Sprintf("[%d]%s ", i, s)
		assert.Must(len(buf) >= len(m))
		assert.Must(string(buf[:len(m)]) == m)
		buf = buf[len(m):]
	}
	assert.Must(len(buf) == 0)
	assert.MustNoError(r.Close())
}
コード例 #3
0
ファイル: decoder_test.go プロジェクト: hushi55/Grep
func hexStringToObject(t *testing.T, s string) interface{} {
	p, err := hex.DecodeString(strings.NewReplacer("\t", "", "\r", "", "\n", "", " ", "").Replace(s))
	assert.MustNoError(err)
	o, err := DecodeDump(p)
	assert.MustNoError(err)
	assert.Must(o != nil)
	return o
}
コード例 #4
0
ファイル: server_test.go プロジェクト: TigerZhang/redis-port
func TestServerServe(t *testing.T) {
	h := &testHandler{make(map[string]int)}
	s, err := NewServer(h)
	assert.MustNoError(err)
	resp, err := Decode(bufio.NewReader(bytes.NewReader([]byte("*2\r\n$3\r\nset\r\n$3\r\nfoo\r\n"))))
	assert.MustNoError(err)
	_, err = s.Dispatch(nil, resp)
	assert.MustNoError(err)
	testmapcount(t, h.c, map[string]int{"foo": 1})
}
コード例 #5
0
ファイル: decoder_test.go プロジェクト: TigerZhang/redis-port
func TestDecodeSimpleRequest1(t *testing.T) {
	resp, err := DecodeFromBytes([]byte("\r\n"))
	assert.MustNoError(err)
	x, ok := resp.(*Array)
	assert.Must(ok)
	assert.Must(len(x.Value) == 0)
}
コード例 #6
0
ファイル: encoder_test.go プロジェクト: hushi55/Grep
func TestEncodeHash(t *testing.T) {
	docheck := func(m map[string]string) {
		p, err := EncodeDump(toHash(m))
		assert.MustNoError(err)
		o, err := DecodeDump(p)
		assert.MustNoError(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)
}
コード例 #7
0
ファイル: encoder_test.go プロジェクト: hushi55/Grep
func TestEncodeList(t *testing.T) {
	docheck := func(list ...string) {
		p, err := EncodeDump(toList(list...))
		assert.MustNoError(err)
		o, err := DecodeDump(p)
		assert.MustNoError(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...)
}
コード例 #8
0
ファイル: encoder_test.go プロジェクト: hushi55/Grep
func TestEncodeSet(t *testing.T) {
	docheck := func(set ...string) {
		p, err := EncodeDump(toSet(set...))
		assert.MustNoError(err)
		o, err := DecodeDump(p)
		assert.MustNoError(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...)
}
コード例 #9
0
ファイル: loader_test.go プロジェクト: hushi55/Grep
func getobj(t *testing.T, entries map[string]*BinEntry, key string) (*BinEntry, interface{}) {
	e := entries[key]
	assert.Must(e != nil)
	o, err := DecodeDump(e.Value)
	assert.MustNoError(err)
	return e, o
}
コード例 #10
0
ファイル: backlog_test.go プロジェクト: TigerZhang/redis-port
func testBacklog(t *testing.T, bl *Backlog, size int) {
	input := randSlice(32)

	r1, err := bl.NewReader()
	assert.MustNoError(err)

	checkWriter(bl, input)
	checkReader(r1, input)
	checkReader(r1, []byte{})

	input = randSlice(size)
	checkWriter(bl, input)
	checkReader(r1, input)
	checkWriter(bl, randSlice(size))

	assert.Must(r1.IsValid() == true)

	r2, err := bl.NewReader()
	assert.MustNoError(err)

	input = []byte{0xde, 0xad, 0xbe, 0xef}
	checkWriter(bl, input)

	assert.Must(r1.IsValid() == false)

	_, err = r1.Read([]byte{0})
	assert.Must(errors.Equal(err, ErrInvalidOffset))

	b := make([]byte, len(input))
	n, err := io.ReadFull(r2, b)
	assert.MustNoError(err)
	assert.Must(n == len(b) && bytes.Equal(b, input))

	bl.Close()

	assert.Must(r1.IsValid() == false)
	assert.Must(r2.IsValid() == false)

	_, err = r1.Read([]byte{0})
	assert.Must(errors.Equal(err, ErrClosedBacklog))

	_, err = r2.Read([]byte{0})
	assert.Must(errors.Equal(err, ErrClosedBacklog))

	_, err = bl.Write([]byte{0})
	assert.Must(errors.Equal(err, ErrClosedBacklog))
}
コード例 #11
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func testPipe3(t *testing.T, fileName string) {
	r, w, f := openPipe(t, fileName)
	defer f.Close()

	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.MustNoError(err)
			c <- n
		}
		assert.MustNoError(r.Close())
		c <- 0
	}()

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

	sum := 0
	for i := 1; i < size; i++ {
		sum += i
	}
	for {
		n := <-c
		if n == 0 {
			break
		}
		sum -= n
	}
	assert.Must(sum == 0)
}
コード例 #12
0
ファイル: encoder_test.go プロジェクト: hushi55/Grep
func TestEncodeString(t *testing.T) {
	docheck := func(text string) {
		p, err := EncodeDump(toString(text))
		assert.MustNoError(err)
		o, err := DecodeDump(p)
		assert.MustNoError(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())
}
コード例 #13
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func TestWriteNil(t *testing.T) {
	r, w := New()

	go func() {
		n, err := w.Write(nil)
		assert.MustNoError(err)
		assert.Must(n == 0)
		assert.MustNoError(w.Close())
	}()

	time.Sleep(time.Millisecond * 10)

	buf := make([]byte, 4096)
	n, err := io.ReadFull(r, buf)
	assert.Must(errors.Equal(err, io.EOF))
	assert.Must(n == 0)
	assert.MustNoError(r.Close())
}
コード例 #14
0
ファイル: encoder_test.go プロジェクト: hushi55/Grep
func TestEncodeZSet(t *testing.T) {
	docheck := func(m map[string]float64) {
		p, err := EncodeDump(toZSet(m))
		assert.MustNoError(err)
		o, err := DecodeDump(p)
		assert.MustNoError(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)
}
コード例 #15
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func delayClose(t *testing.T, closer Closer, c chan int, u pipeTest) {
	time.Sleep(time.Millisecond * 10)
	var err error
	if u.witherr {
		err = closer.CloseWithError(u.err)
	} else {
		err = closer.Close()
	}
	assert.MustNoError(err)
	c <- 0
}
コード例 #16
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func testPipe1(t *testing.T, fileName string) {
	r, w, f := openPipe(t, fileName)
	defer f.Close()

	s := "Hello world!!"

	go func(data []byte) {
		n, err := w.Write(data)
		assert.MustNoError(err)
		assert.Must(n == len(data))
		assert.MustNoError(w.Close())
	}([]byte(s))

	buf := make([]byte, 64)
	n, err := io.ReadFull(r, buf)
	assert.Must(errors.Equal(err, io.EOF))
	assert.Must(n == len(s))
	assert.Must(string(buf[:n]) == s)
	assert.MustNoError(r.Close())
}
コード例 #17
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func TestPipeReadClose2(t *testing.T) {
	r, w := New()
	c := make(chan int, 1)

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

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

	assert.Must(errors.Equal(err, io.ErrClosedPipe))
	assert.Must(n == 0)
	assert.MustNoError(w.Close())
}
コード例 #18
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func openPipe(t *testing.T, fileName string) (pr Reader, pw Writer, pf *os.File) {
	buffSize := 8192
	fileSize := 1024 * 1024 * 32
	if fileName == "" {
		pr, pw = NewSize(buffSize)
	} else {
		f, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0600)
		assert.MustNoError(err)
		pr, pw = NewFilePipe(fileSize, f)
		pf = f
	}
	return
}
コード例 #19
0
ファイル: decoder_test.go プロジェクト: TigerZhang/redis-port
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.MustNoError(err)
	x, ok := resp.(*Array)
	assert.Must(ok)
	assert.Must(len(x.Value) == 2)
	s1, ok := x.Value[0].(*BulkBytes)
	assert.Must(ok)
	assert.Must(bytes.Equal(s1.Value, []byte("LLEN")))
	s2, ok := x.Value[1].(*BulkBytes)
	assert.Must(ok)
	assert.Must(bytes.Equal(s2.Value, []byte("mylist")))
}
コード例 #20
0
ファイル: loader_test.go プロジェクト: hushi55/Grep
func DecodeHexRdb(t *testing.T, s string, n int) map[string]*BinEntry {
	p, err := hex.DecodeString(strings.NewReplacer("\t", "", "\r", "", "\n", "", " ", "").Replace(s))
	assert.MustNoError(err)
	r := bytes.NewReader(p)
	l := NewLoader(r)
	assert.MustNoError(l.Header())
	entries := make(map[string]*BinEntry)
	var i int = 0
	for {
		e, err := l.NextBinEntry()
		assert.MustNoError(err)
		if e == nil {
			break
		}
		assert.Must(e.DB == 0)
		entries[string(e.Key)] = e
		i++
	}
	assert.MustNoError(l.Footer())
	assert.Must(r.Len() == 0)
	assert.Must(len(entries) == i && i == n)
	return entries
}
コード例 #21
0
ファイル: server_test.go プロジェクト: TigerZhang/redis-port
func TestHandlerFunc(t *testing.T) {
	h := &testHandler{make(map[string]int)}
	s, err := NewServer(h)
	assert.MustNoError(err)
	key1, key2, key3, key4 := "key1", "key2", "key3", "key4"
	s.t["get"](nil)
	testmapcount(t, h.c, map[string]int{})
	s.t["get"](nil, []byte(key1), []byte(key2))
	testmapcount(t, h.c, map[string]int{key1: 1, key2: 1})
	s.t["get"](nil, [][]byte{[]byte(key1), []byte(key3)}...)
	testmapcount(t, h.c, map[string]int{key1: 2, key2: 1, key3: 1})
	s.t["set"](nil)
	testmapcount(t, h.c, map[string]int{key1: 2, key2: 1, key3: 1})
	s.t["set"](nil, []byte(key1), []byte(key4))
	testmapcount(t, h.c, map[string]int{key1: 3, key2: 1, key3: 1, key4: 1})
	s.t["set"](nil, [][]byte{[]byte(key1), []byte(key2), []byte(key3)}...)
	testmapcount(t, h.c, map[string]int{key1: 4, key2: 2, key3: 2, key4: 1})
}
コード例 #22
0
ファイル: decoder_test.go プロジェクト: TigerZhang/redis-port
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",
	}
	for _, s := range test {
		_, err := DecodeFromBytes([]byte(s))
		assert.MustNoError(err)
	}
}
コード例 #23
0
ファイル: decoder_test.go プロジェクト: TigerZhang/redis-port
func TestDecodeSimpleRequest2(t *testing.T) {
	test := []string{
		"hello world\r\n",
		"hello world    \r\n",
		"    hello world    \r\n",
		"    hello     world\r\n",
		"    hello     world    \r\n",
	}
	for _, s := range test {
		resp, err := DecodeFromBytes([]byte(s))
		assert.MustNoError(err)
		x, ok := resp.(*Array)
		assert.Must(ok)
		assert.Must(len(x.Value) == 2)
		s1, ok := x.Value[0].(*BulkBytes)
		assert.Must(ok && bytes.Equal(s1.Value, []byte("hello")))
		s2, ok := x.Value[1].(*BulkBytes)
		assert.Must(ok && bytes.Equal(s2.Value, []byte("world")))
	}
}
コード例 #24
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func TestPipeWriteClose(t *testing.T) {
	for _, u := range pipeTests {
		r, w := New()
		c := make(chan int, 1)

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

		n, err := w.Write([]byte("hello, world"))
		expect := u.err
		if expect == nil {
			expect = io.ErrClosedPipe
		}
		assert.Must(errors.Equal(err, expect))
		assert.Must(n == 0)
		assert.MustNoError(w.Close())
	}
}
コード例 #25
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func testPipe4(t *testing.T, fileName string) {
	r, w, f := openPipe(t, fileName)
	defer f.Close()

	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.MustNoError(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 := w.Write(buf)
		assert.MustNoError(err)
		assert.MustNoError(w.Close())
		assert.Must(n == len(buf))
	}()

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

	n, err := io.ReadFull(r, buf)
	assert.MustNoError(err)
	assert.Must(n == len(buf))

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

	for i := 0; i < len(buf); i++ {
		assert.Must(buf[i] == byte(i))
	}
	_, err = io.ReadFull(r, buf)
	assert.Must(errors.Equal(err, io.EOF))
	assert.MustNoError(r.Close())
}
コード例 #26
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func TestPipeReadClose(t *testing.T) {
	for _, u := range pipeTests {
		r, w := New()
		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(errors.Equal(err, expect))
		assert.Must(n == 0)
		assert.MustNoError(r.Close())
	}
}
コード例 #27
0
ファイル: pipe_test.go プロジェクト: TigerZhang/redis-port
func TestWriteRead(t *testing.T) {
	r, w := New()
	p := make(chan []byte, 1)

	go func() {
		var x []byte
		for {
			b := make([]byte, 23)
			n, err := r.Read(b)
			if n != 0 {
				x = append(x, b[:n]...)
			}
			if err != nil {
				p <- x
				return
			}
		}
	}()

	b := make([]byte, 1024*1024*128)
	for i := 0; i < len(b); i++ {
		b[i] = byte(i)
	}
	n, err := w.Write(b)
	assert.MustNoError(err)
	assert.Must(n == len(b))

	w.Close()

	x := <-p
	assert.Must(len(x) == len(b))
	assert.Must(bytes.Equal(b, x))

	n, err = r.Read(b)
	assert.Must(err != nil && n == 0)
}
コード例 #28
0
ファイル: encoder_test.go プロジェクト: hushi55/Grep
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.MustNoError(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.MustNoError(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.MustNoError(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.MustNoError(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.MustNoError(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.MustNoError(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.MustNoError(enc.EncodeFooter())
	rdb := b.Bytes()
	var c atomic2.Int64
	l := NewLoader(stats.NewCountReader(bytes.NewReader(rdb), &c))
	assert.MustNoError(l.Header())
	var i int = 0
	for {
		e, err := l.NextBinEntry()
		assert.MustNoError(err)
		if e == nil {
			break
		}
		assert.Must(objs[i].db == e.DB)
		assert.Must(objs[i].expireat == e.ExpireAt)
		assert.Must(bytes.Equal(objs[i].key, e.Key))
		o, err := DecodeDump(e.Value)
		assert.MustNoError(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(i == len(objs))
	assert.MustNoError(l.Footer())
	assert.Must(c.Get() == int64(len(rdb)))
}
コード例 #29
0
ファイル: encoder_test.go プロジェクト: TigerZhang/redis-port
func testEncodeAndCheck(t *testing.T, resp Resp, expect []byte) {
	b, err := EncodeToBytes(resp)
	assert.MustNoError(err)
	assert.Must(bytes.Equal(b, expect))
}
コード例 #30
0
ファイル: backlog_test.go プロジェクト: TigerZhang/redis-port
func checkReader(r io.Reader, b []byte) {
	x := make([]byte, len(b))
	n, err := io.ReadFull(r, x)
	assert.MustNoError(err)
	assert.Must(n == len(b) && bytes.Equal(x, b))
}