adb: let `adb push` follow symlinks.

Bug: http://b/31491920
Test: touch foo; ln -s foo bar; adb push bar /data/local/tmp
Test: python test_device.py
Change-Id: I0a00b3d49fdf7206e27d66ac110b56e22449a1ad
diff --git a/adb/test_device.py b/adb/test_device.py
index 2efac9d..b12bf88 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -787,6 +787,36 @@
             if host_dir is not None:
                 shutil.rmtree(host_dir)
 
+    @unittest.skipIf(sys.platform == "win32", "symlinks require elevated privileges on windows")
+    def test_push_symlink(self):
+        """Push a symlink.
+
+        Bug: http://b/31491920
+        """
+        try:
+            host_dir = tempfile.mkdtemp()
+
+            # Make sure the temp directory isn't setuid, or else adb will
+            # complain.
+            os.chmod(host_dir, 0o700)
+
+            with open(os.path.join(host_dir, 'foo'), 'w') as f:
+                f.write('foo')
+
+            symlink_path = os.path.join(host_dir, 'symlink')
+            os.symlink('foo', symlink_path)
+
+            self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
+            self.device.shell(['mkdir', self.DEVICE_TEMP_DIR])
+            self.device.push(symlink_path, self.DEVICE_TEMP_DIR)
+            rc, out, _ = self.device.shell_nocheck(
+                ['cat', posixpath.join(self.DEVICE_TEMP_DIR, 'symlink')])
+            self.assertEqual(0, rc)
+            self.assertEqual(out.strip(), 'foo')
+        finally:
+            if host_dir is not None:
+                shutil.rmtree(host_dir)
+
     def test_multiple_push(self):
         """Push multiple files to the device in one adb push command.