# 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.
#
# Client tests for Query Event Hooks

import os
import pytest
import tempfile

from tests.common.custom_cluster_test_suite import CustomClusterTestSuite


class TestHooks(CustomClusterTestSuite):
  """
  Tests for FE QueryEventHook invocations.
  """
  DUMMY_HOOK = "org.apache.impala.testutil.DummyQueryEventHook"
  MINIDUMP_PATH = tempfile.mkdtemp()

  @pytest.mark.execute_serially
  @CustomClusterTestSuite.with_args(
      impala_log_dir=tempfile.mkdtemp(prefix="test_hooks_", dir=os.getenv("LOG_DIR")),
      impalad_args="--query_event_hook_classes={0} "
                   "--minidump_path={1} -logbuflevel=-1"
                   .format(DUMMY_HOOK, MINIDUMP_PATH),
      catalogd_args="--minidump_path={0}".format(MINIDUMP_PATH))
  def test_query_event_hooks_execute(self, unique_database):
    """
    Tests that the post query execution hook actually executes by using a
    dummy hook implementation.
    """
    # Dummy hook should log something (See org.apache.impala.testutil.DummyQueryEventHook)
    self.assert_impalad_log_contains("INFO",
        "{0}.onImpalaStartup".format(self.DUMMY_HOOK), expected_count=-1)
    # Run a test query that triggers a lineage event.
    self.execute_query_expect_success(
        self.client, "select count(*) from functional.alltypes")
    # onQueryComplete() is invoked by the lineage logger.
    self.assert_impalad_log_contains("INFO",
        "{0}.onQueryComplete".format(self.DUMMY_HOOK), expected_count=-1)


class TestHooksStartupFail(CustomClusterTestSuite):
  """
  Tests for failed startup due to bad QueryEventHook startup or registration

  All test cases in this testsuite are expected to fail cluster startup and will
  swallow exceptions thrown during setup_method().
  """
  @classmethod
  def get_workload(cls):
    return 'functional-query'

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

  FAILING_HOOK = "org.apache.impala.testutil.AlwaysErrorQueryEventHook"
  NONEXIST_HOOK = "captain.hook"
  LOG_DIR1 = tempfile.mkdtemp(prefix="test_hooks_startup_fail_", dir=os.getenv("LOG_DIR"))
  LOG_DIR2 = tempfile.mkdtemp(prefix="test_hooks_startup_fail_", dir=os.getenv("LOG_DIR"))
  MINIDUMP_PATH = tempfile.mkdtemp()

  @pytest.mark.execute_serially
  @CustomClusterTestSuite.with_args(
      cluster_size=1,
      impalad_timeout_s=5,
      impala_log_dir=LOG_DIR1,
      impalad_args="--query_event_hook_classes={0} "
                   "--minidump_path={1}"
                   .format(FAILING_HOOK, MINIDUMP_PATH),
      catalogd_args="--minidump_path={0}".format(MINIDUMP_PATH))
  def test_hook_startup_fail(self):
    """
    Tests that exception during QueryEventHook.onImpalaStart will prevent
    successful daemon startup.
    """
    # Parse log file for expected exception.
    self.assert_impalad_log_contains("INFO",
                                     "Exception during onImpalaStartup from "
                                     "QueryEventHook class {0}"
                                     .format(self.FAILING_HOOK), expected_count=-1)

  @pytest.mark.execute_serially
  @CustomClusterTestSuite.with_args(
      cluster_size=1,
      impalad_timeout_s=5,
      impala_log_dir=LOG_DIR2,
      impalad_args="--query_event_hook_classes={0} "
                   "--minidump_path={1}"
                   .format(NONEXIST_HOOK, MINIDUMP_PATH),
      catalogd_args="--minidump_path={0}".format(MINIDUMP_PATH))
  def test_hook_instantiation_fail(self):
    """
    Tests that failure to instantiate a QueryEventHook will prevent
    successful daemon startup.
    """
    # Parse log file for expected exception.
    self.assert_impalad_log_contains("INFO",
                                     "Unable to instantiate query event hook class {0}"
                                     .format(self.NONEXIST_HOOK), expected_count=-1)

  def setup_method(self, method):
    # Explicitly override CustomClusterTestSuite.setup_method() to
    # allow it to exception, since this test suite is for cases where
    # startup fails
    try:
      super(TestHooksStartupFail, self).setup_method(method)
    except Exception:
      self._stop_impala_cluster()

  def teardown_method(self, method):
    # Explicitly override CustomClusterTestSuite.teardown_method() to
    # allow it to exception, since it relies on setup_method() having
    # completed successfully
    try:
      super(TestHooksStartupFail, self).teardown_method(method)
    except Exception:
      self._stop_impala_cluster()
