# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import pytest
import requests
import time
from time import localtime, strftime
from threading import Thread
from tests.beeswax.impala_beeswax import ImpalaBeeswaxException
from tests.common.custom_cluster_test_suite import CustomClusterTestSuite
from tests.common.impala_cluster import ImpalaCluster
from tests.common.skip import SkipIfBuildType

@SkipIfBuildType.not_dev_build
class TestQueryConcurrency(CustomClusterTestSuite):
  """Tests if multiple queries are registered on the coordinator when
  submitted in parallel along with clients trying to access the web UI.
  The intention here is to check that the web server call paths don't hold
  global locks that can conflict with other requests and prevent the impalad
  from servicing them. It is done by simulating a metadata loading pause
  using the configuration key --metadata_loading_pause_injection_ms that
  makes the frontend hold the ClientRequestState::lock_ for longer duration."""

  TEST_QUERY = "select count(*) from tpch.supplier"
  POLLING_TIMEOUT_S = 15

  @classmethod
  def get_workload(self):
    return 'functional-query'

  @classmethod
  def setup_class(cls):
    if cls.exploration_strategy() != 'exhaustive':
      pytest.skip('Runs only in exhaustive mode.')
    super(TestQueryConcurrency, cls).setup_class()

  def poll_query_page(self, impalad, query_id):
    """Polls the debug plan page of a given query id in a loop till the timeout
    of POLLING_TIMEOUT_S is hit."""
    start = time.time()
    while time.time() - start < self.POLLING_TIMEOUT_S:
      try:
        impalad.service.read_debug_webpage("query_plan?query_id=" + query_id)
      except e:
        pass
      time.sleep(1)

  def check_registered_queries(self, impalad, count):
    """Asserts that the registered query count on a given impalad matches 'count'
    before POLLING_TIMEOUT_S is hit."""
    start = time.time()
    while time.time() - start < self.POLLING_TIMEOUT_S:
      inflight_query_ids = impalad.service.get_in_flight_queries()
      if inflight_query_ids is not None and len(inflight_query_ids) == count:
        return inflight_query_ids
      time.sleep(1)
    assert False, "Registered query count doesn't match: " + str(count)

  @pytest.mark.execute_serially
  @CustomClusterTestSuite.with_args("--stress_metadata_loading_pause_injection_ms=100000")
  def test_query_concurrency(self, vector):
    impalad = self.cluster.get_any_impalad()
    client1 = impalad.service.create_beeswax_client()
    client2 = impalad.service.create_beeswax_client()
    q1 = Thread(target = client1.execute_async, args = (self.TEST_QUERY,))
    q2 = Thread(target = client2.execute_async, args = (self.TEST_QUERY,))
    q1.start()
    inflight_query_ids = self.check_registered_queries(impalad, 1)
    Thread(target = self.poll_query_page,\
        args = (impalad, inflight_query_ids[0]['query_id'],)).start()
    time.sleep(2)
    q2.start()
    inflight_query_ids = self.check_registered_queries(impalad, 2)
    result = impalad.service.read_debug_webpage("query_profile_encoded?query_id="\
        + inflight_query_ids[1]['query_id'])
    assert result.startswith("Could not obtain runtime profile")
    client1.close()
    client2.close()
