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

     1  // Copyright 2012-2018 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  package server
    15  
    16  import (
    17  	"bytes"
    18  	"net"
    19  	"testing"
    20  )
    21  
    22  func TestSplitBufferSubOp(t *testing.T) {
    23  	cli, trash := net.Pipe()
    24  	defer cli.Close()
    25  	defer trash.Close()
    26  
    27  	s := &Server{gacc: NewAccount(globalAccountName)}
    28  	if err := s.newGateway(DefaultOptions()); err != nil {
    29  		t.Fatalf("Error creating gateways: %v", err)
    30  	}
    31  	s.registerAccount(s.gacc)
    32  	c := &client{srv: s, acc: s.gacc, msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription), nc: cli}
    33  
    34  	subop := []byte("SUB foo 1\r\n")
    35  	subop1 := subop[:6]
    36  	subop2 := subop[6:]
    37  
    38  	if err := c.parse(subop1); err != nil {
    39  		t.Fatalf("Unexpected parse error: %v\n", err)
    40  	}
    41  	if c.state != SUB_ARG {
    42  		t.Fatalf("Expected SUB_ARG state vs %d\n", c.state)
    43  	}
    44  	if err := c.parse(subop2); err != nil {
    45  		t.Fatalf("Unexpected parse error: %v\n", err)
    46  	}
    47  	if c.state != OP_START {
    48  		t.Fatalf("Expected OP_START state vs %d\n", c.state)
    49  	}
    50  	r := s.gacc.sl.Match("foo")
    51  	if r == nil || len(r.psubs) != 1 {
    52  		t.Fatalf("Did not match subscription properly: %+v\n", r)
    53  	}
    54  	sub := r.psubs[0]
    55  	if !bytes.Equal(sub.subject, []byte("foo")) {
    56  		t.Fatalf("Subject did not match expected 'foo' : '%s'\n", sub.subject)
    57  	}
    58  	if !bytes.Equal(sub.sid, []byte("1")) {
    59  		t.Fatalf("Sid did not match expected '1' : '%s'\n", sub.sid)
    60  	}
    61  	if sub.queue != nil {
    62  		t.Fatalf("Received a non-nil queue: '%s'\n", sub.queue)
    63  	}
    64  }
    65  
    66  func TestSplitBufferUnsubOp(t *testing.T) {
    67  	s := &Server{gacc: NewAccount(globalAccountName), gateway: &srvGateway{}}
    68  	s.registerAccount(s.gacc)
    69  	c := &client{srv: s, acc: s.gacc, msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
    70  
    71  	subop := []byte("SUB foo 1024\r\n")
    72  	if err := c.parse(subop); err != nil {
    73  		t.Fatalf("Unexpected parse error: %v\n", err)
    74  	}
    75  	if c.state != OP_START {
    76  		t.Fatalf("Expected OP_START state vs %d\n", c.state)
    77  	}
    78  
    79  	unsubop := []byte("UNSUB 1024\r\n")
    80  	unsubop1 := unsubop[:8]
    81  	unsubop2 := unsubop[8:]
    82  
    83  	if err := c.parse(unsubop1); err != nil {
    84  		t.Fatalf("Unexpected parse error: %v\n", err)
    85  	}
    86  	if c.state != UNSUB_ARG {
    87  		t.Fatalf("Expected UNSUB_ARG state vs %d\n", c.state)
    88  	}
    89  	if err := c.parse(unsubop2); err != nil {
    90  		t.Fatalf("Unexpected parse error: %v\n", err)
    91  	}
    92  	if c.state != OP_START {
    93  		t.Fatalf("Expected OP_START state vs %d\n", c.state)
    94  	}
    95  	r := s.gacc.sl.Match("foo")
    96  	if r != nil && len(r.psubs) != 0 {
    97  		t.Fatalf("Should be no subscriptions in results: %+v\n", r)
    98  	}
    99  }
   100  
   101  func TestSplitBufferPubOp(t *testing.T) {
   102  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
   103  	pub := []byte("PUB foo.bar INBOX.22 11\r\nhello world\r")
   104  	pub1 := pub[:2]
   105  	pub2 := pub[2:9]
   106  	pub3 := pub[9:15]
   107  	pub4 := pub[15:22]
   108  	pub5 := pub[22:25]
   109  	pub6 := pub[25:33]
   110  	pub7 := pub[33:]
   111  
   112  	if err := c.parse(pub1); err != nil {
   113  		t.Fatalf("Unexpected parse error: %v\n", err)
   114  	}
   115  	if c.state != OP_PU {
   116  		t.Fatalf("Expected OP_PU state vs %d\n", c.state)
   117  	}
   118  	if err := c.parse(pub2); err != nil {
   119  		t.Fatalf("Unexpected parse error: %v\n", err)
   120  	}
   121  	if c.state != PUB_ARG {
   122  		t.Fatalf("Expected OP_PU state vs %d\n", c.state)
   123  	}
   124  	if err := c.parse(pub3); err != nil {
   125  		t.Fatalf("Unexpected parse error: %v\n", err)
   126  	}
   127  	if c.state != PUB_ARG {
   128  		t.Fatalf("Expected OP_PU state vs %d\n", c.state)
   129  	}
   130  	if err := c.parse(pub4); err != nil {
   131  		t.Fatalf("Unexpected parse error: %v\n", err)
   132  	}
   133  	if c.state != PUB_ARG {
   134  		t.Fatalf("Expected PUB_ARG state vs %d\n", c.state)
   135  	}
   136  	if err := c.parse(pub5); err != nil {
   137  		t.Fatalf("Unexpected parse error: %v\n", err)
   138  	}
   139  	if c.state != MSG_PAYLOAD {
   140  		t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state)
   141  	}
   142  
   143  	// Check c.pa
   144  	if !bytes.Equal(c.pa.subject, []byte("foo.bar")) {
   145  		t.Fatalf("PUB arg subject incorrect: '%s'\n", c.pa.subject)
   146  	}
   147  	if !bytes.Equal(c.pa.reply, []byte("INBOX.22")) {
   148  		t.Fatalf("PUB arg reply subject incorrect: '%s'\n", c.pa.reply)
   149  	}
   150  	if c.pa.size != 11 {
   151  		t.Fatalf("PUB arg msg size incorrect: %d\n", c.pa.size)
   152  	}
   153  	if err := c.parse(pub6); err != nil {
   154  		t.Fatalf("Unexpected parse error: %v\n", err)
   155  	}
   156  	if c.state != MSG_PAYLOAD {
   157  		t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state)
   158  	}
   159  	if err := c.parse(pub7); err != nil {
   160  		t.Fatalf("Unexpected parse error: %v\n", err)
   161  	}
   162  	if c.state != MSG_END_N {
   163  		t.Fatalf("Expected MSG_END_N state vs %d\n", c.state)
   164  	}
   165  }
   166  
   167  func TestSplitBufferPubOp2(t *testing.T) {
   168  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
   169  	pub := []byte("PUB foo.bar INBOX.22 11\r\nhello world\r\n")
   170  	pub1 := pub[:30]
   171  	pub2 := pub[30:]
   172  
   173  	if err := c.parse(pub1); err != nil {
   174  		t.Fatalf("Unexpected parse error: %v\n", err)
   175  	}
   176  	if c.state != MSG_PAYLOAD {
   177  		t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state)
   178  	}
   179  	if err := c.parse(pub2); err != nil {
   180  		t.Fatalf("Unexpected parse error: %v\n", err)
   181  	}
   182  	if c.state != OP_START {
   183  		t.Fatalf("Expected OP_START state vs %d\n", c.state)
   184  	}
   185  }
   186  
   187  func TestSplitBufferPubOp3(t *testing.T) {
   188  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
   189  	pubAll := []byte("PUB foo bar 11\r\nhello world\r\n")
   190  	pub := pubAll[:16]
   191  
   192  	if err := c.parse(pub); err != nil {
   193  		t.Fatalf("Unexpected parse error: %v\n", err)
   194  	}
   195  	if !bytes.Equal(c.pa.subject, []byte("foo")) {
   196  		t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo")
   197  	}
   198  
   199  	// Simulate next read of network, make sure pub state is saved
   200  	// until msg payload has cleared.
   201  	copy(pubAll, "XXXXXXXXXXXXXXXX")
   202  	if !bytes.Equal(c.pa.subject, []byte("foo")) {
   203  		t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo")
   204  	}
   205  	if !bytes.Equal(c.pa.reply, []byte("bar")) {
   206  		t.Fatalf("Unexpected reply: '%s' vs '%s'\n", c.pa.reply, "bar")
   207  	}
   208  	if !bytes.Equal(c.pa.szb, []byte("11")) {
   209  		t.Fatalf("Unexpected size bytes: '%s' vs '%s'\n", c.pa.szb, "11")
   210  	}
   211  }
   212  
   213  func TestSplitBufferPubOp4(t *testing.T) {
   214  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
   215  	pubAll := []byte("PUB foo 11\r\nhello world\r\n")
   216  	pub := pubAll[:12]
   217  
   218  	if err := c.parse(pub); err != nil {
   219  		t.Fatalf("Unexpected parse error: %v\n", err)
   220  	}
   221  	if !bytes.Equal(c.pa.subject, []byte("foo")) {
   222  		t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo")
   223  	}
   224  
   225  	// Simulate next read of network, make sure pub state is saved
   226  	// until msg payload has cleared.
   227  	copy(pubAll, "XXXXXXXXXXXX")
   228  	if !bytes.Equal(c.pa.subject, []byte("foo")) {
   229  		t.Fatalf("Unexpected subject: '%s' vs '%s'\n", c.pa.subject, "foo")
   230  	}
   231  	if !bytes.Equal(c.pa.reply, []byte("")) {
   232  		t.Fatalf("Unexpected reply: '%s' vs '%s'\n", c.pa.reply, "")
   233  	}
   234  	if !bytes.Equal(c.pa.szb, []byte("11")) {
   235  		t.Fatalf("Unexpected size bytes: '%s' vs '%s'\n", c.pa.szb, "11")
   236  	}
   237  }
   238  
   239  func TestSplitBufferPubOp5(t *testing.T) {
   240  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
   241  	pubAll := []byte("PUB foo 11\r\nhello world\r\n")
   242  
   243  	// Splits need to be on MSG_END_R now too, so make sure we check that.
   244  	// Split between \r and \n
   245  	pub := pubAll[:len(pubAll)-1]
   246  
   247  	if err := c.parse(pub); err != nil {
   248  		t.Fatalf("Unexpected parse error: %v\n", err)
   249  	}
   250  	if c.msgBuf == nil {
   251  		t.Fatalf("msgBuf should not be nil!\n")
   252  	}
   253  	if !bytes.Equal(c.msgBuf, []byte("hello world\r")) {
   254  		t.Fatalf("c.msgBuf did not snaphot the msg")
   255  	}
   256  }
   257  
   258  func TestSplitConnectArg(t *testing.T) {
   259  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
   260  	connectAll := []byte("CONNECT {\"verbose\":false,\"tls_required\":false," +
   261  		"\"user\":\"test\",\"pedantic\":true,\"pass\":\"pass\"}\r\n")
   262  
   263  	argJSON := connectAll[8:]
   264  
   265  	c1 := connectAll[:5]
   266  	c2 := connectAll[5:22]
   267  	c3 := connectAll[22 : len(connectAll)-2]
   268  	c4 := connectAll[len(connectAll)-2:]
   269  
   270  	if err := c.parse(c1); err != nil {
   271  		t.Fatalf("Unexpected parse error: %v\n", err)
   272  	}
   273  	if c.argBuf != nil {
   274  		t.Fatalf("Unexpected argBug placeholder.\n")
   275  	}
   276  
   277  	if err := c.parse(c2); err != nil {
   278  		t.Fatalf("Unexpected parse error: %v\n", err)
   279  	}
   280  	if c.argBuf == nil {
   281  		t.Fatalf("Expected argBug to not be nil.\n")
   282  	}
   283  	if !bytes.Equal(c.argBuf, argJSON[:14]) {
   284  		t.Fatalf("argBuf not correct, received %q, wanted %q\n", argJSON[:14], c.argBuf)
   285  	}
   286  
   287  	if err := c.parse(c3); err != nil {
   288  		t.Fatalf("Unexpected parse error: %v\n", err)
   289  	}
   290  	if c.argBuf == nil {
   291  		t.Fatalf("Expected argBug to not be nil.\n")
   292  	}
   293  	if !bytes.Equal(c.argBuf, argJSON[:len(argJSON)-2]) {
   294  		t.Fatalf("argBuf not correct, received %q, wanted %q\n",
   295  			argJSON[:len(argJSON)-2], c.argBuf)
   296  	}
   297  
   298  	if err := c.parse(c4); err != nil {
   299  		t.Fatalf("Unexpected parse error: %v\n", err)
   300  	}
   301  	if c.argBuf != nil {
   302  		t.Fatalf("Unexpected argBuf placeholder.\n")
   303  	}
   304  }
   305  
   306  func TestSplitDanglingArgBuf(t *testing.T) {
   307  	s := New(&defaultServerOptions)
   308  	c := &client{srv: s, acc: s.gacc, msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription)}
   309  
   310  	// We test to make sure we do not dangle any argBufs after processing
   311  	// since that could lead to performance issues.
   312  
   313  	// SUB
   314  	subop := []byte("SUB foo 1\r\n")
   315  	c.parse(subop[:6])
   316  	c.parse(subop[6:])
   317  	if c.argBuf != nil {
   318  		t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf)
   319  	}
   320  
   321  	// UNSUB
   322  	unsubop := []byte("UNSUB 1024\r\n")
   323  	c.parse(unsubop[:8])
   324  	c.parse(unsubop[8:])
   325  	if c.argBuf != nil {
   326  		t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf)
   327  	}
   328  
   329  	// PUB
   330  	pubop := []byte("PUB foo.bar INBOX.22 11\r\nhello world\r\n")
   331  	c.parse(pubop[:22])
   332  	c.parse(pubop[22:25])
   333  	if c.argBuf == nil {
   334  		t.Fatal("Expected a non-nil argBuf!")
   335  	}
   336  	c.parse(pubop[25:])
   337  	if c.argBuf != nil {
   338  		t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf)
   339  	}
   340  
   341  	// MINUS_ERR
   342  	errop := []byte("-ERR Too Long\r\n")
   343  	c.parse(errop[:8])
   344  	c.parse(errop[8:])
   345  	if c.argBuf != nil {
   346  		t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf)
   347  	}
   348  
   349  	// CONNECT_ARG
   350  	connop := []byte("CONNECT {\"verbose\":false,\"tls_required\":false," +
   351  		"\"user\":\"test\",\"pedantic\":true,\"pass\":\"pass\"}\r\n")
   352  	c.parse(connop[:22])
   353  	c.parse(connop[22:])
   354  	if c.argBuf != nil {
   355  		t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf)
   356  	}
   357  
   358  	// INFO_ARG
   359  	infoop := []byte("INFO {\"server_id\":\"id\"}\r\n")
   360  	c.parse(infoop[:8])
   361  	c.parse(infoop[8:])
   362  	if c.argBuf != nil {
   363  		t.Fatalf("Expected c.argBuf to be nil: %q\n", c.argBuf)
   364  	}
   365  
   366  	// MSG (the client has to be a ROUTE)
   367  	c = &client{msubs: -1, mpay: -1, subs: make(map[string]*subscription), kind: ROUTER, route: &route{}}
   368  	msgop := []byte("RMSG $foo foo 5\r\nhello\r\n")
   369  	c.parse(msgop[:5])
   370  	c.parse(msgop[5:10])
   371  	if c.argBuf == nil {
   372  		t.Fatal("Expected a non-nil argBuf")
   373  	}
   374  	if string(c.argBuf) != "$foo " {
   375  		t.Fatalf("Expected argBuf to be \"$foo \", got %q", string(c.argBuf))
   376  	}
   377  	c.parse(msgop[10:])
   378  	if c.argBuf != nil {
   379  		t.Fatalf("Expected argBuf to be nil: %q", c.argBuf)
   380  	}
   381  	if c.msgBuf != nil {
   382  		t.Fatalf("Expected msgBuf to be nil: %q", c.msgBuf)
   383  	}
   384  
   385  	c.state = OP_START
   386  	// Parse up-to somewhere in the middle of the payload.
   387  	// Verify that we have saved the MSG_ARG info
   388  	c.parse(msgop[:23])
   389  	if c.argBuf == nil {
   390  		t.Fatal("Expected a non-nil argBuf")
   391  	}
   392  	if string(c.pa.account) != "$foo" {
   393  		t.Fatalf("Expected account to be \"$foo\", got %q", c.pa.account)
   394  	}
   395  	if string(c.pa.subject) != "foo" {
   396  		t.Fatalf("Expected subject to be \"foo\", got %q", c.pa.subject)
   397  	}
   398  	if string(c.pa.reply) != "" {
   399  		t.Fatalf("Expected reply to be \"\", got %q", c.pa.reply)
   400  	}
   401  	if c.pa.size != 5 {
   402  		t.Fatalf("Expected sid to 5, got %v", c.pa.size)
   403  	}
   404  	// msg buffer should be
   405  	if c.msgBuf == nil || string(c.msgBuf) != "hello\r" {
   406  		t.Fatalf("Expected msgBuf to be \"hello\r\", got %q", c.msgBuf)
   407  	}
   408  	c.parse(msgop[23:])
   409  	// At the end, we should have cleaned-up both arg and msg buffers.
   410  	if c.argBuf != nil {
   411  		t.Fatalf("Expected argBuf to be nil: %q", c.argBuf)
   412  	}
   413  	if c.msgBuf != nil {
   414  		t.Fatalf("Expected msgBuf to be nil: %q", c.msgBuf)
   415  	}
   416  }
   417  
   418  func TestSplitRoutedMsgArg(t *testing.T) {
   419  	_, c, _ := setupClient()
   420  	defer c.close()
   421  	// Allow parser to process RMSG
   422  	c.kind = ROUTER
   423  	c.route = &route{}
   424  
   425  	b := make([]byte, 1024)
   426  
   427  	copy(b, []byte("RMSG $G hello.world 6040\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"))
   428  	c.parse(b)
   429  
   430  	copy(b, []byte("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\r\n"))
   431  	c.parse(b)
   432  
   433  	wantAccount := "$G"
   434  	wantSubject := "hello.world"
   435  	wantSzb := "6040"
   436  
   437  	if string(c.pa.account) != wantAccount {
   438  		t.Fatalf("Incorrect account: want %q, got %q", wantAccount, c.pa.account)
   439  	}
   440  	if string(c.pa.subject) != wantSubject {
   441  		t.Fatalf("Incorrect subject: want %q, got %q", wantSubject, c.pa.subject)
   442  	}
   443  	if string(c.pa.szb) != wantSzb {
   444  		t.Fatalf("Incorrect szb: want %q, got %q", wantSzb, c.pa.szb)
   445  	}
   446  }
   447  
   448  func TestSplitBufferMsgOp(t *testing.T) {
   449  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription), kind: ROUTER, route: &route{}}
   450  	msg := []byte("RMSG $G foo.bar _INBOX.22 11\r\nhello world\r")
   451  	msg1 := msg[:2]
   452  	msg2 := msg[2:9]
   453  	msg3 := msg[9:15]
   454  	msg4 := msg[15:22]
   455  	msg5 := msg[22:25]
   456  	msg6 := msg[25:37]
   457  	msg7 := msg[37:40]
   458  	msg8 := msg[40:]
   459  
   460  	if err := c.parse(msg1); err != nil {
   461  		t.Fatalf("Unexpected parse error: %v\n", err)
   462  	}
   463  	if c.state != OP_M {
   464  		t.Fatalf("Expected OP_M state vs %d\n", c.state)
   465  	}
   466  	if err := c.parse(msg2); err != nil {
   467  		t.Fatalf("Unexpected parse error: %v\n", err)
   468  	}
   469  	if c.state != MSG_ARG {
   470  		t.Fatalf("Expected MSG_ARG state vs %d\n", c.state)
   471  	}
   472  	if err := c.parse(msg3); err != nil {
   473  		t.Fatalf("Unexpected parse error: %v\n", err)
   474  	}
   475  	if c.state != MSG_ARG {
   476  		t.Fatalf("Expected MSG_ARG state vs %d\n", c.state)
   477  	}
   478  	if err := c.parse(msg4); err != nil {
   479  		t.Fatalf("Unexpected parse error: %v\n", err)
   480  	}
   481  	if c.state != MSG_ARG {
   482  		t.Fatalf("Expected MSG_ARG state vs %d\n", c.state)
   483  	}
   484  	if err := c.parse(msg5); err != nil {
   485  		t.Fatalf("Unexpected parse error: %v\n", err)
   486  	}
   487  	if c.state != MSG_ARG {
   488  		t.Fatalf("Expected MSG_ARG state vs %d\n", c.state)
   489  	}
   490  	if err := c.parse(msg6); err != nil {
   491  		t.Fatalf("Unexpected parse error: %v\n", err)
   492  	}
   493  	if c.state != MSG_PAYLOAD {
   494  		t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state)
   495  	}
   496  
   497  	// Check c.pa
   498  	if !bytes.Equal(c.pa.subject, []byte("foo.bar")) {
   499  		t.Fatalf("MSG arg subject incorrect: '%s'\n", c.pa.subject)
   500  	}
   501  	if !bytes.Equal(c.pa.reply, []byte("_INBOX.22")) {
   502  		t.Fatalf("MSG arg reply subject incorrect: '%s'\n", c.pa.reply)
   503  	}
   504  	if c.pa.size != 11 {
   505  		t.Fatalf("MSG arg msg size incorrect: %d\n", c.pa.size)
   506  	}
   507  	if err := c.parse(msg7); err != nil {
   508  		t.Fatalf("Unexpected parse error: %v\n", err)
   509  	}
   510  	if c.state != MSG_PAYLOAD {
   511  		t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state)
   512  	}
   513  	if err := c.parse(msg8); err != nil {
   514  		t.Fatalf("Unexpected parse error: %v\n", err)
   515  	}
   516  	if c.state != MSG_END_N {
   517  		t.Fatalf("Expected MSG_END_N state vs %d\n", c.state)
   518  	}
   519  }
   520  
   521  func TestSplitBufferLeafMsgArg(t *testing.T) {
   522  	c := &client{msubs: -1, mpay: -1, mcl: 1024, subs: make(map[string]*subscription), kind: LEAF}
   523  	msg := []byte("LMSG foo + bar baz 11\r\n")
   524  	if err := c.parse(msg); err != nil {
   525  		t.Fatalf("Unexpected parse error: %v\n", err)
   526  	}
   527  	if c.state != MSG_PAYLOAD {
   528  		t.Fatalf("Expected MSG_PAYLOAD state vs %d\n", c.state)
   529  	}
   530  	checkPA := func(t *testing.T) {
   531  		t.Helper()
   532  		if !bytes.Equal(c.pa.subject, []byte("foo")) {
   533  			t.Fatalf("Expected subject to be %q, got %q", "foo", c.pa.subject)
   534  		}
   535  		if !bytes.Equal(c.pa.reply, []byte("bar")) {
   536  			t.Fatalf("Expected reply to be %q, got %q", "bar", c.pa.reply)
   537  		}
   538  		if n := len(c.pa.queues); n != 1 {
   539  			t.Fatalf("Expected 1 queue, got %v", n)
   540  		}
   541  		if !bytes.Equal(c.pa.queues[0], []byte("baz")) {
   542  			t.Fatalf("Expected queues to be %q, got %q", "baz", c.pa.queues)
   543  		}
   544  	}
   545  	checkPA(t)
   546  
   547  	// overwrite msg with payload
   548  	n := copy(msg, []byte("fffffffffff"))
   549  	if err := c.parse(msg[:n]); err != nil {
   550  		t.Fatalf("Unexpected parse error: %v\n", err)
   551  	}
   552  	if c.state != MSG_END_R {
   553  		t.Fatalf("Expected MSG_END_R state vs %d\n", c.state)
   554  	}
   555  	checkPA(t)
   556  
   557  	// Finish processing
   558  	copy(msg, []byte("\r\n"))
   559  	if err := c.parse(msg[:2]); err != nil {
   560  		t.Fatalf("Unexpected parse error: %v\n", err)
   561  	}
   562  	if c.state != OP_START {
   563  		t.Fatalf("Expected OP_START state vs %d\n", c.state)
   564  	}
   565  	if c.pa.subject != nil || c.pa.reply != nil || c.pa.queues != nil || c.pa.size != 0 ||
   566  		c.pa.szb != nil || c.pa.arg != nil {
   567  		t.Fatalf("parser state not cleaned-up properly: %+v", c.pa)
   568  	}
   569  }