@@ -1634,6 +1634,61 @@ func TestNRGTruncateDownToCommitted(t *testing.T) {
16341634 require_Equal (t , n .commit , 2 )
16351635}
16361636
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+
16371692func TestNRGForwardProposalResponse (t * testing.T ) {
16381693 c := createJetStreamClusterExplicit (t , "R3S" , 3 )
16391694 defer c .shutdown ()
0 commit comments