# 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 SQL statement authorization

import logging
import pytest
import os
import tempfile

from impala_py_lib.helpers import find_all_files, is_core_dump
from tests.common.file_utils import assert_file_in_dir_contains
from tests.common.custom_cluster_test_suite import CustomClusterTestSuite

LOG = logging.getLogger('test_provider')


class TestAuthorizationProvider(CustomClusterTestSuite):
  """
  Tests for failed authorization_provider flag.

  All test cases in this testsuite
  are expected to fail cluster startup and will swallow exceptions thrown during
  setup_method().
  """

  BAD_FLAG = "foobar"
  LOG_DIR = tempfile.mkdtemp(prefix="test_provider_", dir=os.getenv("LOG_DIR"))
  MINIDUMP_PATH = tempfile.mkdtemp()

  pre_test_cores = None

  @pytest.mark.execute_serially
  @CustomClusterTestSuite.with_args(
      impala_log_dir=LOG_DIR,
      impalad_args="--minidump_path={0}"
                   "--server-name=server1 "
                   "--ranger_service_type=hive "
                   "--ranger_app_id=impala "
                   "--authorization_provider={1}".format(MINIDUMP_PATH, BAD_FLAG),
      catalogd_args="--minidump_path={0}"
                    "--server-name=server1 "
                    "--ranger_service_type=hive "
                    "--ranger_app_id=impala "
                    "--authorization_provider={1}".format(MINIDUMP_PATH, BAD_FLAG))
  def test_invalid_provider_flag(self, unique_name):
    # parse log file for expected exception
    assert_file_in_dir_contains(TestAuthorizationProvider.LOG_DIR,
                                "InternalException: Could not parse "
                                "authorization_provider flag: {0}"
                                .format(TestAuthorizationProvider.BAD_FLAG))

  def setup_method(self, method):
    # Make a note of any core files that already exist
    possible_cores = find_all_files('*core*')
    self.pre_test_cores = set([f for f in possible_cores if is_core_dump(f)])

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

  def teardown_method(self, method):
    try:
      # The core dumps expected to be generated by this test should be cleaned up
      possible_cores = find_all_files('*core*')
      post_test_cores = set([f for f in possible_cores if is_core_dump(f)])

      for f in (post_test_cores - self.pre_test_cores):
        LOG.info("Cleaned up {core} created by test_invalid_provider_flag".format(core=f))
        os.remove(f)

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