From 6de0b965c7fb2d9b014c9a246486d4fdbf29c73f Mon Sep 17 00:00:00 2001
From: Valerij Maljulin <vmaljuli@redhat.com>
Date: May 19 2020 14:15:30 +0000
Subject: [PATCH 1/2] Flask fix (ambigous variable name 'l' according to PEP8)

More info: https://www.python.org/dev/peps/pep-0008/#names-to-avoid

---

diff --git a/functional-tests/test_monitor.py b/functional-tests/test_monitor.py
index 9562408..d656d75 100644
--- a/functional-tests/test_monitor.py
+++ b/functional-tests/test_monitor.py
@@ -14,8 +14,8 @@ def test_metrics(requests_session, greenwave_server):
     r = requests_session.get(greenwave_server + 'api/v1.0/metrics')
 
     assert r.status_code == 200
-    assert len([l for l in r.text.splitlines()
-                if l.startswith('# TYPE')]) >= min_num_of_metrics
+    assert len([line for line in r.text.splitlines()
+                if line.startswith('# TYPE')]) >= min_num_of_metrics
 
 
 def test_standalone_metrics_server_disabled_by_default(requests_session):
@@ -29,5 +29,5 @@ def test_standalone_metrics_server(requests_session):
 
     r = requests_session.get('http://127.0.0.1:10040/metrics')
 
-    assert len([l for l in r.text.splitlines()
-                if l.startswith('# TYPE')]) >= min_num_of_metrics
+    assert len([line for line in r.text.splitlines()
+                if line.startswith('# TYPE')]) >= min_num_of_metrics

From a72a3a3322cee1bd4ba3754d4e51523c89de62d1 Mon Sep 17 00:00:00 2001
From: Valerij Maljulin <vmaljuli@redhat.com>
Date: May 19 2020 14:15:30 +0000
Subject: [PATCH 2/2] Duplicate requirements removal


JIRA: RHELWF-704

Signed-off-by: Valerij Maljulin <vmaljuli@redhat.com>

---

diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py
index cd2682e..39fad87 100644
--- a/greenwave/api_v1.py
+++ b/greenwave/api_v1.py
@@ -521,7 +521,7 @@ def make_decision():
         'satisfied_requirements':
             [answer.to_json() for answer in answers if answer.is_satisfied],
         'unsatisfied_requirements':
-            [answer.to_json() for answer in answers if not answer.is_satisfied],
+            [answer.to_json() for answer in answers if not answer.is_satisfied]
     }
 
     # Check if on-demand policy was specified
diff --git a/greenwave/tests/test_waive.py b/greenwave/tests/test_waive.py
index dc296e1..9073784 100644
--- a/greenwave/tests/test_waive.py
+++ b/greenwave/tests/test_waive.py
@@ -1,7 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0+
 
+import mock
+
 from greenwave.policies import (
     InvalidRemoteRuleYaml,
+    TestResultPassed,
     TestResultMissing,
     TestResultFailed,
 )
@@ -102,3 +105,66 @@ def test_waive_invalid_gatin_yaml():
     ]
     waived = waive_answers(answers, waivers)
     assert [] == waived
+
+
+def test_waive_answers_duplicates():
+    mock_subject = mock.Mock()
+    mock_subject.type = 'koji_build'
+    mock_subject.identifier = 'glibc-1.0-1588233006.954829.fedora-rawhide'
+    mock_subject.to_dict.return_value = {'item': mock_subject.identifier, 'type': mock_subject.type}
+    test_name1 = 'test1'
+    test_name2 = 'test2'
+    scenario = 'xyz'
+    result_id = 123456
+    answers = [
+        TestResultPassed(mock_subject, test_name1, result_id),
+        TestResultMissing(mock_subject, test_name2, scenario),
+        TestResultFailed(mock_subject, test_name1, scenario, result_id),
+        TestResultPassed(mock_subject, test_name1, result_id),
+        TestResultMissing(mock_subject, test_name2, scenario),
+        TestResultFailed(mock_subject, test_name2, scenario, result_id)
+    ]
+    waivers = [
+        {
+            "subject_identifier": mock_subject.identifier,
+            "subject_type": mock_subject.type,
+            'testcase': test_name2
+        }
+    ]
+    answers_json = [ans.to_json() for ans in waive_answers(answers, waivers)]
+    answers_to_check = [
+        {
+            "subject_identifier": mock_subject.identifier,
+            "subject_type": mock_subject.type,
+            "testcase": test_name1,
+            'result_id': result_id,
+            "type": "test-result-passed"
+        },
+        {
+            "scenario": scenario,
+            "subject_identifier": mock_subject.identifier,
+            "subject_type": mock_subject.type,
+            "testcase": test_name2,
+            "type": "test-result-missing-waived"
+        },
+        {
+            "item": {
+                "item": mock_subject.identifier,
+                "type": mock_subject.type
+            },
+            "scenario": scenario,
+            "testcase": test_name1,
+            'result_id': result_id,
+            "type": "test-result-failed"
+        },
+        {
+            "scenario": scenario,
+            "subject_identifier": mock_subject.identifier,
+            "subject_type": mock_subject.type,
+            "testcase": test_name2,
+            'result_id': result_id,
+            "type": "test-result-failed-waived"
+        },
+    ]
+    assert len(answers_json) == len(answers_to_check)
+    assert all(a in answers_json for a in answers_to_check)
diff --git a/greenwave/waivers.py b/greenwave/waivers.py
index 45d79ce..34ef497 100644
--- a/greenwave/waivers.py
+++ b/greenwave/waivers.py
@@ -1,6 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 
+from greenwave.utils import remove_duplicates
+
+
 def _is_waived(answer, waivers):
     """
     Returns true only if there is a matching waiver for given answer.
@@ -22,6 +25,7 @@ def _maybe_waive(answer, waivers):
     return answer
 
 
+@remove_duplicates
 def waive_answers(answers, waivers):
     """
     Returns answers with unsatisfied answers waived

