# Copyright 2018 Google Inc.
#
# Licensed 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.

import os
import mock
import shutil
import tempfile

from future.tests.base import unittest

from mobly import base_test
from mobly import config_parser
from mobly import records
from mobly import test_runner

from tests.lib import mock_controller
from tests.lib import utils


class TestSuiteTest(unittest.TestCase):
    """Tests for use cases of creating Mobly test suites.

    Tests here target a combination of test_runner and base_test code.
    """
    def setUp(self):
        self.tmp_dir = tempfile.mkdtemp()
        self.mock_test_cls_configs = config_parser.TestRunConfig()
        self.summary_file = os.path.join(self.tmp_dir, 'summary.yaml')
        self.mock_test_cls_configs.summary_writer = records.TestSummaryWriter(
            self.summary_file)
        self.mock_test_cls_configs.log_path = self.tmp_dir
        self.mock_test_cls_configs.user_params = {"some_param": "hahaha"}
        self.mock_test_cls_configs.reporter = mock.MagicMock()
        self.base_mock_test_config = config_parser.TestRunConfig()
        self.base_mock_test_config.test_bed_name = 'SampleTestBed'
        self.base_mock_test_config.controller_configs = {}
        self.base_mock_test_config.user_params = {
            'icecream': 42,
            'extra_param': 'haha'
        }
        self.base_mock_test_config.log_path = self.tmp_dir

    def tearDown(self):
        shutil.rmtree(self.tmp_dir)

    def test_controller_object_not_persistent_across_classes(self):
        test_run_config = self.base_mock_test_config.copy()
        test_run_config.controller_configs = {'MagicDevice': [{'serial': 1}]}

        class FooTest(base_test.BaseTestClass):
            def setup_class(cls1):
                self.controller1 = cls1.register_controller(mock_controller)[0]

        class BarTest(base_test.BaseTestClass):
            def setup_class(cls2):
                self.controller2 = cls2.register_controller(mock_controller)[0]

        tr = test_runner.TestRunner(self.tmp_dir,
                                    test_run_config.test_bed_name)
        with tr.mobly_logger():
            tr.add_test_class(test_run_config, FooTest)
            tr.add_test_class(test_run_config, BarTest)
            tr.run()
        self.assertIsNot(self.controller1, self.controller2)


if __name__ == "__main__":
    unittest.main()
