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

from pyflink.dataset import ExecutionEnvironment
from pyflink.testing.test_case_utils import PythonAPICompletenessTestCase, PyFlinkTestCase


class ExecutionEnvironmentCompletenessTests(PythonAPICompletenessTestCase,
                                            PyFlinkTestCase):

    @classmethod
    def python_class(cls):
        return ExecutionEnvironment

    @classmethod
    def java_class(cls):
        return "org.apache.flink.api.java.ExecutionEnvironment"

    @classmethod
    def excluded_methods(cls):
        # Exclude these methods for the time being, because current
        # ExecutionEnvironment/StreamExecutionEnvironment do not apply to the
        # DataSet/DataStream API, but to the Table API configuration.
        # Currently only the methods for configuration is added.
        # 'setSessionTimeout', 'getSessionTimeout', 'setNumberOfExecutionRetries',
        # 'getNumberOfExecutionRetries' is deprecated, exclude them.
        # 'access$000' is generated by java compiler, exclude it too.
        return {'resetContextEnvironment', 'getSessionTimeout', 'fromParallelCollection',
                'getId', 'registerCachedFile', 'setNumberOfExecutionRetries', 'readTextFile',
                'getNumberOfExecutionRetries', 'registerCachedFilesWithPlan',
                'getLastJobExecutionResult', 'readCsvFile', 'initializeContextEnvironment',
                'createLocalEnvironment', 'createLocalEnvironmentWithWebUI', 'createProgramPlan',
                'getIdString', 'setSessionTimeout', 'fromElements', 'createRemoteEnvironment',
                'startNewSession', 'fromCollection', 'readTextFileWithValue', 'registerDataSink',
                'createCollectionsEnvironment', 'readFile', 'readFileOfPrimitives',
                'generateSequence', 'areExplicitEnvironmentsAllowed', 'createInput',
                'getUserCodeClassLoader', 'getExecutorServiceLoader', 'getConfiguration',
                'executeAsync', 'registerJobListener', 'clearJobListeners', 'configure'}


if __name__ == '__main__':
    import unittest

    try:
        import xmlrunner
        testRunner = xmlrunner.XMLTestRunner(output='target/test-reports')
    except ImportError:
        testRunner = None
    unittest.main(testRunner=testRunner, verbosity=2)
