You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
depot_tools/tests/presubmit_diff_test.py

277 lines
8.4 KiB
Python

#!/usr/bin/env vpython3
# Copyright (c) 2024 The Chromium 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 presubmit_diff.py."""
import os
import sys
import tempfile
import unittest
from typing import Dict, List
from unittest import mock
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import gclient_utils
import presubmit_diff
class PresubmitDiffTest(unittest.TestCase):
def setUp(self):
# State of the local directory.
self.root = tempfile.mkdtemp()
os.makedirs(os.path.join(self.root, "nested"))
# On Windows, writing "\n" in text mode becomes "\r\n". Write in binary
# so that doesn't happen, otherwise tests will fail.
with open(os.path.join(self.root, "unchanged.txt"), "wb") as f:
f.write("unchanged\n".encode("utf-8"))
with open(os.path.join(self.root, "added.txt"), "wb") as f:
f.write("added\n".encode("utf-8"))
with open(os.path.join(self.root, "modified.txt"), "wb") as f:
f.write("modified... foo\n".encode("utf-8"))
with open(os.path.join(self.root, "nested/modified.txt"), "wb") as f:
f.write("goodbye\n".encode("utf-8"))
# State of the remote repository.
fetch_data = {
"unchanged.txt": "unchanged\n".encode("utf-8"),
"deleted.txt": "deleted\n".encode("utf-8"),
"modified.txt": "modified... bar\n".encode("utf-8"),
"nested/modified.txt": "hello\n".encode("utf-8"),
# Intenionally invalid start byte for utf-8.
"deleted_binary": b"\xff\x00",
}
def fetch_side_effect(host, repo, ref, file):
return fetch_data.get(file, b"")
fetch_content_mock = mock.patch("presubmit_diff.fetch_content",
side_effect=fetch_side_effect)
fetch_content_mock.start()
self.addCleanup(mock.patch.stopall)
def tearDown(self):
gclient_utils.rmtree(self.root)
def _test_create_diffs(self, files: List[str], expected: Dict[str, str]):
actual = presubmit_diff.create_diffs("host", "repo", "ref", self.root,
Revert "Reland "add support for -U in presubmit_diff.py"" This reverts commit 9a9142793a90d65cd1424f6826be89ec15bfa233. Reason for revert: failed again Original change's description: > Reland "add support for -U in presubmit_diff.py" > > This reverts commit 4c54361841933e29ec19a3104e4f11f0e898674a. > > Reason for revert: Reland with a fix. > > Find https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6173762/1..2 > Tested by running presubmit_support.py --generate_diff > > > Original change's description: > > Revert "add support for -U in presubmit_diff.py" > > > > This reverts commit b576ab3b78a9d19c33060c821d4f11643397fa30. > > > > Reason for revert: http://b/389876151 > > > > Original change's description: > > > add support for -U in presubmit_diff.py > > > > > > presubmit_diff.py is going to be used to compute the changes to be > > > formatted, and -U helps minimize the number of irrelevant lines > > > from formatting. > > > > > > Bug: 379902295 > > > Change-Id: I9c0a2ee6b5ffa6b9fe4427362556020d525f1105 > > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6168707 > > > Reviewed-by: Gavin Mak <gavinmak@google.com> > > > Commit-Queue: Scott Lee <ddoman@chromium.org> > > > > Bug: 379902295 > > Change-Id: I82dd707e5ae3d4b1760e632506ee0e1bc1d76e09 > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6173760 > > Reviewed-by: Scott Lee <ddoman@chromium.org> > > Commit-Queue: Gavin Mak <gavinmak@google.com> > > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > > Bug: 379902295 > Change-Id: Icbc4aa98bbfaa816143be064217fb2d992b48baf > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6173762 > Reviewed-by: Gavin Mak <gavinmak@google.com> > Commit-Queue: Scott Lee <ddoman@chromium.org> Bug: 379902295 Change-Id: I84875f6667689e1a9085876555bc6aef4ea2d7b4 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/6177776 Commit-Queue: Scott Lee <ddoman@chromium.org> Reviewed-by: Gary Tong <gatong@chromium.org>
1 month ago
files)
self.assertEqual(actual.keys(), expected.keys())
# Manually check each line in the diffs except the "index" line because
# hashes can differ in length.
for file, diff in actual.items():
expected_lines = expected[file].splitlines()
for idx, line in enumerate(diff.splitlines()):
if line.startswith("index "):
continue
self.assertEqual(line, expected_lines[idx])
def test_create_diffs_with_nonexistent_file_raises_error(self):
self.assertRaises(
RuntimeError,
presubmit_diff.create_diffs,
"host",
"repo",
"ref",
self.root,
["doesnotexist.txt"],
)
def test_create_diffs_with_unchanged_file(self):
self._test_create_diffs(
["unchanged.txt"],
{"unchanged.txt": ""},
)
@mock.patch('subprocess2.capture', return_value="".encode("utf-8"))
def test_create_diffs_executes_git_diff_with_unified(self, capture):
create_diffs = presubmit_diff.create_diffs
# None => no -U
create_diffs("host", "repo", "ref", self.root, ["unchanged.txt"], None)
capture.assert_called_with(
["git", "diff", "--no-index", "--", mock.ANY, mock.ANY])
# 0 => -U0
create_diffs("host", "repo", "ref", self.root, ["unchanged.txt"], 0)
capture.assert_called_with(
["git", "diff", "--no-index", "-U0", "--", mock.ANY, mock.ANY])
# 3 => -U3
create_diffs("host", "repo", "ref", self.root, ["unchanged.txt"], 3)
capture.assert_called_with(
["git", "diff", "--no-index", "-U3", "--", mock.ANY, mock.ANY])
def test_create_diffs_with_added_file(self):
expected_diff = """diff --git a/added.txt b/added.txt
new file mode 100644
index 00000000..d5f7fc3f
--- /dev/null
+++ b/added.txt
@@ -0,0 +1 @@
+added
"""
self._test_create_diffs(
["added.txt"],
{"added.txt": expected_diff},
)
def test_create_diffs_with_deleted_file(self):
expected_diff = """diff --git a/deleted.txt b/deleted.txt
deleted file mode 100644
index 71779d2c..00000000
--- a/deleted.txt
+++ /dev/null
@@ -1 +0,0 @@
-deleted
"""
self._test_create_diffs(
["deleted.txt"],
{"deleted.txt": expected_diff},
)
def test_create_diffs_with_binary_file(self):
expected_diff = """diff --git a/deleted_binary b/deleted_binary
deleted file mode 100644
index ce542efaa..00000000
Binary files a/deleted_binary and /dev/null differ
"""
self._test_create_diffs(
["deleted_binary"],
{"deleted_binary": expected_diff},
)
# pylint: disable=line-too-long
def test_create_diffs_with_modified_files(self):
expected_diff = """diff --git a/modified.txt b/modified.txt
index a7dd0b00..12d68703 100644
--- a/modified.txt
+++ b/modified.txt
@@ -1 +1 @@
-modified... bar
+modified... foo
"""
expected_nested_diff = """diff --git a/nested/modified.txt b/nested/modified.txt
index ce013625..dd7e1c6f 100644
--- a/nested/modified.txt
+++ b/nested/modified.txt
@@ -1 +1 @@
-hello
+goodbye
"""
self._test_create_diffs(
["modified.txt", "nested/modified.txt"],
{
"modified.txt": expected_diff,
"nested/modified.txt": expected_nested_diff,
},
)
# Test cases for _process_diff.
def test_process_diff_with_no_changes(self):
self.assertEqual(
presubmit_diff._process_diff(
"",
"/path/to/src",
"/path/to/dst",
),
"",
)
@mock.patch("platform.system", return_value="Linux")
@mock.patch("os.sep", new="/")
def test_process_diff_handles_unix_paths(self, sys_mock):
diff = """diff --git a/path/to/src/file.txt b/path/to/dst/file.txt
index ce013625..dd7e1c6f 100644
--- a/path/to/file.txt
+++ b/path/to/file.txt
@@ -1 +1 @@
-random
+content
"""
expected = """diff --git a/file.txt b/file.txt
index ce013625..dd7e1c6f 100644
--- a/path/to/file.txt
+++ b/path/to/file.txt
@@ -1 +1 @@
-random
+content
"""
self.assertEqual(
presubmit_diff._process_diff(
diff,
"/path/to/src",
"/path/to/dst",
),
expected,
)
# Trailing slashes are handled.
self.assertEqual(
presubmit_diff._process_diff(
diff,
"/path/to/src/",
"/path/to/dst/",
),
expected,
)
@mock.patch("platform.system", return_value="Windows")
@mock.patch("os.sep", new="\\")
def test_process_diff_handles_windows_paths(self, sys_mock):
diff = """diff --git "a/C:\\\\path\\\\to\\\\src\\\\file.txt" "b/C:\\\\path\\\\to\\\\dst\\\\file.txt"
index ce013625..dd7e1c6f 100644
--- "a/C:\\\\path\\\\to\\\\src\\\\file.txt
+++ "b/C:\\\\path\\\\to\\\\dst\\\\file.txt"
@@ -1 +1 @@
-random
+content
"""
expected = """diff --git a/file.txt b/file.txt
index ce013625..dd7e1c6f 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1 @@
-random
+content
"""
self.assertEqual(
expected,
presubmit_diff._process_diff(diff, "C:\\path\\to\\src",
"C:\\path\\to\\dst"),
)
# Trailing slashes are handled.
self.assertEqual(
expected,
presubmit_diff._process_diff(diff, "C:\\path\\to\\src\\",
"C:\\path\\to\\dst\\"),
)
@mock.patch("platform.system", return_value="Linux")
def test_process_diff_without_chunk_header(self, sys_mock):
diff = """diff --git a/path/to/src/file.txt b/path/to/dst/file.txt
old mode 100644
new mode 100755
"""
expected = """diff --git a/file.txt b/file.txt
old mode 100644
new mode 100755
"""
self.assertEqual(
presubmit_diff._process_diff(
diff,
"/path/to/src",
"/path/to/dst",
),
expected,
)
if __name__ == "__main__":
unittest.main()