code: def test_deploy_and_delete_app(mocked_application_state):
      """Deploy app with 2 deployments, transition DEPLOYING -> RUNNING -> DELETING.
      This tests the basic typical workflow.
      """
      app_state, deployment_state_manager = mocked_application_state
  
      # DEPLOY application with deployments {d1, d2}
      d1_id = DeploymentID("d1", "test_app")
      d2_id = DeploymentID("d2", "test_app")
      app_state.deploy(
          {
              "d1": deployment_info("d1", "/hi", "/documentation"),
              "d2": deployment_info("d2"),
          }
      )
      assert app_state.route_prefix == "/hi"
      assert app_state.docs_path == "/documentation"
  
      app_status = app_state.get_application_status_info()
      assert app_status.status == ApplicationStatus.DEPLOYING
      assert app_status.deployment_timestamp > 0
  
      app_state.update()
      # After one update, deployments {d1, d2} should be created
      assert deployment_state_manager.get_deployment(d1_id)
      assert deployment_state_manager.get_deployment(d2_id)
      assert app_state.status == ApplicationStatus.DEPLOYING
  
      # Until both deployments are healthy, app should be deploying
      app_state.update()
      assert app_state.status == ApplicationStatus.DEPLOYING
  
      # Mark deployment d1 healthy (app should be deploying)
      deployment_state_manager.set_deployment_healthy(d1_id)
      app_state.update()
      assert app_state.status == ApplicationStatus.DEPLOYING
  
      # Mark deployment d2 healthy (app should be running)
      deployment_state_manager.set_deployment_healthy(d2_id)
      app_state.update()
      assert app_state.status == ApplicationStatus.RUNNING
  
      # Rerun update, status shouldn't change (still running)
      app_state.update()
      assert app_state.status == ApplicationStatus.RUNNING
  
      # Delete application (app should be deleting)
      app_state.delete()
      assert app_state.status == ApplicationStatus.DELETING
  
      app_state.update()
      deployment_state_manager.set_deployment_deleted(d1_id)
      ready_to_be_deleted = app_state.update()
      assert not ready_to_be_deleted
      assert app_state.status == ApplicationStatus.DELETING
  
      # Once both deployments are deleted, the app should be ready to delete
      deployment_state_manager.set_deployment_deleted(d2_id)
      ready_to_be_deleted = app_state.update()
      assert ready_to_be_deleted
  
imports: import sys
  from typing import Dict, List, Tuple
  from unittest.mock import Mock, PropertyMock, patch
  import pytest
  from ray.exceptions import RayTaskError
  from ray.serve._private.application_state import ApplicationState, ApplicationStateManager, override_deployment_info
  from ray.serve._private.common import ApplicationStatus, DeploymentID, DeploymentStatus, DeploymentStatusInfo, DeploymentStatusTrigger
  from ray.serve._private.config import DeploymentConfig, ReplicaConfig
  from ray.serve._private.deploy_utils import deploy_args_to_deployment_info
  from ray.serve._private.deployment_info import DeploymentInfo
  from ray.serve._private.test_utils import MockKVStore
  from ray.serve._private.utils import get_random_string
  from ray.serve.exceptions import RayServeException
  from ray.serve.schema import DeploymentSchema, ServeApplicationSchema
label_desc: Use image node_id 5 for calling a global function with example usage: test_deploy_and_delete_app(mocked_application_state) without return types