diff --git a/dvc/analytics.py b/dvc/analytics.py index 0bcf31527..ebdfd9baf 100644 --- a/dvc/analytics.py +++ b/dvc/analytics.py @@ -11,7 +11,6 @@ import distro from dvc import __version__ from dvc.config import Config, to_bool -from dvc.daemon import daemon from dvc.exceptions import NotDvcRepoError from dvc.lock import Lock, LockError from dvc.repo import Repo @@ -22,11 +21,11 @@ from dvc.utils import env2bool, is_binary, makedirs logger = logging.getLogger(__name__) -def collect_and_send_report(args=None, return_code=None): +def collect(args=None, return_code=None): """ - Query the system to fill a report and send it on a detached process. + Query the system to fill a report. """ - report = { + return { "cmd_class": args.func.__name__ if hasattr(args, "func") else None, "cmd_return_code": return_code, "dvc_version": __version__, @@ -36,12 +35,6 @@ def collect_and_send_report(args=None, return_code=None): "user_id": find_or_create_user_id(), } - # A temporary file is used as a mean of communication between the - # current and detached process. - with tempfile.NamedTemporaryFile(delete=False, mode="w") as fobj: - json.dump(report, fobj) - daemon(["analytics", fobj.name]) - def is_enabled(): if env2bool("DVC_TEST"): diff --git a/dvc/main.py b/dvc/main.py index 86e1a9e0d..566a46473 100644 --- a/dvc/main.py +++ b/dvc/main.py @@ -2,10 +2,12 @@ from __future__ import unicode_literals import logging +import json from dvc import analytics from dvc.cli import parse_args from dvc.config import ConfigError +from dvc.daemon import daemon from dvc.exceptions import DvcParserError from dvc.exceptions import NotDvcRepoError from dvc.external_repo import clean_repos @@ -82,6 +84,12 @@ def main(argv=None): logger.info(FOOTER) if analytics.is_enabled(): - analytics.collect_and_send_report(args, ret) + report = analytics.collect(args, ret) + + # Use a temporary file to pass the report between the current and + # detached process. + with tempfile.NamedTemporaryFile(delete=False, mode="w") as fobj: + json.dump(report, fobj) + daemon(["analytics", fobj.name]) return ret diff --git a/tests/func/test_analytics.py b/tests/func/test_analytics.py new file mode 100644 index 000000000..608fea00b --- /dev/null +++ b/tests/func/test_analytics.py @@ -0,0 +1,14 @@ +import mock +import json + +from dvc.main import main + + +@mock.patch("dvc.analytics.send") +def test_daemon_analytics(mock_send, tmp_path): + report = {"name": "dummy report"} + fname = tmp_path / "report" + fname.write_text(json.dumps(report)) + + assert 0 == main(["daemon", "analytics", str(fname)]) + assert mock_send.called diff --git a/tests/unit/test_analytics.py b/tests/unit/test_analytics.py index 5012d1617..3800cf0ef 100644 --- a/tests/unit/test_analytics.py +++ b/tests/unit/test_analytics.py @@ -1,9 +1,33 @@ +import json import pytest import mock from dvc import analytics +def test_collect(): + report = analytics.collect(return_code=0) + + assert report["cmd_class"] == None + assert report["cmd_return_code"] == 0 + assert report["scm_class"] in ["Git", None] + assert type(report["is_binary"]) is bool + assert type(report["system_info"]) is dict + assert type(report["dvc_version"]) is str + assert type(report["user_id"]) is str + + +@mock.patch("requests.post") +def test_send(mock_post, tmp_path): + url = "https://analytics.dvc.org" + report = {"name": "dummy report"} + fname = tmp_path / "report" + + fname.write_text(json.dumps(report)) + analytics.send(fname) + mock_post.assert_called_with(url, json=report, timeout=5) + + @pytest.mark.parametrize( "config, result", [