Repository: iterative/dvc

Issue:
gdrive: failed to push data to the cloud - Expecting value: line 1 column 1 (char 0) with empty file
## Bug Report

Hi there, this is actually my first ever `dvc push` and I have a lot of small files. Here's the result of push:

```console
2020-09-22 14:05:41,473 DEBUG: Uploading '.dvc/cache/d4/1d8cd98f00b204e9800998ecf8427e' to 'gdrive://<FOLDER_ID>/d4/1d8cd98f00b204e9800998ecf8427e'                                                         
2020-09-22 14:05:42,008 ERROR: failed to upload '.dvc/cache/d4/1d8cd98f00b204e9800998ecf8427e' to 'gdrive://<FOLDER_ID>/d4/1d8cd98f00b204e9800998ecf8427e' - Expecting value: line 1 column 1 (char 0)      
------------------------------------------------------------                                                                                                                                                                      
Traceback (most recent call last):
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/cache/local.py", line 31, in wrapper
    func(from_info, to_info, *args, **kwargs)
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/tree/base.py", line 351, in upload
    no_progress_bar=no_progress_bar,
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/tree/gdrive.py", line 573, in _upload
    parent_id, to_info.name, no_progress_bar, from_file, name
  File "/snap/dvc/805/lib/python3.6/site-packages/funcy/decorators.py", line 39, in wrapper
    return deco(call, *dargs, **dkwargs)
  File "/snap/dvc/805/lib/python3.6/site-packages/funcy/flow.py", line 122, in retry
    return call()
  File "/snap/dvc/805/lib/python3.6/site-packages/funcy/decorators.py", line 60, in __call__
    return self._func(*self._args, **self._kwargs)
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/tree/gdrive.py", line 370, in _gdrive_upload_file
    item.Upload()
  File "/snap/dvc/805/lib/python3.6/site-packages/pydrive2/files.py", line 531, in Upload
    self._FilesInsert(param=param)
  File "/snap/dvc/805/lib/python3.6/site-packages/pydrive2/auth.py", line 84, in _decorated
    return decoratee(self, *args, **kwargs)
  File "/snap/dvc/805/lib/python3.6/site-packages/pydrive2/files.py", line 639, in _FilesInsert
    raise ApiRequestError(error)
  File "/snap/dvc/805/lib/python3.6/site-packages/pydrive2/files.py", line 34, in __init__
    content = json.loads(http_error.content.decode("utf-8"))
  File "/snap/dvc/805/usr/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/snap/dvc/805/usr/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/snap/dvc/805/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
------------------------------------------------------------
2020-09-22 14:05:42,012 DEBUG: failed to upload full contents of 'data', aborting .dir file upload                                                                                                                                
2020-09-22 14:05:42,012 ERROR: failed to upload '.dvc/cache/1c/3669b1a474b5d6705fd4c23975070c.dir' to 'gdrive://<FOLDER_ID>/1c/3669b1a474b5d6705fd4c23975070c.dir'                                          
2020-09-22 14:05:42,014 DEBUG: fetched: [(3340,)]                                                                                                                                                                                 
2020-09-22 14:05:42,020 ERROR: failed to push data to the cloud - 2 files failed to upload
------------------------------------------------------------
Traceback (most recent call last):
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/command/data_sync.py", line 59, in run
    run_cache=self.args.run_cache,
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/repo/__init__.py", line 51, in wrapper
    return f(repo, *args, **kwargs)
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/repo/push.py", line 35, in push
    return len(used_run_cache) + self.cloud.push(used, jobs, remote=remote)
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/data_cloud.py", line 66, in push
    cache, jobs=jobs, remote=remote, show_checksums=show_checksums,
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/remote/base.py", line 15, in wrapper
    return f(obj, named_cache, remote, *args, **kwargs)
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/cache/local.py", line 431, in push
    download=False,
  File "/snap/dvc/805/lib/python3.6/site-packages/dvc/cache/local.py", line 395, in _process
    raise UploadError(fails)
dvc.exceptions.UploadError: 2 files failed to upload
------------------------------------------------------------
2020-09-22 14:05:42,024 DEBUG: Analytics is enabled.
2020-09-22 14:05:42,077 DEBUG: Trying to spawn '['daemon', '-q', 'analytics', '/tmp/tmp3xs238sk']'
2020-09-22 14:05:42,078 DEBUG: Spawned '['daemon', '-q', 'analytics', '/tmp/tmp3xs238sk']'

```
`.dvc/cache/d4/1d8cd98f00b204e9800998ecf8427e` is empty so it probably corresponds to some empty file. Nevertheless I would like to upload it. 


### Please provide information about your setup

**Output of `dvc version`:**

```console
$ dvc version
DVC version: 1.7.3 (snap)                                                                                                                                                                                                         
---------------------------------                                                                                                                                                                                                 
Platform: Python 3.6.9 on Linux-5.4.0-42-generic-x86_64-with-Ubuntu-18.04-bionic                                                                                                                                                  
Supports: All remotes                                                                                                                                                                                                             
Cache types: hardlink, symlink                                                                                                                                                                                                    
Repo: dvc, git 
```



Discussion:
Related to https://github.com/iterative/dvc/issues/4507 . Looks like we didn't cover Inserts.

Resolving patch:
diff --git a/dvc/tree/gdrive.py b/dvc/tree/gdrive.py
--- a/dvc/tree/gdrive.py
+++ b/dvc/tree/gdrive.py
@@ -366,7 +366,10 @@ def _gdrive_upload_file(
                 total=total,
                 disable=no_progress_bar,
             ) as wrapped:
-                item.content = wrapped
+                # PyDrive doesn't like content property setting for empty files
+                # https://github.com/gsuitedevs/PyDrive/issues/121
+                if total:
+                    item.content = wrapped
                 item.Upload()
         return item
 


Test patch:
diff --git a/tests/func/test_data_cloud.py b/tests/func/test_data_cloud.py
--- a/tests/func/test_data_cloud.py
+++ b/tests/func/test_data_cloud.py
@@ -19,7 +19,17 @@
 from dvc.utils.fs import move, remove
 from dvc.utils.serialize import dump_yaml, load_yaml
 
-from .test_api import all_clouds
+all_clouds = [
+    pytest.lazy_fixture(cloud)
+    for cloud in ["s3", "gs", "azure", "gdrive", "ssh", "http"]
+] + [
+    pytest.param(
+        pytest.lazy_fixture("oss"),
+        marks=pytest.mark.xfail(
+            reason="https://github.com/iterative/dvc/issues/4633",
+        ),
+    )
+]
 
 
 @pytest.mark.parametrize("remote", all_clouds, indirect=True)
@@ -35,6 +45,7 @@ def test_cloud(tmp_dir, dvc, remote):  # pylint:disable=unused-argument
             "data_dir": {
                 "data_sub_dir": {"data_sub": "data_sub"},
                 "data": "data",
+                "empty": "",
             }
         }
     )
@@ -128,6 +139,7 @@ def test_cloud_cli(tmp_dir, dvc, remote):
             "data_dir": {
                 "data_sub_dir": {"data_sub": "data_sub"},
                 "data": "data",
+                "empty": "",
             }
         }
     )