# 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 shutil
import subprocess
import tempfile

from stestr.tests import base


class TestBisectReturnCodes(base.TestCase):
    def setUp(self):
        super().setUp()
        # Setup test dirs
        self.directory = tempfile.mkdtemp(prefix="stestr-unit")
        self.addCleanup(shutil.rmtree, self.directory)
        self.test_dir = os.path.join(self.directory, "tests")
        os.mkdir(self.test_dir)
        # Setup Test files
        self.testr_conf_file = os.path.join(self.directory, ".stestr.conf")
        self.setup_cfg_file = os.path.join(self.directory, "setup.cfg")
        self.init_file = os.path.join(self.test_dir, "__init__.py")
        self.setup_py = os.path.join(self.directory, "setup.py")
        self.user_config = os.path.join(self.directory, "stestr.yaml")
        shutil.copy("stestr/tests/files/testr-conf", self.testr_conf_file)
        shutil.copy("setup.py", self.setup_py)
        shutil.copy("stestr/tests/files/setup.cfg", self.setup_cfg_file)
        shutil.copy("stestr/tests/files/__init__.py", self.init_file)
        shutil.copy("stestr/tests/files/stestr.yaml", self.user_config)

        # Move around the test code
        self.serial_fail_file = os.path.join(self.test_dir, "test_serial_fails.py")
        shutil.copy(
            "stestr/tests/files/bisect-fail-serial-tests", self.serial_fail_file
        )

        # Change directory, run wrapper and check result
        self.addCleanup(os.chdir, os.path.abspath(os.curdir))
        os.chdir(self.directory)
        subprocess.call("stestr init", shell=True)

    def test_bisect_serial_fail_detected(self):
        p = subprocess.Popen(
            "stestr run --serial",
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        out, err = p.communicate()
        self.assertEqual(
            1,
            p.returncode,
            "stestr run returned an unexpected return code"
            "Stdout: %s\nStderr: %s" % (out, err),
        )
        p_analyze = subprocess.Popen(
            "stestr --user-config stestr.yaml run --analyze-isolation",
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        out, err = p_analyze.communicate()
        out = out.decode("utf-8")
        # For debugging potential failures
        lines = str(out.rstrip()).splitlines()
        self.assertEqual(
            3,
            p_analyze.returncode,
            "Analyze isolation returned an unexpected return code"
            "\nStdout: %s\nStderr: %s" % (out, err),
        )
        last_line = (
            "tests.test_serial_fails.TestFakeClass.test_B  "
            "tests.test_serial_fails.TestFakeClass.test_A"
        )
        self.assertEqual(last_line, lines[-1])
