mirror of
https://github.com/lubuntu-team/lugito.git
synced 2025-05-01 21:11:28 +00:00
Added .lugitorc configuration and hooked the config files into the connectors. Updates to HISTORY.rst, README.rst and AUTHORS.rst
This commit is contained in:
parent
f327136c34
commit
e445368ef9
27
.arcconfig
27
.arcconfig
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"hosts": {
|
|
||||||
"http://phab.lubuntu.me/": {
|
|
||||||
"token": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"default": "http://phab.lubunutu.me/api/"
|
|
||||||
},
|
|
||||||
"HMAC": i{
|
|
||||||
"irc": "",
|
|
||||||
},
|
|
||||||
"irc": {
|
|
||||||
"host": "irc.freenode.net",
|
|
||||||
"port": "6697",
|
|
||||||
"username": "",
|
|
||||||
"password": "",
|
|
||||||
"channel": "#lubuntu-devel"
|
|
||||||
},
|
|
||||||
"launchpad": {
|
|
||||||
"application": "lugito",
|
|
||||||
"staging": "production",
|
|
||||||
"version": "devel",
|
|
||||||
"supported_versions": ["Cosmic", "Bionic", "Xenial", "Trusty"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,6 +1,11 @@
|
|||||||
# Created by .ignore support plugin (hsz.mobi)
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
# Config file
|
# Config file
|
||||||
.arcconfig
|
.arcconfig
|
||||||
|
.lugitorc
|
||||||
|
|
||||||
|
# launchpad files
|
||||||
|
devel/*
|
||||||
|
|
||||||
#
|
#
|
||||||
### Python template
|
### Python template
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
|
@ -5,9 +5,9 @@ Credits
|
|||||||
Development Lead
|
Development Lead
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
* Ben Johnston <bjohnston@neomailbox.net>
|
* Simon Quigley
|
||||||
|
|
||||||
Contributors
|
Contributors
|
||||||
------------
|
-----------
|
||||||
|
|
||||||
None yet. Why not be the first?
|
* Ben Johnston (docEbrown) <bjohnston@neomailbox.net>
|
||||||
|
27
HISTORY.rst
27
HISTORY.rst
@ -2,7 +2,28 @@
|
|||||||
History
|
History
|
||||||
=======
|
=======
|
||||||
|
|
||||||
0.1.0 (2018-11-07)
|
0.1.0 (20th May 2018)
|
||||||
------------------
|
----------------------
|
||||||
|
|
||||||
* First release on PyPI.
|
* Initial Release
|
||||||
|
|
||||||
|
|
||||||
|
0.2.0 (21st November 2018)
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* added functionality for reporting creation, comments and edits on comments of
|
||||||
|
diffs
|
||||||
|
* Refactored into Python package
|
||||||
|
* irc and launchpad connections written into separate Python modules
|
||||||
|
* corrected issues with reporting using links with anchors via IRC
|
||||||
|
* added some unittests
|
||||||
|
|
||||||
|
* **Still TODO**
|
||||||
|
|
||||||
|
* Documentation - read the docs
|
||||||
|
* Add decorators to Lugito class to check that a request has been validated before other tasks can be completed
|
||||||
|
* Improve test coverage
|
||||||
|
* Pypi upload
|
||||||
|
* Add exceptions in the event that connector send method calls are not executed correctly
|
||||||
|
* CI and automated docs and Pypi udpate
|
||||||
|
* in-situ testing
|
66
README.md
66
README.md
@ -1,5 +1,65 @@
|
|||||||
# Lugito
|
lugito
|
||||||
|
======
|
||||||
|
|
||||||
This is Lubuntu's friendly IRC notifications bot, hooked up to our Phabricator instance at phab.lubuntu.me
|
[](https://pypi.python.org/pypi/lugito)
|
||||||
|
|
||||||
The code is licensed under the 3-clause BSD license, and is copyrighted by the Lubuntu team. More info available in LICENSE.
|
[](https://travis-ci.org/doc-E-brown/lugito)
|
||||||
|
|
||||||
|
[](https://lugito.readthedocs.io/en/latest/?badge=latest)
|
||||||
|
|
||||||
|
Python Boilerplate contains all the boilerplate you need to create a
|
||||||
|
Python package.
|
||||||
|
|
||||||
|
- Free software: 3 Clause BSD license
|
||||||
|
- Documentation: <https://lugito.readthedocs.io>.
|
||||||
|
|
||||||
|
Temp - Example .lugitorc
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
```
|
||||||
|
[phabricator]
|
||||||
|
host = http://127.0.0.1:9091/api/
|
||||||
|
token = api-nojs2ip33hmp4zn6u6cf72w7d6yh
|
||||||
|
|
||||||
|
[phabricator.hooks]
|
||||||
|
irc = cqg42zdcuqysff632kc6rnsu4m3hjg6c
|
||||||
|
commithook = znkyfflbcia5gviqx5ybad7s6uyfywxi
|
||||||
|
|
||||||
|
[connector.irc]
|
||||||
|
host = irc.freenode.net
|
||||||
|
port = 6697
|
||||||
|
username = someusername
|
||||||
|
password = somepassword
|
||||||
|
channel = #somechannel
|
||||||
|
|
||||||
|
[connector.launchpad]
|
||||||
|
application = lugito
|
||||||
|
staging = production
|
||||||
|
version = devel
|
||||||
|
supported_versions =
|
||||||
|
Cosmic
|
||||||
|
Bionic
|
||||||
|
Xenial
|
||||||
|
Trusty
|
||||||
|
|
||||||
|
[connector.launchpad.package_names]
|
||||||
|
rDEFAULTSETTINGS = lubuntu-default-settings
|
||||||
|
rART = lubuntu-artwork
|
||||||
|
rCALASETTINGS = calamares-settings-ubuntu
|
||||||
|
rQTERMINALPACKAGING = qterminal
|
||||||
|
rLXQTCONFIGPACKAGING = lxqt-config
|
||||||
|
rNMTRAYPACKAGING = nm-tray
|
||||||
|
```
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- TODO
|
||||||
|
|
||||||
|
Credits
|
||||||
|
-------
|
||||||
|
|
||||||
|
This package was created with
|
||||||
|
[Cookiecutter](https://github.com/audreyr/cookiecutter) and the
|
||||||
|
[audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage)
|
||||||
|
project template.
|
||||||
|
52
README.rst
52
README.rst
@ -2,25 +2,55 @@
|
|||||||
lugito
|
lugito
|
||||||
======
|
======
|
||||||
|
|
||||||
|
lugito is a Python package that provides a webserver for connecting updates from Phabricator to communication tools such as irc and other services such as launchpad.
|
||||||
|
|
||||||
.. image:: https://img.shields.io/pypi/v/lugito.svg
|
Installation
|
||||||
:target: https://pypi.python.org/pypi/lugito
|
-------------
|
||||||
|
|
||||||
.. image:: https://img.shields.io/travis/doc-E-brown/lugito.svg
|
lugito can be installed via Pyp
|
||||||
:target: https://travis-ci.org/doc-E-brown/lugito
|
|
||||||
|
|
||||||
.. image:: https://readthedocs.org/projects/lugito/badge/?version=latest
|
|
||||||
:target: https://lugito.readthedocs.io/en/latest/?badge=latest
|
|
||||||
:alt: Documentation Status
|
|
||||||
|
|
||||||
|
|
||||||
|
* Free software: 3 Clause BSD license
|
||||||
|
|
||||||
|
|
||||||
Python Boilerplate contains all the boilerplate you need to create a Python package.
|
Temp - Example .lugitorc
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
[phabricator]
|
||||||
|
host = http://127.0.0.1:9091/api/
|
||||||
|
token = api-nojs2ip33hmp4zn6u6cf72w7d6yh
|
||||||
|
|
||||||
|
[phabricator.hooks]
|
||||||
|
irc = cqg42zdcuqysff632kc6rnsu4m3hjg6c
|
||||||
|
commithook = znkyfflbcia5gviqx5ybad7s6uyfywxi
|
||||||
|
|
||||||
|
[connector.irc]
|
||||||
|
host = irc.freenode.net
|
||||||
|
port = 6697
|
||||||
|
username = someusername
|
||||||
|
password = somepassword
|
||||||
|
channel = #somechannel
|
||||||
|
|
||||||
|
[connector.launchpad]
|
||||||
|
application = lugito
|
||||||
|
staging = production
|
||||||
|
version = devel
|
||||||
|
supported_versions =
|
||||||
|
Cosmic
|
||||||
|
Bionic
|
||||||
|
Xenial
|
||||||
|
Trusty
|
||||||
|
|
||||||
|
[connector.launchpad.package_names]
|
||||||
|
rDEFAULTSETTINGS = lubuntu-default-settings
|
||||||
|
rART = lubuntu-artwork
|
||||||
|
rCALASETTINGS = calamares-settings-ubuntu
|
||||||
|
rQTERMINALPACKAGING = qterminal
|
||||||
|
rLXQTCONFIGPACKAGING = lxqt-config
|
||||||
|
rNMTRAYPACKAGING = nm-tray
|
||||||
|
|
||||||
* Free software: BSD license
|
|
||||||
* Documentation: https://lugito.readthedocs.io.
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
Features
|
||||||
|
@ -2,14 +2,7 @@ from lugito.lugito import (
|
|||||||
Lugito,
|
Lugito,
|
||||||
)
|
)
|
||||||
|
|
||||||
from lugito.connectors.irc import (
|
import lugito.config
|
||||||
IRCConnector,
|
|
||||||
)
|
|
||||||
|
|
||||||
from lugito.connectors.launchpad import (
|
|
||||||
LPConnectook,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
from ._version import get_versions
|
from ._version import get_versions
|
||||||
__version__ = get_versions()['version']
|
__version__ = get_versions()['version']
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
# Imports
|
# Imports
|
||||||
|
|
||||||
|
|
||||||
from lugito.webhooks import run
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
from lugito.webhooks import run
|
||||||
run()
|
run()
|
||||||
|
135
lugito/config.py
Normal file
135
lugito/config.py
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# S.D.G
|
||||||
|
|
||||||
|
"""
|
||||||
|
:mod:`lugito.config`
|
||||||
|
======================================
|
||||||
|
|
||||||
|
Module to manage lugito configuration
|
||||||
|
|
||||||
|
.. currentmodule:: lugito.config
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Imports
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import configparser
|
||||||
|
|
||||||
|
DEFAULT_CONFIG_FILE = os.path.join(
|
||||||
|
os.getcwd(), '.lugitorc')
|
||||||
|
|
||||||
|
logger = logging.getLogger('lugito.config')
|
||||||
|
|
||||||
|
# Add log level
|
||||||
|
ch = logging.StreamHandler()
|
||||||
|
|
||||||
|
formatter = logging.Formatter(
|
||||||
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||||
|
|
||||||
|
ch.setFormatter(formatter)
|
||||||
|
logger.addHandler(ch)
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
CONFIG = {}
|
||||||
|
|
||||||
|
|
||||||
|
def update_config(config_file=DEFAULT_CONFIG_FILE):
|
||||||
|
"""
|
||||||
|
Update the system config from a config file
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
|
||||||
|
config_file: str
|
||||||
|
The path of the lugito config file
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
|
||||||
|
config: dictionary
|
||||||
|
A dictionary of config parameters
|
||||||
|
|
||||||
|
"""
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(config_file)
|
||||||
|
|
||||||
|
# Make some basic assertions for minimum functionality
|
||||||
|
if 'phabricator' not in config:
|
||||||
|
raise ValueError('phabricator section missing from config file: %s' %\
|
||||||
|
config_file)
|
||||||
|
|
||||||
|
if 'host' not in config['phabricator']:
|
||||||
|
raise ValueError('host value missing from phabricator section in'\
|
||||||
|
' config file: %s' % config_file)
|
||||||
|
|
||||||
|
if 'token' not in config['phabricator']:
|
||||||
|
raise ValueError('token value missing from phabricator section in'\
|
||||||
|
' config file: %s' % config_file)
|
||||||
|
|
||||||
|
CONFIG['phabricator'] = {}
|
||||||
|
CONFIG['phabricator']['host'] = config['phabricator']['host']
|
||||||
|
CONFIG['phabricator']['token'] = config['phabricator']['token']
|
||||||
|
|
||||||
|
CONFIG['phabricator']['hooks'] = {}
|
||||||
|
|
||||||
|
# Iterate through hooks for HMAC keys
|
||||||
|
if 'phabricator.hooks' in config:
|
||||||
|
|
||||||
|
for key, value in config['phabricator.hooks'].items():
|
||||||
|
CONFIG['phabricator']['hooks'][key] = value
|
||||||
|
|
||||||
|
CONFIG['connectors'] = {}
|
||||||
|
|
||||||
|
# Iterate through available connectors
|
||||||
|
for key in config.keys():
|
||||||
|
|
||||||
|
# Is a connector section
|
||||||
|
if ('connector.' in key) and (key.count('.') == 1) :
|
||||||
|
connector = key.split('.')[1]
|
||||||
|
|
||||||
|
if 'connectors' not in CONFIG:
|
||||||
|
CONFIG['connectors'] = {}
|
||||||
|
|
||||||
|
if connector not in CONFIG['connectors']:
|
||||||
|
CONFIG['connectors'][connector] = {}
|
||||||
|
|
||||||
|
for param, value in config[key].items():
|
||||||
|
|
||||||
|
# Check for multiple values for a parameter
|
||||||
|
if value.find('\n') >= 0:
|
||||||
|
value = value[1:].split('\n')
|
||||||
|
|
||||||
|
CONFIG['connectors'][connector][param] = value
|
||||||
|
|
||||||
|
# Is a connector sub-section
|
||||||
|
elif ('connector.' in key) and (key.count('.') > 1) :
|
||||||
|
sections = key.split('.')
|
||||||
|
connector = sections[1]
|
||||||
|
subsection = sections[-1]
|
||||||
|
|
||||||
|
if 'connectors' not in CONFIG:
|
||||||
|
CONFIG['connectors'] = {}
|
||||||
|
|
||||||
|
if connector not in CONFIG['connectors']:
|
||||||
|
CONFIG['connectors'][connector] = {}
|
||||||
|
|
||||||
|
CONFIG['connectors'][connector][subsection] = {}
|
||||||
|
|
||||||
|
for param, value in config[key].items():
|
||||||
|
|
||||||
|
# Check for multiple values for a parameter
|
||||||
|
if value.find('\n') >= 0:
|
||||||
|
value = value[1:].split('\n')
|
||||||
|
|
||||||
|
# configparser reads the parameters as lower case
|
||||||
|
# convert all but first character to upper case
|
||||||
|
param = 'r{}'.format(param[1:].upper())
|
||||||
|
CONFIG['connectors'][connector][subsection][param] = value
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
update_config()
|
||||||
|
except ValueError:
|
||||||
|
# The config file is not present
|
||||||
|
logging.warning('Default config file: %s not found' % DEFAULT_CONFIG_FILE)
|
@ -1,3 +1,11 @@
|
|||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# S.D.G
|
# S.D.G
|
||||||
|
|
||||||
|
from lugito.connectors.irc import (
|
||||||
|
irc,
|
||||||
|
)
|
||||||
|
|
||||||
|
from lugito.connectors.launchpad import (
|
||||||
|
launchpad,
|
||||||
|
)
|
||||||
|
@ -18,25 +18,27 @@ import socket
|
|||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import phabricator
|
import phabricator
|
||||||
|
import lugito
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
class IRCConnector(object):
|
class irc(object):
|
||||||
|
|
||||||
def __init__(self, log_level=logging.DEBUG):
|
def __init__(self, log_level=logging.DEBUG, sleep_delay=5):
|
||||||
|
|
||||||
# IRC info
|
# IRC info
|
||||||
# Read the configuration out of the .arcconfig file
|
# Read the configuration out of the .arcconfig file
|
||||||
self.host = phabricator.ARCRC['irc']['host']
|
self.host = lugito.config.CONFIG['connectors']['irc']['host']
|
||||||
self.port = int(phabricator.ARCRC['irc']['port'])
|
self.port = int(lugito.config.CONFIG['connectors']['irc']['port'])
|
||||||
self.username = phabricator.ARCRC['irc']['username']
|
self.username = lugito.config.CONFIG['connectors']['irc']['username']
|
||||||
self.password = phabricator.ARCRC['irc']['password']
|
self.password = lugito.config.CONFIG['connectors']['irc']['password']
|
||||||
self.channel = phabricator.ARCRC['irc']['channel']
|
self.channel = lugito.config.CONFIG['connectors']['irc']['channel']
|
||||||
|
|
||||||
# Phabricator info
|
# Phabricator info
|
||||||
self.phab = phabricator.Phabricator()
|
self.phab = phabricator.Phabricator(
|
||||||
self.phab_host = phabricator.ARCRC['config']['default'].replace(
|
host=lugito.config.CONFIG['phabricator']['host'],
|
||||||
'api/', '')
|
token=lugito.config.CONFIG['phabricator']['token'],)
|
||||||
|
self.phab_host = self.phab.host.replace('api/', '')
|
||||||
|
|
||||||
self.logger = logging.getLogger('lugito.connector.IRCConnector')
|
self.logger = logging.getLogger('lugito.connector.IRCConnector')
|
||||||
|
|
||||||
@ -50,14 +52,17 @@ class IRCConnector(object):
|
|||||||
self.logger.addHandler(ch)
|
self.logger.addHandler(ch)
|
||||||
self.logger.setLevel(log_level)
|
self.logger.setLevel(log_level)
|
||||||
|
|
||||||
|
self.sleep_delay = sleep_delay
|
||||||
|
|
||||||
def _send_raw(self, message):
|
|
||||||
|
def _send_raw(self, message): # pragma: no cover
|
||||||
"""Low level send"""
|
"""Low level send"""
|
||||||
|
|
||||||
self.conn.send(message.encode('utf-8'))
|
self.conn.send(message.encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def _socket_conn(self):
|
def _setup_connection(self):
|
||||||
|
"""Setup connection"""
|
||||||
self.conn = ssl.wrap_socket(
|
self.conn = ssl.wrap_socket(
|
||||||
socket.socket(socket.AF_INET, socket.SOCK_STREAM))
|
socket.socket(socket.AF_INET, socket.SOCK_STREAM))
|
||||||
self.conn.connect((self.host, self.port))
|
self.conn.connect((self.host, self.port))
|
||||||
@ -66,11 +71,11 @@ class IRCConnector(object):
|
|||||||
def connect(self):
|
def connect(self):
|
||||||
"""Connect"""
|
"""Connect"""
|
||||||
|
|
||||||
self._socket_conn()
|
self.logger.info("Connecting to IRC.")
|
||||||
|
self._setup_connection()
|
||||||
|
|
||||||
setup = False
|
setup = False
|
||||||
usersuffix = 0
|
usersuffix = 0
|
||||||
self.logger.info("Connecting to IRC.")
|
|
||||||
|
|
||||||
while not setup:
|
while not setup:
|
||||||
response = self.conn.recv(512).decode("utf-8")
|
response = self.conn.recv(512).decode("utf-8")
|
||||||
@ -84,11 +89,11 @@ class IRCConnector(object):
|
|||||||
self.username, self.password))
|
self.username, self.password))
|
||||||
|
|
||||||
if "You are now identified" in response:
|
if "You are now identified" in response:
|
||||||
sleep(5)
|
sleep(self.sleep_delay)
|
||||||
self._send_raw("JOIN {}\r\n".format(self.channel))
|
self._send_raw("JOIN {}\r\n".format(self.channel))
|
||||||
|
|
||||||
if "477" in response:
|
if "477" in response:
|
||||||
sleep(5)
|
sleep(self.sleep_delay)
|
||||||
self._send_raw("JOIN {}\r\n".format(self.channel))
|
self._send_raw("JOIN {}\r\n".format(self.channel))
|
||||||
|
|
||||||
if "433" in response:
|
if "433" in response:
|
||||||
@ -106,20 +111,32 @@ class IRCConnector(object):
|
|||||||
|
|
||||||
self.logger.info("Successfully connected to the IRC server.")
|
self.logger.info("Successfully connected to the IRC server.")
|
||||||
|
|
||||||
def send_notice(self, message):
|
def send_notice(self, message): # pragma: no cover
|
||||||
self._send_raw("NOTICE {} :{}\r\n".format(self.channel, message))
|
self._send_raw("NOTICE {} :{}\r\n".format(self.channel, message))
|
||||||
|
|
||||||
def send(self, objectstr, who, body, link):
|
def send(self, *args, **kwargs):
|
||||||
"""Send a formatted message"""
|
"""Send a formatted message"""
|
||||||
|
|
||||||
|
if len(args) == 4:
|
||||||
|
objectstr, who, body, link = args
|
||||||
|
|
||||||
|
elif len(kwargs) == 4:
|
||||||
|
objectstr = kwargs['objectstr']
|
||||||
|
who = kwargs['who']
|
||||||
|
body = kwargs['body']
|
||||||
|
link = kwargs['link']
|
||||||
|
|
||||||
|
# else
|
||||||
|
# raise exception
|
||||||
|
|
||||||
# e.g. [T31: Better IRC integration]
|
# e.g. [T31: Better IRC integration]
|
||||||
message = "\x033[\x03\x0313" + objectstr + "\x03\x033]\x03 "
|
message = "\x033[\x03\x0313" + objectstr + "\x03\x033]\x03 "
|
||||||
# e.g. tsimonq2 (Simon Quigley)
|
# e.g. tsimonq2 (Simon Quigley)
|
||||||
message = message + "\x0315" + who + "\x03 "
|
message += "\x0315" + who + "\x03 "
|
||||||
# e.g. commented on the task:
|
# e.g. commented on the task:
|
||||||
message = message + body + ": "
|
message += body + ": "
|
||||||
# e.g. https://phab.lubuntu.me/T40#779
|
# e.g. https://phab.lubuntu.me/T40#779
|
||||||
message = message + "\x032" + link + "\x03"
|
message += "\x032" + link + "\x03"
|
||||||
# Make sure we can debug this if it goes haywire
|
# Make sure we can debug this if it goes haywire
|
||||||
self.logger.debug(message)
|
self.logger.debug(message)
|
||||||
# Sleep for a fifth of a second, so when we have a bunch of messages we have a buffer
|
# Sleep for a fifth of a second, so when we have a bunch of messages we have a buffer
|
||||||
@ -127,7 +144,7 @@ class IRCConnector(object):
|
|||||||
# Aaaaand, send it off!
|
# Aaaaand, send it off!
|
||||||
self.send_notice(message)
|
self.send_notice(message)
|
||||||
|
|
||||||
def gettaskinfo(self, task):
|
def get_task_info(self, task):
|
||||||
|
|
||||||
sendmessage = ""
|
sendmessage = ""
|
||||||
|
|
||||||
@ -189,8 +206,14 @@ class IRCConnector(object):
|
|||||||
|
|
||||||
# If someone wrote something like "Tblah", obviously that's not right.
|
# If someone wrote something like "Tblah", obviously that's not right.
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.send_notice("\x034Error: " + task.strip() + "is an invalid task reference.\x03")
|
|
||||||
return None
|
if anchor is not None:
|
||||||
|
link = '{}#{}'.format(task.strip(), anchor)
|
||||||
|
else:
|
||||||
|
link = task.strip()
|
||||||
|
|
||||||
|
self.send_notice("\x034Error: " + link +\
|
||||||
|
" is an invalid task reference.\x03")
|
||||||
|
|
||||||
|
|
||||||
def bot(self, message, msgtype):
|
def bot(self, message, msgtype):
|
||||||
@ -200,7 +223,7 @@ class IRCConnector(object):
|
|||||||
|
|
||||||
for item in message.split():
|
for item in message.split():
|
||||||
if item.startswith("T") or item.startwith("D"):
|
if item.startswith("T") or item.startwith("D"):
|
||||||
self.gettaskinfo(item.strip())
|
self.get_task_info(item.strip())
|
||||||
|
|
||||||
elif msgtype == "link":
|
elif msgtype == "link":
|
||||||
|
|
||||||
@ -208,7 +231,7 @@ class IRCConnector(object):
|
|||||||
if (item.split()[0].strip().startswith("T")) or \
|
if (item.split()[0].strip().startswith("T")) or \
|
||||||
(item.split()[0].strip().startswith("D")):
|
(item.split()[0].strip().startswith("D")):
|
||||||
|
|
||||||
self.gettaskinfo(item.split()[0].strip())
|
self.get_task_info(item.split()[0].strip())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.sendnotice("\x034Error: unknown command.\x03")
|
self.sendnotice("\x034Error: unknown command.\x03")
|
||||||
|
@ -11,29 +11,53 @@ Define a launchpad connector class
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Imports
|
# Imports
|
||||||
|
import re
|
||||||
import logging
|
import logging
|
||||||
import phabricator
|
import phabricator
|
||||||
from launchpadlib.launchpad import Launchpad
|
import lugito
|
||||||
|
from string import Template
|
||||||
|
from launchpadlib.launchpad import Launchpad as lp
|
||||||
|
|
||||||
|
|
||||||
class LPConnector(object):
|
BUG_MESSAGE = Template(
|
||||||
|
"This bug has been marked as fixed in the Git repository: $link\n"
|
||||||
|
"The commit message is the following: $commit_message\n\n"
|
||||||
|
"(Note: I am only a bot. If this message was received in error, "
|
||||||
|
"please contact my owners on the Lubuntu Team.)")
|
||||||
|
|
||||||
|
RE_COMMIT_MSG = re.compile(r"lp:\s+\#\d+(?:,\s*\#\d+)*")
|
||||||
|
|
||||||
|
|
||||||
|
class launchpad(object):
|
||||||
|
|
||||||
def __init__(self, log_level=logging.DEBUG):
|
def __init__(self, log_level=logging.DEBUG):
|
||||||
|
|
||||||
# Launchpad info
|
# Launchpad info
|
||||||
# Read the configuration out of the .arcconfig file
|
# Read the configuration out of the .lugitorc file
|
||||||
self.application = phabricator.ARCRC['launchpad']['application']
|
self.application = lugito.config.CONFIG['connectors']\
|
||||||
self.staging = phabricator.ARCRC['launchpad']['staging']
|
['launchpad']['application']
|
||||||
self.version = phabricator.ARCRC['launchpad']['version']
|
self.staging = lugito.config.CONFIG['connectors']\
|
||||||
|
['launchpad']['staging']
|
||||||
|
self.version = lugito.config.CONFIG['connectors']\
|
||||||
|
['launchpad']['version']
|
||||||
self.supported_vers =\
|
self.supported_vers =\
|
||||||
phabricator.ARCRC['launchpad']['supported_versions']
|
lugito.config.CONFIG['connectors']\
|
||||||
|
['launchpad']['supported_versions']
|
||||||
|
self.package_names =\
|
||||||
|
lugito.config.CONFIG['connectors']\
|
||||||
|
['launchpad']['package_names']
|
||||||
|
|
||||||
|
|
||||||
# Phabricator info
|
# Phabricator info
|
||||||
self.phab = phabricator.Phabricator()
|
self.phab = phabricator.Phabricator(
|
||||||
self.phab_host = phabricator.ARCRC['config']['default'].replace(
|
host=lugito.config.CONFIG['phabricator']['host'],
|
||||||
|
token=lugito.config.CONFIG['phabricator']['token'],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.phab_host = lugito.config.CONFIG['phabricator']['host'].replace(
|
||||||
'api/', '')
|
'api/', '')
|
||||||
|
|
||||||
self.logger = logging.getLogger('lugito.connector.LPConnector')
|
self.logger = logging.getLogger('lugito.connector.launchpad')
|
||||||
|
|
||||||
# Add log level
|
# Add log level
|
||||||
ch = logging.StreamHandler()
|
ch = logging.StreamHandler()
|
||||||
@ -50,17 +74,74 @@ class LPConnector(object):
|
|||||||
"""Connect"""
|
"""Connect"""
|
||||||
|
|
||||||
self.logger.info("Connecting to Launchpad")
|
self.logger.info("Connecting to Launchpad")
|
||||||
|
self.lp = lp.login_with(
|
||||||
|
self.application,
|
||||||
|
self.staging,
|
||||||
|
self.version)
|
||||||
|
|
||||||
|
def get_package_name(self, name):
|
||||||
|
"""Need to check"""
|
||||||
|
|
||||||
|
if name in self.package_names:
|
||||||
|
return self.package_names[name]
|
||||||
|
|
||||||
|
self.logger.debug('{} is an unsupported repository'.format(
|
||||||
|
name))
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_bugs_list(self, link):
|
||||||
|
"""Get bugs list using a link"""
|
||||||
|
|
||||||
|
regex_search = RE_COMMIT_MSG.search(link.lower())
|
||||||
|
if not regex_search:
|
||||||
|
self.logger.debug('{} not a commit message'.format(link))
|
||||||
|
return []
|
||||||
|
|
||||||
|
return regex_search.group(0).strip("lp: ").replace("#", "").split(", ")
|
||||||
|
|
||||||
|
|
||||||
def send(self, objectstr, who, body, link):
|
def send(self, *args, **kwargs):
|
||||||
pass
|
"""Send the commit message"""
|
||||||
|
|
||||||
|
if len(args) == 2:
|
||||||
|
package_name, commit_msg = args
|
||||||
|
|
||||||
|
elif len(kwargs) == 2:
|
||||||
|
commit_msg = kwargs['commit_msg']
|
||||||
|
package_name = kwargs['package_name']
|
||||||
|
|
||||||
|
# else
|
||||||
|
# raise exception
|
||||||
|
|
||||||
|
package_name = self.get_package_name(package_name)
|
||||||
|
bug_list = self.get_bugs_list(commit_msg)
|
||||||
|
|
||||||
|
if package_name and bug_list:
|
||||||
|
|
||||||
|
for bug in bug_list:
|
||||||
|
goodtask = None
|
||||||
|
bug = self.lp.load("/bugs/" + str(bug).strip())
|
||||||
|
|
||||||
|
for task in bug.bug_tasks:
|
||||||
|
for rel in self.supported_vers:
|
||||||
|
if package_name + " (Ubuntu " + rel + ")" in task.bug_target_display_name:
|
||||||
|
goodtask = task
|
||||||
|
break
|
||||||
|
|
||||||
|
if not goodtask:
|
||||||
|
if package_name + " (Ubuntu)" in task.bug_target_display_name:
|
||||||
|
goodtask = task
|
||||||
|
|
||||||
|
if goodtask:
|
||||||
|
message = BUG_MESSAGE.substitute(
|
||||||
|
link=self.phab_host + package_name,
|
||||||
|
commit_message=commit_msg,
|
||||||
|
)
|
||||||
|
bug.newMessage(content=message)
|
||||||
|
goodtask.status = "Fix Committed"
|
||||||
|
goodtask.lp_save()
|
||||||
|
|
||||||
|
|
||||||
def listen(self):
|
def listen(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
obj = LPConnector()
|
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import hmac
|
|||||||
import http
|
import http
|
||||||
import logging
|
import logging
|
||||||
import phabricator
|
import phabricator
|
||||||
|
import lugito
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
|
||||||
PHAB_WEBHOOK_SIG = "X-Phabricator-Webhook-Signature"
|
PHAB_WEBHOOK_SIG = "X-Phabricator-Webhook-Signature"
|
||||||
@ -31,9 +32,12 @@ class Lugito(object):
|
|||||||
Initialise
|
Initialise
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.phab = phabricator.Phabricator()
|
self.phab = phabricator.Phabricator(
|
||||||
self.HMAC = phabricator.ARCRC['HMAC']
|
host=lugito.config.CONFIG['phabricator']['host'],
|
||||||
self.host = phabricator.ARCRC['config']['default']
|
token=lugito.config.CONFIG['phabricator']['token'],
|
||||||
|
)
|
||||||
|
self.HMAC = lugito.config.CONFIG['phabricator']['hooks']
|
||||||
|
self.host = lugito.config.CONFIG['phabricator']['host']
|
||||||
|
|
||||||
self.logger = logging.getLogger('lugito.lugito')
|
self.logger = logging.getLogger('lugito.lugito')
|
||||||
|
|
||||||
@ -51,15 +55,7 @@ class Lugito(object):
|
|||||||
self.HMAC[key] = bytes(u'%s' % val, 'utf-8')
|
self.HMAC[key] = bytes(u'%s' % val, 'utf-8')
|
||||||
|
|
||||||
|
|
||||||
def _transaction_search(self):
|
def validate_request(self, hmac_key, request):
|
||||||
self.transaction = self.phab.transaction.search(objectIdentifier=
|
|
||||||
self.request_data["object"]["phid"])["data"]
|
|
||||||
|
|
||||||
def _request_data(self, request):
|
|
||||||
self.request_data = json.loads(request.data)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_HMAC(self, hmac_key, request):
|
|
||||||
"""
|
"""
|
||||||
Check a request originated from Phabricator. This method must be called
|
Check a request originated from Phabricator. This method must be called
|
||||||
first to validate a request is from Phabricator before any other method
|
first to validate a request is from Phabricator before any other method
|
||||||
@ -86,8 +82,13 @@ class Lugito(object):
|
|||||||
|
|
||||||
# check if from phabricator
|
# check if from phabricator
|
||||||
if hash_.hexdigest() == request.headers[PHAB_WEBHOOK_SIG]:
|
if hash_.hexdigest() == request.headers[PHAB_WEBHOOK_SIG]:
|
||||||
self._request_data(request)
|
|
||||||
self._transaction_search()
|
# Store the request and transaction
|
||||||
|
self.request_data = json.loads(request.data)
|
||||||
|
self.transaction = self.phab.transaction.search(objectIdentifier=
|
||||||
|
self.request_data["object"]["phid"])["data"]
|
||||||
|
|
||||||
|
|
||||||
self.logger.info('received phid: %s' %\
|
self.logger.info('received phid: %s' %\
|
||||||
self.request_data["object"]["phid"])
|
self.request_data["object"]["phid"])
|
||||||
return True
|
return True
|
||||||
|
@ -17,7 +17,7 @@ import logging
|
|||||||
import threading
|
import threading
|
||||||
from flask import Flask, request
|
from flask import Flask, request
|
||||||
from lugito import Lugito
|
from lugito import Lugito
|
||||||
from lugito.connectors.irc import IRCConnector
|
from lugito.connectors import irc, launchpad
|
||||||
|
|
||||||
# Constants
|
# Constants
|
||||||
GLOBAL_LOG_LEVEL = logging.DEBUG
|
GLOBAL_LOG_LEVEL = logging.DEBUG
|
||||||
@ -26,7 +26,9 @@ GLOBAL_LOG_LEVEL = logging.DEBUG
|
|||||||
lugito = Lugito(GLOBAL_LOG_LEVEL)
|
lugito = Lugito(GLOBAL_LOG_LEVEL)
|
||||||
WEBSITE = lugito.host.replace('/api/', '')
|
WEBSITE = lugito.host.replace('/api/', '')
|
||||||
|
|
||||||
irc_con = IRCConnector()
|
# Connectors
|
||||||
|
irc_con = irc()
|
||||||
|
launchpad_con = launchpad()
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
logger = logging.getLogger('lugito.webhooks')
|
logger = logging.getLogger('lugito.webhooks')
|
||||||
@ -45,11 +47,41 @@ logger.setLevel(GLOBAL_LOG_LEVEL)
|
|||||||
app = Flask('lugito')
|
app = Flask('lugito')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/commithook", methods=["POST"])
|
||||||
|
def commithook():
|
||||||
|
"""Commit hook"""
|
||||||
|
|
||||||
|
if lugito.validate_request('commithook', request):
|
||||||
|
|
||||||
|
author = lugito.get_author_fullname()
|
||||||
|
|
||||||
|
# Without the author we can't continue
|
||||||
|
if author is None:
|
||||||
|
return 'Ok'
|
||||||
|
|
||||||
|
object_type = lugito.request_data["object"]["type"]
|
||||||
|
|
||||||
|
if object_type == "CMIT":
|
||||||
|
logger.debug("Object is a commit.")
|
||||||
|
|
||||||
|
commit_msg = lugito.get_object_string("fullName").replace(
|
||||||
|
lugito.get_object_string("name") + ": ", "")
|
||||||
|
pkg_name = lugito.get_object_string("name")
|
||||||
|
|
||||||
|
|
||||||
|
launchpad_con.send(pkg_name, commit_msg)
|
||||||
|
|
||||||
|
|
||||||
|
return 'Ok'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/irc", methods=["POST"])
|
@app.route("/irc", methods=["POST"])
|
||||||
def _main():
|
def _main():
|
||||||
"""Main route"""
|
"""Main route"""
|
||||||
|
|
||||||
if lugito.validate_HMAC('irc', request):
|
if lugito.validate_request('irc', request):
|
||||||
|
|
||||||
author = lugito.get_author_fullname()
|
author = lugito.get_author_fullname()
|
||||||
|
|
||||||
@ -136,6 +168,7 @@ def _main():
|
|||||||
|
|
||||||
def run():
|
def run():
|
||||||
irc_con.connect()
|
irc_con.connect()
|
||||||
|
launchpad_con.connect()
|
||||||
t = threading.Thread(target=irc_con.listen)
|
t = threading.Thread(target=irc_con.listen)
|
||||||
t.daemon = True
|
t.daemon = True
|
||||||
t.start()
|
t.start()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
[pytest]
|
[pytest]
|
||||||
|
timeout=100
|
||||||
python_files = tests.py test_*.py *_tests.py
|
python_files = tests.py test_*.py *_tests.py
|
||||||
pytest_plugins = "pytest_cov", "pep8"
|
pytest_plugins = "pytest_cov", "pep8"
|
||||||
addopts = --doctest-modules --cov-config=.coveragerc --cov=lugito --cov-report=term-missing
|
addopts = --doctest-modules --cov-config=.coveragerc --cov=lugito --cov-report=term-missing
|
||||||
|
@ -17,7 +17,6 @@ keyring==16.0.2
|
|||||||
launchpadlib==1.10.6
|
launchpadlib==1.10.6
|
||||||
lazr.restfulclient==0.14.0
|
lazr.restfulclient==0.14.0
|
||||||
lazr.uri==1.0.3
|
lazr.uri==1.0.3
|
||||||
-e git+ssh://git@phab.lubuntu.me:2222/source/lugito.git@165c866a5d5a184b0b36552334fa11aba95b5fb8#egg=lugito
|
|
||||||
MarkupSafe==1.1.0
|
MarkupSafe==1.1.0
|
||||||
more-itertools==4.3.0
|
more-itertools==4.3.0
|
||||||
oauthlib==2.1.0
|
oauthlib==2.1.0
|
||||||
@ -31,5 +30,7 @@ pytest-cov==2.6.0
|
|||||||
SecretStorage==3.1.0
|
SecretStorage==3.1.0
|
||||||
six==1.11.0
|
six==1.11.0
|
||||||
testresources==2.0.1
|
testresources==2.0.1
|
||||||
|
versioneer==0.18
|
||||||
wadllib==1.3.3
|
wadllib==1.3.3
|
||||||
Werkzeug==0.14.1
|
Werkzeug==0.14.1
|
||||||
|
twine==1.12.1
|
||||||
|
17
setup.py
17
setup.py
@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""The setup script."""
|
"""The setup script."""
|
||||||
# import versioneer
|
import versioneer
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
with open('README.rst') as readme_file:
|
with open('README.rst') as readme_file:
|
||||||
@ -29,8 +29,8 @@ test_requirements = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
author="",
|
author="Ben Johnston (docEbrown)",
|
||||||
author_email='',
|
author_email='bjohnston@neomailbox.net',
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 2 - Pre-Alpha',
|
'Development Status :: 2 - Pre-Alpha',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
@ -42,11 +42,11 @@ setup(
|
|||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
],
|
],
|
||||||
description="Python Boilerplate contains all the boilerplate "\
|
description="Python package to connect services such as irc and launchpad"\
|
||||||
"you need to create a Python package.",
|
" to Phabricator and provide updates",
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
'lugito=lugito.cli:run',
|
'lugito=lugito.webhooks:run',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
install_requires=requirements,
|
install_requires=requirements,
|
||||||
@ -60,8 +60,7 @@ setup(
|
|||||||
test_suite='tests',
|
test_suite='tests',
|
||||||
tests_require=test_requirements,
|
tests_require=test_requirements,
|
||||||
url='',
|
url='',
|
||||||
version='0.1.0',
|
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
# version=versioneer.get_version(),
|
version=versioneer.get_version(),
|
||||||
# cmdclass=versioneer.get_cmdclass(),
|
cmdclass=versioneer.get_cmdclass(),
|
||||||
)
|
)
|
||||||
|
@ -4,24 +4,4 @@
|
|||||||
"token": "api-nojs2ip33hmp4zn6u6cf72w7d6yh"
|
"token": "api-nojs2ip33hmp4zn6u6cf72w7d6yh"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"config": {
|
|
||||||
"default": "http://127.0.0.1:9091/api/"
|
|
||||||
},
|
|
||||||
"HMAC": {
|
|
||||||
"diffhook": "vglzi6t4gsumnilv27r27no7rs3vgs75",
|
|
||||||
"commithook": "znkyfflbcia5gviqx5ybad7s6uyfywxi"
|
|
||||||
},
|
|
||||||
"irc": {
|
|
||||||
"host": "irc.freenode.net",
|
|
||||||
"port": "6697",
|
|
||||||
"username": "someusername",
|
|
||||||
"password": "somepassword",
|
|
||||||
"channel": "#somechannel"
|
|
||||||
},
|
|
||||||
"launchpad": {
|
|
||||||
"application": "lugito",
|
|
||||||
"staging": "production",
|
|
||||||
"version": "devel",
|
|
||||||
"supported_versions": ["Cosmic", "Bionic", "Xenial", "Trusty"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
32
tests/.lugitorc
Normal file
32
tests/.lugitorc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
[phabricator]
|
||||||
|
host = http://127.0.0.1:9091/api/
|
||||||
|
token = api-nojs2ip33hmp4zn6u6cf72w7d6yh
|
||||||
|
|
||||||
|
[phabricator.hooks]
|
||||||
|
diffhook = vglzi6t4gsumnilv27r27no7rs3vgs75
|
||||||
|
commithook = znkyfflbcia5gviqx5ybad7s6uyfywxi
|
||||||
|
|
||||||
|
[connector.irc]
|
||||||
|
host = irc.freenode.net
|
||||||
|
port = 6697
|
||||||
|
username = someusername
|
||||||
|
password = somepassword
|
||||||
|
channel = #somechannel
|
||||||
|
|
||||||
|
[connector.launchpad]
|
||||||
|
application = lugito
|
||||||
|
staging = production
|
||||||
|
version = devel
|
||||||
|
supported_versions =
|
||||||
|
Cosmic
|
||||||
|
Bionic
|
||||||
|
Xenial
|
||||||
|
Trusty
|
||||||
|
|
||||||
|
[connector.launchpad.package_names]
|
||||||
|
rDEFAULTSETTINGS = lubuntu-default-settings
|
||||||
|
rART = lubuntu-artwork
|
||||||
|
rCALASETTINGS = calamares-settings-ubuntu
|
||||||
|
rQTERMINALPACKAGING = qterminal
|
||||||
|
rLXQTCONFIGPACKAGING = lxqt-config
|
||||||
|
rNMTRAYPACKAGING = nm-tray
|
23
tests/.lugitorc_no_host
Normal file
23
tests/.lugitorc_no_host
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[phabricator]
|
||||||
|
token = api-nojs2ip33hmp4zn6u6cf72w7d6yh
|
||||||
|
|
||||||
|
[phabricator.hooks]
|
||||||
|
diffhook = vglzi6t4gsumnilv27r27no7rs3vgs75
|
||||||
|
commithook = znkyfflbcia5gviqx5ybad7s6uyfywxi
|
||||||
|
|
||||||
|
[connector.irc]
|
||||||
|
host = irc.freenode.net
|
||||||
|
port = 6697
|
||||||
|
username = someusername
|
||||||
|
password = somepassword
|
||||||
|
channel = #somechannel
|
||||||
|
|
||||||
|
[connector.launchpad]
|
||||||
|
application = lugito
|
||||||
|
staging = production
|
||||||
|
version = devel
|
||||||
|
supported_versions =
|
||||||
|
Cosmic
|
||||||
|
Bionic
|
||||||
|
Xenial
|
||||||
|
Trusty
|
20
tests/.lugitorc_no_phab
Normal file
20
tests/.lugitorc_no_phab
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[phabricator.hooks]
|
||||||
|
diffhook = vglzi6t4gsumnilv27r27no7rs3vgs75
|
||||||
|
commithook = znkyfflbcia5gviqx5ybad7s6uyfywxi
|
||||||
|
|
||||||
|
[connector.irc]
|
||||||
|
host = irc.freenode.net
|
||||||
|
port = 6697
|
||||||
|
username = someusername
|
||||||
|
password = somepassword
|
||||||
|
channel = #somechannel
|
||||||
|
|
||||||
|
[connector.launchpad]
|
||||||
|
application = lugito
|
||||||
|
staging = production
|
||||||
|
version = devel
|
||||||
|
supported_versions =
|
||||||
|
Cosmic
|
||||||
|
Bionic
|
||||||
|
Xenial
|
||||||
|
Trusty
|
23
tests/.lugitorc_no_token
Normal file
23
tests/.lugitorc_no_token
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[phabricator]
|
||||||
|
host = http://127.0.0.1/api/
|
||||||
|
|
||||||
|
[phabricator.hooks]
|
||||||
|
diffhook = vglzi6t4gsumnilv27r27no7rs3vgs75
|
||||||
|
commithook = znkyfflbcia5gviqx5ybad7s6uyfywxi
|
||||||
|
|
||||||
|
[connector.irc]
|
||||||
|
host = irc.freenode.net
|
||||||
|
port = 6697
|
||||||
|
username = someusername
|
||||||
|
password = somepassword
|
||||||
|
channel = #somechannel
|
||||||
|
|
||||||
|
[connector.launchpad]
|
||||||
|
application = lugito
|
||||||
|
staging = production
|
||||||
|
version = devel
|
||||||
|
supported_versions =
|
||||||
|
Cosmic
|
||||||
|
Bionic
|
||||||
|
Xenial
|
||||||
|
Trusty
|
1
tests/lugito.ini
Normal file
1
tests/lugito.ini
Normal file
@ -0,0 +1 @@
|
|||||||
|
[lugito]
|
114
tests/test_config.py
Normal file
114
tests/test_config.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# S.D.G
|
||||||
|
|
||||||
|
"""Test config values
|
||||||
|
|
||||||
|
|
||||||
|
:author: Ben Johnston
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Imports
|
||||||
|
import os
|
||||||
|
import pytest
|
||||||
|
import lugito.config
|
||||||
|
|
||||||
|
TEST_FILE = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
'.lugitorc')
|
||||||
|
|
||||||
|
|
||||||
|
TEST_FILE_NO_PHAB = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
'.lugitorc_no_phab')
|
||||||
|
|
||||||
|
|
||||||
|
TEST_FILE_NO_HOST = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
'.lugitorc_no_host')
|
||||||
|
|
||||||
|
|
||||||
|
TEST_FILE_NO_TOKEN = os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
'.lugitorc_no_token')
|
||||||
|
|
||||||
|
|
||||||
|
def test_loading_config_hooks():
|
||||||
|
"""Test loading config"""
|
||||||
|
|
||||||
|
lugito.config.update_config(TEST_FILE)
|
||||||
|
CONFIG = lugito.config.CONFIG
|
||||||
|
|
||||||
|
assert(CONFIG['phabricator']['host'] == 'http://127.0.0.1:9091/api/')
|
||||||
|
assert(CONFIG['phabricator']['token'] == 'api-nojs2ip33hmp4zn6u6cf72w7d6yh')
|
||||||
|
|
||||||
|
# Hooks
|
||||||
|
assert(CONFIG['phabricator']['hooks']['diffhook'] ==\
|
||||||
|
'vglzi6t4gsumnilv27r27no7rs3vgs75')
|
||||||
|
assert(CONFIG['phabricator']['hooks']['commithook'] ==\
|
||||||
|
'znkyfflbcia5gviqx5ybad7s6uyfywxi')
|
||||||
|
|
||||||
|
|
||||||
|
def test_loading_config_connectors():
|
||||||
|
"""Test loading config connectors"""
|
||||||
|
|
||||||
|
|
||||||
|
lugito.config.update_config(TEST_FILE)
|
||||||
|
CONFIG = lugito.config.CONFIG
|
||||||
|
|
||||||
|
# Connectors
|
||||||
|
assert(CONFIG['connectors']['irc'] == {
|
||||||
|
'host': 'irc.freenode.net',
|
||||||
|
'port': '6697',
|
||||||
|
'username': 'someusername',
|
||||||
|
'password':'somepassword',
|
||||||
|
'channel': '#somechannel',
|
||||||
|
})
|
||||||
|
|
||||||
|
if not (CONFIG['connectors']['launchpad'] == {
|
||||||
|
'application': 'lugito',
|
||||||
|
'staging': 'production',
|
||||||
|
'version': 'devel',
|
||||||
|
'supported_versions': ['Cosmic', 'Bionic', 'Xenial', 'Trusty'],
|
||||||
|
'package_names': {
|
||||||
|
'rDEFAULTSETTINGS': 'lubuntu-default-settings',
|
||||||
|
'rART': 'lubuntu-artwork',
|
||||||
|
'rCALASETTINGS': 'calamares-settings-ubuntu',
|
||||||
|
'rQTERMINALPACKAGING': 'qterminal',
|
||||||
|
'rLXQTCONFIGPACKAGING': 'lxqt-config',
|
||||||
|
'rNMTRAYPACKAGING': 'nm-tray',
|
||||||
|
},
|
||||||
|
}):
|
||||||
|
import pdb;pdb.set_trace()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_config_no_phab():
|
||||||
|
"""Test loading config to load phabricator"""
|
||||||
|
|
||||||
|
with pytest.raises(ValueError) as err:
|
||||||
|
|
||||||
|
lugito.config.update_config(TEST_FILE_NO_PHAB)
|
||||||
|
|
||||||
|
assert('phabricator section missing from config file' in str(err))
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_config_no_host():
|
||||||
|
"""Test loading config to load phabricator"""
|
||||||
|
|
||||||
|
with pytest.raises(ValueError) as err:
|
||||||
|
lugito.config.update_config(TEST_FILE_NO_HOST)
|
||||||
|
|
||||||
|
assert('host value missing from phabricator section config file' in str(err))
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_config_no_token():
|
||||||
|
"""Test loading config to load phabricator"""
|
||||||
|
|
||||||
|
with pytest.raises(ValueError) as err:
|
||||||
|
|
||||||
|
lugito.config.update_config(TEST_FILE_NO_TOKEN)
|
||||||
|
|
||||||
|
assert('host value missing from phabricator conffig file' in str(err))
|
@ -10,25 +10,49 @@ Test IRC connector
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import phabricator
|
import phabricator
|
||||||
from lugito import IRCConnector
|
import lugito
|
||||||
from unittest.mock import MagicMock
|
import pytest
|
||||||
|
from lugito.connectors import irc
|
||||||
|
# docEbrown - 20181120
|
||||||
|
# There is a bug in inspect.unwrap preventing the import of call directly
|
||||||
|
import unittest.mock
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
# Setup ###############################################################
|
# Setup ###############################################################
|
||||||
|
|
||||||
TEST_DIR = os.path.dirname(__file__)
|
lugito.config.CONFIG = {
|
||||||
|
'phabricator': {
|
||||||
|
'host': 'http://127.0.0.1:9091/api/',
|
||||||
|
'token': 'api-nojs2ip33hmp4zn6u6cf72w7d6yh',
|
||||||
|
'hooks': {
|
||||||
|
'diffhook': 'vglzi6t4gsumnilv27r27no7rs3vgs75',
|
||||||
|
'commithook': 'znkyfflbcia5gviqx5ybad7s6uyfywxi',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'connectors': {
|
||||||
|
'irc': {
|
||||||
|
'host': 'irc.freenode.net',
|
||||||
|
'port': '6697',
|
||||||
|
'username': 'someusername',
|
||||||
|
'password': 'somepassword',
|
||||||
|
'channel': '#somechannel',
|
||||||
|
},
|
||||||
|
'launchpad': {
|
||||||
|
'application': 'lugito',
|
||||||
|
'staging': 'production',
|
||||||
|
'version': 'devel',
|
||||||
|
'supported_versions': ['Cosmic', 'Bionic', 'Xenial', 'Trusty'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
# Force phabricator to use the ./tests/.arcconfig file
|
|
||||||
TEST_CONFIG = os.path.join(TEST_DIR, '.arcconfig')
|
|
||||||
|
|
||||||
with open(TEST_CONFIG, 'r') as f:
|
|
||||||
phabricator.ARCRC = json.load(f)
|
|
||||||
|
|
||||||
# Tests ###############################################################
|
# Tests ###############################################################
|
||||||
|
|
||||||
def test_init():
|
def test_init():
|
||||||
"""Test initialise irc connector"""
|
"""Test initialise irc connector"""
|
||||||
|
|
||||||
obj = IRCConnector()
|
obj = irc()
|
||||||
|
|
||||||
assert('irc.freenode.net' == obj.host)
|
assert('irc.freenode.net' == obj.host)
|
||||||
assert(6697 == obj.port)
|
assert(6697 == obj.port)
|
||||||
@ -38,12 +62,179 @@ def test_init():
|
|||||||
assert('http://127.0.0.1:9091/' == obj.phab_host)
|
assert('http://127.0.0.1:9091/' == obj.phab_host)
|
||||||
|
|
||||||
|
|
||||||
def test_connect():
|
@patch('phabricator.Phabricator')
|
||||||
|
def test_connect(phab_mock):
|
||||||
"""Test initial connection"""
|
"""Test initial connection"""
|
||||||
|
|
||||||
obj = IRCConnector()
|
obj = irc()
|
||||||
|
|
||||||
obj._socket_conn = MagicMock()
|
assert(phab_mock.is_called())
|
||||||
|
|
||||||
# obj.conn.recv = MagicMock(side_effect=[
|
|
||||||
|
|
||||||
|
@patch('phabricator.Phabricator')
|
||||||
|
def test_send(phab_mock):
|
||||||
|
"""Test sending a message"""
|
||||||
|
|
||||||
|
obj = irc()
|
||||||
|
obj.send_notice = MagicMock()
|
||||||
|
|
||||||
|
objectstr = "objectstr"
|
||||||
|
who = "who"
|
||||||
|
body = "body"
|
||||||
|
link = "link"
|
||||||
|
|
||||||
|
obj.send(objectstr, who, body, link)
|
||||||
|
|
||||||
|
obj.send_notice.assert_called_with(
|
||||||
|
'\x033[\x03\x0313objectstr\x03\x033]\x03 \x0315who\x03 body: \x032link\x03')
|
||||||
|
|
||||||
|
|
||||||
|
@patch('phabricator.Phabricator')
|
||||||
|
def test_send_kwargs(phab_mock):
|
||||||
|
"""Test sending a message - kwargs"""
|
||||||
|
|
||||||
|
obj = irc()
|
||||||
|
obj.send_notice = MagicMock()
|
||||||
|
|
||||||
|
objectstr = "objectstr"
|
||||||
|
who = "who"
|
||||||
|
body = "body"
|
||||||
|
link = "link"
|
||||||
|
|
||||||
|
obj.send(objectstr=objectstr, who=who, body=body, link=link)
|
||||||
|
|
||||||
|
obj.send_notice.assert_called_with(
|
||||||
|
'\x033[\x03\x0313objectstr\x03\x033]\x03 \x0315who\x03 body: \x032link\x03')
|
||||||
|
|
||||||
|
|
||||||
|
def test_connect():
|
||||||
|
"""Test connect"""
|
||||||
|
|
||||||
|
obj = irc(sleep_delay=0)
|
||||||
|
|
||||||
|
obj._send_raw = MagicMock()
|
||||||
|
obj._setup_connection = MagicMock()
|
||||||
|
obj.conn = MagicMock()
|
||||||
|
|
||||||
|
obj.conn.recv.side_effect = [
|
||||||
|
b'No Ident response',
|
||||||
|
b'You are now identified',
|
||||||
|
b'477',
|
||||||
|
b'433',
|
||||||
|
b'PING: something',
|
||||||
|
b'366',
|
||||||
|
]
|
||||||
|
|
||||||
|
obj.connect()
|
||||||
|
|
||||||
|
# No Ident response results
|
||||||
|
assert(unittest.mock.call('NICK someusername1\r\n') in\
|
||||||
|
obj._send_raw.call_args_list)
|
||||||
|
assert(unittest.mock.call('USER someusername * * :someusername\r\n') in\
|
||||||
|
obj._send_raw.call_args_list)
|
||||||
|
assert(unittest.mock.call('PRIVMSG nickserv :identify someusername'\
|
||||||
|
' somepassword\r\n') in obj._send_raw.call_args_list)
|
||||||
|
|
||||||
|
# Now identified / 477
|
||||||
|
assert(unittest.mock.call('JOIN #somechannel\r\n') in\
|
||||||
|
obj._send_raw.call_args_list)
|
||||||
|
|
||||||
|
# 433
|
||||||
|
assert(unittest.mock.call('NICK someusername1\r\n') in\
|
||||||
|
obj._send_raw.call_args_list)
|
||||||
|
assert(unittest.mock.call('USER someusername1 * * :someusername1\r\n') in\
|
||||||
|
obj._send_raw.call_args_list)
|
||||||
|
|
||||||
|
# Ping
|
||||||
|
assert(unittest.mock.call('PONG : something\r\n') in\
|
||||||
|
obj._send_raw.call_args_list)
|
||||||
|
|
||||||
|
|
||||||
|
# docEbrown - 20181120
|
||||||
|
# Address including anchors in reference
|
||||||
|
# https://phab.lubuntu.me/T88#3230
|
||||||
|
def test_get_task_info_with_anchor():
|
||||||
|
"""Test getting task info with anchor"""
|
||||||
|
|
||||||
|
obj = irc()
|
||||||
|
|
||||||
|
obj.send_notice = MagicMock()
|
||||||
|
obj.phab = MagicMock()
|
||||||
|
obj.phab.maniphest.info = MagicMock(
|
||||||
|
return_value={
|
||||||
|
'priorityColor': 'pink',
|
||||||
|
'statusName': 'Open',
|
||||||
|
'title': 'Fix shortcuts related to Super key',
|
||||||
|
'uri': 'https://phab.lubuntu.me/T154'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
link_with_anchor = 'https://phab.lubuntu.me/T154#3228'
|
||||||
|
obj.get_task_info(link_with_anchor)
|
||||||
|
|
||||||
|
assert(unittest.mock.call(task_id=154) in\
|
||||||
|
obj.phab.maniphest.info.call_args_list)
|
||||||
|
assert(obj.send_notice.call_args == \
|
||||||
|
unittest.mock.call('\x033[\x03\x035Unbreak Now!, Open\x03\x033]\x03 '
|
||||||
|
'Fix shortcuts related to Super key: '\
|
||||||
|
'\x032https://phab.lubuntu.me/T154#3228\x03'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_diff_info_with_anchor():
|
||||||
|
"""Test getting diff info with anchor"""
|
||||||
|
|
||||||
|
obj = irc()
|
||||||
|
|
||||||
|
obj.send_notice = MagicMock()
|
||||||
|
obj.phab = MagicMock()
|
||||||
|
obj.phab.differential.query = MagicMock(
|
||||||
|
return_value=[{
|
||||||
|
'statusName': 'Closed',
|
||||||
|
'title': 'Some diff title',
|
||||||
|
'uri': 'https://phab.lubuntu.me/D24'
|
||||||
|
},]
|
||||||
|
)
|
||||||
|
|
||||||
|
link_with_anchor = 'https://phab.lubuntu.me/D24#123'
|
||||||
|
obj.get_task_info(link_with_anchor)
|
||||||
|
|
||||||
|
assert(unittest.mock.call(ids=[24]) in\
|
||||||
|
obj.phab.differential.query.call_args_list)
|
||||||
|
assert(obj.send_notice.call_args == \
|
||||||
|
unittest.mock.call('\x033[\x03Closed\x03\x033]\x03 '
|
||||||
|
'Some diff title: '\
|
||||||
|
'\x032https://phab.lubuntu.me/D24#123\x03'))
|
||||||
|
|
||||||
|
def test_get_task_info_with_error_anchor():
|
||||||
|
"""Test getting task info with anchor"""
|
||||||
|
|
||||||
|
obj = irc()
|
||||||
|
|
||||||
|
obj.send_notice = MagicMock()
|
||||||
|
obj.phab = MagicMock()
|
||||||
|
obj.phab.maniphest.info = MagicMock(side_effect=ValueError(''))
|
||||||
|
|
||||||
|
link_with_anchor = 'https://phab.lubuntu.me/T154#3228'
|
||||||
|
|
||||||
|
obj.get_task_info(link_with_anchor)
|
||||||
|
|
||||||
|
assert(obj.send_notice.call_args ==
|
||||||
|
unittest.mock.call('\x034Error: https://phab.lubuntu.me/T154#3228'\
|
||||||
|
' is an invalid task reference.\x03'))
|
||||||
|
|
||||||
|
def test_get_task_info_with_error_no_anchor():
|
||||||
|
"""Test getting task info with no anchor"""
|
||||||
|
|
||||||
|
obj = irc()
|
||||||
|
|
||||||
|
obj.send_notice = MagicMock()
|
||||||
|
obj.phab = MagicMock()
|
||||||
|
obj.phab.maniphest.info = MagicMock(side_effect=ValueError(''))
|
||||||
|
|
||||||
|
link_with_anchor = 'https://phab.lubuntu.me/T154'
|
||||||
|
|
||||||
|
obj.get_task_info(link_with_anchor)
|
||||||
|
|
||||||
|
assert(obj.send_notice.call_args ==
|
||||||
|
unittest.mock.call('\x034Error: https://phab.lubuntu.me/T154'\
|
||||||
|
' is an invalid task reference.\x03'))
|
||||||
|
@ -9,19 +9,90 @@ Test launchpad connector
|
|||||||
# Imports
|
# Imports
|
||||||
import json
|
import json
|
||||||
import phabricator
|
import phabricator
|
||||||
from lugito.connectors.launchpad import LPConnector
|
import lugito
|
||||||
|
from lugito.connectors import launchpad
|
||||||
|
|
||||||
# Setup ###############################################################
|
# Setup ###############################################################
|
||||||
|
|
||||||
TEST_DIR = os.path.dirname(__file__)
|
lugito.config.CONFIG = {
|
||||||
|
'phabricator': {
|
||||||
|
'host': 'http://127.0.0.1:9091/api/',
|
||||||
|
'token': 'api-nojs2ip33hmp4zn6u6cf72w7d6yh',
|
||||||
|
'hooks': {
|
||||||
|
'diffhook': 'vglzi6t4gsumnilv27r27no7rs3vgs75',
|
||||||
|
'commithook': 'znkyfflbcia5gviqx5ybad7s6uyfywxi',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'connectors': {
|
||||||
|
'irc': {
|
||||||
|
'host': 'irc.freenode.net',
|
||||||
|
'port': '6697',
|
||||||
|
'username': 'someusername',
|
||||||
|
'password': 'somepassword',
|
||||||
|
'channel': '#somechannel',
|
||||||
|
},
|
||||||
|
'launchpad': {
|
||||||
|
'application': 'lugito',
|
||||||
|
'staging': 'production',
|
||||||
|
'version': 'devel',
|
||||||
|
'supported_versions': ['Cosmic', 'Bionic', 'Xenial', 'Trusty'],
|
||||||
|
'package_names': {
|
||||||
|
'rDEFAULTSETTINGS': 'lubuntu-default-settings',
|
||||||
|
'rART': 'lubuntu-artwork',
|
||||||
|
'rCALASETTINGS': 'calamares-settings-ubuntu',
|
||||||
|
'rQTERMINALPACKAGING': 'qterminal',
|
||||||
|
'rLXQTCONFIGPACKAGING': 'lxqt-config',
|
||||||
|
'rNMTRAYPACKAGING': 'nm-tray',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
# Force phabricator to use the ./tests/.arcconfig file
|
|
||||||
TEST_CONFIG = os.path.join(TEST_DIR, '.arcconfig')
|
|
||||||
|
|
||||||
with open(TEST_CONFIG, 'r') as f:
|
|
||||||
phabricator.ARCRC = json.load(f)
|
|
||||||
|
|
||||||
# Tests ###############################################################
|
# Tests ###############################################################
|
||||||
|
|
||||||
|
|
||||||
def test_init()
|
def test_init():
|
||||||
|
"""Test initialising LPConnector"""
|
||||||
|
|
||||||
|
obj = launchpad()
|
||||||
|
|
||||||
|
assert(obj.application == "lugito")
|
||||||
|
assert(obj.staging == "production")
|
||||||
|
assert(obj.version == "devel")
|
||||||
|
assert(obj.supported_vers == ["Cosmic", "Bionic", "Xenial", "Trusty"])
|
||||||
|
assert(obj.package_names == {
|
||||||
|
'rDEFAULTSETTINGS': 'lubuntu-default-settings',
|
||||||
|
'rART': 'lubuntu-artwork',
|
||||||
|
'rCALASETTINGS': 'calamares-settings-ubuntu',
|
||||||
|
'rQTERMINALPACKAGING': 'qterminal',
|
||||||
|
'rLXQTCONFIGPACKAGING': 'lxqt-config',
|
||||||
|
'rNMTRAYPACKAGING': 'nm-tray',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_package_name():
|
||||||
|
"""Test get package name"""
|
||||||
|
|
||||||
|
obj = launchpad()
|
||||||
|
|
||||||
|
assert(obj.get_package_name('rART') == 'lubuntu-artwork')
|
||||||
|
assert(obj.get_package_name('rT') is None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_package_name():
|
||||||
|
"""Test getting package name"""
|
||||||
|
|
||||||
|
obj = launchpad()
|
||||||
|
|
||||||
|
assert(obj.get_package_name('rNMTRAYPACKAGING') == 'nm-tray')
|
||||||
|
assert(obj.get_package_name('rNMTRKAGING') is None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_bugs_list():
|
||||||
|
"""Test getting buglist"""
|
||||||
|
|
||||||
|
obj = launchpad()
|
||||||
|
|
||||||
|
assert(obj.get_bugs_list("lp: #1234") == ['1234'])
|
||||||
|
assert(obj.get_bugs_list("#1234") == [])
|
||||||
|
@ -12,6 +12,7 @@ import pytest
|
|||||||
import phabricator
|
import phabricator
|
||||||
import json
|
import json
|
||||||
import http
|
import http
|
||||||
|
import lugito
|
||||||
from lugito import Lugito
|
from lugito import Lugito
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
@ -19,11 +20,33 @@ from unittest.mock import MagicMock
|
|||||||
|
|
||||||
TEST_DIR = os.path.dirname(__file__)
|
TEST_DIR = os.path.dirname(__file__)
|
||||||
|
|
||||||
# Force phabricator to use the ./tests/.arcconfig file
|
# Apply default values
|
||||||
TEST_CONFIG = os.path.join(TEST_DIR, '.arcconfig')
|
lugito.config.CONFIG = {
|
||||||
|
'phabricator': {
|
||||||
|
'host': 'http://127.0.0.1:9091/api/',
|
||||||
|
'token': 'api-nojs2ip33hmp4zn6u6cf72w7d6yh',
|
||||||
|
'hooks': {
|
||||||
|
'diffhook': 'vglzi6t4gsumnilv27r27no7rs3vgs75',
|
||||||
|
'commithook': 'znkyfflbcia5gviqx5ybad7s6uyfywxi',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'connectors': {
|
||||||
|
'irc': {
|
||||||
|
'host': 'irc.freenode.net',
|
||||||
|
'port': '6697',
|
||||||
|
'username': 'someusername',
|
||||||
|
'password': 'somepassword',
|
||||||
|
'channel': '#somechannel',
|
||||||
|
},
|
||||||
|
'launchpad': {
|
||||||
|
'application': 'lugito',
|
||||||
|
'staging': 'production',
|
||||||
|
'version': 'devel',
|
||||||
|
'supported_versions': ['Cosmic', 'Bionic', 'Xenial', 'Trusty'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
with open(TEST_CONFIG, 'r') as f:
|
|
||||||
phabricator.ARCRC = json.load(f)
|
|
||||||
|
|
||||||
# Pre-prepared request
|
# Pre-prepared request
|
||||||
FAKE_REQUEST = os.path.join(TEST_DIR, 'request.json')
|
FAKE_REQUEST = os.path.join(TEST_DIR, 'request.json')
|
||||||
@ -56,10 +79,12 @@ def test_init():
|
|||||||
'utf-8'))
|
'utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def test_validate_HMAC():
|
def test_validate_request():
|
||||||
"""Test validating HMAC"""
|
"""Test validating HMAC"""
|
||||||
|
|
||||||
obj = Lugito()
|
obj = Lugito()
|
||||||
|
obj.phab = MagicMock()
|
||||||
|
obj.phab.transaction.search = MagicMock()
|
||||||
|
|
||||||
request_mock = MagicMock()
|
request_mock = MagicMock()
|
||||||
|
|
||||||
@ -71,7 +96,8 @@ def test_validate_HMAC():
|
|||||||
"a8f636f03ed4464ddb398ea873ffab409d941f87396f28fa9d22bb58cfbedc9f"
|
"a8f636f03ed4464ddb398ea873ffab409d941f87396f28fa9d22bb58cfbedc9f"
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(obj.validate_HMAC('diffhook', request_mock))
|
assert(obj.validate_request('diffhook', request_mock))
|
||||||
|
assert(obj.phab.transaction.search.is_called())
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_HMAC():
|
def test_invalid_HMAC():
|
||||||
@ -89,7 +115,7 @@ def test_invalid_HMAC():
|
|||||||
"a8f6364464ddb398ea873ffab409d941f87396f28fa9d22bb58cfbedc9f"
|
"a8f6364464ddb398ea873ffab409d941f87396f28fa9d22bb58cfbedc9f"
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(not obj.validate_HMAC('diffhook', request_mock))
|
assert(not obj.validate_request('diffhook', request_mock))
|
||||||
|
|
||||||
|
|
||||||
def test_author_fullname():
|
def test_author_fullname():
|
||||||
@ -141,8 +167,6 @@ def test_get_object_type():
|
|||||||
with open(FAKE_REQ_DATA, 'r') as f:
|
with open(FAKE_REQ_DATA, 'r') as f:
|
||||||
obj.request_data = json.load(f)
|
obj.request_data = json.load(f)
|
||||||
|
|
||||||
obj._transaction_search()
|
|
||||||
|
|
||||||
assert(obj.get_object_type() == 'DREV')
|
assert(obj.get_object_type() == 'DREV')
|
||||||
|
|
||||||
def test_is_new_object_false():
|
def test_is_new_object_false():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user