code: def test_log_agent_resolve_filename(temp_dir):
      """
      Test that LogAgentV1Grpc.resolve_filename(root, filename) works:
      1. Not possible to resolve a file that doesn't exist.
      2. Not able to resolve files outside of the temp dir root.
          - with a absolute path.
          - with a relative path recursive up.
      3. Permits a file in a directory that's symlinked into the root dir.
      """
      root = Path(temp_dir)
      # Create a file in the temp dir.
      file = root / "valid_file"
      file.touch()
      subdir = root / "subdir"
      subdir.mkdir()
  
      # Create a directory in the root that contains a valid file and
      # is symlinked to by a path in the subdir.
      symlinked_dir = root / "symlinked"
      symlinked_dir.mkdir()
      symlinked_file = symlinked_dir / "valid_file"
      symlinked_file.touch()
      symlinked_path_in_subdir = subdir / "symlink_to_outside_dir"
      symlinked_path_in_subdir.symlink_to(symlinked_dir)
  
      # Test file doesn't exist
      with pytest.raises(FileNotFoundError):
          LogAgentV1Grpc._resolve_filename(root, "non-exist-file")
  
      # Test absolute path outside of root is not allowed
      with pytest.raises(FileNotFoundError):
          LogAgentV1Grpc._resolve_filename(
              subdir, root.resolve() / "valid_file"
          )
  
      # Test relative path recursive up is not allowed
      with pytest.raises(FileNotFoundError):
          LogAgentV1Grpc._resolve_filename(subdir, "../valid_file")
  
      # Test relative path a valid file is allowed
      assert (
          LogAgentV1Grpc._resolve_filename(root, "valid_file")
          == (root / "valid_file").resolve()
      )
  
      # Test relative path to a valid file following a symlink is allowed
      assert (
          LogAgentV1Grpc._resolve_filename(
              subdir, "symlink_to_outside_dir/valid_file"
          )
          == (root / "symlinked" / "valid_file").resolve()
      )
  
imports: import json
  import os
  import sys
  import asyncio
  from typing import List
  import urllib
  from unittest.mock import MagicMock, AsyncMock
  import pytest
  from ray.util.state.state_cli import logs_state_cli_group
  from ray.util.state import list_jobs
  import requests
  from click.testing import CliRunner
  import grpc
  from pathlib import Path
  import ray
  from ray._private.test_utils import format_web_url, wait_for_condition, wait_until_server_available
  from ray._private.ray_constants import LOG_PREFIX_TASK_ATTEMPT_START, LOG_PREFIX_TASK_ATTEMPT_END
  from ray._raylet import ActorID, NodeID, TaskID, WorkerID
  from ray.core.generated.common_pb2 import Address
  from ray.core.generated.gcs_service_pb2 import GetTaskEventsReply
  from ray.core.generated.reporter_pb2 import ListLogsReply, StreamLogReply
  from ray.core.generated.gcs_pb2 import ActorTableData, TaskEvents, TaskStateUpdate, TaskLogInfo
  from ray.dashboard.modules.actor.actor_head import actor_table_data_to_dict
  from ray.dashboard.modules.log.log_agent import find_offset_of_content_in_file, find_end_offset_file, find_end_offset_next_n_lines_from_offset, find_start_offset_last_n_lines_from_offset, LogAgentV1Grpc
  from ray.dashboard.modules.log.log_agent import _stream_log_in_chunk
  from ray.dashboard.modules.log.log_manager import LogsManager
  from ray.dashboard.tests.conftest import *
  from ray.util.state import get_log, list_logs, list_nodes, list_workers
  from ray.util.state.common import GetLogOptions
  from ray.util.state.exception import DataSourceUnavailable, RayStateApiException
  from ray.util.state.state_manager import StateDataSourceClient
label_desc: Use image node_id 8 for calling a global function with example usage: test_log_agent_resolve_filename(temp_dir) without return types