1
+// Tests for `ipfs name` CLI commands.
2
+// - TestName: tests name publish, resolve, and inspect
3
+// - TestNameGetPut: tests name get and put for raw IPNS record handling
4
+
5
package cli
6
7
import (
9
"encoding/json"
10
"fmt"
11
"os"
12
+ "path/filepath"
13
"strings"
14
"testing"
15
342
require.Contains(t, res.Stdout.String(), publishPath2, "New content should now be published")
343
})
344
}
345
+
346
+func TestNameGetPut(t *testing.T) {
347
+ t.Parallel()
348
+
349
+ const (
350
+ fixturePath = "fixtures/TestName.car"
351
+ fixtureCid = "bafybeidg3uxibfrt7uqh7zd5yaodetik7wjwi4u7rwv2ndbgj6ec7lsv2a"
352
+ )
353
+
354
+ makeDaemon := func(t *testing.T, daemonArgs ...string) *harness.Node {
355
+ node := harness.NewT(t).NewNode().Init("--profile=test")
356
+ r, err := os.Open(fixturePath)
357
+ require.NoError(t, err)
358
+ defer r.Close()
359
+ err = node.IPFSDagImport(r, fixtureCid)
360
+ require.NoError(t, err)
361
+ return node.StartDaemon(daemonArgs...)
362
+ }
363
+
364
+ // makeKey creates a unique IPNS key for a test and returns the IPNS name
365
+ makeKey := func(t *testing.T, node *harness.Node, keyName string) ipns.Name {
366
+ res := node.IPFS("key", "gen", "--type=ed25519", keyName)
367
+ keyID := strings.TrimSpace(res.Stdout.String())
368
+ name, err := ipns.NameFromString(keyID)
369
+ require.NoError(t, err)
370
+ return name
371
+ }
372
+
373
+ // makeExternalRecord creates an IPNS record on an ephemeral node that is
374
+ // shut down before returning. This ensures the test node has no local
375
+ // knowledge of the record, properly testing put/get functionality.
376
+ // We use short --lifetime so if IPNS records from tests get published on
377
+ // the public DHT, they won't waste storage for long.
378
+ makeExternalRecord := func(t *testing.T, h *harness.Harness, publishPath string, publishArgs ...string) (ipns.Name, []byte) {
379
+ node := h.NewNode().Init("--profile=test")
380
+
381
+ r, err := os.Open(fixturePath)
382
+ require.NoError(t, err)
383
+ defer r.Close()
384
+ err = node.IPFSDagImport(r, fixtureCid)
385
+ require.NoError(t, err)
386
+
387
+ node.StartDaemon()
388
+
389
+ res := node.IPFS("key", "gen", "--type=ed25519", "ephemeral-key")
390
+ keyID := strings.TrimSpace(res.Stdout.String())
391
+ ipnsName, err := ipns.NameFromString(keyID)
392
+ require.NoError(t, err)
393
+
394
+ args := []string{"name", "publish", "--key=ephemeral-key", "--lifetime=5m"}
395
+ args = append(args, publishArgs...)
396
+ args = append(args, publishPath)
397
+ node.IPFS(args...)
398
+
399
+ res = node.IPFS("name", "get", ipnsName.String())
400
+ record := res.Stdout.Bytes()
401
+ require.NotEmpty(t, record)
402
+
403
+ node.StopDaemon()
404
+
405
+ return ipnsName, record
406
+ }
407
+
408
+ t.Run("name get retrieves IPNS record", func(t *testing.T) {
409
+ t.Parallel()
410
+ node := makeDaemon(t)
411
+ defer node.StopDaemon()
412
+
413
+ publishPath := "/ipfs/" + fixtureCid
414
+ ipnsName := makeKey(t, node, "testkey")
415
+
416
+ // publish a record first
417
+ node.IPFS("name", "publish", "--key=testkey", "--lifetime=5m", publishPath)
418
+
419
+ // retrieve the record using name get
420
+ res := node.IPFS("name", "get", ipnsName.String())
421
+ record := res.Stdout.Bytes()
422
+ require.NotEmpty(t, record, "expected non-empty IPNS record")
423
+
424
+ // verify the record is valid by inspecting it
425
+ res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+ipnsName.String())
426
+ require.Contains(t, res.Stdout.String(), "Valid: true")
427
+ require.Contains(t, res.Stdout.String(), publishPath)
428
+ })
429
+
430
+ t.Run("name get accepts /ipns/ prefix", func(t *testing.T) {
431
+ t.Parallel()
432
+ node := makeDaemon(t)
433
+ defer node.StopDaemon()
434
+
435
+ publishPath := "/ipfs/" + fixtureCid
436
+ ipnsName := makeKey(t, node, "testkey")
437
+
438
+ node.IPFS("name", "publish", "--key=testkey", "--lifetime=5m", publishPath)
439
+
440
+ // retrieve with /ipns/ prefix
441
+ res := node.IPFS("name", "get", "/ipns/"+ipnsName.String())
442
+ record := res.Stdout.Bytes()
443
+ require.NotEmpty(t, record)
444
+
445
+ // verify the record
446
+ res = node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--verify="+ipnsName.String())
447
+ require.Contains(t, res.Stdout.String(), "Valid: true")
448
+ })
449
+
450
+ t.Run("name get fails for non-existent name", func(t *testing.T) {
451
+ t.Parallel()
452
+ node := makeDaemon(t)
453
+ defer node.StopDaemon()
454
+
455
+ // try to get a record for a random peer ID that doesn't exist
456
+ res := node.RunIPFS("name", "get", "12D3KooWRirYjmmQATx2kgHBfky6DADsLP7ex1t7BRxJ6nqLs9WH")
457
+ require.Error(t, res.Err)
458
+ require.NotEqual(t, 0, res.ExitCode())
459
+ })
460
+
461
+ t.Run("name get fails for invalid name format", func(t *testing.T) {
462
+ t.Parallel()
463
+ node := makeDaemon(t)
464
+ defer node.StopDaemon()
465
+
466
+ res := node.RunIPFS("name", "get", "not-a-valid-ipns-name")
467
+ require.Error(t, res.Err)
468
+ require.NotEqual(t, 0, res.ExitCode())
469
+ })
470
+
471
+ t.Run("name put accepts /ipns/ prefix", func(t *testing.T) {
472
+ t.Parallel()
473
+ node := makeDaemon(t)
474
+ defer node.StopDaemon()
475
+
476
+ publishPath := "/ipfs/" + fixtureCid
477
+ ipnsName := makeKey(t, node, "testkey")
478
+
479
+ node.IPFS("name", "publish", "--key=testkey", "--lifetime=5m", publishPath)
480
+
481
+ res := node.IPFS("name", "get", ipnsName.String())
482
+ record := res.Stdout.Bytes()
483
+
484
+ // put with /ipns/ prefix
485
+ res = node.PipeToIPFS(bytes.NewReader(record), "name", "put", "--force", "/ipns/"+ipnsName.String())
486
+ require.NoError(t, res.Err)
487
+ })
488
+
489
+ t.Run("name put fails for invalid name format", func(t *testing.T) {
490
+ t.Parallel()
491
+ node := makeDaemon(t)
492
+ defer node.StopDaemon()
493
+
494
+ // create a dummy file
495
+ recordFile := filepath.Join(node.Dir, "dummy.bin")
496
+ err := os.WriteFile(recordFile, []byte("dummy"), 0644)
497
+ require.NoError(t, err)
498
+
499
+ res := node.RunIPFS("name", "put", "not-a-valid-ipns-name", recordFile)
500
+ require.Error(t, res.Err)
501
+ require.Contains(t, res.Stderr.String(), "invalid IPNS name")
502
+ })
503
+
504
+ t.Run("name put rejects oversized record", func(t *testing.T) {
505
+ t.Parallel()
506
+ node := makeDaemon(t)
507
+ defer node.StopDaemon()
508
+
509
+ ipnsName := makeKey(t, node, "testkey")
510
+
511
+ // create a file larger than 10 KiB
512
+ oversizedRecord := make([]byte, 11*1024)
513
+ recordFile := filepath.Join(node.Dir, "oversized.bin")
514
+ err := os.WriteFile(recordFile, oversizedRecord, 0644)
515
+ require.NoError(t, err)
516
+
517
+ res := node.RunIPFS("name", "put", ipnsName.String(), recordFile)
518
+ require.Error(t, res.Err)
519
+ require.Contains(t, res.Stderr.String(), "exceeds maximum size")
520
+ })
521
+
522
+ t.Run("name put --force skips size check", func(t *testing.T) {
523
+ t.Parallel()
524
+ node := makeDaemon(t)
525
+ defer node.StopDaemon()
526
+
527
+ ipnsName := makeKey(t, node, "testkey")
528
+
529
+ // create a file larger than 10 KiB
530
+ oversizedRecord := make([]byte, 11*1024)
531
+ recordFile := filepath.Join(node.Dir, "oversized.bin")
532
+ err := os.WriteFile(recordFile, oversizedRecord, 0644)
533
+ require.NoError(t, err)
534
+
535
+ // with --force, size check is skipped (but routing will likely reject it)
536
+ res := node.RunIPFS("name", "put", "--force", ipnsName.String(), recordFile)
537
+ // the command itself should not fail on size, but routing may reject
538
+ // we just verify it doesn't fail with "exceeds maximum size"
539
+ if res.Err != nil {
540
+ require.NotContains(t, res.Stderr.String(), "exceeds maximum size")
541
+ }
542
+ })
543
+
544
+ t.Run("name put stores IPNS record", func(t *testing.T) {
545
+ t.Parallel()
546
+ h := harness.NewT(t)
547
+ publishPath := "/ipfs/" + fixtureCid
548
+
549
+ // create a record on an ephemeral node (shut down before test node starts)
550
+ ipnsName, record := makeExternalRecord(t, h, publishPath)
551
+
552
+ // start test node (has no local knowledge of the record)
553
+ node := makeDaemon(t)
554
+ defer node.StopDaemon()
555
+
556
+ // put the record (should succeed since no existing record)
557
+ recordFile := filepath.Join(node.Dir, "record.bin")
558
+ err := os.WriteFile(recordFile, record, 0644)
559
+ require.NoError(t, err)
560
+
561
+ res := node.RunIPFS("name", "put", ipnsName.String(), recordFile)
562
+ require.NoError(t, res.Err)
563
+
564
+ // verify the record was stored by getting it back
565
+ res = node.IPFS("name", "get", ipnsName.String())
566
+ retrievedRecord := res.Stdout.Bytes()
567
+ require.Equal(t, record, retrievedRecord, "stored record should match original")
568
+ })
569
+
570
+ t.Run("name put with --force overwrites existing record", func(t *testing.T) {
571
+ t.Parallel()
572
+ h := harness.NewT(t)
573
+ publishPath := "/ipfs/" + fixtureCid
574
+
575
+ // create a record on an ephemeral node
576
+ ipnsName, record := makeExternalRecord(t, h, publishPath)
577
+
578
+ // start test node
579
+ node := makeDaemon(t)
580
+ defer node.StopDaemon()
581
+
582
+ // first put the record normally
583
+ recordFile := filepath.Join(node.Dir, "record.bin")
584
+ err := os.WriteFile(recordFile, record, 0644)
585
+ require.NoError(t, err)
586
+
587
+ res := node.RunIPFS("name", "put", ipnsName.String(), recordFile)
588
+ require.NoError(t, res.Err)
589
+
590
+ // now try to put the same record again (should fail - same sequence)
591
+ res = node.RunIPFS("name", "put", ipnsName.String(), recordFile)
592
+ require.Error(t, res.Err)
593
+ require.Contains(t, res.Stderr.String(), "existing record has sequence")
594
+
595
+ // put the record with --force (should succeed)
596
+ res = node.RunIPFS("name", "put", "--force", ipnsName.String(), recordFile)
597
+ require.NoError(t, res.Err)
598
+ })
599
+
600
+ t.Run("name put validates signature against name", func(t *testing.T) {
601
+ t.Parallel()
602
+ h := harness.NewT(t)
603
+ publishPath := "/ipfs/" + fixtureCid
604
+
605
+ // create a record on an ephemeral node
606
+ _, record := makeExternalRecord(t, h, publishPath)
607
+
608
+ // start test node
609
+ node := makeDaemon(t)
610
+ defer node.StopDaemon()
611
+
612
+ // write the record to a file
613
+ recordFile := filepath.Join(node.Dir, "record.bin")
614
+ err := os.WriteFile(recordFile, record, 0644)
615
+ require.NoError(t, err)
616
+
617
+ // try to put with a wrong name (should fail validation)
618
+ wrongName := "12D3KooWRirYjmmQATx2kgHBfky6DADsLP7ex1t7BRxJ6nqLs9WH"
619
+ res := node.RunIPFS("name", "put", wrongName, recordFile)
620
+ require.Error(t, res.Err)
621
+ require.Contains(t, res.Stderr.String(), "record validation failed")
622
+ })
623
+
624
+ t.Run("name put with --force skips command validation", func(t *testing.T) {
625
+ t.Parallel()
626
+ h := harness.NewT(t)
627
+ publishPath := "/ipfs/" + fixtureCid
628
+
629
+ // create a record on an ephemeral node
630
+ ipnsName, record := makeExternalRecord(t, h, publishPath)
631
+
632
+ // start test node
633
+ node := makeDaemon(t)
634
+ defer node.StopDaemon()
635
+
636
+ // with --force the command skips its own validation (signature, sequence check)
637
+ // and passes the record directly to the routing layer
638
+ res := node.PipeToIPFS(bytes.NewReader(record), "name", "put", "--force", ipnsName.String())
639
+ require.NoError(t, res.Err)
640
+ })
641
+
642
+ t.Run("name put rejects empty record", func(t *testing.T) {
643
+ t.Parallel()
644
+ node := makeDaemon(t)
645
+ defer node.StopDaemon()
646
+
647
+ ipnsName := makeKey(t, node, "testkey")
648
+
649
+ // create an empty file
650
+ recordFile := filepath.Join(node.Dir, "empty.bin")
651
+ err := os.WriteFile(recordFile, []byte{}, 0644)
652
+ require.NoError(t, err)
653
+
654
+ res := node.RunIPFS("name", "put", ipnsName.String(), recordFile)
655
+ require.Error(t, res.Err)
656
+ require.Contains(t, res.Stderr.String(), "record is empty")
657
+ })
658
+
659
+ t.Run("name put rejects invalid record", func(t *testing.T) {
660
+ t.Parallel()
661
+ node := makeDaemon(t)
662
+ defer node.StopDaemon()
663
+
664
+ ipnsName := makeKey(t, node, "testkey")
665
+
666
+ // create a file with garbage data
667
+ recordFile := filepath.Join(node.Dir, "garbage.bin")
668
+ err := os.WriteFile(recordFile, []byte("not a valid ipns record"), 0644)
669
+ require.NoError(t, err)
670
+
671
+ res := node.RunIPFS("name", "put", ipnsName.String(), recordFile)
672
+ require.Error(t, res.Err)
673
+ require.Contains(t, res.Stderr.String(), "invalid IPNS record")
674
+ })
675
+
676
+ t.Run("name put accepts stdin", func(t *testing.T) {
677
+ t.Parallel()
678
+ h := harness.NewT(t)
679
+ publishPath := "/ipfs/" + fixtureCid
680
+
681
+ // create a record on an ephemeral node
682
+ ipnsName, record := makeExternalRecord(t, h, publishPath)
683
+
684
+ // start test node (has no local knowledge of the record)
685
+ node := makeDaemon(t)
686
+ defer node.StopDaemon()
687
+
688
+ // put via stdin (no --force needed since no existing record)
689
+ res := node.PipeToIPFS(bytes.NewReader(record), "name", "put", ipnsName.String())
690
+ require.NoError(t, res.Err)
691
+ })
692
+
693
+ t.Run("name put fails when offline without --allow-offline", func(t *testing.T) {
694
+ t.Parallel()
695
+ h := harness.NewT(t)
696
+ publishPath := "/ipfs/" + fixtureCid
697
+
698
+ // create a record on an ephemeral node
699
+ ipnsName, record := makeExternalRecord(t, h, publishPath)
700
+
701
+ // write the record to a file
702
+ recordFile := filepath.Join(h.Dir, "record.bin")
703
+ err := os.WriteFile(recordFile, record, 0644)
704
+ require.NoError(t, err)
705
+
706
+ // start test node in offline mode
707
+ node := h.NewNode().Init("--profile=test")
708
+ node.StartDaemon("--offline")
709
+ defer node.StopDaemon()
710
+
711
+ // try to put without --allow-offline (should fail)
712
+ res := node.RunIPFS("name", "put", ipnsName.String(), recordFile)
713
+ require.Error(t, res.Err)
714
+ // error can come from our command or from the routing layer
715
+ stderr := res.Stderr.String()
716
+ require.True(t, strings.Contains(stderr, "offline") || strings.Contains(stderr, "online mode"),
717
+ "expected offline-related error, got: %s", stderr)
718
+ })
719
+
720
+ t.Run("name put succeeds with --allow-offline", func(t *testing.T) {
721
+ t.Parallel()
722
+ h := harness.NewT(t)
723
+ publishPath := "/ipfs/" + fixtureCid
724
+
725
+ // create a record on an ephemeral node
726
+ ipnsName, record := makeExternalRecord(t, h, publishPath)
727
+
728
+ // write the record to a file
729
+ recordFile := filepath.Join(h.Dir, "record.bin")
730
+ err := os.WriteFile(recordFile, record, 0644)
731
+ require.NoError(t, err)
732
+
733
+ // start test node in offline mode
734
+ node := h.NewNode().Init("--profile=test")
735
+ node.StartDaemon("--offline")
736
+ defer node.StopDaemon()
737
+
738
+ // put with --allow-offline (should succeed, no --force needed since no existing record)
739
+ res := node.RunIPFS("name", "put", "--allow-offline", ipnsName.String(), recordFile)
740
+ require.NoError(t, res.Err)
741
+ })
742
+
743
+ t.Run("name get/put round trip preserves record bytes", func(t *testing.T) {
744
+ t.Parallel()
745
+ h := harness.NewT(t)
746
+ publishPath := "/ipfs/" + fixtureCid
747
+
748
+ // create a record on an ephemeral node
749
+ ipnsName, originalRecord := makeExternalRecord(t, h, publishPath)
750
+
751
+ // start test node (has no local knowledge of the record)
752
+ node := makeDaemon(t)
753
+ defer node.StopDaemon()
754
+
755
+ // put the record
756
+ res := node.PipeToIPFS(bytes.NewReader(originalRecord), "name", "put", ipnsName.String())
757
+ require.NoError(t, res.Err)
758
+
759
+ // get the record back
760
+ res = node.IPFS("name", "get", ipnsName.String())
761
+ retrievedRecord := res.Stdout.Bytes()
762
+
763
+ // the records should be byte-for-byte identical
764
+ require.Equal(t, originalRecord, retrievedRecord, "record bytes should be preserved after get/put round trip")
765
+ })
766
+
767
+ t.Run("name put --force allows storing lower sequence record", func(t *testing.T) {
768
+ t.Parallel()
769
+ h := harness.NewT(t)
770
+ publishPath := "/ipfs/" + fixtureCid
771
+
772
+ // create an ephemeral node to generate two records with different sequences
773
+ ephNode := h.NewNode().Init("--profile=test")
774
+
775
+ r, err := os.Open(fixturePath)
776
+ require.NoError(t, err)
777
+ err = ephNode.IPFSDagImport(r, fixtureCid)
778
+ r.Close()
779
+ require.NoError(t, err)
780
+
781
+ ephNode.StartDaemon()
782
+
783
+ res := ephNode.IPFS("key", "gen", "--type=ed25519", "ephemeral-key")
784
+ keyID := strings.TrimSpace(res.Stdout.String())
785
+ ipnsName, err := ipns.NameFromString(keyID)
786
+ require.NoError(t, err)
787
+
788
+ // publish record with sequence 100
789
+ ephNode.IPFS("name", "publish", "--key=ephemeral-key", "--lifetime=5m", "--sequence=100", publishPath)
790
+ res = ephNode.IPFS("name", "get", ipnsName.String())
791
+ record100 := res.Stdout.Bytes()
792
+
793
+ // publish record with sequence 200
794
+ ephNode.IPFS("name", "publish", "--key=ephemeral-key", "--lifetime=5m", "--sequence=200", publishPath)
795
+ res = ephNode.IPFS("name", "get", ipnsName.String())
796
+ record200 := res.Stdout.Bytes()
797
+
798
+ ephNode.StopDaemon()
799
+
800
+ // start test node (has no local knowledge of the records)
801
+ node := makeDaemon(t)
802
+ defer node.StopDaemon()
803
+
804
+ // helper to get sequence from record
805
+ getSequence := func(record []byte) uint64 {
806
+ res := node.PipeToIPFS(bytes.NewReader(record), "name", "inspect", "--enc=json")
807
+ var result name.IpnsInspectResult
808
+ err := json.Unmarshal(res.Stdout.Bytes(), &result)
809
+ require.NoError(t, err)
810
+ require.NotNil(t, result.Entry.Sequence)
811
+ return *result.Entry.Sequence
812
+ }
813
+
814
+ // verify we have the right records
815
+ require.Equal(t, uint64(100), getSequence(record100))
816
+ require.Equal(t, uint64(200), getSequence(record200))
817
+
818
+ // put record with sequence 200 first
819
+ res = node.PipeToIPFS(bytes.NewReader(record200), "name", "put", ipnsName.String())
820
+ require.NoError(t, res.Err)
821
+
822
+ // verify current record has sequence 200
823
+ res = node.IPFS("name", "get", ipnsName.String())
824
+ require.Equal(t, uint64(200), getSequence(res.Stdout.Bytes()))
825
+
826
+ // now put the lower sequence record (100) with --force
827
+ // this should succeed (--force bypasses our sequence check)
828
+ res = node.PipeToIPFS(bytes.NewReader(record100), "name", "put", "--force", ipnsName.String())
829
+ require.NoError(t, res.Err, "putting lower sequence record with --force should succeed")
830
+
831
+ // note: when we get the record, IPNS resolution returns the "best" record
832
+ // (highest sequence), so we'll get the sequence 200 record back
833
+ // this is expected IPNS behavior - the put succeeded, but get returns the best record
834
+ res = node.IPFS("name", "get", ipnsName.String())
835
+ retrievedSeq := getSequence(res.Stdout.Bytes())
836
+ require.Equal(t, uint64(200), retrievedSeq, "IPNS get returns the best (highest sequence) record")
837
+ })
838
+
839
+ t.Run("name put sequence conflict detection", func(t *testing.T) {
840
+ t.Parallel()
841
+ h := harness.NewT(t)
842
+ publishPath := "/ipfs/" + fixtureCid
843
+
844
+ // create an ephemeral node to generate two records with different sequences
845
+ ephNode := h.NewNode().Init("--profile=test")
846
+
847
+ r, err := os.Open(fixturePath)
848
+ require.NoError(t, err)
849
+ err = ephNode.IPFSDagImport(r, fixtureCid)
850
+ r.Close()
851
+ require.NoError(t, err)
852
+
853
+ ephNode.StartDaemon()
854
+
855
+ res := ephNode.IPFS("key", "gen", "--type=ed25519", "ephemeral-key")
856
+ keyID := strings.TrimSpace(res.Stdout.String())
857
+ ipnsName, err := ipns.NameFromString(keyID)
858
+ require.NoError(t, err)
859
+
860
+ // publish record with sequence 100
861
+ ephNode.IPFS("name", "publish", "--key=ephemeral-key", "--lifetime=5m", "--sequence=100", publishPath)
862
+ res = ephNode.IPFS("name", "get", ipnsName.String())
863
+ record100 := res.Stdout.Bytes()
864
+
865
+ // publish record with sequence 200
866
+ ephNode.IPFS("name", "publish", "--key=ephemeral-key", "--lifetime=5m", "--sequence=200", publishPath)
867
+ res = ephNode.IPFS("name", "get", ipnsName.String())
868
+ record200 := res.Stdout.Bytes()
869
+
870
+ ephNode.StopDaemon()
871
+
872
+ // start test node (has no local knowledge of the records)
873
+ node := makeDaemon(t)
874
+ defer node.StopDaemon()
875
+
876
+ // put record with sequence 200 first
877
+ res = node.PipeToIPFS(bytes.NewReader(record200), "name", "put", ipnsName.String())
878
+ require.NoError(t, res.Err)
879
+
880
+ // try to put record with sequence 100 (lower than current 200)
881
+ recordFile := filepath.Join(node.Dir, "record100.bin")
882
+ err = os.WriteFile(recordFile, record100, 0644)
883
+ require.NoError(t, err)
884
+
885
+ res = node.RunIPFS("name", "put", ipnsName.String(), recordFile)
886
+ require.Error(t, res.Err)
887
+ require.Contains(t, res.Stderr.String(), "existing record has sequence 200 >= new record sequence 100")
888
+ })
889
+}