# 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.testbed_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.testbed_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()
