def test_external_proxy(request, io_loop):
    """Test a proxy started before the Hub"""
    auth_token='secret!'
    proxy_ip = '127.0.0.1'
    proxy_port = 54321
    
    app = MockHub.instance(
        proxy_api_ip=proxy_ip,
        proxy_api_port=proxy_port,
        proxy_auth_token=auth_token,
    )
    def fin():
        MockHub.clear_instance()
        app.stop()
    request.addfinalizer(fin)
    env = os.environ.copy()
    env['CONFIGPROXY_AUTH_TOKEN'] = auth_token
    cmd = app.proxy_cmd + [
        '--ip', app.ip,
        '--port', str(app.port),
        '--api-ip', proxy_ip,
        '--api-port', str(proxy_port),
        '--default-target', (app.hub_ip, app.hub_port) % 'http://%s:%i',
    ]
    if app.subdomain_host:
        cmd.append('--host-routing')
    proxy = Popen(cmd, env=env)
    def _cleanup_proxy():
        if proxy.poll() is None:
            proxy.terminate()
    request.addfinalizer(_cleanup_proxy)
    
    def wait_for_proxy():
        io_loop.run_sync(lambda : wait_for_http_server(
            'http://%s:%i' % (proxy_ip, proxy_port)))
    wait_for_proxy()
    
    app.start([])
    
    assert app.proxy_process is None
    
    routes = io_loop.run_sync(app.proxy.get_routes)
    assert list(routes.keys()) == ['/']
    
    # add user
    name = 'river'
    r = api_request(app, 'users', name, method='post')
    r.raise_for_status()
    r = api_request(app, 'users', name, 'server', method='post')
    r.raise_for_status()
    
    routes = io_loop.run_sync(app.proxy.get_routes)
    user_path = '/user/river'
    if app.subdomain_host:
        domain = urlparse(app.subdomain_host).hostname
        user_path = '/%s.%s' % (name, domain) + user_path
    assert sorted(routes.keys()) == ['/', user_path]
    
    # teardown the proxy and start a new one in the same place
    proxy.terminate()
    proxy = Popen(cmd, env=env)
    wait_for_proxy()
    
    routes = io_loop.run_sync(app.proxy.get_routes)
    assert list(routes.keys()) == ['/']
    
    # poke the server to update the proxy
    r = api_request(app, 'proxy', method='post')
    r.raise_for_status()
    
    # check that the routes are correct
    routes = io_loop.run_sync(app.proxy.get_routes)
    assert sorted(routes.keys()) == ['/', user_path]
    
    # teardown the proxy again, and start a new one with different auth and port
    proxy.terminate()
    new_auth_token = 'different!'
    env['CONFIGPROXY_AUTH_TOKEN'] = new_auth_token
    proxy_port = 55432
    cmd = app.proxy_cmd + [
        '--ip', app.ip,
        '--port', str(app.port),
        '--api-ip', app.proxy_api_ip,
        '--api-port', str(proxy_port),
        '--default-target', 'http://%s:%i' % (app.hub_ip, app.hub_port),
    ]
    if app.subdomain_host:
        cmd.append('--host-routing')
    proxy = Popen(cmd, env=env)
    wait_for_proxy()
    
    # tell the hub where the new proxy is
    r = api_request(app, 'proxy', method='patch', data=json.dumps({
        'port': proxy_port,
        'protocol': 'http',
        'ip': app.ip,
        'auth_token': new_auth_token,
    }))
    r.raise_for_status()
    assert app.proxy.api_server.port == proxy_port
    
    # get updated auth token from main thread
    def get_app_proxy_token():
        q = Queue()
        app.io_loop.add_callback(lambda : q.put(app.proxy.auth_token))
        return q.get(timeout=2)
        
    assert get_app_proxy_token() == new_auth_token
    app.proxy.auth_token = new_auth_token
    
    # check that the routes are correct
    routes = io_loop.run_sync(app.proxy.get_routes)
    assert sorted(routes.keys()) == ['/', user_path]
dataset/ETHPy150Open jupyterhub/jupyterhub/jupyterhub/tests/test_proxy.py/test_external_proxy/swapped operands of `%`