code: def test_log_batch():
      expected_metrics = {"metric-key0": 1.0, "metric-key1": 4.0}
      expected_params = {
          "param-key0": "param-val0",
          "param-key1": "param-val1",
      }
      exact_expected_tags = {
          "tag-key0": "tag-val0",
          "tag-key1": "tag-val1",
      }
      approx_expected_tags = {
          MLFLOW_USER,
          MLFLOW_SOURCE_NAME,
          MLFLOW_SOURCE_TYPE,
          MLFLOW_RUN_NAME,
      }
  
      t = get_current_time_millis()
      sorted_expected_metrics = sorted(
          expected_metrics.items(), key=lambda kv: kv[0]
      )
      metrics = [
          Metric(key=key, value=value, timestamp=t, step=i)
          for i, (key, value) in enumerate(sorted_expected_metrics)
      ]
      params = [
          Param(key=key, value=value)
          for key, value in expected_params.items()
      ]
      tags = [
          RunTag(key=key, value=value)
          for key, value in exact_expected_tags.items()
      ]
  
      with start_run() as active_run:
          run_id = active_run.info.run_id
          MlflowClient().log_batch(
              run_id=run_id, metrics=metrics, params=params, tags=tags
          )
      client = tracking.MlflowClient()
      finished_run = client.get_run(run_id)
      # Validate metrics
      assert len(finished_run.data.metrics) == 2
      for key, value in finished_run.data.metrics.items():
          assert expected_metrics[key] == value
      metric_history0 = client.get_metric_history(run_id, "metric-key0")
      assert {
          (m.value, m.timestamp, m.step) for m in metric_history0
      } == {(1.0, t, 0)}
      metric_history1 = client.get_metric_history(run_id, "metric-key1")
      assert {
          (m.value, m.timestamp, m.step) for m in metric_history1
      } == {(4.0, t, 1)}
  
      # Validate tags (for automatically-set tags)
      assert len(finished_run.data.tags) == len(
          exact_expected_tags
      ) + len(approx_expected_tags)
      for tag_key, tag_value in finished_run.data.tags.items():
          if tag_key in approx_expected_tags:
              pass
          else:
              assert exact_expected_tags[tag_key] == tag_value
      # Validate params
      assert finished_run.data.params == expected_params
      # test that log_batch works with fewer params
      new_tags = {"1": "2", "3": "4", "5": "6"}
      tags = [
          RunTag(key=key, value=value)
          for key, value in new_tags.items()
      ]
      client.log_batch(run_id=run_id, tags=tags)
      finished_run_2 = client.get_run(run_id)
      # Validate tags (for automatically-set tags)
      assert (
          len(finished_run_2.data.tags)
          == len(finished_run.data.tags) + 3
      )
      for tag_key, tag_value in finished_run_2.data.tags.items():
          if tag_key in new_tags:
              assert new_tags[tag_key] == tag_value
  
imports: import filecmp
  import json
  import os
  import pathlib
  import posixpath
  import random
  import re
  from collections import namedtuple
  from unittest import mock
  import pytest
  import yaml
  import mlflow
  from mlflow import MlflowClient, tracking
  from mlflow.entities import LifecycleStage, Metric, Param, RunStatus, RunTag, ViewType
  from mlflow.environment_variables import MLFLOW_RUN_ID
  from mlflow.exceptions import MlflowException
  from mlflow.protos.databricks_pb2 import INVALID_PARAMETER_VALUE, RESOURCE_DOES_NOT_EXIST, ErrorCode
  from mlflow.store.tracking.file_store import FileStore
  from mlflow.tracking.fluent import start_run
  from mlflow.utils.file_utils import local_file_uri_to_path
  from mlflow.utils.mlflow_tags import MLFLOW_PARENT_RUN_ID, MLFLOW_RUN_NAME, MLFLOW_SOURCE_NAME, MLFLOW_SOURCE_TYPE, MLFLOW_USER
  from mlflow.utils.os import is_windows
  from mlflow.utils.time import get_current_time_millis
  from mlflow.utils.validation import MAX_METRICS_PER_BATCH, MAX_PARAMS_TAGS_PER_BATCH
label_desc: Use image node_id 13 for calling a global function with example usage: test_log_batch() without return types