# 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.

# Injects failures  at specific locations in each of the plan nodes. Currently supports
# two types of failures - cancellation of the query and a failure test hook.
#
from tests.beeswax.impala_beeswax import ImpalaBeeswaxException
from tests.common.impala_test_suite import ImpalaTestSuite
from tests.common.test_dimensions import (
    create_single_exec_option_dimension,
    create_uncompressed_text_dimension)
from time import sleep

# Test injecting error logs in prepare phase and status::OK(). This tests one of race
# conditions in error reporting (IMPALA-3385).
class TestErrorLogs(ImpalaTestSuite):
  @classmethod
  def get_workload(cls):
    return 'functional-query'

  @classmethod
  def add_test_dimensions(cls):
    super(TestErrorLogs, cls).add_test_dimensions()
    cls.ImpalaTestMatrix.add_dimension(create_single_exec_option_dimension())
    cls.ImpalaTestMatrix.add_dimension(
        create_uncompressed_text_dimension(cls.get_workload()))

  def test_errorlog(self, vector):
    query = 'select count(*) from tpch.lineitem;'
    action = 'INJECT_ERROR_LOG'
    location = 'PREPARE'
    # scan node has id=0
    node_id = 0
    # Without restarting impala, reporting thread reports every 5 seconds.
    # Having a lower scan range can make the query run more than 2*5 seconds
    # Select location in prepare to guarantee at least one cleared error maps will
    # be sent to coordinator.
    debug_action = '%d:%s:%s' % (node_id, location, action)
    vector.get_value('exec_option')['debug_action'] = debug_action
    vector.get_value('exec_option')['MAX_SCAN_RANGE_LENGTH'] = '1000'
    self.__execute_inject_error_log_action(query, vector)

  def __execute_inject_error_log_action(self, query, vector):
    try:
      handle = self.execute_query_async(query, vector.get_value('exec_option'))
      # sleep() is used to terminate the query; otherwise it runs for a long time. It is
      # large enough to further guarantee at least one cleared error maps to be sent to
      # coordinator.
      sleep(30)
      cancel_result = self.client.cancel(handle)
      self.client.close_query(handle)
      assert cancel_result.status_code == 0,\
          'Unexpected status code from cancel request: %s' % cancel_result
    # As long as impala did not crash we are good.
    except ImpalaBeeswaxException:
      return
