osutils: add Path tests for CopyDirContents

These ensure that simple cases of `CopyDirContents` work with `Path`s.
This also updates the docs of `CopyDirContents` to note that Path
arguments are specifically supported.

BUG=chromium:1035951
TEST=Unittests

Change-Id: Ib58ee814310c5ae2736f736075e61bd85ce16bb9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2377155
Tested-by: George Burgess <gbiv@chromium.org>
Commit-Queue: George Burgess <gbiv@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/lib/osutils.py b/lib/osutils.py
index 46fc46a..f8c7cc3 100644
--- a/lib/osutils.py
+++ b/lib/osutils.py
@@ -469,8 +469,10 @@
     y.py
 
   Args:
-    from_dir: The directory whose contents should be copied. Must exist.
+    from_dir: The directory whose contents should be copied. Must exist. Either
+      a |Path| or a |str|.
     to_dir: The directory to which contents should be copied. Must exist.
+      Either a |Path| or a |str|.
     symlinks: Whether symlinks should be copied or dereferenced. When True, all
         symlinks will be copied as symlinks into the destination. When False,
         the symlinks will be dereferenced and the contents copied over.
diff --git a/lib/osutils_unittest.py b/lib/osutils_unittest.py
index a37608a..d5812d1 100644
--- a/lib/osutils_unittest.py
+++ b/lib/osutils_unittest.py
@@ -1155,6 +1155,44 @@
         filecmp.cmp(os.path.join(out_dir_symlinks_dir_subdir, 'b.txt'),
                     tmp_subdir_file))
 
+  @unittest.skipIf(sys.version_info.major < 3, 'Requires pathlib from py3')
+  def testCopyingSymlinksAndFilesWithPathArgs(self):
+    """Copying given |Path| arguments works properly for symlinks+files."""
+    in_dir = Path(self.tempdir) / 'input'
+    osutils.SafeMakedirs(in_dir)
+
+    tmp_file = in_dir / 'a.txt'
+    tmp_file.write_text('aaa', encoding='utf-8')
+    tmp_file_link = tmp_file.with_suffix('.link')
+    tmp_file_link.symlink_to(tmp_file)
+
+    out_dir = Path(self.tempdir) / 'output'
+    osutils.SafeMakedirs(out_dir)
+    osutils.CopyDirContents(in_dir, out_dir, symlinks=True)
+
+    out_tmp_file = out_dir / tmp_file.name
+    self.assertEqual(out_tmp_file.read_text(encoding='utf-8'), 'aaa')
+    out_tmp_file_link = out_dir / tmp_file_link.name
+    self.assertEqual(Path(os.readlink(out_tmp_file_link)), tmp_file)
+
+  @unittest.skipIf(sys.version_info.major < 3, 'Requires pathlib from py3')
+  def testCopyingSubDirWithPathArgs(self):
+    """Copying given |Path| arguments works properly for subdirectories."""
+    in_dir = Path(self.tempdir) / 'input'
+    osutils.SafeMakedirs(in_dir)
+
+    tmp_file = in_dir / 'subdir' / 'a.txt'
+    osutils.SafeMakedirs(tmp_file.parent)
+
+    tmp_file.write_text('aaa', encoding='utf-8')
+
+    out_dir = Path(self.tempdir) / 'output'
+    osutils.SafeMakedirs(out_dir)
+    osutils.CopyDirContents(in_dir, out_dir, symlinks=True)
+
+    out_tmp_file = out_dir / 'subdir' / tmp_file.name
+    self.assertEqual(out_tmp_file.read_text(encoding='utf-8'), 'aaa')
+
 
 class WhichTests(cros_test_lib.TempDirTestCase):
   """Test Which."""