code: def test_job_info_json_to_proto():
      """Test that JobInfo JSON can be converted to JobsAPIInfo protobuf."""
      info = JobInfo(
          status=JobStatus.PENDING,
          entrypoint="echo hi",
          error_type="error_type",
          start_time=123,
          end_time=456,
          metadata={"hi": "hi2"},
          entrypoint_num_cpus=1,
          entrypoint_num_gpus=1,
          entrypoint_memory=4,
          entrypoint_resources={"Custom": 1},
          runtime_env={"pip": ["pkg"]},
          driver_agent_http_address="http://localhost:1234",
          driver_node_id="node_id",
      )
      info_json = json.dumps(info.to_json())
      info_proto = Parse(info_json, JobsAPIInfo())
      assert info_proto.status == "PENDING"
      assert info_proto.entrypoint == "echo hi"
      assert info_proto.start_time == 123
      assert info_proto.end_time == 456
      assert info_proto.metadata == {"hi": "hi2"}
      assert info_proto.entrypoint_num_cpus == 1
      assert info_proto.entrypoint_num_gpus == 1
      assert info_proto.entrypoint_memory == 4
      assert info_proto.entrypoint_resources == {"Custom": 1}
      assert info_proto.runtime_env_json == '{"pip": ["pkg"]}'
      assert info_proto.message == (
          "Job has not started yet. It may be waiting for resources "
          "(CPUs, GPUs, memory, custom resources) to become available. "
          "It may be waiting for the runtime environment to be set up."
      )
      assert info_proto.error_type == "error_type"
      assert (
          info_proto.driver_agent_http_address
          == "http://localhost:1234"
      )
      assert info_proto.driver_node_id == "node_id"
  
      minimal_info = JobInfo(
          status=JobStatus.PENDING, entrypoint="echo hi"
      )
      minimal_info_json = json.dumps(minimal_info.to_json())
      minimal_info_proto = Parse(minimal_info_json, JobsAPIInfo())
      assert minimal_info_proto.status == "PENDING"
      assert minimal_info_proto.entrypoint == "echo hi"
      for unset_optional_field in [
          "entrypoint_num_cpus",
          "entrypoint_num_gpus",
          "entrypoint_memory",
          "runtime_env_json",
          "error_type",
          "driver_agent_http_address",
          "driver_node_id",
      ]:
          assert not minimal_info_proto.HasField(unset_optional_field)
  
file_path: ray/dashboard/modules/job/tests/test_common.py
imports: import pytest
  import json
  from ray.dashboard.modules.job.common import JobInfo, JobStatus, http_uri_components_to_uri, uri_to_http_components, validate_request_type, JobSubmitRequest
  from ray.core.generated.gcs_pb2 import JobsAPIInfo
  from google.protobuf.json_format import Parse
label_desc: Use image node_id 4 for calling a global function with example usage: test_job_info_json_to_proto() without return types