code: def test_circular_mapping(self):
      replacer = URLReplacer(
          ports={4000: 5000, 3001: 3002, 3002: 3003, 3003: 3001},
          app_specs=[
              AppSpec(port=3001, app_name="qwerty"),
              AppSpec(port=3002, app_name="foobar"),
              AppSpec(port=3003, app_name="asdasd"),
          ],
          hostname=localhost,
          secure=False,
      )
      assert (
          replacer(
              b"http://0.0.0.0:3001/qwerty and http://0.0.0.0:3002/foobar and http://0.0.0.0:3003/asdasd"
          )
          == b"http://127.0.0.1:3002/qwerty and http://127.0.0.1:3003/foobar and http://127.0.0.1:3001/asdasd"
      )
  
file_path: dstack/src/tests/_internal/core/services/test_logs.py
imports: from dstack._internal.core.models.runs import AppSpec
  from dstack._internal.core.services.logs import URLReplacer
label_desc: Use image node_id 7 for calling the TestTaskURLReplacer obj's underlying member method code with example usage: obj.test_circular_mapping() without return types