github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/jetstream_consumer_test.go (about)

     1  // Copyright 2022-2023 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  //go:build !skip_js_tests
    15  // +build !skip_js_tests
    16  
    17  package server
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"math/rand"
    23  	"sort"
    24  	"strconv"
    25  	"strings"
    26  	"sync"
    27  	"sync/atomic"
    28  	"testing"
    29  	"time"
    30  
    31  	"github.com/nats-io/nats.go"
    32  	"github.com/nats-io/nuid"
    33  )
    34  
    35  func TestJetStreamConsumerMultipleFiltersRemoveFilters(t *testing.T) {
    36  	s := RunBasicJetStreamServer(t)
    37  	defer s.Shutdown()
    38  
    39  	nc, js := jsClientConnect(t, s)
    40  	defer nc.Close()
    41  	acc := s.GlobalAccount()
    42  
    43  	mset, err := acc.addStream(&StreamConfig{
    44  		Name:      "TEST",
    45  		Retention: LimitsPolicy,
    46  		Subjects:  []string{"one", "two", "three"},
    47  		MaxAge:    time.Second * 90,
    48  	})
    49  	require_NoError(t, err)
    50  
    51  	_, err = mset.addConsumer(&ConsumerConfig{
    52  		Durable:        "consumer",
    53  		FilterSubjects: []string{"one", "two"},
    54  	})
    55  	require_NoError(t, err)
    56  
    57  	sendStreamMsg(t, nc, "one", "data")
    58  	sendStreamMsg(t, nc, "two", "data")
    59  	sendStreamMsg(t, nc, "three", "data")
    60  
    61  	consumer, err := js.PullSubscribe("", "consumer", nats.Bind("TEST", "consumer"))
    62  	require_NoError(t, err)
    63  
    64  	msgs, err := consumer.Fetch(1)
    65  	require_NoError(t, err)
    66  	require_True(t, len(msgs) == 1)
    67  
    68  	_, err = mset.addConsumer(&ConsumerConfig{
    69  		Durable:        "consumer",
    70  		FilterSubjects: []string{},
    71  	})
    72  	require_NoError(t, err)
    73  
    74  	msgs, err = consumer.Fetch(1)
    75  	require_NoError(t, err)
    76  	require_True(t, len(msgs) == 1)
    77  
    78  	msgs, err = consumer.Fetch(1)
    79  	require_NoError(t, err)
    80  	require_True(t, len(msgs) == 1)
    81  }
    82  
    83  func TestJetStreamConsumerMultipleFiltersRace(t *testing.T) {
    84  	s := RunBasicJetStreamServer(t)
    85  	defer s.Shutdown()
    86  
    87  	nc, js := jsClientConnect(t, s)
    88  	defer nc.Close()
    89  	acc := s.GlobalAccount()
    90  
    91  	mset, err := acc.addStream(&StreamConfig{
    92  		Name:      "TEST",
    93  		Retention: LimitsPolicy,
    94  		Subjects:  []string{"one", "two", "three", "four"},
    95  		MaxAge:    time.Second * 90,
    96  	})
    97  	require_NoError(t, err)
    98  
    99  	var seqs []uint64
   100  	var mu sync.Mutex
   101  
   102  	total := 10_000
   103  	var wg sync.WaitGroup
   104  
   105  	send := func(subj string) {
   106  		defer wg.Done()
   107  		for i := 0; i < total; i++ {
   108  			sendStreamMsg(t, nc, subj, "data")
   109  		}
   110  	}
   111  	wg.Add(4)
   112  	go send("one")
   113  	go send("two")
   114  	go send("three")
   115  	go send("four")
   116  	wg.Wait()
   117  
   118  	mset.addConsumer(&ConsumerConfig{
   119  		Durable:        "consumer",
   120  		FilterSubjects: []string{"one", "two", "three"},
   121  		AckPolicy:      AckExplicit,
   122  	})
   123  
   124  	done := make(chan struct{})
   125  	wg.Add(10)
   126  	for i := 0; i < 10; i++ {
   127  		go func(t *testing.T) {
   128  			defer wg.Done()
   129  
   130  			c, err := js.PullSubscribe(_EMPTY_, "consumer", nats.Bind("TEST", "consumer"))
   131  			require_NoError(t, err)
   132  
   133  			for {
   134  				select {
   135  				case <-done:
   136  					return
   137  				default:
   138  				}
   139  				msgs, err := c.Fetch(10, nats.MaxWait(2*time.Second))
   140  				// We don't want to stop before at expected number of messages, as we want
   141  				// to also test against getting to many messages.
   142  				// Because of that, we ignore timeout and connection closed errors.
   143  				if err != nil && err != nats.ErrTimeout && err != nats.ErrConnectionClosed {
   144  					t.Errorf("error while fetching messages: %v", err)
   145  				}
   146  
   147  				for _, msg := range msgs {
   148  					info, err := msg.Metadata()
   149  					require_NoError(t, err)
   150  					mu.Lock()
   151  					seqs = append(seqs, info.Sequence.Consumer)
   152  					mu.Unlock()
   153  					msg.Ack()
   154  				}
   155  			}
   156  		}(t)
   157  	}
   158  
   159  	checkFor(t, 30*time.Second, 100*time.Millisecond, func() error {
   160  		mu.Lock()
   161  		defer mu.Unlock()
   162  		if len(seqs) != 3*total {
   163  			return fmt.Errorf("found %d messages instead of %d", len(seqs), 3*total)
   164  		}
   165  		sort.Slice(seqs, func(i, j int) bool {
   166  			return seqs[i] < seqs[j]
   167  		})
   168  		for i := 1; i < len(seqs); i++ {
   169  			if seqs[i] != seqs[i-1]+1 {
   170  				fmt.Printf("seqs: %+v\n", seqs)
   171  				return fmt.Errorf("sequence mismatch at %v", i)
   172  			}
   173  		}
   174  		return nil
   175  	})
   176  	close(done)
   177  	wg.Wait()
   178  }
   179  
   180  func TestJetStreamConsumerMultipleConsumersSingleFilter(t *testing.T) {
   181  	s := RunBasicJetStreamServer(t)
   182  	defer s.Shutdown()
   183  
   184  	nc, js := jsClientConnect(t, s)
   185  	defer nc.Close()
   186  	acc := s.GlobalAccount()
   187  
   188  	// Setup few subjects with varying messages count.
   189  	subjects := []struct {
   190  		subject  string
   191  		messages int
   192  		wc       bool
   193  	}{
   194  		{subject: "one", messages: 5000},
   195  		{subject: "two", messages: 7500},
   196  		{subject: "three", messages: 2500},
   197  		{subject: "four", messages: 1000},
   198  		{subject: "five.>", messages: 3000, wc: true},
   199  	}
   200  
   201  	totalMsgs := 0
   202  	for _, subject := range subjects {
   203  		totalMsgs += subject.messages
   204  	}
   205  
   206  	// Setup consumers, filtering some of the messages from the stream.
   207  	consumers := []*struct {
   208  		name         string
   209  		subjects     []string
   210  		expectedMsgs int
   211  		delivered    atomic.Int32
   212  	}{
   213  		{name: "C1", subjects: []string{"one"}, expectedMsgs: 5000},
   214  		{name: "C2", subjects: []string{"two"}, expectedMsgs: 7500},
   215  		{name: "C3", subjects: []string{"one"}, expectedMsgs: 5000},
   216  		{name: "C4", subjects: []string{"one"}, expectedMsgs: 5000},
   217  	}
   218  
   219  	mset, err := acc.addStream(&StreamConfig{
   220  		Name:      "TEST",
   221  		Retention: LimitsPolicy,
   222  		Subjects:  []string{"one", "two", "three", "four", "five.>"},
   223  		MaxAge:    time.Second * 90,
   224  	})
   225  	require_NoError(t, err)
   226  
   227  	for c, consumer := range consumers {
   228  		_, err := mset.addConsumer(&ConsumerConfig{
   229  			Durable:        consumer.name,
   230  			FilterSubjects: consumer.subjects,
   231  			AckPolicy:      AckExplicit,
   232  			DeliverPolicy:  DeliverAll,
   233  			AckWait:        time.Second * 30,
   234  			DeliverSubject: nc.NewInbox(),
   235  		})
   236  		require_NoError(t, err)
   237  		go func(c int, name string) {
   238  			_, err = js.Subscribe("", func(m *nats.Msg) {
   239  				require_NoError(t, m.Ack())
   240  				require_NoError(t, err)
   241  				consumers[c].delivered.Add(1)
   242  
   243  			}, nats.Bind("TEST", name))
   244  			require_NoError(t, err)
   245  		}(c, consumer.name)
   246  	}
   247  
   248  	// Publish with random intervals, while consumers are active.
   249  	var wg sync.WaitGroup
   250  	for _, subject := range subjects {
   251  		wg.Add(subject.messages)
   252  		go func(subject string, messages int, wc bool) {
   253  			nc, js := jsClientConnect(t, s)
   254  			defer nc.Close()
   255  			time.Sleep(time.Duration(rand.Int63n(1000)+1) * time.Millisecond)
   256  			for i := 0; i < messages; i++ {
   257  				time.Sleep(time.Duration(rand.Int63n(1000)+1) * time.Microsecond)
   258  				// If subject has wildcard, add random last subject token.
   259  				pubSubject := subject
   260  				if wc {
   261  					pubSubject = fmt.Sprintf("%v.%v", subject, rand.Int63n(10))
   262  				}
   263  				_, err := js.PublishAsync(pubSubject, []byte("data"))
   264  				require_NoError(t, err)
   265  				wg.Done()
   266  			}
   267  		}(subject.subject, subject.messages, subject.wc)
   268  	}
   269  	wg.Wait()
   270  
   271  	checkFor(t, time.Second*10, time.Millisecond*500, func() error {
   272  		for _, consumer := range consumers {
   273  			info, err := js.ConsumerInfo("TEST", consumer.name)
   274  			require_NoError(t, err)
   275  			if info.Delivered.Consumer != uint64(consumer.expectedMsgs) {
   276  				return fmt.Errorf("%v:expected consumer delivered seq %v, got %v. actually delivered: %v",
   277  					consumer.name, consumer.expectedMsgs, info.Delivered.Consumer, consumer.delivered.Load())
   278  			}
   279  			if info.AckFloor.Consumer != uint64(consumer.expectedMsgs) {
   280  				return fmt.Errorf("%v: expected consumer ack floor %v, got %v", consumer.name, totalMsgs, info.AckFloor.Consumer)
   281  			}
   282  			if consumer.delivered.Load() != int32(consumer.expectedMsgs) {
   283  
   284  				return fmt.Errorf("%v: expected %v, got %v", consumer.name, consumer.expectedMsgs, consumer.delivered.Load())
   285  			}
   286  		}
   287  		return nil
   288  	})
   289  
   290  }
   291  
   292  func TestJetStreamConsumerMultipleConsumersMultipleFilters(t *testing.T) {
   293  	s := RunBasicJetStreamServer(t)
   294  	defer s.Shutdown()
   295  
   296  	nc, js := jsClientConnect(t, s)
   297  	defer nc.Close()
   298  	acc := s.GlobalAccount()
   299  
   300  	// Setup few subjects with varying messages count.
   301  	subjects := []struct {
   302  		subject  string
   303  		messages int
   304  		wc       bool
   305  	}{
   306  		{subject: "one", messages: 50},
   307  		{subject: "two", messages: 75},
   308  		{subject: "three", messages: 250},
   309  		{subject: "four", messages: 10},
   310  		{subject: "five.>", messages: 300, wc: true},
   311  	}
   312  
   313  	totalMsgs := 0
   314  	for _, subject := range subjects {
   315  		totalMsgs += subject.messages
   316  	}
   317  
   318  	// Setup consumers, filtering some of the messages from the stream.
   319  	consumers := []*struct {
   320  		name         string
   321  		subjects     []string
   322  		expectedMsgs int
   323  		delivered    atomic.Int32
   324  	}{
   325  		{name: "C1", subjects: []string{"one", "two"}, expectedMsgs: 125},
   326  		{name: "C2", subjects: []string{"two", "three"}, expectedMsgs: 325},
   327  		{name: "C3", subjects: []string{"one", "three"}, expectedMsgs: 300},
   328  		{name: "C4", subjects: []string{"one", "five.>"}, expectedMsgs: 350},
   329  	}
   330  
   331  	mset, err := acc.addStream(&StreamConfig{
   332  		Name:      "TEST",
   333  		Retention: LimitsPolicy,
   334  		Subjects:  []string{"one", "two", "three", "four", "five.>"},
   335  		MaxAge:    time.Second * 90,
   336  	})
   337  	require_NoError(t, err)
   338  
   339  	for c, consumer := range consumers {
   340  		_, err := mset.addConsumer(&ConsumerConfig{
   341  			Durable:        consumer.name,
   342  			FilterSubjects: consumer.subjects,
   343  			AckPolicy:      AckExplicit,
   344  			DeliverPolicy:  DeliverAll,
   345  			AckWait:        time.Second * 30,
   346  			DeliverSubject: nc.NewInbox(),
   347  		})
   348  		require_NoError(t, err)
   349  		go func(c int, name string) {
   350  			_, err = js.Subscribe("", func(m *nats.Msg) {
   351  				require_NoError(t, m.Ack())
   352  				require_NoError(t, err)
   353  				consumers[c].delivered.Add(1)
   354  
   355  			}, nats.Bind("TEST", name))
   356  			require_NoError(t, err)
   357  		}(c, consumer.name)
   358  	}
   359  
   360  	// Publish with random intervals, while consumers are active.
   361  	var wg sync.WaitGroup
   362  	for _, subject := range subjects {
   363  		wg.Add(subject.messages)
   364  		go func(subject string, messages int, wc bool) {
   365  			nc, js := jsClientConnect(t, s)
   366  			defer nc.Close()
   367  			time.Sleep(time.Duration(rand.Int63n(1000)+1) * time.Millisecond)
   368  			for i := 0; i < messages; i++ {
   369  				time.Sleep(time.Duration(rand.Int63n(1000)+1) * time.Microsecond)
   370  				// If subject has wildcard, add random last subject token.
   371  				pubSubject := subject
   372  				if wc {
   373  					pubSubject = fmt.Sprintf("%v.%v", subject, rand.Int63n(10))
   374  				}
   375  				ack, err := js.PublishAsync(pubSubject, []byte("data"))
   376  				require_NoError(t, err)
   377  				go func() {
   378  					ack.Ok()
   379  					wg.Done()
   380  				}()
   381  			}
   382  		}(subject.subject, subject.messages, subject.wc)
   383  	}
   384  	done := make(chan struct{})
   385  	go func() {
   386  		wg.Wait()
   387  		close(done)
   388  	}()
   389  
   390  	select {
   391  	case <-time.After(time.Second * 15):
   392  		t.Fatalf("Timed out waiting for acks")
   393  	case <-done:
   394  	}
   395  	wg.Wait()
   396  
   397  	checkFor(t, time.Second*15, time.Second*1, func() error {
   398  		for _, consumer := range consumers {
   399  			info, err := js.ConsumerInfo("TEST", consumer.name)
   400  			require_NoError(t, err)
   401  			if info.Delivered.Consumer != uint64(consumer.expectedMsgs) {
   402  				return fmt.Errorf("%v:expected consumer delivered seq %v, got %v. actually delivered: %v",
   403  					consumer.name, consumer.expectedMsgs, info.Delivered.Consumer, consumer.delivered.Load())
   404  			}
   405  			if info.AckFloor.Consumer != uint64(consumer.expectedMsgs) {
   406  				return fmt.Errorf("%v: expected consumer ack floor %v, got %v", consumer.name, totalMsgs, info.AckFloor.Consumer)
   407  			}
   408  			if consumer.delivered.Load() != int32(consumer.expectedMsgs) {
   409  
   410  				return fmt.Errorf("%v: expected %v, got %v", consumer.name, consumer.expectedMsgs, consumer.delivered.Load())
   411  			}
   412  		}
   413  		return nil
   414  	})
   415  
   416  }
   417  
   418  func TestJetStreamConsumerMultipleFiltersSequence(t *testing.T) {
   419  	s := RunBasicJetStreamServer(t)
   420  	defer s.Shutdown()
   421  
   422  	nc, js := jsClientConnect(t, s)
   423  	defer nc.Close()
   424  	acc := s.GlobalAccount()
   425  
   426  	mset, err := acc.addStream(&StreamConfig{
   427  		Name:      "TEST",
   428  		Retention: LimitsPolicy,
   429  		Subjects:  []string{"one", "two", "three", "four", "five.>"},
   430  		MaxAge:    time.Second * 90,
   431  	})
   432  	require_NoError(t, err)
   433  
   434  	_, err = mset.addConsumer(&ConsumerConfig{
   435  		Durable:        "DUR",
   436  		FilterSubjects: []string{"one", "two"},
   437  		AckPolicy:      AckExplicit,
   438  		DeliverPolicy:  DeliverAll,
   439  		AckWait:        time.Second * 30,
   440  		DeliverSubject: nc.NewInbox(),
   441  	})
   442  	require_NoError(t, err)
   443  
   444  	for i := 0; i < 20; i++ {
   445  		sendStreamMsg(t, nc, "one", fmt.Sprintf("%d", i))
   446  	}
   447  	for i := 20; i < 40; i++ {
   448  		sendStreamMsg(t, nc, "two", fmt.Sprintf("%d", i))
   449  	}
   450  	for i := 40; i < 60; i++ {
   451  		sendStreamMsg(t, nc, "one", fmt.Sprintf("%d", i))
   452  	}
   453  
   454  	sub, err := js.SubscribeSync("", nats.Bind("TEST", "DUR"))
   455  	require_NoError(t, err)
   456  
   457  	for i := 0; i < 60; i++ {
   458  		msg, err := sub.NextMsg(time.Second * 1)
   459  		require_NoError(t, err)
   460  		require_True(t, string(msg.Data) == fmt.Sprintf("%d", i))
   461  	}
   462  }
   463  
   464  func TestJetStreamConsumerActions(t *testing.T) {
   465  	s := RunBasicJetStreamServer(t)
   466  	defer s.Shutdown()
   467  
   468  	nc, _ := jsClientConnect(t, s)
   469  	defer nc.Close()
   470  	acc := s.GlobalAccount()
   471  
   472  	mset, err := acc.addStream(&StreamConfig{
   473  		Name:      "TEST",
   474  		Retention: LimitsPolicy,
   475  		Subjects:  []string{"one", "two", "three", "four", "five.>"},
   476  		MaxAge:    time.Second * 90,
   477  	})
   478  	require_NoError(t, err)
   479  
   480  	// Create Consumer. No consumers existed before, so should be fine.
   481  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   482  		Durable:        "DUR",
   483  		FilterSubjects: []string{"one", "two"},
   484  		AckPolicy:      AckExplicit,
   485  		DeliverPolicy:  DeliverAll,
   486  		AckWait:        time.Second * 30,
   487  	}, ActionCreate)
   488  	require_NoError(t, err)
   489  	// Create consumer again. Should be ok if action is CREATE but config is exactly the same.
   490  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   491  		Durable:        "DUR",
   492  		FilterSubjects: []string{"one", "two"},
   493  		AckPolicy:      AckExplicit,
   494  		DeliverPolicy:  DeliverAll,
   495  		AckWait:        time.Second * 30,
   496  	}, ActionCreate)
   497  	require_NoError(t, err)
   498  	// Create consumer again. Should error if action is CREATE.
   499  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   500  		Durable:        "DUR",
   501  		FilterSubjects: []string{"one"},
   502  		AckPolicy:      AckExplicit,
   503  		DeliverPolicy:  DeliverAll,
   504  		AckWait:        time.Second * 30,
   505  	}, ActionCreate)
   506  	require_Error(t, err)
   507  
   508  	// Update existing consumer. Should be fine, as consumer exists.
   509  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   510  		Durable:        "DUR",
   511  		FilterSubjects: []string{"one"},
   512  		AckPolicy:      AckExplicit,
   513  		DeliverPolicy:  DeliverAll,
   514  		AckWait:        time.Second * 30,
   515  	}, ActionUpdate)
   516  	require_NoError(t, err)
   517  
   518  	// Update consumer. Should error, as this consumer does not exist.
   519  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   520  		Durable:        "NEW",
   521  		FilterSubjects: []string{"one"},
   522  		AckPolicy:      AckExplicit,
   523  		DeliverPolicy:  DeliverAll,
   524  		AckWait:        time.Second * 30,
   525  	}, ActionUpdate)
   526  	require_Error(t, err)
   527  
   528  	// Create new ephemeral. Should be fine as the consumer doesn't exist already
   529  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   530  		Name:           "EPH",
   531  		FilterSubjects: []string{"one"},
   532  		AckPolicy:      AckExplicit,
   533  		DeliverPolicy:  DeliverAll,
   534  		AckWait:        time.Second * 30,
   535  	}, ActionCreate)
   536  	require_NoError(t, err)
   537  
   538  	// Trying to create it again right away. Should error as it already exists (and hasn't been cleaned up yet)
   539  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   540  		Name:           "EPH",
   541  		FilterSubjects: []string{"one"},
   542  		AckPolicy:      AckExplicit,
   543  		DeliverPolicy:  DeliverAll,
   544  		AckWait:        time.Second * 30,
   545  	}, ActionCreate)
   546  	require_Error(t, err)
   547  }
   548  
   549  func TestJetStreamConsumerActionsOnWorkQueuePolicyStream(t *testing.T) {
   550  	s := RunBasicJetStreamServer(t)
   551  	defer s.Shutdown()
   552  
   553  	nc, _ := jsClientConnect(t, s)
   554  	defer nc.Close()
   555  	acc := s.GlobalAccount()
   556  
   557  	mset, err := acc.addStream(&StreamConfig{
   558  		Name:      "TEST",
   559  		Retention: WorkQueuePolicy,
   560  		Subjects:  []string{"one", "two", "three", "four", "five.>"},
   561  	})
   562  	require_NoError(t, err)
   563  
   564  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   565  		Durable:        "C1",
   566  		FilterSubjects: []string{"one", "two"},
   567  		AckPolicy:      AckExplicit,
   568  	}, ActionCreate)
   569  	require_NoError(t, err)
   570  
   571  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   572  		Durable:        "C2",
   573  		FilterSubjects: []string{"three", "four"},
   574  		AckPolicy:      AckExplicit,
   575  	}, ActionCreate)
   576  	require_NoError(t, err)
   577  
   578  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   579  		Durable:        "C3",
   580  		FilterSubjects: []string{"five.*"},
   581  		AckPolicy:      AckExplicit,
   582  	}, ActionCreate)
   583  	require_NoError(t, err)
   584  
   585  	// Updating a consumer by removing a previous subject filter.
   586  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   587  		Durable:        "C1",
   588  		FilterSubjects: []string{"one"}, // Remove a subject.
   589  		AckPolicy:      AckExplicit,
   590  	}, ActionUpdate)
   591  	require_NoError(t, err)
   592  
   593  	// Updating a consumer without overlapping subjects.
   594  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   595  		Durable:        "C2",
   596  		FilterSubjects: []string{"three", "four", "two"}, // Add previously removed subject.
   597  		AckPolicy:      AckExplicit,
   598  	}, ActionUpdate)
   599  	require_NoError(t, err)
   600  
   601  	// Creating a consumer with overlapping subjects should return an error.
   602  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   603  		Durable:        "C4",
   604  		FilterSubjects: []string{"one", "two", "three", "four"},
   605  		AckPolicy:      AckExplicit,
   606  	}, ActionCreate)
   607  	require_Error(t, err)
   608  	if !IsNatsErr(err, JSConsumerWQConsumerNotUniqueErr) {
   609  		t.Errorf("want error %q, got %q", ApiErrors[JSConsumerWQConsumerNotUniqueErr], err)
   610  	}
   611  
   612  	// Updating a consumer with overlapping subjects should return an error.
   613  	_, err = mset.addConsumerWithAction(&ConsumerConfig{
   614  		Durable:        "C3",
   615  		FilterSubjects: []string{"one", "two", "three", "four"},
   616  		AckPolicy:      AckExplicit,
   617  	}, ActionUpdate)
   618  	require_Error(t, err)
   619  	if !IsNatsErr(err, JSConsumerWQConsumerNotUniqueErr) {
   620  		t.Errorf("want error %q, got %q", ApiErrors[JSConsumerWQConsumerNotUniqueErr], err)
   621  	}
   622  }
   623  
   624  func TestJetStreamConsumerActionsViaAPI(t *testing.T) {
   625  	s := RunBasicJetStreamServer(t)
   626  	defer s.Shutdown()
   627  
   628  	nc, _ := jsClientConnect(t, s)
   629  	defer nc.Close()
   630  	acc := s.GlobalAccount()
   631  
   632  	_, err := acc.addStream(&StreamConfig{
   633  		Name:      "TEST",
   634  		Retention: LimitsPolicy,
   635  		Subjects:  []string{"one"},
   636  		MaxAge:    time.Second * 90,
   637  	})
   638  	require_NoError(t, err)
   639  
   640  	// Update non-existing consumer, which should fail.
   641  	request, err := json.Marshal(&CreateConsumerRequest{
   642  		Action: ActionUpdate,
   643  		Config: ConsumerConfig{
   644  			Durable: "hello",
   645  		},
   646  		Stream: "TEST",
   647  	})
   648  	require_NoError(t, err)
   649  
   650  	resp, err := nc.Request("$JS.API.CONSUMER.DURABLE.CREATE.TEST.hello", []byte(request), time.Second*6)
   651  	require_NoError(t, err)
   652  	var ccResp JSApiConsumerCreateResponse
   653  	err = json.Unmarshal(resp.Data, &ccResp)
   654  	require_NoError(t, err)
   655  	require_Error(t, ccResp.Error)
   656  
   657  	// create non existing consumer - which should be fine.
   658  	ccResp.Error = nil
   659  	request, err = json.Marshal(&CreateConsumerRequest{
   660  		Action: ActionCreate,
   661  		Config: ConsumerConfig{
   662  			Durable: "hello",
   663  		},
   664  		Stream: "TEST",
   665  	})
   666  	require_NoError(t, err)
   667  
   668  	resp, err = nc.Request("$JS.API.CONSUMER.DURABLE.CREATE.TEST.hello", []byte(request), time.Second*6)
   669  	require_NoError(t, err)
   670  	err = json.Unmarshal(resp.Data, &ccResp)
   671  	require_NoError(t, err)
   672  	if ccResp.Error != nil {
   673  		t.Fatalf("expected nil, got %v", ccResp.Error)
   674  	}
   675  
   676  	// re-create existing consumer - which should be an error.
   677  	ccResp.Error = nil
   678  	request, err = json.Marshal(&CreateConsumerRequest{
   679  		Action: ActionCreate,
   680  		Config: ConsumerConfig{
   681  			Durable:       "hello",
   682  			FilterSubject: "one",
   683  		},
   684  		Stream: "TEST",
   685  	})
   686  	require_NoError(t, err)
   687  	resp, err = nc.Request("$JS.API.CONSUMER.DURABLE.CREATE.TEST.hello", []byte(request), time.Second*6)
   688  	require_NoError(t, err)
   689  	err = json.Unmarshal(resp.Data, &ccResp)
   690  	require_NoError(t, err)
   691  	if ccResp.Error == nil {
   692  		t.Fatalf("expected err, got nil")
   693  	}
   694  
   695  	// create a named ephemeral consumer
   696  	ccResp.Error = nil
   697  	request, err = json.Marshal(&CreateConsumerRequest{
   698  		Action: ActionCreate,
   699  		Config: ConsumerConfig{
   700  			Name:          "ephemeral",
   701  			FilterSubject: "one",
   702  		},
   703  		Stream: "TEST",
   704  	})
   705  	require_NoError(t, err)
   706  	resp, err = nc.Request("$JS.API.CONSUMER.CREATE.TEST.ephemeral", []byte(request), time.Second*6)
   707  	require_NoError(t, err)
   708  	err = json.Unmarshal(resp.Data, &ccResp)
   709  	require_NoError(t, err)
   710  
   711  	// re-create existing consumer - which should be an error.
   712  	ccResp.Error = nil
   713  	request, err = json.Marshal(&CreateConsumerRequest{
   714  		Action: ActionCreate,
   715  		Config: ConsumerConfig{
   716  			Name:          "ephemeral",
   717  			FilterSubject: "one",
   718  		},
   719  		Stream: "TEST",
   720  	})
   721  	require_NoError(t, err)
   722  	resp, err = nc.Request("$JS.API.CONSUMER.CREATE.TEST.ephemeral", []byte(request), time.Second*6)
   723  	require_NoError(t, err)
   724  	err = json.Unmarshal(resp.Data, &ccResp)
   725  	require_NoError(t, err)
   726  	if ccResp.Error == nil {
   727  		t.Fatalf("expected err, got nil")
   728  	}
   729  }
   730  
   731  func TestJetStreamConsumerActionsUnmarshal(t *testing.T) {
   732  	tests := []struct {
   733  		name      string
   734  		given     []byte
   735  		expected  ConsumerAction
   736  		expectErr bool
   737  	}{
   738  		{name: "action create", given: []byte(`{"action": "create"}`), expected: ActionCreate},
   739  		{name: "action update", given: []byte(`{"action": "update"}`), expected: ActionUpdate},
   740  		{name: "no action", given: []byte("{}"), expected: ActionCreateOrUpdate},
   741  		{name: "unknown", given: []byte(`{"action": "unknown"}`), expected: ActionCreateOrUpdate, expectErr: true},
   742  	}
   743  
   744  	for _, test := range tests {
   745  		t.Run(test.name, func(t *testing.T) {
   746  
   747  			var request CreateConsumerRequest
   748  			err := json.Unmarshal(test.given, &request)
   749  			fmt.Printf("given: %v, expected: %v\n", test.expectErr, err)
   750  			if !test.expectErr {
   751  				require_NoError(t, err)
   752  			} else {
   753  				require_Error(t, err)
   754  			}
   755  			require_True(t, test.expected == request.Action)
   756  		})
   757  	}
   758  }
   759  
   760  func TestJetStreamConsumerMultipleFiltersLastPerSubject(t *testing.T) {
   761  	c := createJetStreamClusterExplicit(t, "R3S", 3)
   762  	defer c.shutdown()
   763  
   764  	nc, js := jsClientConnect(t, c.randomServer())
   765  	defer nc.Close()
   766  
   767  	_, error := js.AddStream(&nats.StreamConfig{
   768  		Name:     "TEST",
   769  		Subjects: []string{"one", "two"},
   770  		Replicas: 3,
   771  	})
   772  	require_NoError(t, error)
   773  
   774  	sendStreamMsg(t, nc, "one", "1")
   775  	sendStreamMsg(t, nc, "one", "2")
   776  	sendStreamMsg(t, nc, "one", "3")
   777  	sendStreamMsg(t, nc, "two", "1")
   778  	sendStreamMsg(t, nc, "two", "2")
   779  	sendStreamMsg(t, nc, "two", "3")
   780  
   781  	_, err := js.AddConsumer("TEST", &nats.ConsumerConfig{
   782  		Name:           "C",
   783  		FilterSubjects: []string{"one", "two"},
   784  		DeliverPolicy:  nats.DeliverLastPerSubjectPolicy,
   785  		Replicas:       3,
   786  		DeliverSubject: "deliver",
   787  	})
   788  	require_NoError(t, err)
   789  
   790  	consumer, err := js.SubscribeSync("", nats.Bind("TEST", "C"))
   791  	require_NoError(t, err)
   792  
   793  	// expect last message for subject "one"
   794  	msg, err := consumer.NextMsg(time.Second)
   795  	require_NoError(t, err)
   796  	require_Equal(t, "3", string(msg.Data))
   797  	require_Equal(t, "one", msg.Subject)
   798  
   799  	// expect last message for subject "two"
   800  	msg, err = consumer.NextMsg(time.Second)
   801  	require_NoError(t, err)
   802  	require_Equal(t, "3", string(msg.Data))
   803  	require_Equal(t, "two", msg.Subject)
   804  
   805  }
   806  
   807  func consumerWithFilterSubjects(filterSubjects []string) *consumer {
   808  	c := consumer{}
   809  	for _, filter := range filterSubjects {
   810  		sub := &subjectFilter{
   811  			subject:          filter,
   812  			hasWildcard:      subjectHasWildcard(filter),
   813  			tokenizedSubject: tokenizeSubjectIntoSlice(nil, filter),
   814  		}
   815  		c.subjf = append(c.subjf, sub)
   816  	}
   817  
   818  	return &c
   819  }
   820  
   821  func filterSubjects(n int) []string {
   822  	fs := make([]string, 0, n)
   823  	for {
   824  		literals := []string{"foo", "bar", nuid.Next(), "xyz", "abcdef"}
   825  		fs = append(fs, strings.Join(literals, "."))
   826  		if len(fs) == n {
   827  			return fs
   828  		}
   829  		// Create more filterSubjects by going through the literals and replacing one with the '*' wildcard.
   830  		l := len(literals)
   831  		for i := 0; i < l; i++ {
   832  			e := make([]string, l)
   833  			for j := 0; j < l; j++ {
   834  				if j == i {
   835  					e[j] = "*"
   836  				} else {
   837  					e[j] = literals[j]
   838  				}
   839  			}
   840  			fs = append(fs, strings.Join(e, "."))
   841  			if len(fs) == n {
   842  				return fs
   843  			}
   844  		}
   845  	}
   846  }
   847  
   848  func TestJetStreamConsumerIsFilteredMatch(t *testing.T) {
   849  	for _, test := range []struct {
   850  		name           string
   851  		filterSubjects []string
   852  		subject        string
   853  		result         bool
   854  	}{
   855  		{"no filter", []string{}, "foo.bar", true},
   856  		{"literal match", []string{"foo.baz", "foo.bar"}, "foo.bar", true},
   857  		{"literal mismatch", []string{"foo.baz", "foo.bar"}, "foo.ban", false},
   858  		{"wildcard > match", []string{"bar.>", "foo.>"}, "foo.bar", true},
   859  		{"wildcard > match", []string{"bar.>", "foo.>"}, "bar.foo", true},
   860  		{"wildcard > mismatch", []string{"bar.>", "foo.>"}, "baz.foo", false},
   861  		{"wildcard * match", []string{"bar.*", "foo.*"}, "foo.bar", true},
   862  		{"wildcard * match", []string{"bar.*", "foo.*"}, "bar.foo", true},
   863  		{"wildcard * mismatch", []string{"bar.*", "foo.*"}, "baz.foo", false},
   864  		{"wildcard * match", []string{"foo.*.x", "foo.*.y"}, "foo.bar.x", true},
   865  		{"wildcard * match", []string{"foo.*.x", "foo.*.y", "foo.*.z"}, "foo.bar.z", true},
   866  		{"many mismatch", filterSubjects(100), "foo.bar.do.not.match.any.filter.subject", false},
   867  		{"many match", filterSubjects(100), "foo.bar.12345.xyz.abcdef", true}, // will be matched by "foo.bar.*.xyz.abcdef"
   868  	} {
   869  		test := test
   870  
   871  		t.Run(test.name, func(t *testing.T) {
   872  			t.Parallel()
   873  
   874  			c := consumerWithFilterSubjects(test.filterSubjects)
   875  			if res := c.isFilteredMatch(test.subject); res != test.result {
   876  				t.Fatalf("Subject %q filtered match of %v, should be %v, got %v",
   877  					test.subject, test.filterSubjects, test.result, res)
   878  			}
   879  		})
   880  	}
   881  }
   882  
   883  func TestJetStreamConsumerWorkQueuePolicyOverlap(t *testing.T) {
   884  	s := RunBasicJetStreamServer(t)
   885  	defer s.Shutdown()
   886  
   887  	nc, js := jsClientConnect(t, s)
   888  	defer nc.Close()
   889  
   890  	_, err := js.AddStream(&nats.StreamConfig{
   891  		Name:      "TEST",
   892  		Subjects:  []string{"foo.*.*"},
   893  		Retention: nats.WorkQueuePolicy,
   894  	})
   895  	require_NoError(t, err)
   896  
   897  	_, err = js.AddConsumer("TEST", &nats.ConsumerConfig{
   898  		Durable:       "ConsumerA",
   899  		FilterSubject: "foo.bar.*",
   900  		AckPolicy:     nats.AckExplicitPolicy,
   901  	})
   902  	require_NoError(t, err)
   903  
   904  	_, err = js.AddConsumer("TEST", &nats.ConsumerConfig{
   905  		Durable:       "ConsumerB",
   906  		FilterSubject: "foo.*.bar",
   907  		AckPolicy:     nats.AckExplicitPolicy,
   908  	})
   909  	require_Error(t, err)
   910  	require_True(t, strings.Contains(err.Error(), "unique"))
   911  }
   912  
   913  func TestJetStreamConsumerIsEqualOrSubsetMatch(t *testing.T) {
   914  	for _, test := range []struct {
   915  		name           string
   916  		filterSubjects []string
   917  		subject        string
   918  		result         bool
   919  	}{
   920  		{"no filter", []string{}, "foo.bar", false},
   921  		{"literal match", []string{"foo.baz", "foo.bar"}, "foo.bar", true},
   922  		{"literal mismatch", []string{"foo.baz", "foo.bar"}, "foo.ban", false},
   923  		{"literal match", []string{"bar.>", "foo.>"}, "foo.>", true},
   924  		{"subset match", []string{"bar.foo.>", "foo.bar.>"}, "bar.>", true},
   925  		{"subset mismatch", []string{"bar.>", "foo.>"}, "baz.foo.>", false},
   926  		{"literal match", filterSubjects(100), "foo.bar.*.xyz.abcdef", true},
   927  		{"subset match", filterSubjects(100), "foo.bar.>", true},
   928  	} {
   929  		test := test
   930  
   931  		t.Run(test.name, func(t *testing.T) {
   932  			t.Parallel()
   933  
   934  			c := consumerWithFilterSubjects(test.filterSubjects)
   935  			if res := c.isEqualOrSubsetMatch(test.subject); res != test.result {
   936  				t.Fatalf("Subject %q subset match of %v, should be %v, got %v",
   937  					test.subject, test.filterSubjects, test.result, res)
   938  			}
   939  		})
   940  	}
   941  }
   942  
   943  func TestJetStreamConsumerBackOff(t *testing.T) {
   944  	s := RunBasicJetStreamServer(t)
   945  	defer s.Shutdown()
   946  
   947  	nc, js := jsClientConnect(t, s)
   948  	defer nc.Close()
   949  
   950  	for _, test := range []struct {
   951  		name      string
   952  		config    nats.ConsumerConfig
   953  		shouldErr bool
   954  	}{
   955  		{
   956  			name: "backoff_with_max_deliver",
   957  			config: nats.ConsumerConfig{
   958  				MaxDeliver: 3,
   959  				BackOff:    []time.Duration{time.Second, time.Minute},
   960  			},
   961  			shouldErr: false,
   962  		},
   963  		{
   964  			name: "backoff_with_max_deliver_smaller",
   965  			config: nats.ConsumerConfig{
   966  				MaxDeliver: 2,
   967  				BackOff:    []time.Duration{time.Second, time.Minute, time.Hour},
   968  			},
   969  			shouldErr: true,
   970  		},
   971  		{
   972  			name: "backoff_with_default_max_deliver",
   973  			config: nats.ConsumerConfig{
   974  				BackOff: []time.Duration{time.Second, time.Minute, time.Hour},
   975  			},
   976  			shouldErr: false,
   977  		},
   978  	} {
   979  		t.Run(test.name, func(t *testing.T) {
   980  			_, err := js.AddStream(&nats.StreamConfig{
   981  				Name:     test.name,
   982  				Subjects: []string{test.name},
   983  			})
   984  			require_NoError(t, err)
   985  
   986  			_, err = js.AddConsumer(test.name, &test.config)
   987  			require_True(t, test.shouldErr == (err != nil))
   988  			if test.shouldErr {
   989  				require_True(t, strings.Contains(err.Error(), "max deliver"))
   990  			}
   991  
   992  			// test if updating consumers works too.
   993  			test.config.Durable = "consumer"
   994  			_, err = js.AddConsumer(test.name, &nats.ConsumerConfig{
   995  				Durable: test.config.Durable,
   996  			})
   997  			require_NoError(t, err)
   998  
   999  			test.config.Description = "Updated"
  1000  			_, err = js.UpdateConsumer(test.name, &test.config)
  1001  			require_True(t, test.shouldErr == (err != nil))
  1002  			if test.shouldErr {
  1003  				require_True(t, strings.Contains(err.Error(), "max deliver"))
  1004  			}
  1005  		})
  1006  
  1007  	}
  1008  }
  1009  
  1010  func TestJetStreamConsumerDelete(t *testing.T) {
  1011  	tests := []struct {
  1012  		name     string
  1013  		replicas int
  1014  	}{
  1015  		{"single server", 1},
  1016  		{"clustered", 3},
  1017  	}
  1018  
  1019  	for _, test := range tests {
  1020  		t.Run(test.name, func(t *testing.T) {
  1021  			var s *Server
  1022  			if test.replicas == 1 {
  1023  				s = RunBasicJetStreamServer(t)
  1024  				defer s.Shutdown()
  1025  			} else {
  1026  				c := createJetStreamClusterExplicit(t, "R3S", test.replicas)
  1027  				defer c.shutdown()
  1028  				s = c.randomServer()
  1029  			}
  1030  
  1031  			nc, js := jsClientConnect(t, s)
  1032  			defer nc.Close()
  1033  
  1034  			_, err := js.AddStream(&nats.StreamConfig{
  1035  				Name:     "TEST",
  1036  				Subjects: []string{"events.>"},
  1037  				MaxAge:   time.Second * 90,
  1038  				Replicas: test.replicas,
  1039  			})
  1040  			require_NoError(t, err)
  1041  
  1042  			_, err = js.AddConsumer("TEST", &nats.ConsumerConfig{
  1043  				Durable:       "consumer",
  1044  				FilterSubject: "events.>",
  1045  				Replicas:      test.replicas,
  1046  			})
  1047  			require_NoError(t, err)
  1048  
  1049  			js.Publish("events.1", []byte("hello"))
  1050  
  1051  			cr := JSApiConsumerGetNextRequest{
  1052  				Batch:   10,
  1053  				Expires: time.Second * 30,
  1054  			}
  1055  			crBytes, err := json.Marshal(cr)
  1056  			require_NoError(t, err)
  1057  
  1058  			inbox := nats.NewInbox()
  1059  			consumerSub, err := nc.SubscribeSync(inbox)
  1060  			require_NoError(t, err)
  1061  
  1062  			err = nc.PublishRequest(fmt.Sprintf(JSApiRequestNextT, "TEST", "consumer"), inbox, crBytes)
  1063  			require_NoError(t, err)
  1064  
  1065  			msg, err := consumerSub.NextMsg(time.Second * 30)
  1066  			require_NoError(t, err)
  1067  			require_Equal(t, "hello", string(msg.Data))
  1068  
  1069  			js.DeleteConsumer("TEST", "consumer")
  1070  
  1071  			msg, err = consumerSub.NextMsg(time.Second * 30)
  1072  			require_NoError(t, err)
  1073  
  1074  			if !strings.Contains(string(msg.Header.Get("Description")), "Consumer Deleted") {
  1075  				t.Fatalf("Expected exclusive consumer error, got %q", msg.Header.Get("Description"))
  1076  			}
  1077  		})
  1078  
  1079  	}
  1080  }
  1081  
  1082  func TestFetchWithDrain(t *testing.T) {
  1083  	s := RunBasicJetStreamServer(t)
  1084  	defer s.Shutdown()
  1085  
  1086  	nc, js := jsClientConnect(t, s)
  1087  	defer nc.Close()
  1088  
  1089  	_, err := js.AddStream(&nats.StreamConfig{
  1090  		Name:      "TEST",
  1091  		Subjects:  []string{"foo"},
  1092  		Retention: nats.LimitsPolicy,
  1093  	})
  1094  	require_NoError(t, err)
  1095  
  1096  	_, err = js.AddConsumer("TEST", &nats.ConsumerConfig{
  1097  		Durable:   "C",
  1098  		AckPolicy: nats.AckExplicitPolicy,
  1099  		AckWait:   time.Second * 10,
  1100  	})
  1101  	require_NoError(t, err)
  1102  
  1103  	const messages = 10_000
  1104  
  1105  	for i := 0; i < messages; i++ {
  1106  		sendStreamMsg(t, nc, "foo", fmt.Sprintf("%d", i+1))
  1107  	}
  1108  
  1109  	cr := JSApiConsumerGetNextRequest{
  1110  		Batch:   100_000,
  1111  		Expires: time.Second * 10,
  1112  	}
  1113  	crBytes, err := json.Marshal(cr)
  1114  	require_NoError(t, err)
  1115  
  1116  	msgs := make(map[int]int)
  1117  
  1118  	processMsg := func(t *testing.T, sub *nats.Subscription, msgs map[int]int) bool {
  1119  		msg, err := sub.NextMsg(time.Second * 1)
  1120  		if err != nil {
  1121  			return false
  1122  		}
  1123  		metadata, err := msg.Metadata()
  1124  		require_NoError(t, err)
  1125  		err = msg.Ack()
  1126  		require_NoError(t, err)
  1127  
  1128  		v, err := strconv.Atoi(string(msg.Data))
  1129  		require_NoError(t, err)
  1130  		require_Equal(t, uint64(v), metadata.Sequence.Stream)
  1131  
  1132  		_, ok := msgs[int(metadata.Sequence.Stream)]
  1133  		if _, ok := msgs[int(metadata.Sequence.Stream-1)]; !ok && len(msgs) > 0 {
  1134  			t.Logf("Stream Sequence gap detected: current %d", metadata.Sequence.Stream)
  1135  		}
  1136  		if ok {
  1137  			t.Fatalf("Message has been seen before")
  1138  		}
  1139  
  1140  		msgs[int(metadata.Sequence.Stream)] = int(metadata.NumDelivered)
  1141  
  1142  		require_NoError(t, err)
  1143  		return true
  1144  	}
  1145  
  1146  	for {
  1147  		inbox := nats.NewInbox()
  1148  		sub, err := nc.SubscribeSync(inbox)
  1149  		require_NoError(t, err)
  1150  
  1151  		err = nc.PublishRequest(fmt.Sprintf(JSApiRequestNextT, "TEST", "C"), inbox, crBytes)
  1152  		require_NoError(t, err)
  1153  
  1154  		// Drain after first message processed.
  1155  		processMsg(t, sub, msgs)
  1156  		sub.Drain()
  1157  
  1158  		for {
  1159  			if !processMsg(t, sub, msgs) {
  1160  				if len(msgs) == messages {
  1161  					return
  1162  				}
  1163  				break
  1164  			}
  1165  		}
  1166  	}
  1167  }
  1168  
  1169  func Benchmark____JetStreamConsumerIsFilteredMatch(b *testing.B) {
  1170  	subject := "foo.bar.do.not.match.any.filter.subject"
  1171  	for n := 1; n <= 1024; n *= 2 {
  1172  		name := fmt.Sprintf("%d filter subjects", int(n))
  1173  		c := consumerWithFilterSubjects(filterSubjects(int(n)))
  1174  		b.Run(name, func(b *testing.B) {
  1175  			c.isFilteredMatch(subject)
  1176  		})
  1177  	}
  1178  }