Hello community,

here is the log from the commit of package python-oslo.service for 
openSUSE:Factory checked in at 2019-05-03 22:42:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-oslo.service (Old)
 and      /work/SRC/openSUSE:Factory/.python-oslo.service.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-oslo.service"

Fri May  3 22:42:45 2019 rev:14 rq:692866 version:1.38.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-oslo.service/python-oslo.service.changes  
2018-11-29 23:01:04.483456542 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-oslo.service.new.5148/python-oslo.service.changes
        2019-05-03 22:42:46.939286405 +0200
@@ -1,0 +2,44 @@
+Mon Apr  8 11:46:55 UTC 2019 - [email protected]
+
+- update to version 1.38.0
+  - Bump oslo.utils lower constraint to 3.40.2
+  - Add better timer APIs to ThreadGroup
+  - Update mailinglist from dev to discuss
+  - Use template for lower-constraints
+  - Stop asserting on Eventlet internals
+  - import zuul job settings from project-config
+  - Use SleepFixture in looping call test suite
+  - Always build universal wheels
+  - Update reno for stable/rocky
+  - Add stop_on_exception to TG timers
+  - add python 3.6 unit test job
+  - Avoid eventlet_backdoor listing on same port
+  - Skips signal handling on Windows
+  - add lib-forward-testing-python3 test job
+  - Fix stop of loopingcall
+  - Ensure connection is active in graceful shutdown tests
+  - Deprecate the ThreadGroup.cancel() API
+  - Use eventletutils Event class
+  - Limit monotonic to py2
+  - Update oslo.service to require yappi 1.0 or newer
+  - Update hacking version
+  - Fixture to mock loopingcall wait()
+  - Clean up .gitignore references to personal tools
+  - Use eventlet Event for loopingcall events
+  - Actually test child SIGHUP signal
+  - Profile Oslo Service processes
+  - Document the threadgroup module
+  - Restore correct signal handling in Python3
+  - add python 3.7 unit test job
+
+-------------------------------------------------------------------
+Wed Feb  6 14:58:36 UTC 2019 - [email protected]
+
+- update to version 1.31.8
+  - Stop asserting on Eventlet internals
+  - Use eventlet Event for loopingcall events
+  - Restore correct signal handling in Python3
+  - Maintain private interface for loopingcall._ThreadingEvent
+  - Fix stop of loopingcall
+
+-------------------------------------------------------------------

Old:
----
  oslo.service-1.31.5.tar.gz

New:
----
  oslo.service-1.38.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-oslo.service.spec ++++++
--- /var/tmp/diff_new_pack.WubMVI/_old  2019-05-03 22:42:47.295287154 +0200
+++ /var/tmp/diff_new_pack.WubMVI/_new  2019-05-03 22:42:47.299287163 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-oslo.service
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -20,13 +20,13 @@
 %global rdo 1
 %endif
 Name:           python-oslo.service
-Version:        1.31.5
+Version:        1.38.0
 Release:        0
 Summary:        OpenStack oslo.service library
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://launchpad.net/oslo.service
-Source0:        
https://files.pythonhosted.org/packages/source/o/oslo.service/oslo.service-1.31.5.tar.gz
+Source0:        
https://files.pythonhosted.org/packages/source/o/oslo.service/oslo.service-1.38.0.tar.gz
 BuildRequires:  openstack-macros
 BuildRequires:  procps
 BuildRequires:  python-devel
@@ -35,53 +35,55 @@
 BuildRequires:  python2-Routes >= 2.3.1
 BuildRequires:  python2-WebOb >= 1.7.1
 BuildRequires:  python2-eventlet >= 0.18.2
-BuildRequires:  python2-fixtures
+BuildRequires:  python2-fixtures >= 3.0.0
 BuildRequires:  python2-greenlet >= 0.4.10
 BuildRequires:  python2-mock
-BuildRequires:  python2-monotonic >= 0.6
 BuildRequires:  python2-oslo.concurrency >= 3.25.0
 BuildRequires:  python2-oslo.config >= 5.1.0
 BuildRequires:  python2-oslo.i18n >= 3.15.3
 BuildRequires:  python2-oslo.log >= 3.36.0
-BuildRequires:  python2-oslo.utils >= 3.33.0
+BuildRequires:  python2-oslo.utils >= 3.40.2
 BuildRequires:  python2-oslotest
 BuildRequires:  python2-pbr
 BuildRequires:  python2-requests
 BuildRequires:  python2-six >= 1.10.0
 BuildRequires:  python2-stestr
+BuildRequires:  python2-yappi
 BuildRequires:  python3-Paste >= 2.0.2
 BuildRequires:  python3-PasteDeploy >= 1.5.0
 BuildRequires:  python3-Routes >= 2.3.1
 BuildRequires:  python3-WebOb >= 1.7.1
 BuildRequires:  python3-devel
 BuildRequires:  python3-eventlet >= 0.18.2
-BuildRequires:  python3-fixtures
+BuildRequires:  python3-fixtures >= 3.0.0
 BuildRequires:  python3-greenlet >= 0.4.10
 BuildRequires:  python3-mock
-BuildRequires:  python3-monotonic >= 0.6
 BuildRequires:  python3-oslo.concurrency >= 3.25.0
 BuildRequires:  python3-oslo.config >= 5.1.0
 BuildRequires:  python3-oslo.i18n >= 3.15.3
 BuildRequires:  python3-oslo.log >= 3.36.0
-BuildRequires:  python3-oslo.utils >= 3.33.0
+BuildRequires:  python3-oslo.utils >= 3.40.2
 BuildRequires:  python3-oslotest
 BuildRequires:  python3-pbr
 BuildRequires:  python3-requests
 BuildRequires:  python3-six >= 1.10.0
 BuildRequires:  python3-stestr
+BuildRequires:  python3-yappi
 Requires:       python-Paste >= 2.0.2
 Requires:       python-PasteDeploy >= 1.5.0
 Requires:       python-Routes >= 2.3.1
 Requires:       python-WebOb >= 1.7.1
+Requires:       python-debtcollector >= 1.2.0
 Requires:       python-eventlet >= 0.18.2
+Requires:       python-fixtures >= 3.0.0
 Requires:       python-greenlet >= 0.4.10
-Requires:       python-monotonic >= 0.6
 Requires:       python-oslo.concurrency >= 3.25.0
 Requires:       python-oslo.config >= 5.1.0
 Requires:       python-oslo.i18n >= 3.15.3
 Requires:       python-oslo.log >= 3.36.0
-Requires:       python-oslo.utils >= 3.33.0
+Requires:       python-oslo.utils >= 3.40.2
 Requires:       python-six >= 1.10.0
+Requires:       python-yappi
 BuildArch:      noarch
 %python_subpackages
 
@@ -105,9 +107,8 @@
 This package contains the documentation.
 
 %prep
-%autosetup -p1 -n oslo.service-1.31.5
+%autosetup -p1 -n oslo.service-1.38.0
 %py_req_cleanup
-sed -i 's/^warning-is-error.*/warning-is-error = 0/g' setup.cfg
 
 %build
 %{python_build}

++++++ _service ++++++
--- /var/tmp/diff_new_pack.WubMVI/_old  2019-05-03 22:42:47.319287205 +0200
+++ /var/tmp/diff_new_pack.WubMVI/_new  2019-05-03 22:42:47.319287205 +0200
@@ -1,8 +1,8 @@
 <services>
   <service mode="disabled" name="renderspec">
-    <param 
name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/rocky/openstack/oslo.service/oslo.service.spec.j2</param>
+    <param 
name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/stein/openstack/oslo.service/oslo.service.spec.j2</param>
     <param name="output-name">python-oslo.service.spec</param>
-    <param 
name="requirements">https://raw.githubusercontent.com/openstack/oslo.service/stable/rocky/requirements.txt</param>
+    <param 
name="requirements">https://raw.githubusercontent.com/openstack/oslo.service/stable/stein/requirements.txt</param>
     <param name="changelog-email">[email protected]</param>
     <param name="changelog-provider">gh,openstack,oslo.service</param>
   </service>

++++++ oslo.service-1.31.5.tar.gz -> oslo.service-1.38.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/.zuul.yaml 
new/oslo.service-1.38.0/.zuul.yaml
--- old/oslo.service-1.31.5/.zuul.yaml  2018-09-25 21:44:54.000000000 +0200
+++ new/oslo.service-1.38.0/.zuul.yaml  2019-02-26 01:07:10.000000000 +0100
@@ -1,15 +1,13 @@
 - project:
     templates:
+      - check-requirements
+      - lib-forward-testing
+      - lib-forward-testing-python3
+      - openstack-lower-constraints-jobs
       - openstack-python-jobs
       - openstack-python35-jobs
+      - openstack-python36-jobs
+      - openstack-python37-jobs
+      - periodic-stable-jobs
       - publish-openstack-docs-pti
-      - check-requirements
-      - lib-forward-testing
       - release-notes-jobs-python3
-      - periodic-stable-jobs
-    check:
-      jobs:
-        - openstack-tox-lower-constraints
-    gate:
-      jobs:
-        - openstack-tox-lower-constraints
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/AUTHORS 
new/oslo.service-1.38.0/AUTHORS
--- old/oslo.service-1.31.5/AUTHORS     2018-09-25 21:47:27.000000000 +0200
+++ new/oslo.service-1.38.0/AUTHORS     2019-02-26 01:09:41.000000000 +0100
@@ -40,15 +40,18 @@
 Doug Hellmann <[email protected]>
 Doug Hellmann <[email protected]>
 Duan Jiong <[email protected]>
+Duc Truong <[email protected]>
 Elena Ezhova <[email protected]>
 Eoghan Glynn <[email protected]>
 Eric Brown <[email protected]>
+Eric Fried <[email protected]>
 Eric Guo <[email protected]>
 Eric Windisch <[email protected]>
 Fengqian.Gao <[email protected]>
 Flavio Percoco <[email protected]>
 Gary Kotton <[email protected]>
 Hengqing Hu <[email protected]>
+HervĂ© Beraud <[email protected]>
 Ian Wienand <[email protected]>
 Ihar Hrachyshka <[email protected]>
 Ilya Shakhat <[email protected]>
@@ -78,6 +81,7 @@
 Maru Newby <[email protected]>
 Matt Riedemann <[email protected]>
 Matthew Treinish <[email protected]>
+Michael Johnson <[email protected]>
 Michael Still <[email protected]>
 Mitsuru Kanabuchi <[email protected]>
 Monty Taylor <[email protected]>
@@ -94,6 +98,7 @@
 Sergey Kraynev <[email protected]>
 Sergey Lukjanov <[email protected]>
 Sergey Vilgelm <[email protected]>
+Slawek Kaplonski <[email protected]>
 Soren Hansen <[email protected]>
 Stephen Finucane <[email protected]>
 Steve Martinelli <[email protected]>
@@ -111,8 +116,9 @@
 Wenzhi Yu <[email protected]>
 Zane Bitter <[email protected]>
 ZhiQiang Fan <[email protected]>
+ZhijunWei <[email protected]>
+ZhongShengping <[email protected]>
 Zhongyue Luo <[email protected]>
-Zuul <[email protected]>
 apporc <[email protected]>
 fujioka yuuichi <[email protected]>
 gecong1973 <[email protected]>
@@ -124,11 +130,11 @@
 liyingjun <[email protected]>
 melanie witt <[email protected]>
 melissaml <[email protected]>
-qingszhao <[email protected]>
 ravikumar-venkatesan <[email protected]>
 ricolin <[email protected]>
 sonu.kumar <[email protected]>
 stanzgy <[email protected]>
+venkata anil <[email protected]>
 venkatamahesh <[email protected]>
 xhzhf <[email protected]>
 yan.haifeng <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/ChangeLog 
new/oslo.service-1.38.0/ChangeLog
--- old/oslo.service-1.31.5/ChangeLog   2018-09-25 21:47:27.000000000 +0200
+++ new/oslo.service-1.38.0/ChangeLog   2019-02-26 01:09:41.000000000 +0100
@@ -1,14 +1,62 @@
 CHANGES
 =======
 
-1.31.5
+1.38.0
 ------
 
-* Add Python 3.5 jobs
+* Update oslo.service to require yappi 1.0 or newer
+* add python 3.7 unit test job
+* Update hacking version
+
+1.37.0
+------
+
+* Bump oslo.utils lower constraint to 3.40.2
+
+1.36.0
+------
+
+* Profile Oslo Service processes
+* Use eventletutils Event class
+* Avoid eventlet\_backdoor listing on same port
+
+1.35.0
+------
+
+* Use template for lower-constraints
+* Deprecate the ThreadGroup.cancel() API
+* Document the threadgroup module
+* Actually test child SIGHUP signal
+* Restore correct signal handling in Python3
+* Add stop\_on\_exception to TG timers
+* Add better timer APIs to ThreadGroup
+* Update mailinglist from dev to discuss
+* Use SleepFixture in looping call test suite
+
+1.33.0
+------
+
+* Fixture to mock loopingcall wait()
+* Limit monotonic to py2
+
+1.32.1
+------
+
+* Fix stop of loopingcall
+* Use eventlet Event for loopingcall events
+* Clean up .gitignore references to personal tools
+* Always build universal wheels
+
+1.32.0
+------
+
+* Ensure connection is active in graceful shutdown tests
+* Stop asserting on Eventlet internals
 * Skips signal handling on Windows
+* add lib-forward-testing-python3 test job
+* add python 3.6 unit test job
 * import zuul job settings from project-config
-* Update UPPER\_CONSTRAINTS\_FILE for stable/rocky
-* Update .gitreview for stable/rocky
+* Update reno for stable/rocky
 
 1.31.3
 ------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/HACKING.rst 
new/oslo.service-1.38.0/HACKING.rst
--- old/oslo.service-1.31.5/HACKING.rst 2018-09-25 21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/HACKING.rst 2019-02-26 01:07:10.000000000 +0100
@@ -1,4 +1,4 @@
 oslo.service Style Commandments
-======================================================
+===============================
 
 Read the OpenStack Style Commandments 
https://docs.openstack.org/hacking/latest/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/PKG-INFO 
new/oslo.service-1.38.0/PKG-INFO
--- old/oslo.service-1.31.5/PKG-INFO    2018-09-25 21:47:28.000000000 +0200
+++ new/oslo.service-1.38.0/PKG-INFO    2019-02-26 01:09:41.000000000 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: oslo.service
-Version: 1.31.5
+Version: 1.38.0
 Summary: oslo.service library
 Home-page: https://docs.openstack.org/oslo.service/latest/
 Author: OpenStack
-Author-email: [email protected]
+Author-email: [email protected]
 License: UNKNOWN
 Description: ========================
         Team and repository tags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/RELEASENOTES.rst 
new/oslo.service-1.38.0/RELEASENOTES.rst
--- old/oslo.service-1.31.5/RELEASENOTES.rst    2018-09-25 21:47:28.000000000 
+0200
+++ new/oslo.service-1.38.0/RELEASENOTES.rst    1970-01-01 01:00:00.000000000 
+0100
@@ -1,3 +0,0 @@
-============
-oslo.service
-============
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/doc/source/conf.py 
new/oslo.service-1.38.0/doc/source/conf.py
--- old/oslo.service-1.31.5/doc/source/conf.py  2018-09-25 21:44:37.000000000 
+0200
+++ new/oslo.service-1.38.0/doc/source/conf.py  2019-02-26 01:07:10.000000000 
+0100
@@ -22,6 +22,7 @@
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
 extensions = [
     'sphinx.ext.autodoc',
+    'sphinx.ext.todo',
     'openstackdocstheme',
     'oslo_config.sphinxext',
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/doc/source/reference/fixture.rst 
new/oslo.service-1.38.0/doc/source/reference/fixture.rst
--- old/oslo.service-1.31.5/doc/source/reference/fixture.rst    1970-01-01 
01:00:00.000000000 +0100
+++ new/oslo.service-1.38.0/doc/source/reference/fixture.rst    2019-02-26 
01:07:10.000000000 +0100
@@ -0,0 +1,8 @@
+=========
+ fixture
+=========
+
+.. automodule:: oslo_service.fixture
+   :members:
+   :undoc-members:
+   :show-inheritance:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/doc/source/reference/index.rst 
new/oslo.service-1.38.0/doc/source/reference/index.rst
--- old/oslo.service-1.31.5/doc/source/reference/index.rst      2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/doc/source/reference/index.rst      2019-02-26 
01:07:10.000000000 +0100
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    eventlet_backdoor
+   fixture
    loopingcall
    periodic_task
    service
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/doc/source/user/usage.rst 
new/oslo.service-1.38.0/doc/source/user/usage.rst
--- old/oslo.service-1.31.5/doc/source/user/usage.rst   2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/doc/source/user/usage.rst   2019-02-26 
01:07:10.000000000 +0100
@@ -179,3 +179,40 @@
             logging.setup(cfg.CONF, 'foo')
 
 
+Profiling
+~~~~~~~~~
+
+Processes spawned through oslo_service.service can be profiled (function
+calltrace) through eventlet_backdoor module. Service has to configure
+backdoor_port option to enable it's workers to listen on TCP ports.
+Then user can send "prof()" command to capture worker processes function
+calltrace.
+
+1) To start profiling send "prof()" command on processes listening port
+
+2) To stop profiling and capture "pstat" calltrace to a file, send prof
+   command with filename as argument i.e "prof(filename)"
+   on worker processes listening port. Stats file (in pstat format) with
+   user provided filename by adding .prof as suffix will be generated
+   in temp directory.
+
+For example, to profile neutron server process (which is listening on
+port 8002 configured through backdoor_port option),
+
+.. code-block:: bash
+
+    $ echo "prof()" | nc localhost 8002
+    $ neutron net-create n1; neutron port-create --name p1 n1;
+    $ neutron port-delete p1; neutron port-delete p1
+    $ echo "prof('neutron')" | nc localhost 8002
+
+
+This will generate "/tmp/neutron.prof" as stats file. Later user can print
+the stats from the trace file like below
+
+.. code-block:: python
+
+    import pstats
+
+    stats = pstats.Stats('/tmp/neutron.prof')
+    stats.print_stats()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/lower-constraints.txt 
new/oslo.service-1.38.0/lower-constraints.txt
--- old/oslo.service-1.31.5/lower-constraints.txt       2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/lower-constraints.txt       2019-02-26 
01:07:16.000000000 +0100
@@ -38,7 +38,7 @@
 oslo.i18n==3.15.3
 oslo.log==3.36.0
 oslo.serialization==2.18.0
-oslo.utils==3.33.0
+oslo.utils==3.40.2
 oslotest==3.2.0
 Paste==2.0.2
 PasteDeploy==1.5.0
@@ -72,3 +72,4 @@
 unittest2==1.1.0
 WebOb==1.7.1
 wrapt==1.7.0
+Yappi==1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo.service.egg-info/PKG-INFO 
new/oslo.service-1.38.0/oslo.service.egg-info/PKG-INFO
--- old/oslo.service-1.31.5/oslo.service.egg-info/PKG-INFO      2018-09-25 
21:47:27.000000000 +0200
+++ new/oslo.service-1.38.0/oslo.service.egg-info/PKG-INFO      2019-02-26 
01:09:41.000000000 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: oslo.service
-Version: 1.31.5
+Version: 1.38.0
 Summary: oslo.service library
 Home-page: https://docs.openstack.org/oslo.service/latest/
 Author: OpenStack
-Author-email: [email protected]
+Author-email: [email protected]
 License: UNKNOWN
 Description: ========================
         Team and repository tags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo.service.egg-info/SOURCES.txt 
new/oslo.service-1.38.0/oslo.service.egg-info/SOURCES.txt
--- old/oslo.service-1.31.5/oslo.service.egg-info/SOURCES.txt   2018-09-25 
21:47:28.000000000 +0200
+++ new/oslo.service-1.38.0/oslo.service.egg-info/SOURCES.txt   2019-02-26 
01:09:41.000000000 +0100
@@ -21,6 +21,7 @@
 doc/source/contributor/index.rst
 doc/source/install/index.rst
 doc/source/reference/eventlet_backdoor.rst
+doc/source/reference/fixture.rst
 doc/source/reference/index.rst
 doc/source/reference/loopingcall.rst
 doc/source/reference/periodic_task.rst
@@ -43,6 +44,7 @@
 oslo_service/_i18n.py
 oslo_service/_options.py
 oslo_service/eventlet_backdoor.py
+oslo_service/fixture.py
 oslo_service/loopingcall.py
 oslo_service/periodic_task.py
 oslo_service/service.py
@@ -56,6 +58,7 @@
 oslo_service/tests/base.py
 oslo_service/tests/eventlet_service.py
 oslo_service/tests/test_eventlet_backdoor.py
+oslo_service/tests/test_fixture.py
 oslo_service/tests/test_loopingcall.py
 oslo_service/tests/test_periodic.py
 oslo_service/tests/test_service.py
@@ -69,11 +72,16 @@
 oslo_service/tests/ssl_cert/privatekey.key
 releasenotes/notes/add-timeout-looping-call-5cc396b75597c3c2.yaml
 releasenotes/notes/add_reno-3b4ae0789e9c45b4.yaml
+releasenotes/notes/profile-worker-5d3fd0f0251d62b8.yaml
+releasenotes/notes/threadgroup-cancel-bd89d72f383a3d9b.yaml
+releasenotes/notes/timer-args-f578c8f9d08b217d.yaml
+releasenotes/notes/timer-stop_on_exception-9f21d7c4d6d1b0d9.yaml
 releasenotes/source/conf.py
 releasenotes/source/index.rst
 releasenotes/source/ocata.rst
 releasenotes/source/pike.rst
 releasenotes/source/queens.rst
+releasenotes/source/rocky.rst
 releasenotes/source/unreleased.rst
 releasenotes/source/_static/.placeholder
 releasenotes/source/_templates/.placeholder
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo.service.egg-info/pbr.json 
new/oslo.service-1.38.0/oslo.service.egg-info/pbr.json
--- old/oslo.service-1.31.5/oslo.service.egg-info/pbr.json      2018-09-25 
21:47:27.000000000 +0200
+++ new/oslo.service-1.38.0/oslo.service.egg-info/pbr.json      2019-02-26 
01:09:41.000000000 +0100
@@ -1 +1 @@
-{"git_version": "67a8a8c", "is_release": true}
\ No newline at end of file
+{"git_version": "ca6f839", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo.service.egg-info/requires.txt 
new/oslo.service-1.38.0/oslo.service.egg-info/requires.txt
--- old/oslo.service-1.31.5/oslo.service.egg-info/requires.txt  2018-09-25 
21:47:27.000000000 +0200
+++ new/oslo.service-1.38.0/oslo.service.egg-info/requires.txt  2019-02-26 
01:09:41.000000000 +0100
@@ -1,8 +1,9 @@
 WebOb>=1.7.1
+debtcollector>=1.2.0
 eventlet!=0.18.3,!=0.20.1,>=0.18.2
+fixtures>=3.0.0
 greenlet>=0.4.10
-monotonic>=0.6
-oslo.utils>=3.33.0
+oslo.utils>=3.40.2
 oslo.concurrency>=3.25.0
 oslo.config>=5.1.0
 oslo.log>=3.36.0
@@ -11,3 +12,7 @@
 PasteDeploy>=1.5.0
 Routes>=2.3.1
 Paste>=2.0.2
+Yappi>=1.0
+
+[:(python_version<'3.3')]
+monotonic>=0.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo_service/__init__.py 
new/oslo.service-1.38.0/oslo_service/__init__.py
--- old/oslo.service-1.31.5/oslo_service/__init__.py    2018-09-25 
21:44:54.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/__init__.py    2019-02-26 
01:07:10.000000000 +0100
@@ -13,7 +13,6 @@
 import os
 
 import eventlet.patcher
-import monotonic
 from oslo_log import log as logging
 
 time = eventlet.patcher.original('time')
@@ -21,10 +20,13 @@
 
 LOG = logging.getLogger(__name__)
 
+# TODO(bnemec): When we have a minimum dependency on a version of eventlet
+# that uses monotonic by default, remove this monkey patching.
 if hasattr(time, 'monotonic'):
     # Use builtin monotonic clock, Python 3.3+
     _monotonic = time.monotonic
 else:
+    import monotonic
     _monotonic = monotonic.monotonic
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo_service/eventlet_backdoor.py 
new/oslo.service-1.38.0/oslo_service/eventlet_backdoor.py
--- old/oslo.service-1.31.5/oslo_service/eventlet_backdoor.py   2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/eventlet_backdoor.py   2019-02-26 
01:07:10.000000000 +0100
@@ -21,13 +21,15 @@
 import logging
 import os
 import pprint
-import socket
 import sys
+import tempfile
 import traceback
 
 import eventlet.backdoor
 import greenlet
+import yappi
 
+from eventlet.green import socket
 from oslo_service._i18n import _
 from oslo_service import _options
 
@@ -89,6 +91,30 @@
     return [o for o in gc.get_objects() if isinstance(o, t)]
 
 
+def _capture_profile(fname=''):
+    if not fname:
+        yappi.set_clock_type('cpu')
+        # We need to set context to greenlet to profile greenlets
+        # https://bitbucket.org/sumerc/yappi/pull-requests/3
+        yappi.set_context_id_callback(
+            lambda: id(greenlet.getcurrent()))
+        yappi.set_context_name_callback(
+            lambda: greenlet.getcurrent().__class__.__name__)
+        yappi.start()
+    else:
+        yappi.stop()
+        stats = yappi.get_func_stats()
+        # User should provide filename. This file with a suffix .prof
+        # will be created in temp directory.
+        try:
+            stats_file = os.path.join(tempfile.gettempdir(), fname + '.prof')
+            stats.save(stats_file, "pstat")
+        except Exception as e:
+            print("Error while saving the trace stats ", str(e))
+        finally:
+            yappi.clear_stats()
+
+
 def _print_greenthreads(simple=True):
     for i, gt in enumerate(_find_objects(greenlet.greenlet)):
         print(i, gt)
@@ -121,11 +147,24 @@
             port_range, ex, _options.help_for_backdoor_port)
 
 
-def _listen(host, start_port, end_port, listen_func):
+def _listen_func(host, port):
+    # eventlet is setting SO_REUSEPORT by default from v0.20.
+    # But we can configure it by passing reuse_port argument
+    # from v0.22
+    try:
+        return eventlet.listen((host, port), reuse_port=False)
+    except TypeError:
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.bind((host, port))
+        sock.listen(50)
+        return sock
+
+
+def _listen(host, start_port, end_port):
     try_port = start_port
     while True:
         try:
-            return listen_func((host, try_port))
+            return _listen_func(host, try_port)
         except socket.error as exc:
             if (exc.errno != errno.EADDRINUSE or
                try_port >= end_port):
@@ -162,6 +201,7 @@
         'fo': _find_objects,
         'pgt': _print_greenthreads,
         'pnt': _print_nativethreads,
+        'prof': _capture_profile,
     }
 
     if conf.backdoor_port is None and conf.backdoor_socket is None:
@@ -169,7 +209,7 @@
 
     if conf.backdoor_socket is None:
         start_port, end_port = _parse_port_range(str(conf.backdoor_port))
-        sock = _listen('localhost', start_port, end_port, eventlet.listen)
+        sock = _listen('localhost', start_port, end_port)
         # In the case of backdoor port being zero, a port number is assigned by
         # listen().  In any case, pull the port number out here.
         where_running = sock.getsockname()[1]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo_service/fixture.py 
new/oslo.service-1.38.0/oslo_service/fixture.py
--- old/oslo.service-1.31.5/oslo_service/fixture.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/oslo.service-1.38.0/oslo_service/fixture.py     2019-02-26 
01:07:10.000000000 +0100
@@ -0,0 +1,52 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import fixtures
+
+
+class SleepFixture(fixtures.Fixture):
+    """A fixture for mocking the ``wait()`` within :doc:`loopingcall` events.
+
+    This exists so test cases can exercise code that uses :doc:`loopingcall`
+    without actually incurring wall clock time for sleeping.
+
+    The mock for the ``wait()`` is accessible via the fixture's ``mock_wait``
+    attribute.
+
+    .. note:: It is not recommended to assert specific arguments (i.e. timeout
+              values) to the mock, as this relies on the internals of
+              :doc:`loopingcall` not changing.
+
+    .. todo:: Figure out a way to make an enforceable contract allowing
+              verification of timeout values.
+
+    Example usage::
+
+        from oslo.service import fixture
+        ...
+        class MyTest(...):
+            def setUp(self):
+                ...
+                self.sleepfx = self.useFixture(fixture.SleepFixture())
+                ...
+
+            def test_this(self):
+                ...
+                thing_that_hits_a_loopingcall()
+                ...
+                self.assertEqual(5, self.sleepfx.mock_wait.call_count)
+                ...
+    """
+    def _setUp(self):
+        # Provide access to the mock so that calls to it can be asserted
+        self.mock_wait = self.useFixture(fixtures.MockPatch(
+            'oslo_utils.eventletutils.EventletEvent.wait')).mock
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo_service/loopingcall.py 
new/oslo.service-1.38.0/oslo_service/loopingcall.py
--- old/oslo.service-1.31.5/oslo_service/loopingcall.py 2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/loopingcall.py 2019-02-26 
01:07:10.000000000 +0100
@@ -17,7 +17,6 @@
 
 import random
 import sys
-import threading
 import time
 
 from eventlet import event
@@ -77,53 +76,6 @@
     return func
 
 
-def _Event():
-    if eventletutils.is_monkey_patched('thread'):
-        return _ThreadingEvent()
-    else:
-        return _GreenEvent()
-
-
-class _ThreadingEvent(object):
-    def __init__(self):
-        self._abort = threading.Event()
-
-    def is_running(self):
-        return not self._abort.is_set()
-
-    def clear(self):
-        self._abort.clear()
-
-    def wait(self, timeout):
-        self._abort.wait(timeout)
-
-    def stop(self):
-        self._abort.set()
-
-    def done(self):
-        pass
-
-
-class _GreenEvent(object):
-    def __init__(self):
-        self._running = False
-
-    def is_running(self):
-        return self._running
-
-    def clear(self):
-        self._running = True
-
-    def wait(self, timeout):
-        greenthread.sleep(timeout)
-
-    def stop(self):
-        self._running = False
-
-    def done(self):
-        self._running = False
-
-
 class LoopingCallBase(object):
     _KIND = _("Unknown looping call")
 
@@ -136,24 +88,24 @@
         self.f = f
         self._thread = None
         self.done = None
-        self._event = _Event()
+        self._abort = eventletutils.EventletEvent()
 
     @property
     def _running(self):
-        return self._event.is_running()
+        return not self._abort.is_set()
 
     def stop(self):
-        self._event.stop()
+        if self._running:
+            self._abort.set()
 
     def wait(self):
         return self.done.wait()
 
     def _on_done(self, gt, *args, **kwargs):
         self._thread = None
-        self._event.done()
 
     def _sleep(self, timeout):
-        self._event.wait(timeout)
+        self._abort.wait(timeout)
 
     def _start(self, idle_for, initial_delay=None, stop_on_exception=True):
         """Start the looping
@@ -171,13 +123,18 @@
         if self._thread is not None:
             raise RuntimeError(self._RUN_ONLY_ONE_MESSAGE)
         self.done = event.Event()
-        self._event.clear()
+        self._abort.clear()
         self._thread = greenthread.spawn(
             self._run_loop, idle_for,
             initial_delay=initial_delay, stop_on_exception=stop_on_exception)
         self._thread.link(self._on_done)
         return self.done
 
+    # NOTE(bnemec): This is just a wrapper function we can mock so we aren't
+    # affected by other users of the StopWatch class.
+    def _elapsed(self, watch):
+        return watch.elapsed()
+
     def _run_loop(self, idle_for_func,
                   initial_delay=None, stop_on_exception=True):
         kind = self._KIND
@@ -194,7 +151,7 @@
                 watch.stop()
                 if not self._running:
                     break
-                idle = idle_for_func(result, watch.elapsed())
+                idle = idle_for_func(result, self._elapsed(watch))
                 LOG.trace('%(kind)s %(func_name)r sleeping '
                           'for %(idle).02f seconds',
                           {'func_name': func_name, 'idle': idle,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo_service/periodic_task.py 
new/oslo.service-1.38.0/oslo_service/periodic_task.py
--- old/oslo.service-1.31.5/oslo_service/periodic_task.py       2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/periodic_task.py       2019-02-26 
01:07:10.000000000 +0100
@@ -14,15 +14,17 @@
 import copy
 import logging
 import random
-import time
-
-from monotonic import monotonic as now  # noqa
-from oslo_utils import reflection
 import six
+import time
 
 from oslo_service._i18n import _
 from oslo_service import _options
+from oslo_utils import reflection
 
+if hasattr(time, 'monotonic'):
+    now = time.monotonic
+else:
+    from monotonic import monotonic as now  # noqa
 
 LOG = logging.getLogger(__name__)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo_service/service.py 
new/oslo.service-1.38.0/oslo_service/service.py
--- old/oslo.service-1.31.5/oslo_service/service.py     2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/service.py     2019-02-26 
01:07:10.000000000 +0100
@@ -28,7 +28,6 @@
 import logging
 import os
 import random
-import select
 import signal
 import six
 import sys
@@ -140,8 +139,8 @@
         self._ignore_signals = ('SIG_DFL', 'SIG_IGN')
         self._signals_by_name = dict((name, getattr(signal, name))
                                      for name in dir(signal)
-                                     if name.startswith("SIG")
-                                     and name not in self._ignore_signals)
+                                     if name.startswith("SIG") and
+                                     name not in self._ignore_signals)
         self.signals_to_name = dict(
             (sigval, name)
             for (name, sigval) in self._signals_by_name.items())
@@ -204,8 +203,9 @@
         For Python 3.5 and later, deal with the changes in PEP 475 that prevent
         a signal from interrupting eventlet's call to poll() or sleep().
         """
+        select_module = eventlet.patcher.original('select')
         self.__force_interrupt_on_signal = (sys.version_info >= (3, 5) and
-                                            hasattr(select, 'poll'))
+                                            hasattr(select_module, 'poll'))
 
         if self.__force_interrupt_on_signal:
             try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo_service/tests/eventlet_service.py 
new/oslo.service-1.38.0/oslo_service/tests/eventlet_service.py
--- old/oslo.service-1.31.5/oslo_service/tests/eventlet_service.py      
2018-09-25 21:44:54.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/tests/eventlet_service.py      
2019-02-26 01:07:10.000000000 +0100
@@ -17,6 +17,7 @@
 
 import socket
 import sys
+import time
 
 import eventlet.wsgi
 import greenlet
@@ -122,10 +123,13 @@
             pass
 
 
-def run(port_queue, workers=3):
+def run(port_queue, workers=3, process_time=0):
     eventlet.patcher.monkey_patch()
 
     def hi_app(environ, start_response):
+        # Some requests need to take time to process so the connection
+        # remains active.
+        time.sleep(process_time)
         start_response('200 OK', [('Content-Type', 'application/json')])
         yield 'hi'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo_service/tests/test_eventlet_backdoor.py 
new/oslo.service-1.38.0/oslo_service/tests/test_eventlet_backdoor.py
--- old/oslo.service-1.31.5/oslo_service/tests/test_eventlet_backdoor.py        
2018-09-25 21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/tests/test_eventlet_backdoor.py        
2019-02-26 01:07:10.000000000 +0100
@@ -106,6 +106,14 @@
                           eventlet_backdoor.initialize_if_enabled, self.conf)
 
     @mock.patch.object(eventlet, 'spawn')
+    def test_backdoor_port_range_inuse(self, spawn_mock):
+        self.config(backdoor_port='8800:8801')
+        port = eventlet_backdoor.initialize_if_enabled(self.conf)
+        self.assertEqual(8800, port)
+        port = eventlet_backdoor.initialize_if_enabled(self.conf)
+        self.assertEqual(8801, port)
+
+    @mock.patch.object(eventlet, 'spawn')
     @mock.patch.object(eventlet, 'listen')
     def test_backdoor_port_range(self, listen_mock, spawn_mock):
         self.config(backdoor_port='8800:8899')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo_service/tests/test_fixture.py 
new/oslo.service-1.38.0/oslo_service/tests/test_fixture.py
--- old/oslo.service-1.31.5/oslo_service/tests/test_fixture.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/oslo.service-1.38.0/oslo_service/tests/test_fixture.py  2019-02-26 
01:07:10.000000000 +0100
@@ -0,0 +1,36 @@
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import mock
+from oslotest import base as test_base
+
+from oslo_service import fixture
+from oslo_service import loopingcall
+
+
+class FixtureTestCase(test_base.BaseTestCase):
+    def setUp(self):
+        super(FixtureTestCase, self).setUp()
+        self.sleepfx = self.useFixture(fixture.SleepFixture())
+
+    def test_sleep_fixture(self):
+        @loopingcall.RetryDecorator(max_retry_count=3, inc_sleep_time=2,
+                                    exceptions=(ValueError,))
+        def retried_method():
+            raise ValueError("!")
+
+        self.assertRaises(ValueError, retried_method)
+        self.assertEqual(3, self.sleepfx.mock_wait.call_count)
+        # TODO(efried): This is cheating, and shouldn't be done by real callers
+        # yet - see todo in SleepFixture.
+        self.sleepfx.mock_wait.assert_has_calls(
+            [mock.call(x) for x in (2, 4, 6)])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo_service/tests/test_loopingcall.py 
new/oslo.service-1.38.0/oslo_service/tests/test_loopingcall.py
--- old/oslo.service-1.31.5/oslo_service/tests/test_loopingcall.py      
2018-09-25 21:44:54.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/tests/test_loopingcall.py      
2019-02-26 01:07:10.000000000 +0100
@@ -18,11 +18,9 @@
 from oslotest import base as test_base
 
 import oslo_service
+from oslo_service import fixture
 from oslo_service import loopingcall
 
-threading = eventlet.patcher.original('threading')
-time = eventlet.patcher.original('time')
-
 
 class LoopingCallTestCase(test_base.BaseTestCase):
 
@@ -53,45 +51,6 @@
         self.assertEqual(oslo_service._monotonic,
                          hub.clock)
 
-    def test_eventlet_use_hub_override(self):
-        ns = {}
-
-        def task():
-            try:
-                self._test_eventlet_use_hub_override()
-            except Exception as exc:
-                ns['result'] = exc
-            else:
-                ns['result'] = 'ok'
-
-        # test overriding the hub of in a new thread to not modify the hub
-        # of the main thread
-        thread = threading.Thread(target=task)
-        thread.start()
-        thread.join()
-        self.assertEqual('ok', ns['result'])
-
-    def _test_eventlet_use_hub_override(self):
-        # Make sure that by default the
-        # oslo_service.service_hub() kicks in
-        old_clock = eventlet.hubs.get_hub().clock
-        self.assertEqual(oslo_service._monotonic,
-                         old_clock)
-
-        # eventlet will use time.monotonic() by default, same clock than
-        # oslo.service_hub():
-        # https://github.com/eventlet/eventlet/pull/303
-        if not hasattr(time, 'monotonic'):
-            # If anyone wants to override it
-            try:
-                eventlet.hubs.use_hub('poll')
-            except Exception:
-                eventlet.hubs.use_hub('selects')
-
-            # then we get a new clock and the override works fine too!
-            clock = eventlet.hubs.get_hub().clock
-            self.assertNotEqual(old_clock, clock)
-
     def test_return_false(self):
         def _raise_it():
             raise loopingcall.LoopingCallDone(False)
@@ -114,6 +73,7 @@
             raise RuntimeError()
 
     def test_do_not_stop_on_exception(self):
+        self.useFixture(fixture.SleepFixture())
         self.num_runs = 2
 
         timer = loopingcall.FixedIntervalLoopingCall(self._raise_and_then_done)
@@ -142,7 +102,18 @@
         wait_ev.set()
         timer.wait()
 
+    def test_no_double_stop(self):
+        def _raise_it():
+            raise loopingcall.LoopingCallDone(False)
+
+        timer = loopingcall.FixedIntervalLoopingCall(_raise_it)
+        timer.start(interval=0.5)
+
+        timer.stop()
+        timer.stop()
+
     def test_repeat(self):
+        self.useFixture(fixture.SleepFixture())
         self.num_runs = 2
 
         timer = loopingcall.FixedIntervalLoopingCall(self._wait_for_zero)
@@ -151,23 +122,19 @@
     def assertAlmostEqual(self, expected, actual, precision=7, message=None):
         self.assertEqual(0, round(actual - expected, precision), message)
 
-    @mock.patch('eventlet.greenthread.sleep')
-    @mock.patch('oslo_utils.timeutils.now')
-    def test_interval_adjustment(self, time_mock, sleep_mock):
+    @mock.patch('oslo_service.loopingcall.LoopingCallBase._sleep')
+    @mock.patch('oslo_service.loopingcall.LoopingCallBase._elapsed')
+    def test_interval_adjustment(self, elapsed_mock, sleep_mock):
         """Ensure the interval is adjusted to account for task duration."""
         self.num_runs = 3
 
-        now = 1234567890
         second = 1
         smidgen = 0.01
 
-        time_mock.side_effect = [now,  # restart
-                                 now + second - smidgen,  # end
-                                 now,  # restart
-                                 now + second + second,  # end
-                                 now,  # restart
-                                 now + second + smidgen,  # end
-                                 now]  # restart
+        elapsed_mock.side_effect = [second - smidgen,
+                                    second + second,
+                                    second + smidgen,
+                                    ]
         timer = loopingcall.FixedIntervalLoopingCall(self._wait_for_zero)
         timer.start(interval=1.01).wait()
 
@@ -250,6 +217,7 @@
             raise RuntimeError()
 
     def test_do_not_stop_on_exception(self):
+        self.useFixture(fixture.SleepFixture())
         self.num_runs = 2
 
         timer = loopingcall.DynamicLoopingCall(self._raise_and_then_done)
@@ -265,6 +233,7 @@
             return sleep_for
 
     def test_repeat(self):
+        self.useFixture(fixture.SleepFixture())
         self.num_runs = 2
 
         timer = loopingcall.DynamicLoopingCall(self._wait_for_zero)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo_service/tests/test_service.py 
new/oslo.service-1.38.0/oslo_service/tests/test_service.py
--- old/oslo.service-1.31.5/oslo_service/tests/test_service.py  2018-09-25 
21:44:54.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/tests/test_service.py  2019-02-26 
01:07:10.000000000 +0100
@@ -227,7 +227,7 @@
 
         os.kill(start_workers[0], signal.SIGHUP)
         # Wait at most 5 seconds to respawn a worker
-        cond = lambda: start_workers == self._get_workers()
+        cond = lambda: start_workers != self._get_workers()
         timeout = 5
         self._wait(cond, timeout)
 
@@ -478,17 +478,30 @@
         signal_handler.clear()
 
     @mock.patch('sys.version_info', (3, 5))
-    @mock.patch.object(service, 'select', spec=[])
-    def test_setup_signal_interruption_no_select_poll(self, mock_select):
+    def test_setup_signal_interruption_no_select_poll(self):
         # NOTE(claudiub): SignalHandler is a singleton, which means that it
         # might already be initialized. We need to clear to clear the cache
         # in order to prevent race conditions between tests.
         service.SignalHandler.__class__._instances.clear()
-        signal_handler = service.SignalHandler()
+        with mock.patch('eventlet.patcher.original',
+                        return_value=object()) as get_original:
+            signal_handler = service.SignalHandler()
+            get_original.assert_called_with('select')
         self.addCleanup(service.SignalHandler.__class__._instances.clear)
         self.assertFalse(
             signal_handler._SignalHandler__force_interrupt_on_signal)
 
+    @mock.patch('sys.version_info', (3, 5))
+    def test_setup_signal_interruption_select_poll(self):
+        # NOTE(claudiub): SignalHandler is a singleton, which means that it
+        # might already be initialized. We need to clear to clear the cache
+        # in order to prevent race conditions between tests.
+        service.SignalHandler.__class__._instances.clear()
+        signal_handler = service.SignalHandler()
+        self.addCleanup(service.SignalHandler.__class__._instances.clear)
+        self.assertTrue(
+            signal_handler._SignalHandler__force_interrupt_on_signal)
+
     @mock.patch('signal.alarm')
     @mock.patch("os.kill")
     @mock.patch("oslo_service.service.ProcessLauncher.stop")
@@ -625,13 +638,19 @@
 
     def run_server(self):
         queue = multiprocessing.Queue()
+        # NOTE(bnemec): process_time of 5 needs to be longer than the graceful
+        # shutdown timeout in the "exceeded" test below, but also needs to be
+        # shorter than the timeout in the regular graceful shutdown test.
         proc = multiprocessing.Process(target=eventlet_service.run,
                                        args=(queue,),
-                                       kwargs={'workers': self.workers})
+                                       kwargs={'workers': self.workers,
+                                               'process_time': 5})
         proc.start()
 
         port = queue.get()
         conn = socket.create_connection(('127.0.0.1', port))
+        # Send request to make the connection active.
+        conn.sendall(b'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
 
         # NOTE(blk-u): The sleep shouldn't be necessary. There must be a bug in
         # the server implementation where it takes some time to set up the
@@ -660,10 +679,14 @@
         # connected.
         os.kill(proc.pid, signal.SIGTERM)
 
-        # server with graceful shutdown must wait forewer if
+        # server with graceful shutdown must wait forever if
         # option graceful_shutdown_timeout is not specified.
-        # we can not wait forever ... so 3 seconds are enough
-        time.sleep(3)
+        # we can not wait forever ... so 1 second is enough.
+        # NOTE(bnemec): In newer versions of eventlet that drop idle
+        # connections, this needs to be long enough to allow the signal
+        # handler to fire but short enough that our request doesn't complete
+        # or the connection will be closed and the server will stop.
+        time.sleep(1)
 
         self.assertTrue(proc.is_alive())
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/oslo_service/tests/test_threadgroup.py 
new/oslo.service-1.38.0/oslo_service/tests/test_threadgroup.py
--- old/oslo.service-1.31.5/oslo_service/tests/test_threadgroup.py      
2018-09-25 21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/tests/test_threadgroup.py      
2019-02-26 01:07:10.000000000 +0100
@@ -49,6 +49,50 @@
         self.assertEqual(('arg',), timer.args)
         self.assertEqual({'kwarg': 'kwarg'}, timer.kw)
 
+    def test_add_dynamic_timer_args(self):
+        def foo(*args, **kwargs):
+            pass
+
+        self.tg.add_dynamic_timer_args(foo, ['arg'], {'kwarg': 'kwarg'},
+                                       initial_delay=1,
+                                       periodic_interval_max=2,
+                                       stop_on_exception=False)
+
+        self.assertEqual(1, len(self.tg.timers))
+
+        timer = self.tg.timers[0]
+        self.assertTrue(timer._running)
+        self.assertEqual(('arg',), timer.args)
+        self.assertEqual({'kwarg': 'kwarg'}, timer.kw)
+
+    def test_add_timer(self):
+        def foo(*args, **kwargs):
+            pass
+
+        self.tg.add_timer(1, foo, 1,
+                          'arg', kwarg='kwarg')
+
+        self.assertEqual(1, len(self.tg.timers))
+
+        timer = self.tg.timers[0]
+        self.assertTrue(timer._running)
+        self.assertEqual(('arg',), timer.args)
+        self.assertEqual({'kwarg': 'kwarg'}, timer.kw)
+
+    def test_add_timer_args(self):
+        def foo(*args, **kwargs):
+            pass
+
+        self.tg.add_timer_args(1, foo, ['arg'], {'kwarg': 'kwarg'},
+                               initial_delay=1, stop_on_exception=False)
+
+        self.assertEqual(1, len(self.tg.timers))
+
+        timer = self.tg.timers[0]
+        self.assertTrue(timer._running)
+        self.assertEqual(('arg',), timer.args)
+        self.assertEqual({'kwarg': 'kwarg'}, timer.kw)
+
     def test_stop_current_thread(self):
 
         stop_event = event.Event()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/oslo_service/threadgroup.py 
new/oslo.service-1.38.0/oslo_service/threadgroup.py
--- old/oslo.service-1.31.5/oslo_service/threadgroup.py 2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/oslo_service/threadgroup.py 2019-02-26 
01:07:10.000000000 +0100
@@ -14,7 +14,9 @@
 
 import logging
 import threading
+import warnings
 
+from debtcollector import removals
 import eventlet
 from eventlet import greenpool
 
@@ -51,47 +53,187 @@
         return self._ident
 
     def stop(self):
+        """Kill the thread by raising GreenletExit within it."""
         self.thread.kill()
 
     def wait(self):
+        """Block until the thread completes and return the result."""
         return self.thread.wait()
 
     def link(self, func, *args, **kwargs):
+        """Schedule a function to be run upon completion of the thread."""
         self.thread.link(func, *args, **kwargs)
 
     def cancel(self, *throw_args):
+        """Prevent the thread from starting if it has not already done so.
+
+        :param throw_args: the `exc_info` data to raise from :func:`wait`.
+        """
         self.thread.cancel(*throw_args)
 
 
 class ThreadGroup(object):
-    """The point of the ThreadGroup class is to:
+    """A group of greenthreads and timers.
+
+    The point of the ThreadGroup class is to:
 
     * keep track of timers and greenthreads (making it easier to stop them
       when need be).
     * provide an easy API to add timers.
+
+    .. note::
+        The API is inconsistent, confusing, and not orthogonal. The same verbs
+        often mean different things when applied to timers and threads,
+        respectively. Read the documentation carefully.
     """
+
     def __init__(self, thread_pool_size=10):
+        """Create a ThreadGroup with a pool of greenthreads.
+
+        :param thread_pool_size: the maximum number of threads allowed to run
+                                 concurrently.
+        """
         self.pool = greenpool.GreenPool(thread_pool_size)
         self.threads = []
         self.timers = []
 
     def add_dynamic_timer(self, callback, initial_delay=None,
                           periodic_interval_max=None, *args, **kwargs):
+        """Add a timer that controls its own period dynamically.
+
+        The period of each iteration of the timer is controlled by the return
+        value of the callback function on the previous iteration.
+
+        .. warning::
+            Passing arguments to the callback function is deprecated. Use the
+            :func:`add_dynamic_timer_args` method to pass arguments for the
+            callback function.
+
+        :param callback: The callback function to run when the timer is
+                         triggered.
+        :param initial_delay: The delay in seconds before first triggering the
+                              timer. If not set, the timer is liable to be
+                              scheduled immediately.
+        :param periodic_interval_max: The maximum interval in seconds to allow
+                                      the callback function to request. If
+                                      provided, this is also used as the
+                                      default delay if None is returned by the
+                                      callback function.
+        :returns: an :class:`oslo_service.loopingcall.DynamicLoopingCall`
+                  instance
+        """
+        if args or kwargs:
+            warnings.warn("Calling add_dynamic_timer() with arguments to the "
+                          "callback function is deprecated. Use "
+                          "add_dynamic_timer_args() instead.",
+                          DeprecationWarning)
+        return self.add_dynamic_timer_args(
+            callback, args, kwargs,
+            initial_delay=initial_delay,
+            periodic_interval_max=periodic_interval_max)
+
+    def add_dynamic_timer_args(self, callback, args=None, kwargs=None,
+                               initial_delay=None, periodic_interval_max=None,
+                               stop_on_exception=True):
+        """Add a timer that controls its own period dynamically.
+
+        The period of each iteration of the timer is controlled by the return
+        value of the callback function on the previous iteration.
+
+        :param callback: The callback function to run when the timer is
+                         triggered.
+        :param args: A list of positional args to the callback function.
+        :param kwargs: A dict of keyword args to the callback function.
+        :param initial_delay: The delay in seconds before first triggering the
+                              timer. If not set, the timer is liable to be
+                              scheduled immediately.
+        :param periodic_interval_max: The maximum interval in seconds to allow
+                                      the callback function to request. If
+                                      provided, this is also used as the
+                                      default delay if None is returned by the
+                                      callback function.
+        :param stop_on_exception: Pass ``False`` to have the timer continue
+                                  running even if the callback function raises
+                                  an exception.
+        :returns: an :class:`oslo_service.loopingcall.DynamicLoopingCall`
+                  instance
+        """
+        args = args or []
+        kwargs = kwargs or {}
         timer = loopingcall.DynamicLoopingCall(callback, *args, **kwargs)
         timer.start(initial_delay=initial_delay,
-                    periodic_interval_max=periodic_interval_max)
+                    periodic_interval_max=periodic_interval_max,
+                    stop_on_exception=stop_on_exception)
         self.timers.append(timer)
         return timer
 
     def add_timer(self, interval, callback, initial_delay=None,
                   *args, **kwargs):
+        """Add a timer with a fixed period.
+
+        .. warning::
+            Passing arguments to the callback function is deprecated. Use the
+            :func:`add_timer_args` method to pass arguments for the callback
+            function.
+
+        :param interval: The minimum period in seconds between calls to the
+                         callback function.
+        :param callback: The callback function to run when the timer is
+                         triggered.
+        :param initial_delay: The delay in seconds before first triggering the
+                              timer. If not set, the timer is liable to be
+                              scheduled immediately.
+        :returns: an :class:`oslo_service.loopingcall.FixedIntervalLoopingCall`
+                  instance
+        """
+        if args or kwargs:
+            warnings.warn("Calling add_timer() with arguments to the callback "
+                          "function is deprecated. Use add_timer_args() "
+                          "instead.",
+                          DeprecationWarning)
+        return self.add_timer_args(interval, callback, args, kwargs,
+                                   initial_delay=initial_delay)
+
+    def add_timer_args(self, interval, callback, args=None, kwargs=None,
+                       initial_delay=None, stop_on_exception=True):
+        """Add a timer with a fixed period.
+
+        :param interval: The minimum period in seconds between calls to the
+                         callback function.
+        :param callback: The callback function to run when the timer is
+                         triggered.
+        :param args: A list of positional args to the callback function.
+        :param kwargs: A dict of keyword args to the callback function.
+        :param initial_delay: The delay in seconds before first triggering the
+                              timer. If not set, the timer is liable to be
+                              scheduled immediately.
+        :param stop_on_exception: Pass ``False`` to have the timer continue
+                                  running even if the callback function raises
+                                  an exception.
+        :returns: an :class:`oslo_service.loopingcall.FixedIntervalLoopingCall`
+                  instance
+        """
+        args = args or []
+        kwargs = kwargs or {}
         pulse = loopingcall.FixedIntervalLoopingCall(callback, *args, **kwargs)
         pulse.start(interval=interval,
-                    initial_delay=initial_delay)
+                    initial_delay=initial_delay,
+                    stop_on_exception=stop_on_exception)
         self.timers.append(pulse)
         return pulse
 
     def add_thread(self, callback, *args, **kwargs):
+        """Spawn a new thread.
+
+        This call will block until capacity is available in the thread pool.
+        After that, it returns immediately (i.e. *before* the new thread is
+        scheduled).
+
+        :param callback: the function to run in the new thread.
+        :param args: positional arguments to the callback function.
+        :param kwargs: keyword arguments to the callback function.
+        :returns: a :class:`Thread` object
+        """
         gt = self.pool.spawn(callback, *args, **kwargs)
         th = Thread(gt, self, link=False)
         self.threads.append(th)
@@ -99,9 +241,19 @@
         return th
 
     def thread_done(self, thread):
+        """Remove a completed thread from the group.
+
+        This method is automatically called on completion of a thread in the
+        group, and should not be called explicitly.
+        """
         self.threads.remove(thread)
 
     def timer_done(self, timer):
+        """Remove a timer from the group.
+
+        :param timer: The timer object returned from :func:`add_timer` or its
+                      analogues.
+        """
         self.timers.remove(timer)
 
     def _perform_action_on_threads(self, action_func, on_error_func):
@@ -126,6 +278,18 @@
             lambda x: LOG.exception('Error stopping thread.'))
 
     def stop_timers(self, wait=False):
+        """Stop all timers in the group and remove them from the group.
+
+        No new invocations of timers will be triggered after they are stopped,
+        but calls that are in progress will not be interrupted.
+
+        To wait for in-progress calls to complete, pass ``wait=True`` - calling
+        :func:`wait` will not have the desired effect as the timers will have
+        already been removed from the group.
+
+        :param wait: If true, block until all timers have been stopped before
+                     returning.
+        """
         for timer in self.timers:
             timer.stop()
         if wait:
@@ -133,11 +297,25 @@
         self.timers = []
 
     def stop(self, graceful=False):
-        """stop function has the option of graceful=True/False.
+        """Stop all timers and threads in the group.
 
-        * In case of graceful=True, wait for all threads to be finished.
-          Never kill threads.
-        * In case of graceful=False, kill threads immediately.
+        No new invocations of timers will be triggered after they are stopped,
+        but calls that are in progress will not be interrupted.
+
+        If ``graceful`` is false, kill all threads immediately by raising
+        GreenletExit. Note that in this case, this method will **not** block
+        until all threads and running timer callbacks have actually exited. To
+        guarantee that all threads have exited, call :func:`wait`.
+
+        If ``graceful`` is true, do not kill threads. Block until all threads
+        and running timer callbacks have completed. This is equivalent to
+        calling :func:`stop_timers` with ``wait=True`` followed by
+        :func:`wait`.
+
+        :param graceful: If true, block until all timers have stopped and all
+                         threads completed; never kill threads. Otherwise,
+                         kill threads immediately and return immediately even
+                         if there are timer callbacks still running.
         """
         self.stop_timers(wait=graceful)
         if graceful:
@@ -165,6 +343,25 @@
             lambda x: LOG.exception('Error waiting on thread.'))
 
     def wait(self):
+        """Block until all timers and threads in the group are complete.
+
+        .. note::
+            Before calling this method, any timers should be stopped first by
+            calling :func:`stop_timers`, :func:`stop`, or :func:`cancel` with a
+            ``timeout`` argument. Otherwise this will block forever.
+
+        .. note::
+            Calling :func:`stop_timers` removes the timers from the group, so a
+            subsequent call to this method will not wait for any in-progress
+            timer calls to complete.
+
+        Any exceptions raised by the threads will be logged but suppressed.
+
+        .. note::
+            This call guarantees only that the threads themselves have
+            completed, **not** that any cleanup functions added via
+            :func:`Thread.link` have completed.
+        """
         self._wait_timers()
         self._wait_threads()
 
@@ -178,7 +375,42 @@
                 return True
         return False
 
+    @removals.remove(removal_version='?')
     def cancel(self, *throw_args, **kwargs):
+        """Cancel unstarted threads in the group, and optionally stop the rest.
+
+        .. warning::
+            This method is deprecated and should not be used. It will be
+            removed in a future release.
+
+        If called without the ``timeout`` argument, this does **not** stop any
+        running threads, but prevents any threads in the group that have not
+        yet started from running, then returns immediately. Timers are not
+        affected.
+
+        If the 'timeout' argument is supplied, then it serves as a grace period
+        to allow running threads to finish. After the timeout, any threads in
+        the group that are still running will be killed by raising GreenletExit
+        in them, and all timers will be stopped (so that they are not
+        retriggered - timer calls that are in progress will not be
+        interrupted). This method will **not** block until all threads have
+        actually exited, nor that all in-progress timer calls have completed.
+        To guarantee that all threads have exited, call :func:`wait`. If all
+        threads complete before the timeout expires, timers will be left
+        running; there is no way to then stop those timers, so for consistent
+        behaviour :func`stop_timers` should be called before calling this
+        method.
+
+        :param throw_args: the `exc_info` data to raise from
+                           :func:`Thread.wait` for any of the unstarted
+                           threads. (Though note that :func:`ThreadGroup.wait`
+                           suppresses exceptions.)
+        :param timeout: time to wait for running threads to complete before
+                        calling stop(). If not supplied, threads that are
+                        already running continue to completion.
+        :param wait_time: length of time in seconds to sleep between checks of
+                          whether any threads are still alive. (Default 1s.)
+        """
         self._perform_action_on_threads(
             lambda x: x.cancel(*throw_args),
             lambda x: LOG.exception('Error canceling thread.'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/releasenotes/notes/profile-worker-5d3fd0f0251d62b8.yaml 
new/oslo.service-1.38.0/releasenotes/notes/profile-worker-5d3fd0f0251d62b8.yaml
--- 
old/oslo.service-1.31.5/releasenotes/notes/profile-worker-5d3fd0f0251d62b8.yaml 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/oslo.service-1.38.0/releasenotes/notes/profile-worker-5d3fd0f0251d62b8.yaml 
    2019-02-26 01:07:10.000000000 +0100
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Add support for profiling (capture function calltrace) service's worker
+    processes.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/releasenotes/notes/reno.cache 
new/oslo.service-1.38.0/releasenotes/notes/reno.cache
--- old/oslo.service-1.31.5/releasenotes/notes/reno.cache       2018-09-25 
21:47:28.000000000 +0200
+++ new/oslo.service-1.38.0/releasenotes/notes/reno.cache       1970-01-01 
01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
----
-file-contents: {}
-notes: []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/releasenotes/notes/threadgroup-cancel-bd89d72f383a3d9b.yaml
 
new/oslo.service-1.38.0/releasenotes/notes/threadgroup-cancel-bd89d72f383a3d9b.yaml
--- 
old/oslo.service-1.31.5/releasenotes/notes/threadgroup-cancel-bd89d72f383a3d9b.yaml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/oslo.service-1.38.0/releasenotes/notes/threadgroup-cancel-bd89d72f383a3d9b.yaml
 2019-02-26 01:07:10.000000000 +0100
@@ -0,0 +1,5 @@
+---
+deprecations:
+  - |
+    The ``ThreadGroup.cancel()`` method is deprecated and will be removed in a
+    future major release.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/releasenotes/notes/timer-args-f578c8f9d08b217d.yaml 
new/oslo.service-1.38.0/releasenotes/notes/timer-args-f578c8f9d08b217d.yaml
--- old/oslo.service-1.31.5/releasenotes/notes/timer-args-f578c8f9d08b217d.yaml 
1970-01-01 01:00:00.000000000 +0100
+++ new/oslo.service-1.38.0/releasenotes/notes/timer-args-f578c8f9d08b217d.yaml 
2019-02-26 01:07:10.000000000 +0100
@@ -0,0 +1,15 @@
+---
+features:
+  - |
+    The ThreadGroup class has new add_timer_args() and add_dynamic_timer_args()
+    methods to create timers passing the positional and keyword arguments to
+    the callback as a sequence and a mapping. This API provides more
+    flexibility for the addition of timer control options in the future.
+deprecations:
+  - |
+    The API of the ThreadGroup add_timer() and add_dynamic_timer() methods has
+    been identified as error-prone when passing arguments intended for the
+    callback function. Passing callback arguments in this way is now
+    deprecated. Callers should use the new add_timer_args() or
+    add_dynamic_timer_args() methods (respectively) instead when it is
+    necessary to pass arguments to the timer callback function.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslo.service-1.31.5/releasenotes/notes/timer-stop_on_exception-9f21d7c4d6d1b0d9.yaml
 
new/oslo.service-1.38.0/releasenotes/notes/timer-stop_on_exception-9f21d7c4d6d1b0d9.yaml
--- 
old/oslo.service-1.31.5/releasenotes/notes/timer-stop_on_exception-9f21d7c4d6d1b0d9.yaml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/oslo.service-1.38.0/releasenotes/notes/timer-stop_on_exception-9f21d7c4d6d1b0d9.yaml
    2019-02-26 01:07:10.000000000 +0100
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    The ThreadGroup add_timer_args() and add_dynamic_timer_args() methods now
+    support passing a stop_on_exception=False argument to allow the timer to
+    keep running even when an exception is raised by the callback function.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/releasenotes/source/index.rst 
new/oslo.service-1.38.0/releasenotes/source/index.rst
--- old/oslo.service-1.31.5/releasenotes/source/index.rst       2018-09-25 
21:44:54.000000000 +0200
+++ new/oslo.service-1.38.0/releasenotes/source/index.rst       2019-02-26 
01:07:10.000000000 +0100
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    unreleased
+   rocky
    queens
    pike
    ocata
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/releasenotes/source/rocky.rst 
new/oslo.service-1.38.0/releasenotes/source/rocky.rst
--- old/oslo.service-1.31.5/releasenotes/source/rocky.rst       1970-01-01 
01:00:00.000000000 +0100
+++ new/oslo.service-1.38.0/releasenotes/source/rocky.rst       2019-02-26 
01:07:10.000000000 +0100
@@ -0,0 +1,6 @@
+===================================
+ Rocky Series Release Notes
+===================================
+
+.. release-notes::
+   :branch: stable/rocky
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/requirements.txt 
new/oslo.service-1.38.0/requirements.txt
--- old/oslo.service-1.31.5/requirements.txt    2018-09-25 21:44:37.000000000 
+0200
+++ new/oslo.service-1.38.0/requirements.txt    2019-02-26 01:07:16.000000000 
+0100
@@ -3,10 +3,12 @@
 # process, which may cause wedges in the gate later.
 
 WebOb>=1.7.1 # MIT
+debtcollector>=1.2.0 # Apache 2.0
 eventlet!=0.18.3,!=0.20.1,>=0.18.2 # MIT
+fixtures>=3.0.0 # Apache-2.0/BSD
 greenlet>=0.4.10 # MIT
-monotonic>=0.6 # Apache-2.0
-oslo.utils>=3.33.0 # Apache-2.0
+monotonic>=0.6;python_version<'3.3'  # Apache-2.0
+oslo.utils>=3.40.2 # Apache-2.0
 oslo.concurrency>=3.25.0 # Apache-2.0
 oslo.config>=5.1.0 # Apache-2.0
 oslo.log>=3.36.0 # Apache-2.0
@@ -15,3 +17,4 @@
 PasteDeploy>=1.5.0 # MIT
 Routes>=2.3.1 # MIT
 Paste>=2.0.2 # MIT
+Yappi>=1.0 # MIT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/setup.cfg 
new/oslo.service-1.38.0/setup.cfg
--- old/oslo.service-1.31.5/setup.cfg   2018-09-25 21:47:28.000000000 +0200
+++ new/oslo.service-1.38.0/setup.cfg   2019-02-26 01:09:41.000000000 +0100
@@ -4,7 +4,7 @@
 description-file = 
        README.rst
 author = OpenStack
-author-email = [email protected]
+author-email = [email protected]
 home-page = https://docs.openstack.org/oslo.service/latest/
 classifier = 
        Environment :: OpenStack
@@ -51,7 +51,7 @@
 mapping_file = babel.cfg
 output_file = oslo_service/locale/oslo_service.pot
 
-[wheel]
+[bdist_wheel]
 universal = true
 
 [egg_info]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/test-requirements.txt 
new/oslo.service-1.38.0/test-requirements.txt
--- old/oslo.service-1.31.5/test-requirements.txt       2018-09-25 
21:44:37.000000000 +0200
+++ new/oslo.service-1.38.0/test-requirements.txt       2019-02-26 
01:07:10.000000000 +0100
@@ -3,7 +3,7 @@
 # process, which may cause wedges in the gate later.
 
 fixtures>=3.0.0 # Apache-2.0/BSD
-hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
+hacking>=1.1.0,<1.2.0 # Apache-2.0
 mock>=2.0.0 # BSD
 oslotest>=3.2.0 # Apache-2.0
 requests>=2.14.2 # Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslo.service-1.31.5/tox.ini 
new/oslo.service-1.38.0/tox.ini
--- old/oslo.service-1.31.5/tox.ini     2018-09-25 21:44:54.000000000 +0200
+++ new/oslo.service-1.38.0/tox.ini     2019-02-26 01:07:10.000000000 +0100
@@ -9,7 +9,7 @@
     CLIENT_NAME=oslo.service
 install_command = pip install {opts} {packages}
 deps =
-  
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/rocky}
+  
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
   -r{toxinidir}/test-requirements.txt
   -r{toxinidir}/requirements.txt
 whitelist_externals = find
@@ -38,9 +38,10 @@
 
 [flake8]
 # E123, E125 skipped as they are invalid PEP-8.
+# E731 skipped as assign a lambda expression
 
 show-source = True
-ignore = E123,E125
+ignore = E123,E125,E731
 exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
 
 [hacking]
@@ -53,7 +54,7 @@
 [testenv:bandit]
 basepython = python3
 deps =
-  
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/rocky}
+  
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
   -r{toxinidir}/test-requirements.txt
   -r{toxinidir}/requirements.txt
 commands = bandit -r oslo_service -n5 -x tests {posargs}


Reply via email to