Merge "Add de-duplication to periodic triggers"
diff --git a/tests/fixtures/layout-idle.yaml b/tests/fixtures/layout-idle.yaml
new file mode 100644
index 0000000..e4574fa
--- /dev/null
+++ b/tests/fixtures/layout-idle.yaml
@@ -0,0 +1,12 @@
+pipelines:
+  - name: periodic
+    manager: IndependentPipelineManager
+    trigger:
+      timer:
+        - time: '* * * * * */1'
+
+projects:
+  - name: org/project
+    periodic:
+      - project-test1
+      - project-test2
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index 7e1416f..a99a946 100755
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -3201,6 +3201,33 @@
         self.assertIn('project-bitrot-stable-old', status_jobs)
         self.assertIn('project-bitrot-stable-older', status_jobs)
 
+    def test_idle(self):
+        "Test that frequent periodic jobs work"
+        self.worker.hold_jobs_in_build = True
+        self.config.set('zuul', 'layout_config',
+                        'tests/fixtures/layout-idle.yaml')
+        self.sched.reconfigure(self.config)
+        self.registerJobs()
+
+        # The pipeline triggers every second, so we should have seen
+        # several by now.
+        time.sleep(5)
+        self.waitUntilSettled()
+        self.assertEqual(len(self.builds), 2)
+        self.worker.release('.*')
+        self.waitUntilSettled()
+        self.assertEqual(len(self.builds), 0)
+        self.assertEqual(len(self.history), 2)
+
+        time.sleep(5)
+        self.waitUntilSettled()
+        self.assertEqual(len(self.builds), 2)
+        self.assertEqual(len(self.history), 2)
+        self.worker.release('.*')
+        self.waitUntilSettled()
+        self.assertEqual(len(self.builds), 0)
+        self.assertEqual(len(self.history), 4)
+
     def test_check_smtp_pool(self):
         self.config.set('zuul', 'layout_config',
                         'tests/fixtures/layout-smtp.yaml')
diff --git a/zuul/model.py b/zuul/model.py
index 9028577..7f496db 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -882,6 +882,8 @@
         return None
 
     def equals(self, other):
+        if (self.project == other.project):
+            return True
         return False
 
     def isUpdateOf(self, other):