mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-15 10:40:41 -07:00
217 lines
6.1 KiB
Go
217 lines
6.1 KiB
Go
// Copyright 2019 The NATS Authors
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package server
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestMemStoreBasics(t *testing.T) {
|
|
ms, err := newMemStore(&MsgSetConfig{Storage: MemoryStorage})
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error creating store: %v", err)
|
|
}
|
|
subj, msg := "foo", []byte("Hello World")
|
|
if seq, err := ms.StoreMsg(subj, msg); err != nil {
|
|
t.Fatalf("Error storing msg: %v", err)
|
|
} else if seq != 1 {
|
|
t.Fatalf("Expected sequence to be 1, got %d", seq)
|
|
}
|
|
stats := ms.Stats()
|
|
if stats.Msgs != 1 {
|
|
t.Fatalf("Expected 1 msg, got %d", stats.Msgs)
|
|
}
|
|
expectedSize := memStoreMsgSize(subj, msg)
|
|
if stats.Bytes != expectedSize {
|
|
t.Fatalf("Expected %d bytes, got %d", expectedSize, stats.Bytes)
|
|
}
|
|
nsubj, nmsg, _, err := ms.LoadMsg(1)
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error looking up msg: %v", err)
|
|
}
|
|
if nsubj != subj {
|
|
t.Fatalf("Subjects don't match, original %q vs %q", subj, nsubj)
|
|
}
|
|
if !bytes.Equal(nmsg, msg) {
|
|
t.Fatalf("Msgs don't match, original %q vs %q", msg, nmsg)
|
|
}
|
|
}
|
|
|
|
func TestMemStoreMsgLimit(t *testing.T) {
|
|
ms, err := newMemStore(&MsgSetConfig{Storage: MemoryStorage, MaxMsgs: 10})
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error creating store: %v", err)
|
|
}
|
|
subj, msg := "foo", []byte("Hello World")
|
|
for i := 0; i < 10; i++ {
|
|
ms.StoreMsg(subj, msg)
|
|
}
|
|
stats := ms.Stats()
|
|
if stats.Msgs != 10 {
|
|
t.Fatalf("Expected %d msgs, got %d", 10, stats.Msgs)
|
|
}
|
|
if _, err := ms.StoreMsg(subj, msg); err != nil {
|
|
t.Fatalf("Error storing msg: %v", err)
|
|
}
|
|
stats = ms.Stats()
|
|
if stats.Msgs != 10 {
|
|
t.Fatalf("Expected %d msgs, got %d", 10, stats.Msgs)
|
|
}
|
|
if stats.LastSeq != 11 {
|
|
t.Fatalf("Expected the last sequence to be 11 now, but got %d", stats.LastSeq)
|
|
}
|
|
if stats.FirstSeq != 2 {
|
|
t.Fatalf("Expected the first sequence to be 2 now, but got %d", stats.FirstSeq)
|
|
}
|
|
// Make sure we can not lookup seq 1.
|
|
if _, _, _, err := ms.LoadMsg(1); err == nil {
|
|
t.Fatalf("Expected error looking up seq 1 but got none")
|
|
}
|
|
}
|
|
|
|
func TestMemStoreBytesLimit(t *testing.T) {
|
|
subj, msg := "foo", make([]byte, 512)
|
|
storedMsgSize := memStoreMsgSize(subj, msg)
|
|
|
|
toStore := uint64(1024)
|
|
maxBytes := storedMsgSize * toStore
|
|
|
|
ms, err := newMemStore(&MsgSetConfig{Storage: MemoryStorage, MaxBytes: int64(maxBytes)})
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error creating store: %v", err)
|
|
}
|
|
|
|
for i := uint64(0); i < toStore; i++ {
|
|
ms.StoreMsg(subj, msg)
|
|
}
|
|
stats := ms.Stats()
|
|
if stats.Msgs != toStore {
|
|
t.Fatalf("Expected %d msgs, got %d", toStore, stats.Msgs)
|
|
}
|
|
if stats.Bytes != storedMsgSize*toStore {
|
|
t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, stats.Bytes)
|
|
}
|
|
|
|
// Now send 10 more and check that bytes limit enforced.
|
|
for i := 0; i < 10; i++ {
|
|
if _, err := ms.StoreMsg(subj, msg); err != nil {
|
|
t.Fatalf("Error storing msg: %v", err)
|
|
}
|
|
}
|
|
stats = ms.Stats()
|
|
if stats.Msgs != toStore {
|
|
t.Fatalf("Expected %d msgs, got %d", toStore, stats.Msgs)
|
|
}
|
|
if stats.Bytes != storedMsgSize*toStore {
|
|
t.Fatalf("Expected bytes to be %d, got %d", storedMsgSize*toStore, stats.Bytes)
|
|
}
|
|
if stats.FirstSeq != 11 {
|
|
t.Fatalf("Expected first sequence to be 11, got %d", stats.FirstSeq)
|
|
}
|
|
if stats.LastSeq != toStore+10 {
|
|
t.Fatalf("Expected last sequence to be %d, got %d", toStore+10, stats.LastSeq)
|
|
}
|
|
}
|
|
|
|
func TestMemStoreAgeLimit(t *testing.T) {
|
|
maxAge := 10 * time.Millisecond
|
|
ms, err := newMemStore(&MsgSetConfig{Storage: MemoryStorage, MaxAge: maxAge})
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error creating store: %v", err)
|
|
}
|
|
// Store some messages. Does not really matter how many.
|
|
subj, msg := "foo", []byte("Hello World")
|
|
toStore := 100
|
|
for i := 0; i < toStore; i++ {
|
|
ms.StoreMsg(subj, msg)
|
|
}
|
|
stats := ms.Stats()
|
|
if stats.Msgs != uint64(toStore) {
|
|
t.Fatalf("Expected %d msgs, got %d", toStore, stats.Msgs)
|
|
}
|
|
checkExpired := func(t *testing.T) {
|
|
t.Helper()
|
|
checkFor(t, time.Second, maxAge, func() error {
|
|
stats = ms.Stats()
|
|
if stats.Msgs != 0 {
|
|
return fmt.Errorf("Expected no msgs, got %d", stats.Msgs)
|
|
}
|
|
if stats.Bytes != 0 {
|
|
return fmt.Errorf("Expected no bytes, got %d", stats.Bytes)
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
// Let them expire
|
|
checkExpired(t)
|
|
// Now add some more and make sure that timer will fire again.
|
|
for i := 0; i < toStore; i++ {
|
|
ms.StoreMsg(subj, msg)
|
|
}
|
|
stats = ms.Stats()
|
|
if stats.Msgs != uint64(toStore) {
|
|
t.Fatalf("Expected %d msgs, got %d", toStore, stats.Msgs)
|
|
}
|
|
checkExpired(t)
|
|
}
|
|
|
|
func TestMemStoreTimeStamps(t *testing.T) {
|
|
ms, err := newMemStore(&MsgSetConfig{Storage: MemoryStorage})
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error creating store: %v", err)
|
|
}
|
|
last := time.Now().UnixNano()
|
|
subj, msg := "foo", []byte("Hello World")
|
|
for i := 0; i < 10; i++ {
|
|
time.Sleep(5 * time.Microsecond)
|
|
ms.StoreMsg(subj, msg)
|
|
}
|
|
for seq := uint64(1); seq <= 10; seq++ {
|
|
_, _, ts, err := ms.LoadMsg(seq)
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error looking up msg: %v", err)
|
|
}
|
|
// These should be different
|
|
if ts <= last {
|
|
t.Fatalf("Expected different timestamps, got %v", ts)
|
|
}
|
|
last = ts
|
|
}
|
|
}
|
|
|
|
func TestMemStoreEraseMsg(t *testing.T) {
|
|
ms, err := newMemStore(&MsgSetConfig{Storage: MemoryStorage})
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error creating store: %v", err)
|
|
}
|
|
subj, msg := "foo", []byte("Hello World")
|
|
ms.StoreMsg(subj, msg)
|
|
_, smsg, _, err := ms.LoadMsg(1)
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error looking up msg: %v", err)
|
|
}
|
|
if !bytes.Equal(msg, smsg) {
|
|
t.Fatalf("Expected same msg, got %q vs %q", smsg, msg)
|
|
}
|
|
if !ms.EraseMsg(1) {
|
|
t.Fatalf("Expected erase msg to return success")
|
|
}
|
|
if bytes.Equal(msg, smsg) {
|
|
t.Fatalf("Expected msg to be erased")
|
|
}
|
|
}
|