diff --git a/src/middlewared/middlewared/plugins/audit/backend.py b/src/middlewared/middlewared/plugins/audit/backend.py index 2a9793650a3f2..4ac0e2e0ac84e 100644 --- a/src/middlewared/middlewared/plugins/audit/backend.py +++ b/src/middlewared/middlewared/plugins/audit/backend.py @@ -218,6 +218,8 @@ def query(self, db_name, filters, options): if wrapper is not None: order_by[i] = wrapper(order_by[i]) + qs = qs.order_by(*order_by) + if options['offset']: qs = qs.offset(options['offset']) diff --git a/tests/api2/test_audit_basic.py b/tests/api2/test_audit_basic.py index 5c68b59efc010..8f2237848a989 100644 --- a/tests/api2/test_audit_basic.py +++ b/tests/api2/test_audit_basic.py @@ -215,6 +215,22 @@ def test_audit_query(self, initialize_for_smb_tests): retries -= 1 assert ops_count > initial_ops_count, f"retries remaining = {retries}" + def test_audit_order_by(self): + # Perform two queries that can be represented using SQL queryset + # and then compare what we get with different ordering to validate + # that order_by directive is functional + head_ts = call('audit.query', {'services': ['SMB'], 'query-options': { + 'get': True, + 'order_by': ['message_timestamp'] + }})['message_timestamp'] + + tail_ts = call('audit.query', {'query-options': { + 'get': True, + 'order_by': ['-message_timestamp'] + }})['message_timestamp'] + + assert head_ts != tail_ts + def test_audit_export(self): for backend in ['CSV', 'JSON', 'YAML']: report_path = call('audit.export', {'export_format': backend}, job=True)