def test_longer_timeout_allows_long_task_to_finish(self, app_longer_timeout):
     hades_logs = HadesLogs(app_longer_timeout)
     try:
         tasks = list(hades_logs.fetch_logs(nasipaddress='', nasportid='magic_sleep'))
     except HadesTimeout:
         pytest.fail("HadesTimeout triggered even with significantly longer timeout")
     else:
         assert tasks == []
Exemple #2
0
 def setUp(self):
     super().setUp()
     self.app = Flask('test')
     self.app.config.update(self.hades_logs_config)
     self.hades_logs = HadesLogs(self.app)
     self.valid_kwargs = {
         'nasipaddress': '141.30.223.206',
         'nasportid': 'C6'
     }
Exemple #3
0
 def setUp(self):
     super().setUp()
     self.app = Flask('test')
     self.app.config.update({
         'HADES_CELERY_APP_NAME': 'test',
         'HADES_BROKER_URI': 'amqp://localhost:5762/',
         'HADES_RESULT_BACKEND_URI': 'rpc://localhost:5762/',
     })
     self.hades_logs = HadesLogs(self.app)
Exemple #4
0
    def create_app(self):
        app = super().create_app()

        # Setup dummy_tasks hades logs
        app.config.update(self.hades_logs_config)
        HadesLogs(app)

        return app
Exemple #5
0
 def hades_logs(self):
     app = Flask('test')
     app.config.update({
         'HADES_CELERY_APP_NAME': 'test',
         # intentionally wrong urls to trigger `OperationalError`s
         'HADES_BROKER_URI': 'amqp://localhost:5762/',
         'HADES_RESULT_BACKEND_URI': 'rpc://localhost:5762/',
     })
     return HadesLogs(app)
Exemple #6
0
 def test_longer_timeout_allows_long_task_to_finish(self):
     self.app.config.update({'HADES_TIMEOUT': 15})
     self.hades_logs = HadesLogs(self.app)
     try:
         tasks = self.fetch_logs(nasipaddress='', nasportid='magic_sleep')
     except HadesTimeout:
         self.fail(
             "HadesTimeout triggered even with significantly longer timeout"
         )
     else:
         self.assertEqual(tasks, [])
Exemple #7
0
class SimpleFlaskWithHadesLogsBase(DummyHadesWorkerBase):
    def setUp(self):
        super().setUp()
        self.app = Flask('test')
        self.app.config.update(self.hades_logs_config)
        self.hades_logs = HadesLogs(self.app)
        self.valid_kwargs = {'nasipaddress': '141.30.223.206', 'nasportid': 'C6'}

    def fetch_logs(self, *a, **kw):
        """Call :py:meth:`hades_logs.fetch_logs` and convert to list

        :rtype: list
        """
        return list(self.hades_logs.fetch_logs(*a, **kw))
Exemple #8
0
class CorrectURIsConfiguredTestCase(TestCase):
    """Provides ``HadesLogs`` with syntactically correct URIs"""
    def setUp(self):
        super().setUp()
        self.app = Flask('test')
        self.app.config.update({
            'HADES_CELERY_APP_NAME': 'test',
            'HADES_BROKER_URI': 'amqp://localhost:5762/',
            'HADES_RESULT_BACKEND_URI': 'rpc://localhost:5762/',
        })
        self.hades_logs = HadesLogs(self.app)

    def test_empty_task_raises_operational_error(self):
        # This throws an OSError as there is no `HadesLogs` around to
        # catch it.
        with self.assertRaises(OSError):
            self.hades_logs.celery.signature('').apply_async().wait()

    def test_fetch_logs_logs_and_raises_connection_refused(self):
        with self.assertRaises(HadesOperationalError), \
             self.assertLogs('hades_logs', level=logging.INFO) as cm:
            self.hades_logs.fetch_logs(None, None)
        self.assertEqual(len(cm.output), 1)
        self.assertIn("waiting for task", cm.output.pop().lower())
Exemple #9
0
class SimpleFlaskWithHadesLogsBase(DummyHadesWorkerBase):
    def setUp(self):
        super().setUp()
        self.app = Flask('test')
        self.app.config.update(self.hades_logs_config)
        self.hades_logs = HadesLogs(self.app)
        self.valid_kwargs = {
            'nasipaddress': '141.30.223.206',
            'nasportid': 'C6'
        }

    def fetch_logs(self, *a, **kw):
        """Call :py:meth:`hades_logs.fetch_logs` and convert to list

        :rtype: list
        """
        return list(self.hades_logs.fetch_logs(*a, **kw))
Exemple #10
0
class TaskCreatedTestCase(ConfiguredFlaskAppTestBase):
    """Provide a task created by :py:meth`create_task`"""
    def setUp(self):
        super().setUp()
        self.hades_logs = HadesLogs(self.app)
        self.task = self.hades_logs.create_task('taskname', 'foo', bar='baz')

    def test_task_bound_to_app(self):
        self.assertTrue(self.task.app is self.hades_logs.celery)

    def test_task_name_correct(self):
        # In celery 4.0, this is `self.task.name`
        self.assertEqual(self.task.task, 'test.taskname')

    def test_task_args_passed(self):
        self.assertEqual(self.task.args, ('foo',))

    def test_task_kwargs_passed(self):
        self.assertEqual(self.task.kwargs, {'bar': 'baz'})
Exemple #11
0
 def test_init_app_initializes_app(self, app, caplog):
     l = HadesLogs()
     with self.assert_registers_extension(app, caplog):
         l.init_app(app)
Exemple #12
0
 def hades_logs(self, app):
     return HadesLogs(app)
Exemple #13
0
 def test_init_initializes_app(self, app, caplog):
     with assert_unconfigured(caplog):
         HadesLogs(app)
Exemple #14
0
 def test_init_app_initializes_app(self, app, caplog):
     logs = HadesLogs()
     with assert_unconfigured(caplog):
         logs.init_app(app)
Exemple #15
0
 def test_init_initializes_app(self):
     with self.assert_unconfigured():
         HadesLogs(self.app)
Exemple #16
0
def test_plain_init_works():
    # noinspection PyBroadException
    try:
        HadesLogs()
    except Exception:  # pylint: disable=broad-except
        pytest.fail("Bare init didn't work")
Exemple #17
0
def make_app(debug=False):
    """  Create and configure the main? Flask app object

    :return: The fully configured app object
    """
    app = PycroftFlask(__name__)
    app.debug = debug

    # initialization code
    login_manager.init_app(app)
    app.register_blueprint(user.bp, url_prefix="/user")
    app.register_blueprint(facilities.bp, url_prefix="/facilities")
    app.register_blueprint(infrastructure.bp, url_prefix="/infrastructure")
    app.register_blueprint(properties.bp, url_prefix="/properties")
    app.register_blueprint(finance.bp, url_prefix="/finance")
    app.register_blueprint(login.bp)
    app.register_blueprint(api.bp, url_prefix="/api/v0")

    template_filters.register_filters(app)
    template_tests.register_checks(app)

    babel = Babel(app)
    try:
        HadesLogs(app)
    except KeyError as e:
        app.logger.info("HadesLogs configuration incomplete, skipping.")
        app.logger.info("Original error: %s", str(e))

    page_resources.init_app(app)

    user.nav.register_on(app)
    finance.nav.register_on(app)
    facilities.nav.register_on(app)
    infrastructure.nav.register_on(app)
    properties.nav.register_on(app)

    @app.errorhandler(403)
    @app.errorhandler(404)
    @app.errorhandler(500)
    def errorpage(e):
        """Handle errors according to their error code

        :param e: The error from the errorhandler
        """
        # We need this path hard-coding because the global app errorhandlers have higher
        # precedence than anything registered to a blueprint.
        # A clean solution would be flask supporting nested blueprints (see flask #539)
        if request.path.startswith('/api/'):
            return api.errorpage(e)

        if not hasattr(e, 'code'):
            code = 500
        else:
            code = e.code
        if code == 500:
            message = str(e)
        elif code == 403:
            message = gettext(u"You are not allowed to access this page.")
        elif code == 404:
            message = gettext(u"Page not found.")
        else:
            raise AssertionError()
        return render_template('error.html', error=message), code

    @app.route('/')
    def redirect_to_index():
        return redirect(url_for('user.overview'))

    @app.teardown_request
    def shutdown_session(exception=None):
        session.Session.remove()

    @app.before_request
    def require_login():
        """Request a login for every page
        except the login blueprint and the static folder.

        Blueprint "None" is needed for "/static/*" GET requests.
        """
        if current_user.is_anonymous and request.blueprint not in ("login", 'api', None):
            return current_app.login_manager.unauthorized()

    return app
Exemple #18
0
 def setUp(self):
     super().setUp()
     self.hades_logs = HadesLogs(self.app)
Exemple #19
0
def make_app(debug=False):
    """  Create and configure the main? Flask app object

    :return: The fully configured app object
    """
    app = PycroftFlask(__name__)
    app.debug = debug

    # initialization code
    login_manager.init_app(app)
    app.register_blueprint(user.bp, url_prefix="/user")
    app.register_blueprint(facilities.bp, url_prefix="/facilities")
    app.register_blueprint(infrastructure.bp, url_prefix="/infrastructure")
    app.register_blueprint(properties.bp, url_prefix="/properties")
    app.register_blueprint(finance.bp, url_prefix="/finance")
    app.register_blueprint(host.bp, url_prefix="/host")
    app.register_blueprint(task.bp, url_prefix="/task")
    app.register_blueprint(login.bp)
    app.register_blueprint(api.bp, url_prefix="/api/v0")

    template_filters.register_filters(app)
    template_tests.register_checks(app)

    babel = Babel(app)
    try:
        HadesLogs(app)
    except KeyError as e:
        app.logger.info("HadesLogs configuration incomplete, skipping.")
        app.logger.info("Original error: %s", str(e))

    page_resources.init_app(app)

    user.nav.register_on(app)
    finance.nav.register_on(app)
    facilities.nav.register_on(app)
    infrastructure.nav.register_on(app)
    task.nav.register_on(app)
    properties.nav.register_on(app)

    @app.errorhandler(403)
    @app.errorhandler(404)
    @app.errorhandler(500)
    def errorpage(e):
        """Handle errors according to their error code

        :param e: The error from the errorhandler
        """
        # We need this path hard-coding because the global app errorhandlers have higher
        # precedence than anything registered to a blueprint.
        # A clean solution would be flask supporting nested blueprints (see flask #539)
        if request.path.startswith('/api/'):
            return api.errorpage(e)

        if not hasattr(e, 'code'):
            code = 500
        else:
            code = e.code
        if code == 500:
            message = str(e)
        elif code == 403:
            message = gettext("You are not allowed to access this page.")
        elif code == 404:
            message = gettext("Page not found.")
        else:
            raise AssertionError()
        return render_template('error.html', error=message), code

    @app.route('/')
    def redirect_to_index():
        return redirect(url_for('user.overview'))

    @app.route('/version/')
    def version():
        pycroft_dir = './'
        return render_template(
            'version.html',
            active_branch=get_repo_active_branch(pycroft_dir),
            commits=get_latest_commits(pycroft_dir, 20))

    @app.route('/debug-sentry')
    def debug_sentry():
        app.logger.warning(
            "Someone used the debug-sentry endpoint! Also, this is a test warning."
        )
        app.logger.info("An info log for inbetween")
        app.logger.error(
            "Someone used the debug-sentry endpoint! Also, this is a test error.",
            extra={'pi': 3.141})
        div_by_zero = 1 / 0

    @app.teardown_request
    def shutdown_session(exception=None):
        if app.testing:
            # things are not necessarily committed here,
            # so `remove` would result in a `ROLLBACK TO SAVEPOINT` to a pre-setup state.
            return

        session.Session.remove()

    @app.before_request
    def require_login():
        """Request a login for every page
        except the login blueprint and the static folder.

        Blueprint "None" is needed for "/static/*" GET requests.
        """
        if current_user.is_anonymous and request.blueprint not in ("login",
                                                                   'api',
                                                                   None):
            return current_app.login_manager.unauthorized()

    register_commands(app)

    return app
Exemple #20
0
 def test_init_app_initializes_app(self):
     l = HadesLogs()
     with self.assert_unconfigured():
         l.init_app(self.app)
Exemple #21
0
 def setUp(self):
     super().setUp()
     self.hades_logs = HadesLogs(self.app)
     self.task = self.hades_logs.create_task('taskname', 'foo', bar='baz')
Exemple #22
0
 def setUp(self):
     super().setUp()
     self.app.config['HADES_TIMEOUT'] = 10
     self.hades_logs = HadesLogs(self.app)
Exemple #23
0
 def test_init_initializes_app(self):
     with self.assert_registers_extension(self.app):
         HadesLogs(self.app)
Exemple #24
0
 def test_plain_init_works(self):
     try:
         HadesLogs()
     except Exception:  # pylint: disable=broad-except
         self.fail("Bare init didn't work")
Exemple #25
0
 def hades_logs(self, app):
     app.config['HADES_TIMEOUT'] = 10
     return HadesLogs(app)
Exemple #26
0
 def setUp(self):
     super().setUp()
     self.app = Flask('test')
     self.app.config.update(self.hades_logs_config)
     self.hades_logs = HadesLogs(self.app)
     self.valid_kwargs = {'nasipaddress': '141.30.223.206', 'nasportid': 'C6'}
Exemple #27
0
 def test_init_app_initializes_app(self):
     l = HadesLogs()
     with self.assert_registers_extension(self.app):
         l.init_app(self.app)