#!/usr/bin/env fuchsia-vendored-python
# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unit tests for verify_sdk_compatibility.py"""

import os
import tarfile
import tempfile
import unittest
from tempfile import TemporaryDirectory
from verify_sdk_compatibility import (
    fail_on_breaking_changes, NotifyOnAdditions, SdkCompatibilityError,
    MissingInputError, generate_sdk_layout_golden_file)


class VerifySdkCompatibilityTests(unittest.TestCase):

    def test_fail_on_breaking_changes(self):
        with TemporaryDirectory() as root_build_dir:
            golden1 = os.path.join(root_build_dir, "test_gold1")
            afile = os.path.join(root_build_dir, "afile")
            with open(afile, 'w') as f:
                f.write("file_content")
            start = "/"
            manifest = {
                os.path.relpath(afile, start),
            }
            with open(golden1, 'w') as f:
                for p in manifest:
                    f.write(p)
                    f.write("\n")

            golden2 = os.path.join(root_build_dir, "test_gold2")
            manifest = {
                os.path.relpath(afile, start),
            }
            with open(golden2, 'w') as f:
                for p in manifest:
                    f.write(p + "/")
                    f.write("\n")

            bfile = os.path.join(root_build_dir, "bfile")
            with open(bfile, 'w') as f:
                f.write("file_content")
            golden3 = os.path.join(root_build_dir, "test_gold3")
            manifest = {
                os.path.relpath(afile, start),
                os.path.relpath(bfile, start)
            }
            with open(golden3, 'w') as f:
                for p in manifest:
                    f.write(p)
                    f.write("\n")
            cfile = os.path.join(root_build_dir, "cfile")
            with open(cfile, 'w') as f:
                f.write("file_content")
            dfile = os.path.join(root_build_dir, "dfile")
            with open(dfile, 'w') as f:
                f.write("file_content")
            efile = os.path.join(root_build_dir, "efile")
            with open(efile, 'w') as f:
                f.write("file_content")
            update_golden_path = os.path.join(root_build_dir, "updated")
            with tempfile.NamedTemporaryFile('wb', suffix='.tar.gz',
                                             delete=False) as f:
                with tarfile.open(f.name, mode='w:gz') as tar_curr:
                    tar_curr.add(afile)
                # Assert that a case with no changes should pass.
                mock_gold = "path/to/core.golden"
                self.assertTrue(
                    fail_on_breaking_changes(f.name, golden1, mock_gold) is None
                )
                # Assert that additions to the SDK layout will trigger a notification.
                with tarfile.open(f.name, mode='w:gz') as tar_curr:
                    tar_curr.add(afile)
                    tar_curr.add(bfile)
                    tar_curr.add(cfile)
                self.assertRaisesRegex(
                    NotifyOnAdditions, ".*(?=.*bfile)(?=.*cfile).*",
                    fail_on_breaking_changes, f.name, golden1,
                    update_golden_path)
                # Assert that a mismatch of types will not pass.
                with self.assertRaises(SdkCompatibilityError):
                    fail_on_breaking_changes(
                        f.name, golden2, update_golden_path)
                # Assert that a nonexistent golden file will not pass.
                with self.assertRaises(MissingInputError):
                    fail_on_breaking_changes(f.name, mock_gold, mock_gold)
                # Assert that files with different order, same contents will pass.
                with tarfile.open(f.name, mode='w:gz') as tar_curr:
                    tar_curr.add(bfile)
                    tar_curr.add(afile)
                self.assertTrue(
                    fail_on_breaking_changes(f.name, golden3, mock_gold) is None
                )
                # Assert that a case with breaking changes will not pass (deletion).
                with tarfile.open(f.name, mode='w:gz') as tar_curr:
                    tar_curr.add(bfile)
                self.assertRaisesRegex(
                    SdkCompatibilityError, ".*afile.*",
                    fail_on_breaking_changes, f.name, golden3,
                    update_golden_path)
                # Assert that a case with no matching files does not pass.
                with tarfile.open(f.name, mode='w:gz') as tar_curr:
                    tar_curr.add(dfile)
                    tar_curr.add(efile)
                    tar_curr.add(cfile)
                self.assertRaisesRegex(
                    SdkCompatibilityError, ".*(?=.*bfile)(?=.*afile).*",
                    fail_on_breaking_changes, f.name, golden3,
                    update_golden_path)
                # Assert that a case with one missing path does not pass.
                manifest = {
                    os.path.relpath(cfile, start),
                    os.path.relpath(bfile, start)
                }
                with open(golden3, 'w') as file:
                    for p in manifest:
                        file.write(p)
                        file.write("\n")
                self.assertRaisesRegex(
                    SdkCompatibilityError, ".*bfile*", fail_on_breaking_changes,
                    f.name, golden3, update_golden_path)

            with tempfile.NamedTemporaryFile('wb', suffix='.tar.gz',
                                             delete=False) as f3:
                # Assert that an empty tar file will not pass.
                with self.assertRaises(MissingInputError):
                    fail_on_breaking_changes(f3.name, golden1, mock_gold)

    def test_generate_sdk_layout_golden_file(self):
        with TemporaryDirectory() as root_build_dir:
            file1 = os.path.join(root_build_dir, "test_file1")
            with open(file1, 'w') as f:
                f.write("file_content")

            file2 = os.path.join(root_build_dir, "test_file2")
            with open(file2, 'w') as f:
                f.write("file_content")

            start = "/"
            layout = {
                os.path.relpath(file1, start),
                os.path.relpath(file2, start)
            }

            with tempfile.NamedTemporaryFile('wb', suffix='.tar.gz',
                                             delete=False) as f:
                with tarfile.open(f.name, mode='w:gz') as tar_curr:
                    tar_curr.add(file1)
                    tar_curr.add(file2)
                self.assertTrue(
                    str(generate_sdk_layout_golden_file(f.name)) == str(layout))


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