code: def test_retry_on_failure(
      self, mock_rmtree, mock_popen, mock_mkdtemp
  ):
      # Verify it retries after subprocess failure
      mock_mkdtemp.return_value = "temp_dir"
      mock_process = mock.Mock()
      mock_popen.return_value = mock_process
      mock_process.pid = 42
  
      def mock_wait():
          # First time fail, then succeed
          if mock_popen.call_count == 1:
              return 1
          return 0
  
      mock_process.wait = mock_wait
      colocation = (
          multi_processing_colocation.MultiProcessingColocation(
              [python.PyNode(_run_no_op)], num_retries_on_failure=1
          )
      )
      colocation.run()
      self.assertEqual(mock_mkdtemp.call_count, 2)
      self.assertEqual(mock_popen.call_count, 2)
      self.assertEqual(mock_rmtree.call_count, 2)
  
file_path: launchpad/launchpad/nodes/multi_processing_colocation/node_test.py
imports: import shutil
  import subprocess
  import tempfile
  from unittest import mock
  from absl.testing import absltest
  from launchpad.nodes.multi_processing_colocation import node
  from launchpad.nodes.python import node
label_desc: Use image node_id 3 for calling the NodeTest obj's underlying member method code with example usage: obj.test_retry_on_failure(mock_rmtree, mock_popen, mock_mkdtemp) and returns: int, int