code: def test_op_saves_and_restores_its_state(self) -> None:
      pipeline1 = read_sequence([1, 2, 3, 4]).and_return()
      pipeline2 = read_sequence([5, 6, 7, 8]).and_return()
  
      pipeline = DataPipeline.concat(
          [pipeline1, pipeline2]
      ).and_return()
  
      d = None
  
      it = iter(pipeline)
  
      # Move to the second example.
      for _ in range(6):
          d = next(it)
  
      assert d == 6
  
      state_dict = pipeline.state_dict()
  
      # Read one more example before we roll back.
      d = next(it)
  
      assert d == 7
  
      # Expected to roll back to the second example.
      pipeline.load_state_dict(state_dict)
  
      # Move to EOD.
      for _ in range(2):
          d = next(it)
  
      assert d == 8
  
      state_dict = pipeline.state_dict()
  
      pipeline.reset()
  
      # Expected to be EOD.
      pipeline.load_state_dict(state_dict)
  
      with pytest.raises(StopIteration):
          next(iter(pipeline))
  
imports: import pytest
  from fairseq2.data import DataPipeline, DataPipelineError, read_sequence
  from fairseq2.data.text import read_text
label_desc: Use image node_id 4 for calling the TestConcatOp obj's underlying member method code with example usage: obj.test_op_saves_and_restores_its_state() without return types