code: def test_group_workers_by_ip(ray_start_2_cpus):
      def create_worker_group(ips):
          wg = WorkerGroup(num_workers=2)
          wg.workers = [
              Worker(
                  actor=None,
                  metadata=WorkerMetadata(
                      node_id="dummy",
                      node_ip=ip,
                      hostname="dummy",
                      resource_ids={},
                      pid=0,
                  ),
              )
              for ip in ips
          ]
          return wg
  
      wg = create_worker_group(
          ["2", "3", "1", "4", "2", "1", "3", "3", "4", "2"]
      )
      wg.sort_workers_by_ip_and_gpu_id()
      expected = ["2", "2", "2", "3", "3", "3", "1", "1", "4", "4"]
      ips = [w.metadata.node_ip for w in wg.workers]
      assert ips == expected, (
          "Workers should be grouped by IP "
          "and follow the same original order of IPs encountered (2, 3, 1, 4)."
      )
  
      wg = create_worker_group(
          ["2", "3", "1", "4", "2", "1", "3", "3", "4", "2"]
      )
      wg.sort_workers_by_ip_and_gpu_id(_first_ip="1")
      expected = ["1", "1", "2", "2", "2", "3", "3", "3", "4", "4"]
      ips = [w.metadata.node_ip for w in wg.workers]
      assert (
          ips == expected
      ), "Workers should be grouped by IP, with the first IP being 1."
  
imports: import time
  from collections import defaultdict
  import pytest
  import ray
  import ray._private.ray_constants
  from ray.train._internal.worker_group import Worker, WorkerGroup, WorkerMetadata
label_desc: Use image node_id 13 for calling a global function with example usage: test_group_workers_by_ip(ray_start_2_cpus) and returns: wg