diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index c235a57..0c1a2f0 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,13 +1,14 @@
- repo: git@github.com:asottile/reorder_python_imports
- sha: v0.3.0
- commit_stage: [commit]
+ sha: v0.3.2
+ commit_stage:
+ - commit
hooks:
- id: reorder-python-imports
stages: commit_stage
-
- repo: git://github.com/pre-commit/pre-commit-hooks
- sha: v0.6.0
- commit_stage: [commit]
+ sha: v0.8.0
+ commit_stage:
+ - commit
hooks:
- id: trailing-whitespace
- id: check-ast
@@ -15,16 +16,15 @@
- id: check-merge-conflict
- id: check-symlinks
- id: debug-statements
- #- id: detect-aws-credentials
- id: detect-private-key
- id: double-quote-string-fixer
- id: end-of-file-fixer
- id: fix-encoding-pragma
- id: flake8
stages: commit_stage
-
- repo: local
- push_stage: [push]
+ push_stage:
+ - push
hooks:
- id: check-tox
name: Tox Tests
diff --git a/.travis.yml b/.travis.yml
index 9b5a6e8..de125e6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,18 +1,14 @@
language: python
python:
- - 2.6
- - 2.7
- - pypy
- - 3.2
- 3.3
- 3.4
+ - 3.5
+ - 3.6
- nightly
- - pypy3
-matrix:
- allow_failures:
- - python: 2.6
- - python: 2.7
- - python: pypy
+addons:
+ apt:
+ packages:
+ - pandoc
install:
- pip install -r requirements.txt
- pip install -r requirements-dev.txt
diff --git a/README.md b/README.md
index cc47d65..9c6b339 100644
--- a/README.md
+++ b/README.md
@@ -30,8 +30,10 @@ pip3 install qmon
```
This is how it'll appear in hipchat:
+
![hipchat_window](http://i.imgur.com/G1vnPUm.png)
Find us:
+
* [PyPi](https://pypi.python.org/pypi/qmon)
diff --git a/qmon/main.py b/qmon/main.py
index 6f8e54a..55022a7 100644
--- a/qmon/main.py
+++ b/qmon/main.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
#
# main.py - All commandline interactions
# This file is a part of QMon.
@@ -18,7 +19,6 @@
# You should have received a copy of the GNU General Public License
# along with QMon. If not, see .
#
-
from __future__ import print_function
import logging
@@ -26,6 +26,7 @@
import qmon.monitor
from qmon import __version__
+from qmon import monitor
def print_version():
@@ -43,6 +44,8 @@ def parse_known_args():
parser.add_argument('--host', required=True, help='Redis host')
parser.add_argument('--port', '-p', help='Redis port')
parser.add_argument('--room', '-r', help='HipChat Room')
+ parser.add_argument('--sleep-time', '-t', default=monitor.TIME_GAP_IN_SECONDS, help='Number of seconds to sleep')
+ parser.add_argument('--stop-once-empty', '-s', action='store_true', help='Stop when no items left in queue')
parser.add_argument('-V', '--version',
action='store_true',
dest='version',
@@ -55,7 +58,14 @@ def main():
args, otherthings, parser = parse_known_args()
setup_logging()
- qmon.monitor.monitor_queue(queue_name=args.queue_name, host=args.host, port=args.port, room=args.room)
+ qmon.monitor.monitor_queue(
+ queue_name=args.queue_name,
+ host=args.host,
+ port=args.port,
+ room=args.room,
+ sleep_time=args.sleep_time,
+ stop_once_empty=args.stop_once_empty
+ )
return 0
diff --git a/qmon/monitor.py b/qmon/monitor.py
index 15bd4b0..a659bae 100644
--- a/qmon/monitor.py
+++ b/qmon/monitor.py
@@ -30,9 +30,15 @@ def __should_i_notify_subscribers_now():
return should_notify
-def monitor_queue(queue_name, host, port, room):
+def monitor_queue(queue_name, host, port, room, sleep_time=TIME_GAP_IN_SECONDS, stop_once_empty=False):
+ sleep_time = int(sleep_time)
+ if sleep_time < 1:
+ raise ValueError('Sleep time too low. Please specify sleep time in seconds.')
+ if room is None:
+ raise ValueError('Please specify a valid room name')
logger.info('Connecting to hipchat')
- hc = hypchat.HypChat(os.environ['HIP_TOKEN'])
+ hip_token = os.environ['HIP_TOKEN'] # Please specify your token using: export HIP_TOKEN=my_hipchat_token
+ hc = hypchat.HypChat(hip_token)
room = hc.get_room(room)
room.notification(
@@ -45,7 +51,7 @@ def monitor_queue(queue_name, host, port, room):
last_notify_items_length = 0
last_items_length = 0
rd = qmon.status.redis_connection_cached(host, port)
- while items_in_queue:
+ while not stop_once_empty or items_in_queue:
items_in_queue = qmon.status.get_items_in_queue(queue_name, redis_conn=rd, default=0)
if last_items_length != items_in_queue:
message = '{} queue status: {:,d}'.format(queue_name, items_in_queue)
@@ -54,7 +60,7 @@ def monitor_queue(queue_name, host, port, room):
if notified:
last_notify_items_length = items_in_queue
last_items_length = items_in_queue
- time.sleep(TIME_GAP_IN_SECONDS)
+ time.sleep(sleep_time)
room.notification(
'All done for {queue}.'.format(queue=queue_name),
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 953186b..866d1ff 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -5,3 +5,5 @@ nose2
mock
coverage
unittest2
+
+pypandoc
diff --git a/setup.py b/setup.py
index 0155e85..b1dc8ed 100644
--- a/setup.py
+++ b/setup.py
@@ -1,11 +1,11 @@
-# coding=utf-8
+# -*- coding: utf-8 -*-
from distutils.core import setup
from setuptools import find_packages
def get_version():
- return '0.1.1'
+ return '0.2.0'
def get_requirements():
@@ -18,26 +18,36 @@ def get_long_description():
try:
import pypandoc
long_description = pypandoc.convert('README.md', 'rst')
- except (IOError, ImportError):
+
+ readme_note = """\
+ .. note::
+ For the latest source, discussion, etc, please visit the
+ `GitHub repository `_\n\n"""
+ long_description = readme_note + long_description
+ with open('README.rst', 'w') as fhan:
+ fhan.write(long_description)
+ except (IOError, ImportError) as e:
+ raise e
with open('README.md') as fhan:
long_description = fhan.read()
return long_description
-add_keywords = dict(
- entry_points={
- 'console_scripts': ['qmon = qmon.main:main'],
- }, )
-
-setup(
- name='QMon',
- description='Redis Monitor - monitor number of items and more for any type of redis queue',
- version=get_version(),
- packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),
- license='GPLv3+',
- author='Shubham Chaudhary',
- author_email='me@shubhamchaudhary.in',
- url='https://github.com/shubhamchaudhary/qmon',
- long_description=get_long_description(),
- install_requires=get_requirements(),
- **add_keywords)
+if __name__ == '__main__':
+ add_keywords = dict(
+ entry_points={
+ 'console_scripts': ['qmon = qmon.main:main'],
+ }, )
+
+ setup(
+ name='QMon',
+ description='Redis Monitor - monitor number of items and more for any type of redis queue',
+ version=get_version(),
+ packages=find_packages(exclude=['*.tests', '*.tests.*', 'tests.*', 'tests']),
+ license='GPLv3+',
+ author='Shubham Chaudhary',
+ author_email='me@shubhamchaudhary.in',
+ url='https://github.com/shubhamchaudhary/qmon',
+ long_description=get_long_description(),
+ install_requires=get_requirements(),
+ **add_keywords)
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1 @@
+
diff --git a/tests/test_monitor.py b/tests/test_monitor.py
new file mode 100644
index 0000000..8e5ac34
--- /dev/null
+++ b/tests/test_monitor.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+import unittest
+from unittest import mock
+
+from qmon.monitor import monitor_queue
+
+
+@mock.patch('qmon.monitor.time.sleep')
+@mock.patch('qmon.monitor.os.environ')
+@mock.patch('qmon.monitor.hypchat.HypChat')
+@mock.patch('qmon.monitor.qmon.status.get_items_in_queue')
+@mock.patch('qmon.monitor.qmon.status.redis_connection_cached')
+class TestMonitor(unittest.TestCase):
+ def setup_mock(self, mock_hypchat, mock_items_in_queue, mock_os, mock_redis, items_in_queue=None):
+ if not items_in_queue:
+ items_in_queue = [0]
+ mock_items_in_queue.side_effect = items_in_queue
+ redis = mock.MagicMock()
+ mock_redis.return_value = redis
+ mock_os.__getitem__.return_value = 'dummy_token'
+ client = mock.MagicMock()
+ room = mock.MagicMock()
+ client.get_room.return_value = room
+ mock_hypchat.return_value = client
+ return room
+
+ def test_monitor_queue__no_items__only_start_notification_and_end_notification(
+ self, mock_redis, mock_items_in_queue, mock_hypchat, mock_os, mock_sleep
+ ):
+ room = self.setup_mock(mock_hypchat, mock_items_in_queue, mock_os, mock_redis, items_in_queue=[0])
+
+ monitor_queue(
+ 'dummy_queue',
+ 'dummy_host',
+ 10,
+ 'dummy_room',
+ stop_once_empty=True,
+ )
+
+ room.notification.assert_has_calls([
+ mock.call('Starting to monitor queue=dummy_queue on port=10', color='yellow', notify=True),
+ mock.call('All done for dummy_queue.', color='yellow', notify=True),
+ ])
+ self.assertEqual(2, room.notification.call_count)
+
+ def test_monitor_queue__some_items__send_notification(
+ self, mock_redis, mock_items_in_queue, mock_hypchat, mock_os, mock_sleep
+ ):
+ room = self.setup_mock(mock_hypchat, mock_items_in_queue, mock_os, mock_redis, items_in_queue=[30, 0])
+
+ monitor_queue(
+ 'dummy_queue',
+ 'dummy_host',
+ 10,
+ 'dummy_room',
+ stop_once_empty=True,
+ )
+
+ room.notification.assert_has_calls([
+ mock.call('dummy_queue queue status: 30', color='gray', notify=False),
+ mock.call('dummy_queue queue status: 0', color='gray', notify=False),
+ ])
+ self.assertEqual(4, room.notification.call_count)