| # 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. |
| # |
| # Tests for IMPALA-3307 |
| |
| import pytest |
| |
| from tests.common.custom_cluster_test_suite import CustomClusterTestSuite |
| from tests.util.filesystem_utils import get_fs_path |
| |
| class TestSharedTimezoneDatabase(CustomClusterTestSuite): |
| '''IMPALA-3307 adds two startup flags to impalad: |
| 1. --hdfs_zone_info_zip to specify an HDFS/S3/ADLS path to a zip file that contains |
| the shared compiled time-zone database to use instead of the default |
| /usr/share/zoneinfo. |
| 2. --hdfs_zone_alias_conf to specify an HDFS/S3/ADLS path to a shared config file |
| that contains definitions for non-standard time-zone aliases. |
| |
| This file tests that the startup flags behave as expected. |
| ''' |
| |
| @classmethod |
| def add_test_dimensions(cls): |
| super(CustomClusterTestSuite, cls).add_test_dimensions() |
| # Timestamp conversion doesn't depend on file format and compression. |
| # Cut down on testing time by limiting the file format and compression. |
| cls.ImpalaTestMatrix.add_constraint(lambda v: |
| v.get_value('table_format').file_format == 'text' and |
| v.get_value('table_format').compression_codec == 'none') |
| |
| |
| @CustomClusterTestSuite.with_args("-hdfs_zone_info_zip=%s" % |
| get_fs_path("/test-warehouse/tzdb/2017c.zip")) |
| def test_shared_timezones(self, vector): |
| result = self.client.execute("select timezone, utctime, localtime, \ |
| from_utc_timestamp(utctime,timezone) as impalaresult from \ |
| functional.alltimezones where localtime != from_utc_timestamp(utctime,timezone)") |
| assert(len(result.data) == 0) |
| |
| |
| @CustomClusterTestSuite.with_args("-hdfs_zone_info_zip=%s" % |
| get_fs_path("/test-warehouse/tzdb/2017c.zip")) |
| def test_invalid_aliases(self, vector): |
| """ Test that conversions from/to invalid timezones return the timestamp |
| without change and issue a warning. |
| |
| IMPALA-7060/IMPALA-3307 removed many abbreviations, aliases and some timezones, |
| because these timezone names are not supported by Hive and Spark. |
| """ |
| timestamp = '2018-04-19 13:07:48.891829000' |
| for function in ['from_utc_timestamp', 'to_utc_timestamp']: |
| for timezone in ['invalid timezone', 'CEST', 'Mideast/Riyadh87']: |
| result = self.execute_query_expect_success(self.client, |
| "select {0}('{1}', '{2}');".format(function, timestamp, timezone)) |
| assert "UDF WARNING: Unknown timezone '%s'" % timezone == result.log.strip() |
| assert timestamp == result.get_data() |
| |
| |
| @CustomClusterTestSuite.with_args("-hdfs_zone_info_zip=%s -hdfs_zone_alias_conf=%s" % |
| (get_fs_path("/test-warehouse/tzdb/2017c.zip"), |
| get_fs_path("/test-warehouse/tzdb/alias.conf"))) |
| def test_shared_timezone_aliases(self, vector): |
| ts_utc = '2018-04-19 13:07:48.891829000' |
| ts_utc_plus5400sec = '2018-04-19 14:37:48.891829000' |
| ts_utc_min5400sec = '2018-04-19 11:37:48.891829000' |
| |
| # Test tz abbreviations that are not listed in the custom aliases config file. |
| # Impala should issue a warning and fall back to UTC. |
| for abbrev in ['PST', 'JST', 'ACT', 'VST']: |
| result = self.execute_query_expect_success(self.client, |
| "select from_utc_timestamp('{0}', '{1}');".format(ts_utc, abbrev)) |
| assert "UDF WARNING: Unknown timezone '%s'" % abbrev == result.log.strip() |
| assert ts_utc == result.get_data() |
| |
| # Test custom tz aliases defined as aliases for time-zones. |
| data = self.execute_query_expect_success(self.client, """ |
| select from_utc_timestamp('{0}', 'America/Cancun'), |
| from_utc_timestamp('{0}', 'Cancun'), |
| from_utc_timestamp('{0}', 'America/Argentina/Mendoza'), |
| from_utc_timestamp('{0}', 'Mendoza'), |
| from_utc_timestamp('{0}', 'Mendoza2'), |
| from_utc_timestamp('{0}', 'Utc'), |
| from_utc_timestamp('{0}', 'Etc/GMT+1'), |
| from_utc_timestamp('{0}', 'GMT-01:00'), |
| from_utc_timestamp('{0}', 'Asia/Riyadh'), |
| from_utc_timestamp('{0}', 'Mideast/Riyadh89'); |
| """.format(ts_utc)).get_data() |
| ts_cancun, ts_cancun_alias,\ |
| ts_mendoza, ts_mendoza_alias, ts_mendoza_alias2,\ |
| ts_utc_alias,\ |
| ts_gmt_plus_1hour, ts_gmt_plus_1hour_alias,\ |
| ts_riyadh, ts_riyadh_alias = data.split('\t') |
| |
| assert ts_cancun == ts_cancun_alias |
| assert ts_mendoza == ts_mendoza_alias == ts_mendoza_alias2 |
| assert ts_utc == ts_utc_alias |
| assert ts_gmt_plus_1hour == ts_gmt_plus_1hour_alias |
| assert ts_riyadh == ts_riyadh_alias |
| |
| # Test custom tz reviations defined as UTC offsets. |
| data = self.execute_query_expect_success(self.client, """ |
| select from_utc_timestamp('{0}', 'Fifty-Four-Hundred'), |
| from_utc_timestamp('{0}', 'Min-Fifty-Four-Hundred'); |
| """.format(ts_utc)).get_data() |
| assert [ts_utc_plus5400sec, ts_utc_min5400sec] == data.split('\t') |