@@ -1634,6 +1634,61 @@ func TestNRGTruncateDownToCommitted(t *testing.T) {
1634
1634
require_Equal (t , n .commit , 2 )
1635
1635
}
1636
1636
1637
+ type mockWALTruncateAlwaysFails struct {
1638
+ WAL
1639
+ }
1640
+
1641
+ func (m mockWALTruncateAlwaysFails ) Truncate (seq uint64 ) error {
1642
+ return errors .New ("test: truncate always fails" )
1643
+ }
1644
+
1645
+ func TestNRGTruncateDownToCommittedWhenTruncateFails (t * testing.T ) {
1646
+ n , cleanup := initSingleMemRaftNode (t )
1647
+ defer cleanup ()
1648
+
1649
+ n .Lock ()
1650
+ n .wal = mockWALTruncateAlwaysFails {n .wal }
1651
+ n .Unlock ()
1652
+
1653
+ // Create a sample entry, the content doesn't matter, just that it's stored.
1654
+ esm := encodeStreamMsgAllowCompress ("foo" , "_INBOX.foo" , nil , nil , 0 , 0 , true )
1655
+ entries := []* Entry {newEntry (EntryNormal , esm )}
1656
+
1657
+ nats0 := "S1Nunr6R" // "nats-0"
1658
+ nats1 := "yrzKKRBu" // "nats-1"
1659
+
1660
+ // Timeline, we are leader
1661
+ aeMsg1 := encode (t , & appendEntry {leader : nats0 , term : 1 , commit : 0 , pterm : 0 , pindex : 0 , entries : entries })
1662
+ aeMsg2 := encode (t , & appendEntry {leader : nats0 , term : 1 , commit : 1 , pterm : 1 , pindex : 1 , entries : entries })
1663
+
1664
+ // Timeline, after leader change
1665
+ aeMsg3 := encode (t , & appendEntry {leader : nats1 , term : 2 , commit : 0 , pterm : 1 , pindex : 1 , entries : entries })
1666
+
1667
+ // Simply receive first message.
1668
+ n .processAppendEntry (aeMsg1 , n .aesub )
1669
+ require_Equal (t , n .commit , 0 )
1670
+ require_Equal (t , n .wal .State ().Msgs , 1 )
1671
+ entry , err := n .loadEntry (1 )
1672
+ require_NoError (t , err )
1673
+ require_Equal (t , entry .leader , nats0 )
1674
+
1675
+ // Receive second message, which commits the first message.
1676
+ n .processAppendEntry (aeMsg2 , n .aesub )
1677
+ require_Equal (t , n .commit , 1 )
1678
+ require_Equal (t , n .wal .State ().Msgs , 2 )
1679
+ entry , err = n .loadEntry (2 )
1680
+ require_NoError (t , err )
1681
+ require_Equal (t , entry .leader , nats0 )
1682
+
1683
+ // We receive an entry from another leader, should truncate down to commit / remove the second message.
1684
+ // But, truncation fails so should register that and not change pindex/pterm.
1685
+ bindex , bterm := n .pindex , n .pterm
1686
+ n .processAppendEntry (aeMsg3 , n .aesub )
1687
+ require_Error (t , n .werr , errors .New ("test: truncate always fails" ))
1688
+ require_Equal (t , bindex , n .pindex )
1689
+ require_Equal (t , bterm , n .pterm )
1690
+ }
1691
+
1637
1692
func TestNRGForwardProposalResponse (t * testing.T ) {
1638
1693
c := createJetStreamClusterExplicit (t , "R3S" , 3 )
1639
1694
defer c .shutdown ()
0 commit comments