Repository: iterative/dvc

Issue:
tests: erepo upstream should not be its cache
Setting default remote as [repository cache](https://github.com/iterative/dvc/blob/f9d4ef8abd5427b0ec75f7f3c1211abd8528aa99/tests/conftest.py#L152) inside `erepo` is kinda hacky. This is not a real use case, and some test relay on the `erepo` property (that is automatically adding cached files to remote because cache and remote are the same thing). `erepo` remote should not be its cache. 

This issue will probably be obsolete after #2599. In that case, the code responsible for setting remote in `erepo` should be completely removed.

Related #2852 

Discussion:

Patch:
diff --git a/dvc/config.py b/dvc/config.py
index dde2cb081..1d96d7555 100644
--- a/dvc/config.py
+++ b/dvc/config.py
@@ -151,6 +151,7 @@ SCHEMA = {
                     Optional("listobjects", default=False): Bool,
                     Optional("use_ssl", default=True): Bool,
                     "sse": str,
+                    "sse_kms_key_id": str,
                     "acl": str,
                     "grant_read": str,
                     "grant_read_acp": str,
diff --git a/dvc/remote/s3.py b/dvc/remote/s3.py
index 0ebb4099f..8d92642e9 100644
--- a/dvc/remote/s3.py
+++ b/dvc/remote/s3.py
@@ -46,6 +46,10 @@ class S3Remote(BaseRemote):
         if self.sse:
             self.extra_args["ServerSideEncryption"] = self.sse
 
+        self.sse_kms_key_id = config.get("sse_kms_key_id")
+        if self.sse_kms_key_id:
+            self.extra_args["SSEKMSKeyId"] = self.sse_kms_key_id
+
         self.acl = config.get("acl")
         if self.acl:
             self.extra_args["ACL"] = self.acl
diff --git a/dvc/stage/cache.py b/dvc/stage/cache.py
index c383d8725..18c2cb2f5 100644
--- a/dvc/stage/cache.py
+++ b/dvc/stage/cache.py
@@ -1,5 +1,6 @@
 import logging
 import os
+from contextlib import contextmanager
 
 import yaml
 from funcy import first
@@ -76,6 +77,45 @@ class StageCache:
 
         return None
 
+    def _create_stage(self, cache):
+        from dvc.stage import create_stage, PipelineStage
+
+        stage = create_stage(
+            PipelineStage,
+            repo=self.repo,
+            path="dvc.yaml",
+            cmd=cache["cmd"],
+            deps=[dep["path"] for dep in cache["deps"]],
+            outs=[out["path"] for out in cache["outs"]],
+        )
+        StageLoader.fill_from_lock(stage, cache)
+        return stage
+
+    @contextmanager
+    def _cache_type_copy(self):
+        cache_types = self.repo.cache.local.cache_types
+        self.repo.cache.local.cache_types = ["copy"]
+        try:
+            yield
+        finally:
+            self.repo.cache.local.cache_types = cache_types
+
+    def _uncached_outs(self, stage, cache):
+        # NOTE: using temporary stage to avoid accidentally modifying original
+        # stage and to workaround `commit/checkout` not working for uncached
+        # outputs.
+        cached_stage = self._create_stage(cache)
+
+        outs_no_cache = [
+            out.def_path for out in stage.outs if not out.use_cache
+        ]
+
+        # NOTE: using copy link to make it look like a git-tracked file
+        with self._cache_type_copy():
+            for out in cached_stage.outs:
+                if out.def_path in outs_no_cache:
+                    yield out
+
     def save(self, stage):
         cache_key = _get_stage_hash(stage)
         if not cache_key:
@@ -84,7 +124,13 @@ class StageCache:
         cache = to_single_stage_lockfile(stage)
         cache_value = _get_cache_hash(cache)
 
-        if self._load_cache(cache_key, cache_value):
+        existing_cache = self._load_cache(cache_key, cache_value)
+        cache = existing_cache or cache
+
+        for out in self._uncached_outs(stage, cache):
+            out.commit()
+
+        if existing_cache:
             return
 
         # sanity check
@@ -104,6 +150,9 @@ class StageCache:
             return
         StageLoader.fill_from_lock(stage, cache)
 
+        for out in self._uncached_outs(stage, cache):
+            out.checkout()
+
     @staticmethod
     def _transfer(func, from_remote, to_remote):
         ret = []
@@ -134,7 +183,6 @@ class StageCache:
 
     def get_used_cache(self, used_run_cache, *args, **kwargs):
         from dvc.cache import NamedCache
-        from dvc.stage import create_stage, PipelineStage
 
         cache = NamedCache()
 
@@ -142,14 +190,6 @@ class StageCache:
             entry = self._load_cache(key, value)
             if not entry:
                 continue
-            stage = create_stage(
-                PipelineStage,
-                repo=self.repo,
-                path="dvc.yaml",
-                cmd=entry["cmd"],
-                deps=[dep["path"] for dep in entry["deps"]],
-                outs=[out["path"] for out in entry["outs"]],
-            )
-            StageLoader.fill_from_lock(stage, entry)
+            stage = self._create_stage(entry)
             cache.update(stage.get_used_cache(*args, **kwargs))
         return cache


Test patch:
diff --git a/tests/dir_helpers.py b/tests/dir_helpers.py
index 8e1d87630..3ad9a8bf5 100644
--- a/tests/dir_helpers.py
+++ b/tests/dir_helpers.py
@@ -59,10 +59,10 @@ __all__ = [
     "tmp_dir",
     "scm",
     "dvc",
-    "local_remote",
     "run_copy",
     "erepo_dir",
     "git_dir",
+    "setup_remote",
 ]
 
 
@@ -256,17 +256,6 @@ def _git_init(path):
     git.close()
 
 
-@pytest.fixture
-def local_remote(request, tmp_dir, dvc, make_tmp_dir):
-    path = make_tmp_dir("local-remote")
-    with dvc.config.edit() as conf:
-        conf["remote"]["upstream"] = {"url": fspath(path)}
-        conf["core"]["remote"] = "upstream"
-    if "scm" in request.fixturenames:
-        tmp_dir.scm_add([dvc.config.files["repo"]], commit="add remote")
-    return path
-
-
 @pytest.fixture
 def run_copy(tmp_dir, dvc):
     tmp_dir.gen(
@@ -287,17 +276,7 @@ def run_copy(tmp_dir, dvc):
 
 @pytest.fixture
 def erepo_dir(make_tmp_dir):
-    path = make_tmp_dir("erepo", scm=True, dvc=True)
-
-    # Chdir for git and dvc to work locally
-    with path.chdir():
-        with path.dvc.config.edit() as conf:
-            cache_dir = path.dvc.cache.local.cache_dir
-            conf["remote"]["upstream"] = {"url": cache_dir}
-            conf["core"]["remote"] = "upstream"
-        path.scm_add([path.dvc.config.files["repo"]], commit="add remote")
-
-    return path
+    return make_tmp_dir("erepo", scm=True, dvc=True)
 
 
 @pytest.fixture
@@ -305,3 +284,20 @@ def git_dir(make_tmp_dir):
     path = make_tmp_dir("git-erepo", scm=True)
     path.scm.commit("init repo")
     return path
+
+
+@pytest.fixture
+def setup_remote(make_tmp_dir):
+    def create(repo, url=None, name="upstream", default=True):
+        if not url:
+            url = fspath(make_tmp_dir("local_remote"))
+        with repo.config.edit() as conf:
+            conf["remote"][name] = {"url": url}
+            if default:
+                conf["core"]["remote"] = name
+
+        repo.scm.add(repo.config.files["repo"])
+        repo.scm.commit("add '{}' remote".format(name))
+        return url
+
+    return create
diff --git a/tests/func/test_api.py b/tests/func/test_api.py
index 2f1aef069..cf384971e 100644
--- a/tests/func/test_api.py
+++ b/tests/func/test_api.py
@@ -36,8 +36,8 @@ def test_get_url(tmp_dir, dvc, remote_url):
 
 
 @pytest.mark.parametrize("remote_url", remote_params, indirect=True)
-def test_get_url_external(erepo_dir, remote_url):
-    _set_remote_url_and_commit(erepo_dir.dvc, remote_url)
+def test_get_url_external(erepo_dir, remote_url, setup_remote):
+    setup_remote(erepo_dir.dvc, url=remote_url)
     with erepo_dir.chdir():
         erepo_dir.dvc_gen("foo", "foo", commit="add foo")
 
@@ -71,8 +71,8 @@ def test_open(remote_url, tmp_dir, dvc):
 
 
 @pytest.mark.parametrize("remote_url", all_remote_params, indirect=True)
-def test_open_external(remote_url, erepo_dir):
-    _set_remote_url_and_commit(erepo_dir.dvc, remote_url)
+def test_open_external(remote_url, erepo_dir, setup_remote):
+    setup_remote(erepo_dir.dvc, url=remote_url)
 
     with erepo_dir.chdir():
         erepo_dir.dvc_gen("version", "master", commit="add version")
@@ -106,13 +106,6 @@ def test_missing(remote_url, tmp_dir, dvc):
         api.read("foo")
 
 
-def _set_remote_url_and_commit(repo, remote_url):
-    with repo.config.edit() as conf:
-        conf["remote"]["upstream"]["url"] = remote_url
-    repo.scm.add([repo.config.files["repo"]])
-    repo.scm.commit("modify remote")
-
-
 def test_open_scm_controlled(tmp_dir, erepo_dir):
     erepo_dir.scm_gen({"scm_controlled": "file content"}, commit="create file")
 
diff --git a/tests/func/test_data_cloud.py b/tests/func/test_data_cloud.py
index e17633b1b..21c1ba495 100644
--- a/tests/func/test_data_cloud.py
+++ b/tests/func/test_data_cloud.py
@@ -8,7 +8,7 @@ from unittest import SkipTest
 import pytest
 
 from dvc.cache import NamedCache
-from dvc.compat import fspath, fspath_py35
+from dvc.compat import fspath
 from dvc.data_cloud import DataCloud
 from dvc.external_repo import clean_repos
 from dvc.main import main
@@ -688,14 +688,13 @@ class TestShouldWarnOnNoChecksumInLocalAndRemoteCache(TestDvc):
         assert self.message_bar_part in self._caplog.text
 
 
-def test_verify_checksums(tmp_dir, scm, dvc, mocker, tmp_path_factory):
+def test_verify_checksums(
+    tmp_dir, scm, dvc, mocker, tmp_path_factory, setup_remote
+):
+
+    setup_remote(dvc, name="upstream")
     tmp_dir.dvc_gen({"file": "file1 content"}, commit="add file")
     tmp_dir.dvc_gen({"dir": {"subfile": "file2 content"}}, commit="add dir")
-
-    dvc.config["remote"]["local_remote"] = {
-        "url": fspath(tmp_path_factory.mktemp("local_remote"))
-    }
-    dvc.config["core"]["remote"] = "local_remote"
     dvc.push()
 
     # remove artifacts and cache to trigger fetching
@@ -711,7 +710,7 @@ def test_verify_checksums(tmp_dir, scm, dvc, mocker, tmp_path_factory):
     # Removing cache will invalidate existing state entries
     remove(dvc.cache.local.cache_dir)
 
-    dvc.config["remote"]["local_remote"]["verify"] = True
+    dvc.config["remote"]["upstream"]["verify"] = True
 
     dvc.pull()
     assert checksum_spy.call_count == 3
@@ -784,13 +783,15 @@ def recurse_list_dir(d):
     ]
 
 
-def test_dvc_pull_pipeline_stages(tmp_dir, dvc, local_remote, run_copy):
+def test_dvc_pull_pipeline_stages(tmp_dir, dvc, run_copy, setup_remote):
+    setup_remote(dvc)
     (stage0,) = tmp_dir.dvc_gen("foo", "foo")
     stage1 = run_copy("foo", "bar", single_stage=True)
     stage2 = run_copy("bar", "foobar", name="copy-bar-foobar")
+    dvc.push()
+
     outs = ["foo", "bar", "foobar"]
 
-    dvc.push()
     clean(outs, dvc)
     dvc.pull()
     assert all((tmp_dir / file).exists() for file in outs)
@@ -814,7 +815,8 @@ def test_dvc_pull_pipeline_stages(tmp_dir, dvc, local_remote, run_copy):
     assert set(stats["added"]) == set(outs)
 
 
-def test_pipeline_file_target_ops(tmp_dir, dvc, local_remote, run_copy):
+def test_pipeline_file_target_ops(tmp_dir, dvc, run_copy, setup_remote):
+    remote_path = setup_remote(dvc)
     tmp_dir.dvc_gen("foo", "foo")
     run_copy("foo", "bar", single_stage=True)
 
@@ -829,8 +831,11 @@ def test_pipeline_file_target_ops(tmp_dir, dvc, local_remote, run_copy):
     remove(dvc.stage_cache.cache_dir)
 
     dvc.push()
+
+    outs = ["foo", "bar", "lorem", "ipsum", "baz", "lorem2"]
+
     # each one's a copy of other, hence 3
-    assert len(recurse_list_dir(fspath_py35(local_remote))) == 3
+    assert len(recurse_list_dir(remote_path)) == 3
 
     clean(outs, dvc)
     assert set(dvc.pull(["dvc.yaml"])["added"]) == {"lorem2", "baz"}
@@ -839,13 +844,15 @@ def test_pipeline_file_target_ops(tmp_dir, dvc, local_remote, run_copy):
     assert set(dvc.pull()["added"]) == set(outs)
 
     # clean everything in remote and push
-    clean(local_remote.iterdir())
+    from tests.dir_helpers import TmpDir
+
+    clean(TmpDir(remote_path).iterdir())
     dvc.push(["dvc.yaml:copy-ipsum-baz"])
-    assert len(recurse_list_dir(fspath_py35(local_remote))) == 1
+    assert len(recurse_list_dir(remote_path)) == 1
 
-    clean(local_remote.iterdir())
+    clean(TmpDir(remote_path).iterdir())
     dvc.push(["dvc.yaml"])
-    assert len(recurse_list_dir(fspath_py35(local_remote))) == 2
+    assert len(recurse_list_dir(remote_path)) == 2
 
     with pytest.raises(StageNotFound):
         dvc.push(["dvc.yaml:StageThatDoesNotExist"])
@@ -862,8 +869,10 @@ def test_pipeline_file_target_ops(tmp_dir, dvc, local_remote, run_copy):
         ({}, "Everything is up to date"),
     ],
 )
-def test_push_stats(tmp_dir, dvc, fs, msg, local_remote, caplog):
+def test_push_stats(tmp_dir, dvc, fs, msg, caplog, setup_remote):
+    setup_remote(dvc)
     tmp_dir.dvc_gen(fs)
+
     caplog.clear()
     with caplog.at_level(level=logging.INFO, logger="dvc"):
         main(["push"])
@@ -878,7 +887,8 @@ def test_push_stats(tmp_dir, dvc, fs, msg, local_remote, caplog):
         ({}, "Everything is up to date."),
     ],
 )
-def test_fetch_stats(tmp_dir, dvc, fs, msg, local_remote, caplog):
+def test_fetch_stats(tmp_dir, dvc, fs, msg, caplog, setup_remote):
+    setup_remote(dvc)
     tmp_dir.dvc_gen(fs)
     dvc.push()
     clean(list(fs.keys()), dvc)
@@ -888,7 +898,8 @@ def test_fetch_stats(tmp_dir, dvc, fs, msg, local_remote, caplog):
     assert msg in caplog.text
 
 
-def test_pull_stats(tmp_dir, dvc, local_remote, caplog):
+def test_pull_stats(tmp_dir, dvc, caplog, setup_remote):
+    setup_remote(dvc)
     tmp_dir.dvc_gen({"foo": "foo", "bar": "bar"})
     dvc.push()
     clean(["foo", "bar"], dvc)
diff --git a/tests/func/test_external_repo.py b/tests/func/test_external_repo.py
index 34236b418..d6f951f79 100644
--- a/tests/func/test_external_repo.py
+++ b/tests/func/test_external_repo.py
@@ -43,9 +43,11 @@ def test_source_change(erepo_dir):
     assert old_rev != new_rev
 
 
-def test_cache_reused(erepo_dir, mocker):
+def test_cache_reused(erepo_dir, mocker, setup_remote):
+    setup_remote(erepo_dir.dvc)
     with erepo_dir.chdir():
         erepo_dir.dvc_gen("file", "text", commit="add file")
+    erepo_dir.dvc.push()
 
     download_spy = mocker.spy(LocalRemote, "download")
 
@@ -63,6 +65,8 @@ def test_cache_reused(erepo_dir, mocker):
 
 
 def test_known_sha(erepo_dir):
+    erepo_dir.scm.commit("init")
+
     url = "file://{}".format(erepo_dir)
     with external_repo(url) as repo:
         rev = repo.scm.get_rev()
@@ -92,7 +96,7 @@ def test_pull_subdir_file(tmp_dir, erepo_dir):
     assert dest.read_text() == "contents"
 
 
-def test_relative_remote(erepo_dir, tmp_dir):
+def test_relative_remote(erepo_dir, tmp_dir, setup_remote):
     # these steps reproduce the script on this issue:
     # https://github.com/iterative/dvc/issues/2756
     with erepo_dir.chdir():
@@ -100,13 +104,8 @@ def test_relative_remote(erepo_dir, tmp_dir):
 
     upstream_dir = tmp_dir
     upstream_url = relpath(upstream_dir, erepo_dir)
-    with erepo_dir.dvc.config.edit() as conf:
-        conf["remote"]["upstream"] = {"url": upstream_url}
-        conf["core"]["remote"] = "upstream"
+    setup_remote(erepo_dir.dvc, url=upstream_url, name="upstream")
 
-    erepo_dir.scm_add(
-        erepo_dir.dvc.config.files["repo"], commit="Update dvc config"
-    )
     erepo_dir.dvc.push()
 
     (erepo_dir / "file").unlink()
diff --git a/tests/func/test_gc.py b/tests/func/test_gc.py
index 6eace936c..050548334 100644
--- a/tests/func/test_gc.py
+++ b/tests/func/test_gc.py
@@ -238,18 +238,18 @@ def test_gc_without_workspace_raises_error(tmp_dir, dvc):
         dvc.gc(force=True, workspace=False)
 
 
-def test_gc_cloud_with_or_without_specifier(tmp_dir, erepo_dir):
+def test_gc_cloud_with_or_without_specifier(tmp_dir, erepo_dir, setup_remote):
     dvc = erepo_dir.dvc
-    with erepo_dir.chdir():
-        from dvc.exceptions import InvalidArgumentError
+    setup_remote(dvc)
+    from dvc.exceptions import InvalidArgumentError
 
-        with pytest.raises(InvalidArgumentError):
-            dvc.gc(force=True, cloud=True)
+    with pytest.raises(InvalidArgumentError):
+        dvc.gc(force=True, cloud=True)
 
-        dvc.gc(cloud=True, all_tags=True)
-        dvc.gc(cloud=True, all_commits=True)
-        dvc.gc(cloud=True, all_branches=True)
-        dvc.gc(cloud=True, all_commits=False, all_branches=True, all_tags=True)
+    dvc.gc(cloud=True, all_tags=True)
+    dvc.gc(cloud=True, all_commits=True)
+    dvc.gc(cloud=True, all_branches=True)
+    dvc.gc(cloud=True, all_commits=False, all_branches=True, all_tags=True)
 
 
 def test_gc_without_workspace_on_tags_branches_commits(tmp_dir, dvc):
@@ -295,13 +295,8 @@ def test_gc_with_possible_args_positive(tmp_dir, dvc):
         assert main(["gc", "-vf", flag]) == 0
 
 
-def test_gc_cloud_positive(tmp_dir, dvc, tmp_path_factory):
-    with dvc.config.edit() as conf:
-        storage = fspath(tmp_path_factory.mktemp("test_remote_base"))
-        conf["remote"]["local_remote"] = {"url": storage}
-        conf["core"]["remote"] = "local_remote"
-
-    dvc.push()
+def test_gc_cloud_positive(tmp_dir, dvc, tmp_path_factory, setup_remote):
+    setup_remote(dvc)
 
     for flag in ["-cw", "-ca", "-cT", "-caT", "-cwT"]:
         assert main(["gc", "-vf", flag]) == 0
diff --git a/tests/func/test_get.py b/tests/func/test_get.py
index b05d06b69..3ee57aced 100644
--- a/tests/func/test_get.py
+++ b/tests/func/test_get.py
@@ -197,9 +197,11 @@ def test_get_file_from_dir(tmp_dir, erepo_dir):
     assert (tmp_dir / "X").read_text() == "foo"
 
 
-def test_get_url_positive(tmp_dir, erepo_dir, caplog):
+def test_get_url_positive(tmp_dir, erepo_dir, caplog, setup_remote):
+    setup_remote(erepo_dir.dvc)
     with erepo_dir.chdir():
         erepo_dir.dvc_gen("foo", "foo")
+    erepo_dir.dvc.push()
 
     caplog.clear()
     with caplog.at_level(logging.ERROR, logger="dvc"):
@@ -225,15 +227,17 @@ def test_get_url_git_only_repo(tmp_dir, scm, caplog):
 
 
 def test_get_pipeline_tracked_outs(
-    tmp_dir, dvc, scm, git_dir, local_remote, run_copy
+    tmp_dir, dvc, scm, git_dir, run_copy, setup_remote
 ):
     from dvc.dvcfile import PIPELINE_FILE, PIPELINE_LOCK
 
+    setup_remote(dvc)
     tmp_dir.gen("foo", "foo")
     run_copy("foo", "bar", name="copy-foo-bar")
+    dvc.push()
+
     dvc.scm.add([PIPELINE_FILE, PIPELINE_LOCK])
     dvc.scm.commit("add pipeline stage")
-    dvc.push()
 
     with git_dir.chdir():
         Repo.get("file:///{}".format(fspath(tmp_dir)), "bar", out="baz")
diff --git a/tests/func/test_import.py b/tests/func/test_import.py
index 6ca40fb3c..f2b22e007 100644
--- a/tests/func/test_import.py
+++ b/tests/func/test_import.py
@@ -309,17 +309,20 @@ def test_pull_no_rev_lock(erepo_dir, tmp_dir, dvc):
     assert (tmp_dir / "foo_imported").read_text() == "contents"
 
 
-def test_import_from_bare_git_repo(tmp_dir, make_tmp_dir, erepo_dir):
+def test_import_from_bare_git_repo(
+    tmp_dir, make_tmp_dir, erepo_dir, setup_remote
+):
     import git
 
     git.Repo.init(fspath(tmp_dir), bare=True)
 
+    setup_remote(erepo_dir.dvc)
     with erepo_dir.chdir():
         erepo_dir.dvc_gen({"foo": "foo"}, commit="initial")
-        erepo_dir.dvc.push()
+    erepo_dir.dvc.push()
 
-        erepo_dir.scm.repo.create_remote("origin", fspath(tmp_dir))
-        erepo_dir.scm.repo.remote("origin").push("master")
+    erepo_dir.scm.repo.create_remote("origin", fspath(tmp_dir))
+    erepo_dir.scm.repo.remote("origin").push("master")
 
     dvc_repo = make_tmp_dir("dvc-repo", scm=True, dvc=True)
     with dvc_repo.chdir():
@@ -327,15 +330,17 @@ def test_import_from_bare_git_repo(tmp_dir, make_tmp_dir, erepo_dir):
 
 
 def test_import_pipeline_tracked_outs(
-    tmp_dir, dvc, scm, erepo_dir, local_remote, run_copy
+    tmp_dir, dvc, scm, erepo_dir, run_copy, setup_remote
 ):
     from dvc.dvcfile import PIPELINE_FILE, PIPELINE_LOCK
 
+    setup_remote(dvc)
     tmp_dir.gen("foo", "foo")
     run_copy("foo", "bar", name="copy-foo-bar")
+    dvc.push()
+
     dvc.scm.add([PIPELINE_FILE, PIPELINE_LOCK])
     dvc.scm.commit("add pipeline stage")
-    dvc.push()
 
     with erepo_dir.chdir():
         erepo_dir.dvc.imp(
diff --git a/tests/func/test_remote.py b/tests/func/test_remote.py
index a8d30d819..8e349efb9 100644
--- a/tests/func/test_remote.py
+++ b/tests/func/test_remote.py
@@ -173,10 +173,8 @@ def test_dir_checksum_should_be_key_order_agnostic(tmp_dir, dvc):
     assert checksum1 == checksum2
 
 
-def test_partial_push_n_pull(tmp_dir, dvc, tmp_path_factory):
-    url = fspath(tmp_path_factory.mktemp("upstream"))
-    dvc.config["remote"]["upstream"] = {"url": url}
-    dvc.config["core"]["remote"] = "upstream"
+def test_partial_push_n_pull(tmp_dir, dvc, tmp_path_factory, setup_remote):
+    setup_remote(dvc, name="upstream")
 
     foo = tmp_dir.dvc_gen({"foo": "foo content"})[0].outs[0]
     bar = tmp_dir.dvc_gen({"bar": "bar content"})[0].outs[0]
@@ -212,11 +210,10 @@ def test_partial_push_n_pull(tmp_dir, dvc, tmp_path_factory):
         assert download_error_info.value.amount == 3
 
 
-def test_raise_on_too_many_open_files(tmp_dir, dvc, tmp_path_factory, mocker):
-    storage = fspath(tmp_path_factory.mktemp("test_remote_base"))
-    dvc.config["remote"]["local_remote"] = {"url": storage}
-    dvc.config["core"]["remote"] = "local_remote"
-
+def test_raise_on_too_many_open_files(
+    tmp_dir, dvc, tmp_path_factory, mocker, setup_remote
+):
+    setup_remote(dvc)
     tmp_dir.dvc_gen({"file": "file content"})
 
     mocker.patch.object(
@@ -245,11 +242,8 @@ def test_external_dir_resource_on_no_cache(tmp_dir, dvc, tmp_path_factory):
         dvc.run(deps=[fspath(external_dir)], single_stage=True)
 
 
-def test_push_order(tmp_dir, dvc, tmp_path_factory, mocker):
-    url = fspath(tmp_path_factory.mktemp("upstream"))
-    dvc.config["remote"]["upstream"] = {"url": url}
-    dvc.config["core"]["remote"] = "upstream"
-
+def test_push_order(tmp_dir, dvc, tmp_path_factory, mocker, setup_remote):
+    setup_remote(dvc)
     tmp_dir.dvc_gen({"foo": {"bar": "bar content"}})
     tmp_dir.dvc_gen({"baz": "baz content"})
 
diff --git a/tests/unit/remote/test_s3.py b/tests/unit/remote/test_s3.py
index c32091e0a..b9ee1ebd3 100644
--- a/tests/unit/remote/test_s3.py
+++ b/tests/unit/remote/test_s3.py
@@ -53,3 +53,8 @@ def test_grants_mutually_exclusive_acl_error(dvc, grants):
 
         with pytest.raises(ConfigError):
             S3Remote(dvc, config)
+
+
+def test_sse_kms_key_id(dvc):
+    remote = S3Remote(dvc, {"url": url, "sse_kms_key_id": "key"})
+    assert remote.extra_args["SSEKMSKeyId"] == "key"
diff --git a/tests/unit/test_stage.py b/tests/unit/test_stage.py
index dcfb771c4..09121da2b 100644
--- a/tests/unit/test_stage.py
+++ b/tests/unit/test_stage.py
@@ -106,22 +106,36 @@ def test_always_changed(dvc):
 
 def test_stage_cache(tmp_dir, dvc, run_copy, mocker):
     tmp_dir.gen("dep", "dep")
-    stage = run_copy("dep", "out", single_stage=True)
+    tmp_dir.gen(
+        "script.py",
+        (
+            'open("out", "w+").write("out"); '
+            'open("out_no_cache", "w+").write("out_no_cache")'
+        ),
+    )
+    stage = dvc.run(
+        cmd="python script.py",
+        deps=["script.py", "dep"],
+        outs=["out"],
+        outs_no_cache=["out_no_cache"],
+        single_stage=True,
+    )
 
     with dvc.lock, dvc.state:
         stage.remove(remove_outs=True, force=True)
 
     assert not (tmp_dir / "out").exists()
+    assert not (tmp_dir / "out_no_cache").exists()
     assert not (tmp_dir / "out.dvc").exists()
 
     cache_dir = os.path.join(
         dvc.stage_cache.cache_dir,
-        "75",
-        "75f8a9097d76293ff4b3684d52e4ad0e83686d31196f27eb0b2ea9fd5085565e",
+        "10",
+        "10b45372fdf4ec14d3f779c5b256378d7a12780e4c7f549a44138e492f098bfe",
     )
     cache_file = os.path.join(
         cache_dir,
-        "c1747e52065bc7801262fdaed4d63f5775e5da304008bd35e2fea4e6b1ccb272",
+        "bb32e04c6da96a7192513390acedbe4cd6123f8fe5b0ba5fffe39716fe87f6f4",
     )
 
     assert os.path.isdir(cache_dir)
@@ -137,4 +151,6 @@ def test_stage_cache(tmp_dir, dvc, run_copy, mocker):
     assert checkout_spy.call_count == 1
 
     assert (tmp_dir / "out").exists()
-    assert (tmp_dir / "out").read_text() == "dep"
+    assert (tmp_dir / "out_no_cache").exists()
+    assert (tmp_dir / "out").read_text() == "out"
+    assert (tmp_dir / "out_no_cache").read_text() == "out_no_cache"