From 8f418a272950e410dc9fe616183b211ad1c54b61 Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@ess.eu>
Date: Fri, 30 Oct 2020 11:45:36 +0100
Subject: [PATCH] Fix inventory export to excel

IN RQ 1.0, the `timeout` argument on `queue.enqueue()`
has been deprecated in favor of `job_timeout`

JIRA INFRA-2780 #action In Progress
---
 app/inventory/views.py         |  2 +-
 tests/functional/conftest.py   | 12 ++++++++++++
 tests/functional/test_tasks.py | 24 ++++++++++++++++++++++++
 tests/functional/test_web.py   | 11 +++++++++++
 4 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 tests/functional/test_tasks.py

diff --git a/app/inventory/views.py b/app/inventory/views.py
index 5e9b998..cd630f0 100644
--- a/app/inventory/views.py
+++ b/app/inventory/views.py
@@ -46,7 +46,7 @@ def list_items():
 @login_required
 def _generate_excel_file():
     task = current_user.launch_task(
-        "generate_items_excel_file", func="generate_items_excel_file", timeout=180
+        "generate_items_excel_file", func="generate_items_excel_file", job_timeout=180
     )
     db.session.commit()
     return utils.redirect_to_job_status(task.id)
diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py
index 7d89ab6..edfb191 100644
--- a/tests/functional/conftest.py
+++ b/tests/functional/conftest.py
@@ -9,10 +9,12 @@ Pytest fixtures common to all functional tests.
 :license: BSD 2-Clause, see LICENSE for more details.
 
 """
+import redis
 import pytest
 import sqlalchemy as sa
 from pytest_factoryboy import register
 from flask_ldap3_login import AuthenticationResponse, AuthenticationResponseStatus
+from rq import push_connection, pop_connection
 from app.factory import create_app
 from app.extensions import db as _db
 from app.models import SearchableMixin, Host, Item, AnsibleGroup
@@ -45,6 +47,7 @@ def app(request):
         "TESTING": True,
         "WTF_CSRF_ENABLED": False,
         "SQLALCHEMY_DATABASE_URI": "postgresql://ics:icspwd@postgres/csentry_db_test",
+        "RQ_REDIS_URL": "redis://redis:6379/4",
         "ELASTICSEARCH_INDEX_SUFFIX": "-test",
         "ELASTICSEARCH_REFRESH": "true",
         "CACHE_TYPE": "null",
@@ -135,8 +138,17 @@ def session(db, request):
     Host.create_index()
     AnsibleGroup.create_index()
 
+    # Setup RQ redis connection
+    redis_connection = redis.from_url(db.app.config["RQ_REDIS_URL"])
+    redis_connection.flushdb()
+    push_connection(redis_connection)
+
     yield session
 
+    # Clean RQ redis connnection
+    redis_connection.flushdb()
+    pop_connection()
+
     # ELASTICSEARCH_INDEX_SUFFIX is set to "-test"
     # Delete all "*-test" indices after each test
     db.app.elasticsearch.indices.delete("*-test", ignore=404)
diff --git a/tests/functional/test_tasks.py b/tests/functional/test_tasks.py
new file mode 100644
index 0000000..06c7280
--- /dev/null
+++ b/tests/functional/test_tasks.py
@@ -0,0 +1,24 @@
+import pytest
+
+
+@pytest.mark.parametrize(
+    "name, func, input_kwargs, output_args",
+    [
+        ("my task1", "my_func1", {}, ""),
+        (
+            "my task2",
+            "my_func2",
+            {"arg1": "foo", "arg2": True},
+            "arg1='foo', arg2=True",
+        ),
+        # job_timeout is used by enqueue for the job
+        ("another task", "func_to_run", {"job_timeout": 180}, ""),
+        # timeout is NOT used by enqueue for the job (deprecated in RQ >= 1.0)
+        # it's passed to the function
+        ("task4", "my_func4", {"timeout": 60}, "timeout=60"),
+    ],
+)
+def test_launch_task_kwargs(user, name, func, input_kwargs, output_args):
+    task = user.launch_task(name, func=func, **input_kwargs)
+    assert task.name == name
+    assert task.command == f"app.tasks.{func}({output_args})"
diff --git a/tests/functional/test_web.py b/tests/functional/test_web.py
index 7e4da7b..d7d46c5 100644
--- a/tests/functional/test_web.py
+++ b/tests/functional/test_web.py
@@ -1056,3 +1056,14 @@ def test_retrieve_groups(logged_client, ansible_group_factory):
     response = logged_client.post("/network/_retrieve_groups")
     groups = response.get_json()["data"]
     assert {group1.name, group2.name} == set(group["name"] for group in groups)
+
+
+def test_generate_excel_file(logged_client):
+    response = logged_client.get("/inventory/items/_generate_excel_file")
+    assert response.status_code == 202
+    assert "/status/" in response.headers["Location"]
+    job_id = response.headers["Location"].split("/")[-1]
+    task = models.Task.query.get(job_id)
+    assert task is not None
+    assert task.name == "generate_items_excel_file"
+    assert task.command == "app.tasks.generate_items_excel_file()"
-- 
GitLab