...

Source file src/go.etcd.io/etcd/raft/v3/rafttest/interaction_env_handler_process_ready.go

Documentation: go.etcd.io/etcd/raft/v3/rafttest

     1  // Copyright 2019 The etcd Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package rafttest
    16  
    17  import (
    18  	"fmt"
    19  	"testing"
    20  
    21  	"github.com/cockroachdb/datadriven"
    22  	"go.etcd.io/etcd/raft/v3"
    23  	"go.etcd.io/etcd/raft/v3/raftpb"
    24  )
    25  
    26  func (env *InteractionEnv) handleProcessReady(t *testing.T, d datadriven.TestData) error {
    27  	idxs := nodeIdxs(t, d)
    28  	for _, idx := range idxs {
    29  		var err error
    30  		if len(idxs) > 1 {
    31  			fmt.Fprintf(env.Output, "> %d handling Ready\n", idx+1)
    32  			env.withIndent(func() { err = env.ProcessReady(idx) })
    33  		} else {
    34  			err = env.ProcessReady(idx)
    35  		}
    36  		if err != nil {
    37  			return err
    38  		}
    39  	}
    40  	return nil
    41  }
    42  
    43  // ProcessReady runs Ready handling on the node with the given index.
    44  func (env *InteractionEnv) ProcessReady(idx int) error {
    45  	// TODO(tbg): Allow simulating crashes here.
    46  	rn, s := env.Nodes[idx].RawNode, env.Nodes[idx].Storage
    47  	rd := rn.Ready()
    48  	env.Output.WriteString(raft.DescribeReady(rd, defaultEntryFormatter))
    49  	// TODO(tbg): the order of operations here is not necessarily safe. See:
    50  	// https://github.com/etcd-io/etcd/pull/10861
    51  	if !raft.IsEmptyHardState(rd.HardState) {
    52  		if err := s.SetHardState(rd.HardState); err != nil {
    53  			return err
    54  		}
    55  	}
    56  	if err := s.Append(rd.Entries); err != nil {
    57  		return err
    58  	}
    59  	if !raft.IsEmptySnap(rd.Snapshot) {
    60  		if err := s.ApplySnapshot(rd.Snapshot); err != nil {
    61  			return err
    62  		}
    63  	}
    64  	for _, ent := range rd.CommittedEntries {
    65  		var update []byte
    66  		var cs *raftpb.ConfState
    67  		switch ent.Type {
    68  		case raftpb.EntryConfChange:
    69  			var cc raftpb.ConfChange
    70  			if err := cc.Unmarshal(ent.Data); err != nil {
    71  				return err
    72  			}
    73  			update = cc.Context
    74  			cs = rn.ApplyConfChange(cc)
    75  		case raftpb.EntryConfChangeV2:
    76  			var cc raftpb.ConfChangeV2
    77  			if err := cc.Unmarshal(ent.Data); err != nil {
    78  				return err
    79  			}
    80  			cs = rn.ApplyConfChange(cc)
    81  			update = cc.Context
    82  		default:
    83  			update = ent.Data
    84  		}
    85  
    86  		// Record the new state by starting with the current state and applying
    87  		// the command.
    88  		lastSnap := env.Nodes[idx].History[len(env.Nodes[idx].History)-1]
    89  		var snap raftpb.Snapshot
    90  		snap.Data = append(snap.Data, lastSnap.Data...)
    91  		// NB: this hard-codes an "appender" state machine.
    92  		snap.Data = append(snap.Data, update...)
    93  		snap.Metadata.Index = ent.Index
    94  		snap.Metadata.Term = ent.Term
    95  		if cs == nil {
    96  			sl := env.Nodes[idx].History
    97  			cs = &sl[len(sl)-1].Metadata.ConfState
    98  		}
    99  		snap.Metadata.ConfState = *cs
   100  		env.Nodes[idx].History = append(env.Nodes[idx].History, snap)
   101  	}
   102  
   103  	env.Messages = append(env.Messages, rd.Messages...)
   104  
   105  	rn.Advance(rd)
   106  	return nil
   107  }
   108  

View as plain text