You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2019/11/14 17:23:47 UTC

[allura] branch db/8340 updated (5229706 -> ad856f3)

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8340
in repository https://gitbox.apache.org/repos/asf/allura.git.


 discard 5229706  [#8340] misc other coverage
 discard 0e9a818  [#8340] tests for scripts/commands
     new cd4a53e  [#8340] tests for scripts/commands
     new ad856f3  [#8340] misc other coverage

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (5229706)
            \
             N -- N -- N   refs/heads/db/8340 (ad856f3)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Allura/allura/lib/helpers.py                | 16 ++--------------
 Allura/allura/tests/decorators.py           |  2 +-
 Allura/allura/tests/functional/test_root.py | 14 ++++++++++++--
 Allura/allura/tests/test_commands.py        | 12 ++++++++----
 Allura/allura/tests/test_helpers.py         | 11 +++++++++--
 5 files changed, 32 insertions(+), 23 deletions(-)


[allura] 02/02: [#8340] misc other coverage

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8340
in repository https://gitbox.apache.org/repos/asf/allura.git

commit ad856f3cbe512bcc5d366939fda1a17d93ecec12
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Wed Nov 13 18:13:32 2019 -0500

    [#8340] misc other coverage
---
 Allura/allura/config/app_cfg.py              |  1 -
 Allura/allura/lib/helpers.py                 | 60 ++--------------------------
 Allura/allura/tests/decorators.py            |  2 +-
 Allura/allura/tests/functional/test_admin.py |  4 ++
 Allura/allura/tests/functional/test_root.py  | 14 ++++++-
 Allura/allura/tests/test_helpers.py          | 16 ++++----
 6 files changed, 29 insertions(+), 68 deletions(-)

diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index 222fa54..f5b1464 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -103,7 +103,6 @@ class AlluraJinjaRenderer(JinjaRenderer):
             cache_size=config.get('jinja_cache_size', -1),
             extensions=['jinja2.ext.do', 'jinja2.ext.i18n'])
         jinja2_env.install_gettext_translations(tg.i18n)
-        jinja2_env.filters['filesizeformat'] = helpers.do_filesizeformat
         jinja2_env.filters['datetimeformat'] = helpers.datetimeformat
         jinja2_env.filters['filter'] = lambda s, t=None: filter(t and jinja2_env.tests[t], s)
         jinja2_env.filters['nl2br'] = helpers.nl2br_jinja_filter
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 82285f9..69342c5 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -58,7 +58,7 @@ from tg.decorators import before_validate
 from formencode.variabledecode import variable_decode
 import formencode
 from jinja2 import Markup
-from jinja2.filters import contextfilter, escape
+from jinja2.filters import contextfilter, escape, do_filesizeformat
 from paste.deploy.converters import asbool, aslist, asint
 
 from webhelpers import date, feedgenerator, html, number, misc, text
@@ -233,14 +233,6 @@ def make_neighborhoods(ids):
     return _make_xs('Neighborhood', ids)
 
 
-def make_projects(ids):
-    return _make_xs('Project', ids)
-
-
-def make_users(ids):
-    return _make_xs('User', ids)
-
-
 def make_roles(ids):
     return _make_xs('ProjectRole', ids)
 
@@ -265,6 +257,8 @@ def make_app_admin_only(app):
 
 @contextmanager
 def push_config(obj, **kw):
+    # if you need similar for a dict, use mock.patch.dict
+
     saved_attrs = {}
     new_attrs = []
     for k, v in kw.iteritems():
@@ -745,40 +739,6 @@ def render_any_markup(name, txt, code_mode=False, linenumbers_style=TABLE):
                 txt = '<pre>%s</pre>' % txt
     return Markup(txt)
 
-# copied from jinja2 dev
-# latest release, 2.6, implements this incorrectly
-# can remove and use jinja2 implementation after upgrading to 2.7
-
-
-def do_filesizeformat(value, binary=False):
-    """Format the value like a 'human-readable' file size (i.e. 13 kB,
-4.1 MB, 102 Bytes, etc). Per default decimal prefixes are used (Mega,
-Giga, etc.), if the second parameter is set to `True` the binary
-prefixes are used (Mebi, Gibi).
-"""
-    bytes = float(value)
-    base = binary and 1024 or 1000
-    prefixes = [
-        (binary and 'KiB' or 'kB'),
-        (binary and 'MiB' or 'MB'),
-        (binary and 'GiB' or 'GB'),
-        (binary and 'TiB' or 'TB'),
-        (binary and 'PiB' or 'PB'),
-        (binary and 'EiB' or 'EB'),
-        (binary and 'ZiB' or 'ZB'),
-        (binary and 'YiB' or 'YB')
-    ]
-    if bytes == 1:
-        return '1 Byte'
-    elif bytes < base:
-        return '%d Bytes' % bytes
-    else:
-        for i, prefix in enumerate(prefixes):
-            unit = base ** (i + 2)
-            if bytes < unit:
-                return '%.1f %s' % ((base * bytes / unit), prefix)
-        return '%.1f %s' % ((base * bytes / unit), prefix)
-
 
 def nl2br_jinja_filter(value):
     result = '<br>\n'.join(escape(line) for line in value.split('\n'))
@@ -1165,20 +1125,6 @@ def login_overlay(exceptions=None):
         c.show_login_overlay = True
 
 
-def get_filter(ctx, filter_name):
-    """
-    Gets a named Jinja2 filter, passing through
-    any context requested by the filter.
-    """
-    filter_ = ctx.environment.filters[filter_name]
-    if getattr(filter_, 'contextfilter', False):
-        return partial(filter_, ctx)
-    elif getattr(filter_, 'evalcontextfilter', False):
-        return partial(filter_, ctx.eval_ctx)
-    elif getattr(filter_, 'environmentfilter', False):
-        return partial(filter_, ctx.environment)
-
-
 def unidiff(old, new):
     """Returns unified diff between `one` and `two`."""
     return '\n'.join(difflib.unified_diff(
diff --git a/Allura/allura/tests/decorators.py b/Allura/allura/tests/decorators.py
index 726a402..f044c0e 100644
--- a/Allura/allura/tests/decorators.py
+++ b/Allura/allura/tests/decorators.py
@@ -200,7 +200,7 @@ def out_audits(*messages, **kwargs):
             message=re.compile(preamble + message))).count(), 'Found unexpected: "%s"' % message
 
 
-# not a decorator but use it with LogCapture() decorator
+# not a decorator but use it with LogCapture() context manager
 def assert_logmsg_and_no_warnings_or_errors(logs, msg):
     """
     :param testfixtures.logcapture.LogCapture logs: LogCapture() instance
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 3b2c4df..534863e 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -951,6 +951,10 @@ class TestProjectAdmin(TestController):
             assert url.endswith('/admin/ext/foo'), url
             assert_equals('here the foo settings go', foo_page.body)
 
+    def test_nbhd_invitations(self):
+        r = self.app.get('/admin/invitations')
+        r.mustcontain('Neighborhood Invitation(s) for test')
+
 
 class TestExport(TestController):
 
diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py
index 34da302..514e50b 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -28,6 +28,8 @@ functional tests exercise the whole application and its WSGI stack.
 Please read http://pythonpaste.org/webtest/ for more information.
 
 """
+import os
+
 from tg import tmpl_context as c
 from nose.tools import assert_equal
 from ming.orm.ormsession import ThreadLocalORMSession
@@ -37,7 +39,7 @@ from IPython.testing.decorators import module_not_available, skipif
 from allura.tests import decorators as td
 from allura.tests import TestController
 from allura import model as M
-from allura.lib.helpers import push_config
+from allura.lib import helpers as h
 from alluratest.controller import setup_trove_categories
 
 
@@ -69,6 +71,14 @@ class TestRootController(TestController):
         assert cat_links[0].find('a').get('href') == '/browse/clustering'
         assert cat_links[0].find('a').find('span').string == 'Clustering'
 
+    def test_validation(self):
+        # this is not configured ON currently, so adding an individual test to get coverage of the validator itself
+        with mock.patch.dict(os.environ, ALLURA_VALIDATION='all'):
+            self.app.get('/neighborhood')
+            self.app.get('/nf/markdown_to_html?markdown=aaa&project=test&app=bugs&neighborhood=%s'
+                         % M.Neighborhood.query.get(name='Projects')._id,
+                         validate_chunk=True)
+
     def test_sidebar_escaping(self):
         # use this as a convenient way to get something in the sidebar
         M.ProjectCategory(name='test-xss', label='<script>alert(1)</script>')
@@ -123,7 +133,7 @@ class TestRootController(TestController):
         # Install home app
         nb = M.Neighborhood.query.get(name='Adobe')
         p = nb.neighborhood_project
-        with push_config(c, user=M.User.query.get(username='test-admin')):
+        with h.push_config(c, user=M.User.query.get(username='test-admin')):
             p.install_app('home', 'home', 'Home', ordinal=0)
 
         response = self.app.get('/adobe/')
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index 3abde3b..8fccf90 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -107,11 +107,6 @@ def test_find_project():
     assert proj is None
 
 
-def test_make_users():
-    r = h.make_users([None]).next()
-    assert r.username == '*anonymous', r
-
-
 def test_make_roles():
     h.set_context('test', 'wiki', neighborhood='Projects')
     pr = M.ProjectRole.anonymous()
@@ -594,8 +589,11 @@ def test_base64uri_img():
 
 
 def test_base64uri_text():
-    b64txt = h.base64uri('blah blah blah 123 456 foo bar baz', mimetype='text/plain')
-    assert b64txt.startswith('data:text/plain;base64,'), b64txt
+    b64txt = h.base64uri('blah blah blah\n123 456\nfoo bar baz', mimetype='text/plain')
+    assert_equals(b64txt, 'data:text/plain;base64,YmxhaCBibGFoIGJsYWgKMTIzIDQ1Ngpmb28gYmFyIGJheg==')
+
+    b64txt = h.base64uri('blah blah blah\n123 456\nfoo bar baz', mimetype='text/plain', windows_line_endings=True)
+    assert_equals(b64txt, 'data:text/plain;base64,YmxhaCBibGFoIGJsYWgNCjEyMyA0NTYNCmZvbyBiYXIgYmF6')
 
 
 def test_slugify():
@@ -649,3 +647,7 @@ def test_hide_private_info():
 
     with h.push_config(h.tg.config, hide_private_info=False):
         assert_equals(h.hide_private_info('foo bar baz@bing.com'), 'foo bar baz@bing.com')
+
+
+def test_emojize():
+    assert_equals(h.emojize(':smile:'), u'😄')


[allura] 01/02: [#8340] tests for scripts/commands

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8340
in repository https://gitbox.apache.org/repos/asf/allura.git

commit cd4a53ebd6f547c7dacb5f433ce1fedbaa1a8420
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Wed Nov 13 16:34:46 2019 -0500

    [#8340] tests for scripts/commands
---
 Allura/allura/tests/decorators.py             | 17 +++++-
 Allura/allura/tests/scripts/test_reindexes.py | 74 +++++++++++++++++++++++++++
 Allura/allura/tests/test_commands.py          | 46 +++++++++++++++--
 ForgeGit/forgegit/tests/test_tasks.py         | 17 ++----
 4 files changed, 135 insertions(+), 19 deletions(-)

diff --git a/Allura/allura/tests/decorators.py b/Allura/allura/tests/decorators.py
index 7c42206..726a402 100644
--- a/Allura/allura/tests/decorators.py
+++ b/Allura/allura/tests/decorators.py
@@ -14,7 +14,7 @@
 #       KIND, either express or implied.  See the License for the
 #       specific language governing permissions and limitations
 #       under the License.
-
+import logging
 import sys
 import re
 from functools import wraps
@@ -198,3 +198,18 @@ def out_audits(*messages, **kwargs):
     for message in messages:
         assert not M.AuditLog.query.find(dict(
             message=re.compile(preamble + message))).count(), 'Found unexpected: "%s"' % message
+
+
+# not a decorator but use it with LogCapture() decorator
+def assert_logmsg_and_no_warnings_or_errors(logs, msg):
+    """
+    :param testfixtures.logcapture.LogCapture logs: LogCapture() instance
+    :param str msg: Message to look for
+    """
+    found_msg = False
+    for r in logs.records:
+        if msg in r.getMessage():
+            found_msg = True
+        if r.levelno > logging.INFO:
+            raise AssertionError('unexpected log {} {}'.format(r.levelname, r.getMessage()))
+    assert found_msg, 'Did not find {} in logs: {}'.format(msg, '\n'.join([r.getMessage() for r in logs.records]))
diff --git a/Allura/allura/tests/scripts/test_reindexes.py b/Allura/allura/tests/scripts/test_reindexes.py
new file mode 100644
index 0000000..d6dbeb0
--- /dev/null
+++ b/Allura/allura/tests/scripts/test_reindexes.py
@@ -0,0 +1,74 @@
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you under the Apache License, Version 2.0 (the
+#       "License"); you may not use this file except in compliance
+#       with the License.  You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#       Unless required by applicable law or agreed to in writing,
+#       software distributed under the License is distributed on an
+#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#       KIND, either express or implied.  See the License for the
+#       specific language governing permissions and limitations
+#       under the License.
+from nose.tools import assert_in, assert_equal
+from testfixtures import LogCapture
+
+from allura.scripts.reindex_projects import ReindexProjects
+from allura.scripts.reindex_users import ReindexUsers
+from allura.tests.decorators import assert_logmsg_and_no_warnings_or_errors
+from alluratest.controller import setup_basic_test
+from allura import model as M
+
+
+class TestReindexProjects(object):
+
+    def setUp(self):
+        setup_basic_test()
+
+    def run_script(self, options):
+        cls = ReindexProjects
+        opts = cls.parser().parse_args(options)
+        cls.execute(opts)
+
+    def test(self):
+        with LogCapture() as logs:
+            self.run_script(['-n', '/p/', '-p', 'test'])
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex project test')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex done')
+
+    def test_with_tasks(self):
+        with LogCapture() as logs:
+            self.run_script(['-n', '/p/', '-p', 'test', '--tasks'])
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex project test')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex queued')
+        assert_equal(M.MonQTask.query.find({'task_name': 'allura.tasks.index_tasks.add_projects'}).count(), 1)
+
+
+class TestReindexUsers(object):
+
+    def setUp(self):
+        setup_basic_test()
+
+    def run_script(self, options):
+        cls = ReindexUsers
+        opts = cls.parser().parse_args(options)
+        cls.execute(opts)
+
+    def test(self):
+        with LogCapture() as logs:
+            self.run_script([])
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex user root')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex user test-user-1')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex done')
+
+    def test_with_tasks(self):
+        with LogCapture() as logs:
+            self.run_script(['--tasks'])
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex user root')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex user test-user-1')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Reindex queued')
+        assert_equal(M.MonQTask.query.find({'task_name': 'allura.tasks.index_tasks.add_users'}).count(), 1)
diff --git a/Allura/allura/tests/test_commands.py b/Allura/allura/tests/test_commands.py
index ee97f7e..3ad18b6 100644
--- a/Allura/allura/tests/test_commands.py
+++ b/Allura/allura/tests/test_commands.py
@@ -16,6 +16,8 @@
 #       under the License.
 
 from nose.tools import assert_raises, assert_in
+from testfixtures import OutputCapture
+
 from datadiff.tools import assert_equal
 
 from ming.base import Object
@@ -26,7 +28,7 @@ import pkg_resources
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura.command import base, script, set_neighborhood_features, \
-    create_neighborhood, show_models, taskd_cleanup
+    create_neighborhood, show_models, taskd_cleanup, taskd
 from allura import model as M
 from allura.lib.exceptions import InvalidNBFeatureValueError
 from allura.tests import decorators as td
@@ -262,6 +264,18 @@ class TestEnsureIndexCommand(object):
         ])
 
 
+class TestTaskCommand(object):
+
+    def test_commit(self):
+        exit_code = taskd.TaskCommand('task').run([test_config, 'commit'])
+        assert_equal(M.MonQTask.query.find({'task_name': 'allura.tasks.index_tasks.commit'}).count(), 1)
+        assert_equal(exit_code, 0)
+
+    def test_list(self):
+        exit_code = taskd.TaskCommand('task').run([test_config, 'list'])
+        assert_equal(exit_code, 0)
+
+
 class TestTaskdCleanupCommand(object):
 
     def setUp(self):
@@ -376,7 +390,19 @@ def test_status_log_retries():
     assert cmd._taskd_status.mock_calls == expected_calls
 
 
-class TestBackgroundCommand(object):
+class TestShowModels(object):
+
+    def test_show_models(self):
+        cmd = show_models.ShowModelsCommand('models')
+        with OutputCapture() as output:
+            cmd.run([test_config])
+        assert_in('''allura.model.notification.SiteNotification
+         - <FieldProperty content>
+         - <FieldProperty page_regex>
+        ''', output.captured)
+
+
+class TestReindexAsTask(object):
 
     cmd = 'allura.command.show_models.ReindexCommand'
     task_name = 'allura.command.base.run_command'
@@ -401,9 +427,13 @@ class TestBackgroundCommand(object):
     def test_invalid_args(self):
         M.MonQTask.query.remove()
         show_models.ReindexCommand.post('--invalid-option')
-        with td.raises(Exception) as e:
-            M.MonQTask.run_ready()
-        assert_in('Error parsing args', str(e.exc))
+        try:
+            with td.raises(Exception) as e:
+                M.MonQTask.run_ready()
+            assert_in('Error parsing args', str(e.exc))
+        finally:
+            # cleanup - remove bad MonQTask
+            M.MonQTask.query.remove()
 
 
 class TestReindexCommand(object):
@@ -418,6 +448,7 @@ class TestReindexCommand(object):
         assert not g.solr.delete.called, 'solr.delete() must not be called'
 
     @patch('pysolr.Solr')
+    @td.with_wiki  # so there's some artifacts to reindex
     def test_solr_hosts_1(self, Solr):
         cmd = show_models.ReindexCommand('reindex')
         cmd.options, args = cmd.parser.parse_args([
@@ -494,3 +525,8 @@ class TestReindexCommand(object):
         cmd.options = Mock(ming_config=None)
         with td.raises(pymongo.errors.InvalidDocument):
             cmd._post_add_artifacts(range(5))
+
+    @td.with_wiki  # so there's some artifacts to reindex
+    def test_ming_config(self):
+        cmd = show_models.ReindexCommand('reindex')
+        cmd.run([test_config, '-p', 'test', '--tasks', '--ming-config', 'test.ini'])
diff --git a/ForgeGit/forgegit/tests/test_tasks.py b/ForgeGit/forgegit/tests/test_tasks.py
index 812a8b4..4563457 100644
--- a/ForgeGit/forgegit/tests/test_tasks.py
+++ b/ForgeGit/forgegit/tests/test_tasks.py
@@ -14,7 +14,6 @@
 #       KIND, either express or implied.  See the License for the
 #       specific language governing permissions and limitations
 #       under the License.
-import logging
 import unittest
 import mock
 from testfixtures import LogCapture
@@ -27,6 +26,7 @@ from allura.scripts.refreshrepo import RefreshRepo
 from allura.scripts.refresh_last_commits import RefreshLastCommits
 from allura.lib import helpers as h
 from allura.tasks import repo_tasks
+from allura.tests.decorators import assert_logmsg_and_no_warnings_or_errors
 from allura import model as M
 from forgegit.tests import with_git
 from forgegit.tests.functional.test_controllers import _TestCase as GitRealDataBaseTestCase
@@ -73,28 +73,19 @@ class TestCoreAlluraTasks(GitRealDataBaseTestCase):
         super(TestCoreAlluraTasks, self).setUp()
         self.setup_with_tools()
 
-    def _assert_logmsg_and_no_warnings_or_errors(self, logs, msg):
-        found_msg = False
-        for r in logs.records:
-            if msg in r.getMessage():
-                found_msg = True
-            if r.levelno > logging.INFO:
-                raise AssertionError('unexpected log {} {}'.format(r.levelname, r.getMessage()))
-        assert found_msg, 'Did not find {} in logs: {}'.format(msg, '\n'.join([str(r) for r in logs.records]))
-
     def test_refreshrepo(self):
         opts = RefreshRepo.parser().parse_args(
             ['--nbhd', '/p/', '--project', 'test', '--clean', '--all', '--repo-types', 'git'])
         with LogCapture() as logs:
             RefreshRepo.execute(opts)
-        self._assert_logmsg_and_no_warnings_or_errors(logs, 'Refreshing ALL commits in ')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Refreshing ALL commits in ')
 
         # run again with some different params
         opts = RefreshRepo.parser().parse_args(
             ['--nbhd', '/p/', '--project', 'test', '--clean-after', '2010-01-01T00:00:00'])
         with LogCapture() as logs:
             RefreshRepo.execute(opts)
-        self._assert_logmsg_and_no_warnings_or_errors(logs, 'Refreshing NEW commits in ')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Refreshing NEW commits in ')
 
     def test_refresh_last_commits(self):
         repo = c.app.repo
@@ -105,7 +96,7 @@ class TestCoreAlluraTasks(GitRealDataBaseTestCase):
         with LogCapture() as logs:
             RefreshLastCommits.execute(opts)
 
-        self._assert_logmsg_and_no_warnings_or_errors(logs, 'Refreshing all last commits ')
+        assert_logmsg_and_no_warnings_or_errors(logs, 'Refreshing all last commits ')
 
         # mostly just making sure nothing errored, but here's at least one thing we can assert:
         assert repo.status == 'ready'