Przeglądaj źródła

HUE-8936 [tracing] Adding opentracing lib

Romain 6 lat temu
rodzic
commit
cd8ab9c8ed
66 zmienionych plików z 5135 dodań i 0 usunięć
  1. 31 0
      desktop/core/ext-py/opentracing-2.2.0/.editorconfig
  2. 78 0
      desktop/core/ext-py/opentracing-2.2.0/.gitignore
  3. 19 0
      desktop/core/ext-py/opentracing-2.2.0/.travis.yml
  4. 223 0
      desktop/core/ext-py/opentracing-2.2.0/CHANGELOG.rst
  5. 201 0
      desktop/core/ext-py/opentracing-2.2.0/LICENSE
  6. 9 0
      desktop/core/ext-py/opentracing-2.2.0/MANIFEST.in
  7. 96 0
      desktop/core/ext-py/opentracing-2.2.0/Makefile
  8. 316 0
      desktop/core/ext-py/opentracing-2.2.0/PKG-INFO
  9. 294 0
      desktop/core/ext-py/opentracing-2.2.0/README.rst
  10. 20 0
      desktop/core/ext-py/opentracing-2.2.0/docs/Makefile
  11. 72 0
      desktop/core/ext-py/opentracing-2.2.0/docs/api.rst
  12. 1 0
      desktop/core/ext-py/opentracing-2.2.0/docs/changelog.rst
  13. 25 0
      desktop/core/ext-py/opentracing-2.2.0/docs/conf.py
  14. 7 0
      desktop/core/ext-py/opentracing-2.2.0/docs/index.rst
  15. 36 0
      desktop/core/ext-py/opentracing-2.2.0/docs/make.bat
  16. 79 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/__init__.py
  17. 0 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/ext/__init__.py
  18. 20 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/ext/tags.py
  19. 0 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/harness/__init__.py
  20. 325 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/harness/api_check.py
  21. 160 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/harness/scope_check.py
  22. 52 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/logs.py
  23. 24 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/__init__.py
  24. 49 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/binary_propagator.py
  25. 51 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/context.py
  26. 30 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/propagator.py
  27. 94 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/span.py
  28. 67 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/text_propagator.py
  29. 187 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/tracer.py
  30. 93 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/propagation.py
  31. 84 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/scope.py
  32. 65 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_manager.py
  33. 79 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/__init__.py
  34. 138 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/asyncio.py
  35. 26 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/constants.py
  36. 114 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/gevent.py
  37. 280 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/tornado.py
  38. 252 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/span.py
  39. 142 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/tags.py
  40. 348 0
      desktop/core/ext-py/opentracing-2.2.0/opentracing/tracer.py
  41. 5 0
      desktop/core/ext-py/opentracing-2.2.0/requirements-test.txt
  42. 3 0
      desktop/core/ext-py/opentracing-2.2.0/requirements.txt
  43. 19 0
      desktop/core/ext-py/opentracing-2.2.0/setup.cfg
  44. 47 0
      desktop/core/ext-py/opentracing-2.2.0/setup.py
  45. 0 0
      desktop/core/ext-py/opentracing-2.2.0/tests/__init__.py
  46. 29 0
      desktop/core/ext-py/opentracing-2.2.0/tests/conftest.py
  47. 0 0
      desktop/core/ext-py/opentracing-2.2.0/tests/ext/__init__.py
  48. 0 0
      desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/__init__.py
  49. 36 0
      desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_api.py
  50. 69 0
      desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_propagation.py
  51. 39 0
      desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_span.py
  52. 46 0
      desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_tracer.py
  53. 0 0
      desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/__init__.py
  54. 51 0
      desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_asyncio.py
  55. 36 0
      desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_gevent.py
  56. 30 0
      desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_threadlocal.py
  57. 38 0
      desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_tornado.py
  58. 33 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_api.py
  59. 75 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_api_check_mixin.py
  60. 49 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_globaltracer.py
  61. 121 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_noop_span.py
  62. 30 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_noop_tracer.py
  63. 85 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_scope.py
  64. 66 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_scope_check_mixin.py
  65. 34 0
      desktop/core/ext-py/opentracing-2.2.0/tests/test_scope_manager.py
  66. 7 0
      desktop/core/ext-py/opentracing-2.2.0/tox.ini

+ 31 - 0
desktop/core/ext-py/opentracing-2.2.0/.editorconfig

@@ -0,0 +1,31 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+# Matches multiple files with brace expansion notation
+# Set default charset
+[*.py]
+charset = utf-8
+
+# 4 space indentation
+[*.py]
+indent_style = space
+indent_size = 4
+
+# Tab indentation (no size specified)
+[Makefile]
+indent_style = tab
+
+# Matches the exact files either package.json or .travis.yml
+[{package.json,.travis.yml}]
+indent_style = space
+indent_size = 2
+
+# Remove any whitespace characters preceding newline characters
+trim_trailing_whitespace = true

+ 78 - 0
desktop/core/ext-py/opentracing-2.2.0/.gitignore

@@ -0,0 +1,78 @@
+*.py[cod]
+*.orig
+
+# Ignore gen/ directory where we temporarily store thrift classes to help with development
+gen/
+
+# No local dbs
+*.db
+
+# C extensions
+*.so
+
+# Packages
+*.egg
+*.egg-info
+
+.tests
+
+bin
+build
+develop-eggs
+dist
+eggs
+parts
+sdist
+var
+
+.installed.cfg
+lib64
+__pycache__
+.cache/
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.coverage*
+.tox
+.noseids
+
+# Translations
+*.mo
+
+# Ignore python virtual environments
+env*
+thrift_env
+
+# Ignore local logs
+*.log
+logs/*
+!logs/.gitkeep
+
+# Ignore local log
+npm-debug.log
+
+# Ignore docs
+docs/_build/*
+
+# ignore ipython profile stuff
+config/profile_default/
+!config/profile_default/ipython_config.py
+config/README
+protobuf/*.py
+
+.phutil_module_cache
+
+# Ignore coverage output
+*.xml
+coverage/
+
+# Ignore benchmarks output
+perf.log
+perf.svg
+
+# vim
+*.swp
+.idea/

+ 19 - 0
desktop/core/ext-py/opentracing-2.2.0/.travis.yml

@@ -0,0 +1,19 @@
+dist: xenial
+
+language: python
+python:
+  - "2.7"
+  - "3.5"
+  - "3.6"
+  - "3.7"
+  - "3.8-dev"
+
+matrix:
+  allow_failures:
+    - python: "3.8-dev"
+
+install:
+  - make bootstrap
+
+script:
+  - make test testbed lint

+ 223 - 0
desktop/core/ext-py/opentracing-2.2.0/CHANGELOG.rst

@@ -0,0 +1,223 @@
+.. :changelog:
+
+History
+=======
+
+2.2.0 (2019-05-10)
+------------------
+
+- Fix __exit__ method of Scope class (#120) <Aliaksei Urbanski>
+- Add support for Python 3.5/3.7 and fix tests (#121) <Aliaksei Urbanski>
+
+
+2.1.0 (2019-04-27)
+------------------
+
+- Add support for indicating if a global tracer has been registered (#109) <Mike Goldsmith>
+- Use pytest-cov==2.6.0 as 2.6.1 depends on pytest>=3.6.0 (#113) <Carlos Alberto Cortez>
+- Better error handling in context managers for Span/Scope. (#101) <Carlos Alberto Cortez>
+- Add log fields constants to opentracing.logs. (#99) <Carlos Alberto Cortez>
+- Move opentracing.ext.tags to opentracing.tags. (#103) <Carlos Alberto Cortez>
+- Add SERVICE tag (#100) <Carlos Alberto Cortez>
+- Fix unclosed active scope in tests (#97) <Michał Szymański>
+- Initial implementation of a global Tracer. (#95) <Carlos Alberto Cortez>
+
+
+2.0.0 (2018-07-10)
+------------------
+
+- Implement ScopeManager for in-process propagation.
+- Added a set of default ScopeManager implementations.
+- Added testbed/ for testing API changes.
+- Added MockTracer for instrumentation testing.
+
+
+1.3.0 (2018-01-14)
+------------------
+
+- Added sphinx-generated documentation.
+- Remove 'futures' from install_requires (#62)
+- Add a harness check for unicode keys and vals (#40)
+- Have the harness try all tag value types (#39)
+
+
+1.2.2 (2016-10-03)
+------------------
+
+- Fix KeyError when checking kwargs for optional values
+
+
+1.2.1 (2016-09-22)
+------------------
+
+- Make Span.log(self, \**kwargs) smarter
+
+
+1.2.0 (2016-09-21)
+------------------
+
+- Add Span.log_kv and deprecate older logging methods
+
+
+1.1.0 (2016-08-06)
+------------------
+
+- Move set/get_baggage back to Span; add SpanContext.baggage
+- Raise exception on unknown format
+
+
+2.0.0.dev3 (2016-07-26)
+-----------------------
+
+- Support SpanContext
+
+
+2.0.0.dev1 (2016-07-12)
+-----------------------
+
+- Rename ChildOf/FollowsFrom to child_of/follows_from
+- Rename span_context to referee in Reference
+- Document expected behavior when referee=None
+
+
+2.0.0.dev0 (2016-07-11)
+-----------------------
+
+- Support SpanContext (and real semvers)
+
+
+1.0rc4 (2016-05-21)
+-------------------
+
+- Add standard tags per http://opentracing.io/data-semantics/
+
+
+1.0rc3 (2016-03-22)
+-------------------
+
+- No changes yet
+
+
+1.0rc3 (2016-03-22)
+-------------------
+
+- Move to simpler carrier formats
+
+
+1.0rc2 (2016-03-11)
+-------------------
+
+- Remove the Injector/Extractor layer
+
+
+1.0rc1 (2016-02-24)
+-------------------
+
+- Upgrade to 1.0 RC specification
+
+
+0.6.3 (2016-01-16)
+------------------
+
+- Rename repository back to opentracing-python
+
+
+0.6.2 (2016-01-15)
+------------------
+
+- Validate chaining of logging calls
+
+
+0.6.1 (2016-01-09)
+------------------
+
+- Fix typo in the attributes API test
+
+
+0.6.0 (2016-01-09)
+------------------
+
+- Change inheritance to match api-go: TraceContextSource extends codecs,
+  Tracer extends TraceContextSource
+- Create API harness
+
+
+0.5.2 (2016-01-08)
+------------------
+
+- Update README and meta.
+
+
+0.5.1 (2016-01-08)
+------------------
+
+- Prepare for PYPI publishing.
+
+
+0.5.0 (2016-01-07)
+------------------
+
+- Remove debug flag
+- Allow passing tags to start methods
+- Add Span.add_tags() method
+
+
+0.4.2 (2016-01-07)
+------------------
+
+- Add SPAN_KIND tag
+
+
+0.4.0 (2016-01-06)
+------------------
+
+- Rename marshal -> encode
+
+
+0.3.1 (2015-12-30)
+------------------
+
+- Fix std context implementation to refer to Trace Attributes instead of metadata
+
+
+0.3.0 (2015-12-29)
+------------------
+
+- Rename trace tags to Trace Attributes. Rename RPC tags to PEER. Add README.
+
+
+0.2.0 (2015-12-28)
+------------------
+
+- Export global `tracer` variable.
+
+
+0.1.4 (2015-12-28)
+------------------
+
+- Rename RPC_SERVICE tag to make it symmetric
+
+
+0.1.3 (2015-12-27)
+------------------
+
+- Allow repeated keys for span tags; add standard tag names for RPC
+
+
+0.1.2 (2015-12-27)
+------------------
+
+- Move creation of child context to TraceContextSource
+
+
+0.1.1 (2015-12-27)
+------------------
+
+- Add log methods
+
+
+0.1.0 (2015-12-27)
+------------------
+
+- Initial public API
+

+ 201 - 0
desktop/core/ext-py/opentracing-2.2.0/LICENSE

@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "{}"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright The OpenTracing Authors
+
+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.

+ 9 - 0
desktop/core/ext-py/opentracing-2.2.0/MANIFEST.in

@@ -0,0 +1,9 @@
+recursive-include opentracing *
+recursive-include example *.py
+recursive-include example *.thrift
+recursive-include tests *.py
+prune testbed
+include *
+global-exclude *.pyc
+graft docs
+prune docs/_build

+ 96 - 0
desktop/core/ext-py/opentracing-2.2.0/Makefile

@@ -0,0 +1,96 @@
+project := opentracing
+
+pytest := PYTHONDONTWRITEBYTECODE=1 py.test --tb short -rxs \
+	--cov-config .coveragerc --cov $(project) tests
+
+html_report := --cov-report=html
+test_args := --cov-report xml --cov-report term-missing
+
+.PHONY: clean-pyc clean-build docs clean testbed
+.DEFAULT_GOAL : help
+
+help:
+	@echo "bootstrap - initialize local environement for development. Requires virtualenv."
+	@echo "clean - remove all build, test, coverage and Python artifacts"
+	@echo "clean-build - remove build artifacts"
+	@echo "clean-pyc - remove Python file artifacts"
+	@echo "clean-test - remove test and coverage artifacts"
+	@echo "lint - check style with flake8"
+	@echo "test - run tests quickly with the default Python"
+	@echo "testbed - run testbed scenarios with the default Python"
+	@echo "coverage - check code coverage quickly with the default Python"
+	@echo "docs - generate Sphinx HTML documentation, including API docs"
+	@echo "release - package and upload a release"
+	@echo "dist - package"
+	@echo "install - install the package to the active Python's site-packages"
+
+check-virtual-env:
+	@echo virtual-env: $${VIRTUAL_ENV?"Please run in virtual-env"}
+
+bootstrap: check-virtual-env
+	pip install -r requirements.txt
+	pip install -r requirements-test.txt
+	python setup.py develop
+
+clean: clean-build clean-pyc clean-test
+
+clean-build:
+	rm -fr build/
+	rm -fr dist/
+	rm -fr .eggs/
+	find . -name '*.egg-info' -exec rm -fr {} +
+	find . -name '*.egg' -exec rm -rf {} +
+
+clean-pyc:
+	find . -name '*.pyc' -exec rm -f {} +
+	find . -name '*.pyo' -exec rm -f {} +
+	find . -name '*~' -exec rm -f {} +
+	find . -name '__pycache__' -exec rm -fr {} +
+
+clean-test:
+	rm -f .coverage
+	rm -f coverage.xml
+	rm -fr htmlcov/
+
+lint:
+	flake8 $(project) tests
+
+test:
+	$(pytest) $(test_args)
+
+testbed:
+	PYTHONDONTWRITEBYTECODE=1 python -m testbed
+
+jenkins:
+	pip install -r requirements.txt
+	pip install -r requirements-test.txt
+	python setup.py develop
+	CLAY_CONFIG=config/test.yaml $(pytest) $(test_args) --junit-xml=jenkins.xml
+
+coverage:
+	coverage run --source $(project) setup.py test
+	coverage report -m
+	coverage html
+	open htmlcov/index.html
+
+docs:
+	pip show -q opentracing || python setup.py develop
+	$(MAKE) -C docs clean
+	$(MAKE) -C docs html
+
+release: clean
+	@echo Please see README
+#	python setup.py sdist upload
+#	python setup.py bdist_wheel upload
+
+dist: clean
+	@echo Please see README
+#	python setup.py sdist
+#	python setup.py bdist_wheel
+#	ls -l dist
+
+install:
+	pip install -r requirements.txt
+	pip install -r requirements-test.txt
+	echo skipping pip install -r requirements-doc.txt
+	python setup.py install

+ 316 - 0
desktop/core/ext-py/opentracing-2.2.0/PKG-INFO

@@ -0,0 +1,316 @@
+Metadata-Version: 2.1
+Name: opentracing
+Version: 2.2.0
+Summary: OpenTracing API for Python. See documentation at http://opentracing.io
+Home-page: https://github.com/opentracing/opentracing-python
+Author: The OpenTracing Authors
+Author-email: opentracing@googlegroups.com
+License: Apache License 2.0
+Description: 
+        OpenTracing API for Python
+        ==========================
+        
+        |GitterChat| |BuildStatus| |PyPI| |ReadTheDocs|
+        
+        This library is a Python platform API for OpenTracing.
+        
+        Required Reading
+        ----------------
+        
+        In order to understand the Python platform API, one must first be familiar with
+        the `OpenTracing project <http://opentracing.io>`_ and
+        `terminology <http://opentracing.io/documentation/pages/spec.html>`_ more
+        specifically.
+        
+        Status
+        ------
+        
+        In the current version, ``opentracing-python`` provides only the API and a
+        basic no-op implementation that can be used by instrumentation libraries to
+        collect and propagate distributed tracing context.
+        
+        Future versions will include a reference implementation utilizing an
+        abstract Recorder interface, as well as a
+        `Zipkin <http://openzipkin.github.io>`_-compatible Tracer.
+        
+        Usage
+        -----
+        
+        The work of instrumentation libraries generally consists of three steps:
+        
+        1. When a service receives a new request (over HTTP or some other protocol),
+           it uses OpenTracing's inject/extract API to continue an active trace, creating a
+           Span object in the process. If the request does not contain an active trace,
+           the service starts a new trace and a new *root* Span.
+        2. The service needs to store the current Span in some request-local storage,
+           (called ``Span`` *activation*) where it can be retrieved from when a child Span must
+           be created, e.g. in case of the service making an RPC to another service.
+        3. When making outbound calls to another service, the current Span must be
+           retrieved from request-local storage, a child span must be created (e.g., by
+           using the ``start_child_span()`` helper), and that child span must be embedded
+           into the outbound request (e.g., using HTTP headers) via OpenTracing's
+           inject/extract API.
+        
+        Below are the code examples for the previously mentioned steps. Implementation
+        of request-local storage needed for step 2 is specific to the service and/or frameworks /
+        instrumentation libraries it is using, exposed as a ``ScopeManager`` child contained
+        as ``Tracer.scope_manager``. See details below.
+        
+        Inbound request
+        ^^^^^^^^^^^^^^^
+        
+        Somewhere in your server's request handler code:
+        
+        .. code-block:: python
+        
+           def handle_request(request):
+               span = before_request(request, opentracing.global_tracer())
+               # store span in some request-local storage using Tracer.scope_manager,
+               # using the returned `Scope` as Context Manager to ensure
+               # `Span` will be cleared and (in this case) `Span.finish()` be called.
+               with tracer.scope_manager.activate(span, True) as scope:
+                   # actual business logic
+                   handle_request_for_real(request)
+        
+        
+           def before_request(request, tracer):
+               span_context = tracer.extract(
+                   format=Format.HTTP_HEADERS,
+                   carrier=request.headers,
+               )
+               span = tracer.start_span(
+                   operation_name=request.operation,
+                   child_of(span_context))
+               span.set_tag('http.url', request.full_url)
+        
+               remote_ip = request.remote_ip
+               if remote_ip:
+                   span.set_tag(tags.PEER_HOST_IPV4, remote_ip)
+        
+               caller_name = request.caller_name
+               if caller_name:
+                   span.set_tag(tags.PEER_SERVICE, caller_name)
+        
+               remote_port = request.remote_port
+               if remote_port:
+                   span.set_tag(tags.PEER_PORT, remote_port)
+        
+               return span
+        
+        Outbound request
+        ----------------
+        
+        Somewhere in your service that's about to make an outgoing call:
+        
+        .. code-block:: python
+        
+           from opentracing import tags
+           from opentracing.propagation import Format
+           from opentracing_instrumentation import request_context
+        
+           # create and serialize a child span and use it as context manager
+           with before_http_request(
+               request=out_request,
+               current_span_extractor=request_context.get_current_span):
+        
+               # actual call
+               return urllib2.urlopen(request)
+        
+        
+           def before_http_request(request, current_span_extractor):
+               op = request.operation
+               parent_span = current_span_extractor()
+               outbound_span = opentracing.global_tracer().start_span(
+                   operation_name=op,
+                   child_of=parent_span
+               )
+        
+               outbound_span.set_tag('http.url', request.full_url)
+               service_name = request.service_name
+               host, port = request.host_port
+               if service_name:
+                   outbound_span.set_tag(tags.PEER_SERVICE, service_name)
+               if host:
+                   outbound_span.set_tag(tags.PEER_HOST_IPV4, host)
+               if port:
+                   outbound_span.set_tag(tags.PEER_PORT, port)
+        
+               http_header_carrier = {}
+               opentracing.global_tracer().inject(
+                   span_context=outbound_span,
+                   format=Format.HTTP_HEADERS,
+                   carrier=http_header_carrier)
+        
+               for key, value in http_header_carrier.iteritems():
+                   request.add_header(key, value)
+        
+               return outbound_span
+        
+        Scope and within-process propagation
+        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+        
+        For getting/setting the current active ``Span`` in the used request-local storage,
+        OpenTracing requires that every ``Tracer`` contains a ``ScopeManager`` that grants
+        access to the active ``Span`` through a ``Scope``. Any ``Span`` may be transferred to
+        another task or thread, but not ``Scope``.
+        
+        .. code-block:: python
+        
+               # Access to the active span is straightforward.
+               scope = tracer.scope_manager.active()
+               if scope is not None:
+                   scope.span.set_tag('...', '...')
+        
+        The common case starts a ``Scope`` that's automatically registered for intra-process
+        propagation via ``ScopeManager``.
+        
+        Note that ``start_active_span('...')`` automatically finishes the span on ``Scope.close()``
+        (``start_active_span('...', finish_on_close=False)`` does not finish it, in contrast).
+        
+        .. code-block:: python
+        
+               # Manual activation of the Span.
+               span = tracer.start_span(operation_name='someWork')
+               with tracer.scope_manager.activate(span, True) as scope:
+                   # Do things.
+        
+               # Automatic activation of the Span.
+               # finish_on_close is a required parameter.
+               with tracer.start_active_span('someWork', finish_on_close=True) as scope:
+                   # Do things.
+        
+               # Handling done through a try construct:
+               span = tracer.start_span(operation_name='someWork')
+               scope = tracer.scope_manager.activate(span, True)
+               try:
+                   # Do things.
+               except Exception as e:
+                   scope.set_tag('error', '...')
+               finally:
+                   scope.finish()
+        
+        **If there is a Scope, it will act as the parent to any newly started Span** unless
+        the programmer passes ``ignore_active_span=True`` at ``start_span()``/``start_active_span()``
+        time or specified parent context explicitly:
+        
+        .. code-block:: python
+        
+               scope = tracer.start_active_span('someWork', ignore_active_span=True)
+        
+        Each service/framework ought to provide a specific ``ScopeManager`` implementation
+        that relies on their own request-local storage (thread-local storage, or coroutine-based storage
+        for asynchronous frameworks, for example).
+        
+        Scope managers
+        ^^^^^^^^^^^^^^
+        
+        This project includes a set of ``ScopeManager`` implementations under the ``opentracing.scope_managers`` submodule, which can be imported on demand:
+        
+        .. code-block:: python
+        
+           from opentracing.scope_managers import ThreadLocalScopeManager
+        
+        There exist implementations for ``thread-local`` (the default instance of the submodule ``opentracing.scope_managers``), ``gevent``, ``Tornado`` and ``asyncio``:
+        
+        .. code-block:: python
+        
+           from opentracing.scope_managers.gevent import GeventScopeManager # requires gevent
+           from opentracing.scope_managers.tornado import TornadoScopeManager # requires tornado<6
+           from opentracing.scope_managers.asyncio import AsyncioScopeManager # requires Python 3.4 or newer.
+        
+        Development
+        -----------
+        
+        Tests
+        ^^^^^
+        
+        .. code-block:: sh
+        
+           virtualenv env
+           . ./env/bin/activate
+           make bootstrap
+           make test
+        
+        You can use `tox <https://tox.readthedocs.io>`_ to run tests as well.
+        
+        .. code-block:: sh
+        
+            tox
+        
+        Testbed suite
+        ^^^^^^^^^^^^^
+        
+        A testbed suite designed to test API changes and experimental features is included under the *testbed* directory. For more information, see the `Testbed README <testbed/README.md>`_.
+        
+        Instrumentation Tests
+        ---------------------
+        
+        This project has a working design of interfaces for the OpenTracing API. There is a MockTracer to
+        facilitate unit-testing of OpenTracing Python instrumentation.
+        
+        .. code-block:: python
+        
+               from opentracing.mocktracer import MockTracer
+        
+               tracer = MockTracer()
+               with tracer.start_span('someWork') as span:
+                   pass
+        
+               spans = tracer.finished_spans()
+               someWorkSpan = spans[0]
+        
+        
+        Documentation
+        ^^^^^^^^^^^^^
+        
+        .. code-block:: sh
+        
+           virtualenv env
+           . ./env/bin/activate
+           make bootstrap
+           make docs
+        
+        The documentation is written to *docs/_build/html*.
+        
+        LICENSE
+        ^^^^^^^
+        
+        `Apache 2.0 License <./LICENSE>`__.
+        
+        Releases
+        ^^^^^^^^
+        
+        Before new release, add a summary of changes since last version to CHANGELOG.rst
+        
+        .. code-block:: sh
+        
+           pip install zest.releaser[recommended]
+           prerelease
+           release
+           git push origin master --follow-tags
+           python setup.py sdist upload -r pypi upload_docs -r pypi
+           postrelease
+           git push
+        
+        .. |GitterChat| image:: http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg
+           :target: https://gitter.im/opentracing/public
+        .. |BuildStatus| image:: https://travis-ci.org/opentracing/opentracing-python.svg?branch-master
+           :target: https://travis-ci.org/opentracing/opentracing-python
+        .. |PyPI| image:: https://badge.fury.io/py/opentracing.svg
+           :target: https://badge.fury.io/py/opentracing
+        .. |ReadTheDocs| image:: http://readthedocs.org/projects/opentracing-python/badge/?version=latest
+           :target: https://opentracing-python.readthedocs.io/en/latest/?badge=latest
+           :alt: Documentation Status
+        
+Keywords: opentracing
+Platform: any
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Provides-Extra: tests

+ 294 - 0
desktop/core/ext-py/opentracing-2.2.0/README.rst

@@ -0,0 +1,294 @@
+OpenTracing API for Python
+==========================
+
+|GitterChat| |BuildStatus| |PyPI| |ReadTheDocs|
+
+This library is a Python platform API for OpenTracing.
+
+Required Reading
+----------------
+
+In order to understand the Python platform API, one must first be familiar with
+the `OpenTracing project <http://opentracing.io>`_ and
+`terminology <http://opentracing.io/documentation/pages/spec.html>`_ more
+specifically.
+
+Status
+------
+
+In the current version, ``opentracing-python`` provides only the API and a
+basic no-op implementation that can be used by instrumentation libraries to
+collect and propagate distributed tracing context.
+
+Future versions will include a reference implementation utilizing an
+abstract Recorder interface, as well as a
+`Zipkin <http://openzipkin.github.io>`_-compatible Tracer.
+
+Usage
+-----
+
+The work of instrumentation libraries generally consists of three steps:
+
+1. When a service receives a new request (over HTTP or some other protocol),
+   it uses OpenTracing's inject/extract API to continue an active trace, creating a
+   Span object in the process. If the request does not contain an active trace,
+   the service starts a new trace and a new *root* Span.
+2. The service needs to store the current Span in some request-local storage,
+   (called ``Span`` *activation*) where it can be retrieved from when a child Span must
+   be created, e.g. in case of the service making an RPC to another service.
+3. When making outbound calls to another service, the current Span must be
+   retrieved from request-local storage, a child span must be created (e.g., by
+   using the ``start_child_span()`` helper), and that child span must be embedded
+   into the outbound request (e.g., using HTTP headers) via OpenTracing's
+   inject/extract API.
+
+Below are the code examples for the previously mentioned steps. Implementation
+of request-local storage needed for step 2 is specific to the service and/or frameworks /
+instrumentation libraries it is using, exposed as a ``ScopeManager`` child contained
+as ``Tracer.scope_manager``. See details below.
+
+Inbound request
+^^^^^^^^^^^^^^^
+
+Somewhere in your server's request handler code:
+
+.. code-block:: python
+
+   def handle_request(request):
+       span = before_request(request, opentracing.global_tracer())
+       # store span in some request-local storage using Tracer.scope_manager,
+       # using the returned `Scope` as Context Manager to ensure
+       # `Span` will be cleared and (in this case) `Span.finish()` be called.
+       with tracer.scope_manager.activate(span, True) as scope:
+           # actual business logic
+           handle_request_for_real(request)
+
+
+   def before_request(request, tracer):
+       span_context = tracer.extract(
+           format=Format.HTTP_HEADERS,
+           carrier=request.headers,
+       )
+       span = tracer.start_span(
+           operation_name=request.operation,
+           child_of(span_context))
+       span.set_tag('http.url', request.full_url)
+
+       remote_ip = request.remote_ip
+       if remote_ip:
+           span.set_tag(tags.PEER_HOST_IPV4, remote_ip)
+
+       caller_name = request.caller_name
+       if caller_name:
+           span.set_tag(tags.PEER_SERVICE, caller_name)
+
+       remote_port = request.remote_port
+       if remote_port:
+           span.set_tag(tags.PEER_PORT, remote_port)
+
+       return span
+
+Outbound request
+----------------
+
+Somewhere in your service that's about to make an outgoing call:
+
+.. code-block:: python
+
+   from opentracing import tags
+   from opentracing.propagation import Format
+   from opentracing_instrumentation import request_context
+
+   # create and serialize a child span and use it as context manager
+   with before_http_request(
+       request=out_request,
+       current_span_extractor=request_context.get_current_span):
+
+       # actual call
+       return urllib2.urlopen(request)
+
+
+   def before_http_request(request, current_span_extractor):
+       op = request.operation
+       parent_span = current_span_extractor()
+       outbound_span = opentracing.global_tracer().start_span(
+           operation_name=op,
+           child_of=parent_span
+       )
+
+       outbound_span.set_tag('http.url', request.full_url)
+       service_name = request.service_name
+       host, port = request.host_port
+       if service_name:
+           outbound_span.set_tag(tags.PEER_SERVICE, service_name)
+       if host:
+           outbound_span.set_tag(tags.PEER_HOST_IPV4, host)
+       if port:
+           outbound_span.set_tag(tags.PEER_PORT, port)
+
+       http_header_carrier = {}
+       opentracing.global_tracer().inject(
+           span_context=outbound_span,
+           format=Format.HTTP_HEADERS,
+           carrier=http_header_carrier)
+
+       for key, value in http_header_carrier.iteritems():
+           request.add_header(key, value)
+
+       return outbound_span
+
+Scope and within-process propagation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For getting/setting the current active ``Span`` in the used request-local storage,
+OpenTracing requires that every ``Tracer`` contains a ``ScopeManager`` that grants
+access to the active ``Span`` through a ``Scope``. Any ``Span`` may be transferred to
+another task or thread, but not ``Scope``.
+
+.. code-block:: python
+
+       # Access to the active span is straightforward.
+       scope = tracer.scope_manager.active()
+       if scope is not None:
+           scope.span.set_tag('...', '...')
+
+The common case starts a ``Scope`` that's automatically registered for intra-process
+propagation via ``ScopeManager``.
+
+Note that ``start_active_span('...')`` automatically finishes the span on ``Scope.close()``
+(``start_active_span('...', finish_on_close=False)`` does not finish it, in contrast).
+
+.. code-block:: python
+
+       # Manual activation of the Span.
+       span = tracer.start_span(operation_name='someWork')
+       with tracer.scope_manager.activate(span, True) as scope:
+           # Do things.
+
+       # Automatic activation of the Span.
+       # finish_on_close is a required parameter.
+       with tracer.start_active_span('someWork', finish_on_close=True) as scope:
+           # Do things.
+
+       # Handling done through a try construct:
+       span = tracer.start_span(operation_name='someWork')
+       scope = tracer.scope_manager.activate(span, True)
+       try:
+           # Do things.
+       except Exception as e:
+           scope.set_tag('error', '...')
+       finally:
+           scope.finish()
+
+**If there is a Scope, it will act as the parent to any newly started Span** unless
+the programmer passes ``ignore_active_span=True`` at ``start_span()``/``start_active_span()``
+time or specified parent context explicitly:
+
+.. code-block:: python
+
+       scope = tracer.start_active_span('someWork', ignore_active_span=True)
+
+Each service/framework ought to provide a specific ``ScopeManager`` implementation
+that relies on their own request-local storage (thread-local storage, or coroutine-based storage
+for asynchronous frameworks, for example).
+
+Scope managers
+^^^^^^^^^^^^^^
+
+This project includes a set of ``ScopeManager`` implementations under the ``opentracing.scope_managers`` submodule, which can be imported on demand:
+
+.. code-block:: python
+
+   from opentracing.scope_managers import ThreadLocalScopeManager
+
+There exist implementations for ``thread-local`` (the default instance of the submodule ``opentracing.scope_managers``), ``gevent``, ``Tornado`` and ``asyncio``:
+
+.. code-block:: python
+
+   from opentracing.scope_managers.gevent import GeventScopeManager # requires gevent
+   from opentracing.scope_managers.tornado import TornadoScopeManager # requires tornado<6
+   from opentracing.scope_managers.asyncio import AsyncioScopeManager # requires Python 3.4 or newer.
+
+Development
+-----------
+
+Tests
+^^^^^
+
+.. code-block:: sh
+
+   virtualenv env
+   . ./env/bin/activate
+   make bootstrap
+   make test
+
+You can use `tox <https://tox.readthedocs.io>`_ to run tests as well.
+
+.. code-block:: sh
+
+    tox
+
+Testbed suite
+^^^^^^^^^^^^^
+
+A testbed suite designed to test API changes and experimental features is included under the *testbed* directory. For more information, see the `Testbed README <testbed/README.md>`_.
+
+Instrumentation Tests
+---------------------
+
+This project has a working design of interfaces for the OpenTracing API. There is a MockTracer to
+facilitate unit-testing of OpenTracing Python instrumentation.
+
+.. code-block:: python
+
+       from opentracing.mocktracer import MockTracer
+
+       tracer = MockTracer()
+       with tracer.start_span('someWork') as span:
+           pass
+
+       spans = tracer.finished_spans()
+       someWorkSpan = spans[0]
+
+
+Documentation
+^^^^^^^^^^^^^
+
+.. code-block:: sh
+
+   virtualenv env
+   . ./env/bin/activate
+   make bootstrap
+   make docs
+
+The documentation is written to *docs/_build/html*.
+
+LICENSE
+^^^^^^^
+
+`Apache 2.0 License <./LICENSE>`__.
+
+Releases
+^^^^^^^^
+
+Before new release, add a summary of changes since last version to CHANGELOG.rst
+
+.. code-block:: sh
+
+   pip install zest.releaser[recommended]
+   prerelease
+   release
+   git push origin master --follow-tags
+   python setup.py sdist upload -r pypi upload_docs -r pypi
+   postrelease
+   git push
+
+.. |GitterChat| image:: http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg
+   :target: https://gitter.im/opentracing/public
+.. |BuildStatus| image:: https://travis-ci.org/opentracing/opentracing-python.svg?branch-master
+   :target: https://travis-ci.org/opentracing/opentracing-python
+.. |PyPI| image:: https://badge.fury.io/py/opentracing.svg
+   :target: https://badge.fury.io/py/opentracing
+.. |ReadTheDocs| image:: http://readthedocs.org/projects/opentracing-python/badge/?version=latest
+   :target: https://opentracing-python.readthedocs.io/en/latest/?badge=latest
+   :alt: Documentation Status

+ 20 - 0
desktop/core/ext-py/opentracing-2.2.0/docs/Makefile

@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+SPHINXPROJ    = opentracing-python
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

+ 72 - 0
desktop/core/ext-py/opentracing-2.2.0/docs/api.rst

@@ -0,0 +1,72 @@
+Python API
+==========
+
+Classes
+-------
+.. autoclass:: opentracing.Span
+   :members:
+
+.. autoclass:: opentracing.SpanContext
+   :members:
+
+.. autoclass:: opentracing.Scope
+   :members:
+
+.. autoclass:: opentracing.ScopeManager
+   :members:
+
+.. autoclass:: opentracing.Tracer
+   :members:
+
+.. autoclass:: opentracing.ReferenceType
+   :members:
+
+.. autoclass:: opentracing.Reference
+   :members:
+
+.. autoclass:: opentracing.Format
+   :members:
+
+Utility Functions
+-----------------
+.. autofunction:: opentracing.global_tracer
+
+.. autofunction:: opentracing.set_global_tracer
+
+.. autofunction:: opentracing.start_child_span
+
+.. autofunction:: opentracing.child_of
+
+.. autofunction:: opentracing.follows_from
+
+Exceptions
+----------
+.. autoclass:: opentracing.InvalidCarrierException
+   :members:
+
+.. autoclass:: opentracing.SpanContextCorruptedException
+   :members:
+
+.. autoclass:: opentracing.UnsupportedFormatException
+   :members:
+   
+MockTracer
+--------------
+.. autoclass:: opentracing.mocktracer.MockTracer
+   :members:
+
+Scope managers
+--------------
+.. autoclass:: opentracing.scope_managers.ThreadLocalScopeManager
+   :members:
+
+.. autoclass:: opentracing.scope_managers.gevent.GeventScopeManager
+   :members:
+
+.. autoclass:: opentracing.scope_managers.tornado.TornadoScopeManager
+   :members:
+
+.. autofunction:: opentracing.scope_managers.tornado.tracer_stack_context
+
+.. autoclass:: opentracing.scope_managers.asyncio.AsyncioScopeManager
+   :members:

+ 1 - 0
desktop/core/ext-py/opentracing-2.2.0/docs/changelog.rst

@@ -0,0 +1 @@
+.. include:: ../CHANGELOG.rst

+ 25 - 0
desktop/core/ext-py/opentracing-2.2.0/docs/conf.py

@@ -0,0 +1,25 @@
+import sphinx_rtd_theme
+
+
+project = 'opentracing-python'
+copyright = 'The OpenTracing Authors'
+author = 'The OpenTracing Authors'
+version = '1.2.3.dev0'
+release = '1.2'
+
+needs_sphinx = '1.0'
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']
+templates_path = []
+source_suffix = '.rst'
+source_encoding = 'utf-8'
+master_doc = 'index'
+
+html_theme = 'sphinx_rtd_theme'
+html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+html_static_path = []
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+intersphinx_mapping = {
+    'python': ('https://docs.python.org/', None),
+}
+

+ 7 - 0
desktop/core/ext-py/opentracing-2.2.0/docs/index.rst

@@ -0,0 +1,7 @@
+.. include:: ../README.rst
+
+.. toctree::
+   :hidden:
+
+   api
+   changelog

+ 36 - 0
desktop/core/ext-py/opentracing-2.2.0/docs/make.bat

@@ -0,0 +1,36 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+set SPHINXPROJ=opentracing-python
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.http://sphinx-doc.org/
+	exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd

+ 79 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/__init__.py

@@ -0,0 +1,79 @@
+# Copyright The OpenTracing Authors
+# Copyright Uber Technologies, Inc
+#
+# 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.
+
+from __future__ import absolute_import
+from .span import Span  # noqa
+from .span import SpanContext  # noqa
+from .scope import Scope  # noqa
+from .scope_manager import ScopeManager  # noqa
+from .tracer import child_of  # noqa
+from .tracer import follows_from  # noqa
+from .tracer import Reference  # noqa
+from .tracer import ReferenceType  # noqa
+from .tracer import Tracer  # noqa
+from .tracer import start_child_span  # noqa
+from .propagation import Format  # noqa
+from .propagation import InvalidCarrierException  # noqa
+from .propagation import SpanContextCorruptedException  # noqa
+from .propagation import UnsupportedFormatException  # noqa
+
+# Global variable that should be initialized to an instance of real tracer.
+# Note: it should be accessed via 'opentracing.tracer', not via
+# 'from opentracing import tracer', the latter seems to take a copy.
+# DEPRECATED, use global_tracer() and set_global_tracer() instead.
+tracer = Tracer()
+is_tracer_registered = False
+
+
+def global_tracer():
+    """Returns the global tracer.
+    The default value is an instance of :class:`opentracing.Tracer`
+
+    :rtype: :class:`Tracer`
+    :return: The global tracer instance.
+    """
+    return tracer
+
+
+def set_global_tracer(value):
+    """Sets the global tracer.
+    It is an error to pass ``None``.
+
+    :param value: the :class:`Tracer` used as global instance.
+    :type value: :class:`Tracer`
+    """
+    if value is None:
+        raise ValueError('The global Tracer tracer cannot be None')
+
+    global tracer, is_tracer_registered
+    tracer = value
+    is_tracer_registered = True
+
+
+def is_global_tracer_registered():
+    """Indicates if a global tracer has been registered.
+
+    :rtype: :value:bool
+    :return: True if a global tracer has been registered, otherwise False.
+    """
+    return is_tracer_registered
+
+
+def _reset_global_tracer():
+    """Reset any previously registered tracer. Intended for internal usage."""
+
+    global tracer, is_tracer_registered
+    tracer = Tracer()
+    is_tracer_registered = False

+ 0 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/ext/__init__.py


+ 20 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/ext/tags.py

@@ -0,0 +1,20 @@
+# Copyright The OpenTracing Authors
+# Copyright Uber Technologies, Inc
+#
+# 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.
+
+from __future__ import absolute_import
+
+# DEPRECATED module, use opentracing.tags instead
+
+from ..tags import *  # noqa

+ 0 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/harness/__init__.py


+ 325 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/harness/api_check.py

@@ -0,0 +1,325 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+
+import mock
+import time
+import pytest
+
+import opentracing
+from opentracing import Format
+
+
+class APICompatibilityCheckMixin(object):
+    """
+    A mixin class for validation that a given tracer implementation
+    satisfies the requirements of the OpenTracing API.
+    """
+
+    def tracer(self):
+        raise NotImplementedError('Subclass must implement tracer()')
+
+    def check_baggage_values(self):
+        """If true, the test will validate Baggage items by storing and
+        retrieving them from the trace context. If false, it will only attempt
+        to store and retrieve the Baggage items to check the API compliance,
+        but not actually validate stored values. The latter mode is only
+        useful for no-op tracer.
+        """
+        return True
+
+    def check_scope_manager(self):
+        """If true, the test suite will validate the `ScopeManager` propagation
+        to ensure correct parenting. If false, it will only use the API without
+        asserting. The latter mode is only useful for no-op tracer.
+        """
+        return True
+
+    def is_parent(self, parent, span):
+        """Utility method that must be defined by Tracer implementers to define
+        how the test suite can check when a `Span` is a parent of another one.
+        It depends by the underlying implementation that is not part of the
+        OpenTracing API.
+        """
+        return False
+
+    def test_active_span(self):
+        tracer = self.tracer()
+        span = tracer.start_span('Fry')
+
+        if self.check_scope_manager():
+            assert tracer.active_span is None
+            assert tracer.scope_manager.active is None
+
+            with tracer.scope_manager.activate(span, True):
+                assert tracer.active_span is span
+                assert tracer.scope_manager.active.span is span
+
+    def test_start_active_span(self):
+        # the first usage returns a `Scope` that wraps a root `Span`
+        tracer = self.tracer()
+        with tracer.start_active_span('Fry') as scope:
+            assert scope.span is not None
+            if self.check_scope_manager():
+                assert self.is_parent(None, scope.span)
+
+    def test_start_active_span_parent(self):
+        # ensure the `ScopeManager` provides the right parenting
+        tracer = self.tracer()
+        with tracer.start_active_span('Fry') as parent:
+            with tracer.start_active_span('Farnsworth') as child:
+                if self.check_scope_manager():
+                    assert self.is_parent(parent.span, child.span)
+
+    def test_start_active_span_ignore_active_span(self):
+        # ensure the `ScopeManager` ignores the active `Scope`
+        # if the flag is set
+        tracer = self.tracer()
+        with tracer.start_active_span('Fry') as parent:
+            with tracer.start_active_span('Farnsworth',
+                                          ignore_active_span=True) as child:
+                if self.check_scope_manager():
+                    assert not self.is_parent(parent.span, child.span)
+
+    def test_start_active_span_not_finish_on_close(self):
+        # ensure a `Span` is finished when the `Scope` close
+        tracer = self.tracer()
+        scope = tracer.start_active_span('Fry', finish_on_close=False)
+        with mock.patch.object(scope.span, 'finish') as finish:
+            scope.close()
+
+        assert finish.call_count == 0
+
+    def test_start_active_span_finish_on_close(self):
+        # a `Span` is not finished when the flag is set
+        tracer = self.tracer()
+        scope = tracer.start_active_span('Fry', finish_on_close=True)
+        with mock.patch.object(scope.span, 'finish') as finish:
+            scope.close()
+
+        if self.check_scope_manager():
+            assert finish.call_count == 1
+
+    def test_start_active_span_default_finish_on_close(self):
+        # a `Span` is finished when no flag is set
+        tracer = self.tracer()
+        scope = tracer.start_active_span('Fry')
+        with mock.patch.object(scope.span, 'finish') as finish:
+            scope.close()
+
+        if self.check_scope_manager():
+            assert finish.call_count == 1
+
+    def test_start_span(self):
+        tracer = self.tracer()
+        span = tracer.start_span(operation_name='Fry')
+        span.finish()
+        with tracer.start_span(operation_name='Fry',
+                               tags={'birthday': 'August 14 1974'}) as span:
+            span.log_event('birthplace',
+                           payload={'hospital': 'Brooklyn Pre-Med Hospital',
+                                    'city': 'Old New York'})
+
+    def test_start_span_propagation(self):
+        # `start_span` must inherit the current active `Scope` span
+        tracer = self.tracer()
+        with tracer.start_active_span('Fry') as parent:
+            with tracer.start_span(operation_name='Farnsworth') as child:
+                if self.check_scope_manager():
+                    assert self.is_parent(parent.span, child)
+
+    def test_start_span_propagation_ignore_active_span(self):
+        # `start_span` doesn't inherit the current active `Scope` span
+        # if the flag is set
+        tracer = self.tracer()
+        with tracer.start_active_span('Fry') as parent:
+            with tracer.start_span(operation_name='Farnsworth',
+                                   ignore_active_span=True) as child:
+                if self.check_scope_manager():
+                    assert not self.is_parent(parent.span, child)
+
+    def test_start_span_with_parent(self):
+        tracer = self.tracer()
+        parent_span = tracer.start_span(operation_name='parent')
+        assert parent_span is not None
+        span = tracer.start_span(
+            operation_name='Leela',
+            child_of=parent_span)
+        span.finish()
+        span = tracer.start_span(
+            operation_name='Leela',
+            references=[opentracing.follows_from(parent_span.context)],
+            tags={'birthplace': 'sewers'})
+        span.finish()
+        parent_span.finish()
+
+    def test_start_child_span(self):
+        tracer = self.tracer()
+        parent_span = tracer.start_span(operation_name='parent')
+        assert parent_span is not None
+        child_span = opentracing.start_child_span(
+            parent_span, operation_name='Leela')
+        child_span.finish()
+        parent_span.finish()
+
+    def test_set_operation_name(self):
+        span = self.tracer().start_span().set_operation_name('Farnsworth')
+        span.finish()
+
+    def test_span_as_context_manager(self):
+        tracer = self.tracer()
+        finish = {'called': False}
+
+        def mock_finish(*_):
+            finish['called'] = True
+
+        with tracer.start_span(operation_name='antiquing') as span:
+            setattr(span, 'finish', mock_finish)
+        assert finish['called'] is True
+
+        # now try with exception
+        finish['called'] = False
+        try:
+            with tracer.start_span(operation_name='antiquing') as span:
+                setattr(span, 'finish', mock_finish)
+                raise ValueError()
+        except ValueError:
+            assert finish['called'] is True
+        else:
+            raise AssertionError('Expected ValueError')  # pragma: no cover
+
+    def test_span_tag_value_types(self):
+        with self.tracer().start_span(operation_name='ManyTypes') as span:
+            span. \
+                set_tag('an_int', 9). \
+                set_tag('a_bool', True). \
+                set_tag('a_string', 'aoeuidhtns')
+
+    def test_span_tags_with_chaining(self):
+        span = self.tracer().start_span(operation_name='Farnsworth')
+        span. \
+            set_tag('birthday', '9 April, 2841'). \
+            set_tag('loves', 'different lengths of wires')
+        span. \
+            set_tag('unicode_val', u'non-ascii: \u200b'). \
+            set_tag(u'unicode_key_\u200b', 'ascii val')
+        span.finish()
+
+    def test_span_logs(self):
+        span = self.tracer().start_span(operation_name='Fry')
+
+        # Newer API
+        span.log_kv(
+            {'frozen.year': 1999, 'frozen.place': 'Cryogenics Labs'})
+        span.log_kv(
+            {'defrosted.year': 2999, 'defrosted.place': 'Cryogenics Labs'},
+            time.time())
+
+        # Older API
+        span.\
+            log_event('frozen', {'year': 1999, 'place': 'Cryogenics Labs'}). \
+            log_event('defrosted', {'year': 2999}). \
+            log_event('became his own grandfather', 1947)
+        span.\
+            log(event='frozen'). \
+            log(payload={'year': 1999}). \
+            log(timestamp=time.time(),
+                event='frozen',
+                payload={'year': 1999}). \
+            log(timestamp=time.time(),
+                event='unfrozen',
+                payload={'year': 2999})
+
+    def test_span_baggage(self):
+        with self.tracer().start_span(operation_name='Fry') as span:
+            assert span.context.baggage == {}
+            span_ref = span.set_baggage_item('Kiff-loves', 'Amy')
+            assert span_ref is span
+            val = span.get_baggage_item('Kiff-loves')
+            if self.check_baggage_values():
+                assert 'Amy' == val
+            pass
+
+    def test_context_baggage(self):
+        with self.tracer().start_span(operation_name='Fry') as span:
+            assert span.context.baggage == {}
+            span.set_baggage_item('Kiff-loves', 'Amy')
+            if self.check_baggage_values():
+                assert span.context.baggage == {'Kiff-loves': 'Amy'}
+            pass
+
+    def test_text_propagation(self):
+        with self.tracer().start_span(operation_name='Bender') as span:
+            text_carrier = {}
+            self.tracer().inject(
+                span_context=span.context,
+                format=opentracing.Format.TEXT_MAP,
+                carrier=text_carrier)
+            extracted_ctx = self.tracer().extract(
+                format=opentracing.Format.TEXT_MAP,
+                carrier=text_carrier)
+            assert extracted_ctx.baggage == {}
+
+    def test_binary_propagation(self):
+        with self.tracer().start_span(operation_name='Bender') as span:
+            bin_carrier = bytearray()
+            self.tracer().inject(
+                span_context=span.context,
+                format=opentracing.Format.BINARY,
+                carrier=bin_carrier)
+            extracted_ctx = self.tracer().extract(
+                format=opentracing.Format.BINARY,
+                carrier=bin_carrier)
+            assert extracted_ctx.baggage == {}
+
+    def test_mandatory_formats(self):
+        formats = [
+            (Format.TEXT_MAP, {}),
+            (Format.HTTP_HEADERS, {}),
+            (Format.BINARY, bytearray()),
+        ]
+        with self.tracer().start_span(operation_name='Bender') as span:
+            for fmt, carrier in formats:
+                # expecting no exceptions
+                span.tracer.inject(span.context, fmt, carrier)
+                span.tracer.extract(fmt, carrier)
+
+    def test_unknown_format(self):
+        custom_format = 'kiss my shiny metal ...'
+        with self.tracer().start_span(operation_name='Bender') as span:
+            with pytest.raises(opentracing.UnsupportedFormatException):
+                span.tracer.inject(span.context, custom_format, {})
+            with pytest.raises(opentracing.UnsupportedFormatException):
+                span.tracer.extract(custom_format, {})
+
+    def test_tracer_start_active_span_scope(self):
+        # the Tracer ScopeManager should store the active Scope
+        tracer = self.tracer()
+        scope = tracer.start_active_span('Fry')
+
+        if self.check_scope_manager():
+            assert tracer.scope_manager.active == scope
+
+        scope.close()
+
+    def test_tracer_start_span_scope(self):
+        # the Tracer ScopeManager should not store the new Span
+        tracer = self.tracer()
+        span = tracer.start_span(operation_name='Fry')
+
+        if self.check_scope_manager():
+            assert tracer.scope_manager.active is None
+
+        span.finish()

+ 160 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/harness/scope_check.py

@@ -0,0 +1,160 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+from __future__ import absolute_import
+
+import mock
+
+from opentracing.span import Span
+
+
+class ScopeCompatibilityCheckMixin(object):
+    """
+    A mixin class for validation that a given scope manager implementation
+    satisfies the requirements of the OpenTracing API.
+    """
+
+    def scope_manager(self):
+        raise NotImplementedError('Subclass must implement scope_manager()')
+
+    def run_test(self, test_fn):
+        """
+        Utility method that can be optionally defined by ScopeManager
+        implementers to run the passed test_fn() function
+        in a given environment, such as a coroutine or greenlet.
+        By default, it simply runs the passed test_fn() function
+        in the current thread.
+        """
+
+        test_fn()
+
+    def test_missing_active_external(self):
+        # test that 'active' does not fail outside the run_test()
+        # implementation (greenlet or coroutine).
+        scope_manager = self.scope_manager()
+        assert scope_manager.active is None
+
+    def test_missing_active(self):
+        def fn():
+            scope_manager = self.scope_manager()
+            assert scope_manager.active is None
+
+        self.run_test(fn)
+
+    def test_activate(self):
+        def fn():
+            scope_manager = self.scope_manager()
+            span = mock.MagicMock(spec=Span)
+
+            scope = scope_manager.activate(span, False)
+            assert scope is not None
+            assert scope_manager.active is scope
+
+            scope.close()
+            assert span.finish.call_count == 0
+            assert scope_manager.active is None
+
+        self.run_test(fn)
+
+    def test_activate_external(self):
+        # test that activate() does not fail outside the run_test()
+        # implementation (greenlet or corotuine).
+        scope_manager = self.scope_manager()
+        span = mock.MagicMock(spec=Span)
+
+        scope = scope_manager.activate(span, False)
+        assert scope is not None
+        assert scope_manager.active is scope
+
+        scope.close()
+        assert span.finish.call_count == 0
+        assert scope_manager.active is None
+
+    def test_activate_finish_on_close(self):
+        def fn():
+            scope_manager = self.scope_manager()
+            span = mock.MagicMock(spec=Span)
+
+            scope = scope_manager.activate(span, True)
+            assert scope is not None
+            assert scope_manager.active is scope
+
+            scope.close()
+            assert span.finish.call_count == 1
+            assert scope_manager.active is None
+
+        self.run_test(fn)
+
+    def test_activate_nested(self):
+        def fn():
+            # when a Scope is closed, the previous one must be re-activated.
+            scope_manager = self.scope_manager()
+            parent_span = mock.MagicMock(spec=Span)
+            child_span = mock.MagicMock(spec=Span)
+
+            with scope_manager.activate(parent_span, True) as parent:
+                assert parent is not None
+                assert scope_manager.active is parent
+
+                with scope_manager.activate(child_span, True) as child:
+                    assert child is not None
+                    assert scope_manager.active is child
+
+                assert scope_manager.active is parent
+
+            assert parent_span.finish.call_count == 1
+            assert child_span.finish.call_count == 1
+
+            assert scope_manager.active is None
+
+        self.run_test(fn)
+
+    def test_activate_finish_on_close_nested(self):
+        def fn():
+            # finish_on_close must be correctly handled
+            scope_manager = self.scope_manager()
+            parent_span = mock.MagicMock(spec=Span)
+            child_span = mock.MagicMock(spec=Span)
+
+            parent = scope_manager.activate(parent_span, False)
+            with scope_manager.activate(child_span, True):
+                pass
+            parent.close()
+
+            assert parent_span.finish.call_count == 0
+            assert child_span.finish.call_count == 1
+            assert scope_manager.active is None
+
+        self.run_test(fn)
+
+    def test_close_wrong_order(self):
+        def fn():
+            # only the active `Scope` can be closed
+            scope_manager = self.scope_manager()
+            parent_span = mock.MagicMock(spec=Span)
+            child_span = mock.MagicMock(spec=Span)
+
+            parent = scope_manager.activate(parent_span, True)
+            child = scope_manager.activate(child_span, True)
+            parent.close()
+
+            assert parent_span.finish.call_count == 0
+            assert scope_manager.active == child
+
+        self.run_test(fn)

+ 52 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/logs.py

@@ -0,0 +1,52 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+
+# The following log fields are described in greater detail at the
+# following url:
+# https://github.com/opentracing/specification/blob/master/semantic_conventions.md
+
+# ---------------------------------------------------------------------------
+# The type or "kind" of an error (only for event="error" logs). E.g.,
+# "Exception", "OSError"
+# ---------------------------------------------------------------------------
+ERROR_KIND = 'error.kind'
+
+# ---------------------------------------------------------------------------
+# The actual Exception/Error object instance itself. E.g., A python
+# exceptions.NameError instance
+# ---------------------------------------------------------------------------
+ERROR_OBJECT = 'error.object'
+
+# ---------------------------------------------------------------------------
+# A stable identifier for some notable moment in the lifetime of a Span.
+# For instance, a mutex lock acquisition or release or the sorts of lifetime
+# events in a browser page load described in the Performance.timing
+# specification. E.g., from Zipkin, "cs", "sr", "ss", or "cr". Or, more
+# generally, "initialized" or "timed out". For errors, "error"
+# ---------------------------------------------------------------------------
+EVENT = 'event'
+
+# ---------------------------------------------------------------------------
+# A concise, human-readable, one-line message explaining the event. E.g.,
+# "Could not connect to backend", "Cache invalidation succeeded"
+# ---------------------------------------------------------------------------
+MESSAGE = 'message'
+
+# ---------------------------------------------------------------------------
+# A stack trace in platform-conventional format; may or may not pertain to
+# an error.
+# ---------------------------------------------------------------------------
+STACK = 'stack'

+ 24 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/__init__.py

@@ -0,0 +1,24 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from .tracer import MockTracer  # noqa
+from .propagator import Propagator  # noqa

+ 49 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/binary_propagator.py

@@ -0,0 +1,49 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+import pickle
+
+from .propagator import Propagator
+
+from opentracing import InvalidCarrierException, SpanContextCorruptedException
+
+
+class BinaryPropagator(Propagator):
+    """A MockTracer Propagator for Format.BINARY."""
+
+    def inject(self, span_context, carrier):
+        if type(carrier) is not bytearray:
+            raise InvalidCarrierException()
+
+        data = pickle.dumps(span_context)
+        carrier.extend(data)
+
+    def extract(self, carrier):
+        if type(carrier) is not bytearray:
+            raise InvalidCarrierException()
+
+        try:
+            span_context = pickle.loads(carrier)
+        except (EOFError, pickle.PickleError):
+            raise SpanContextCorruptedException()
+
+        return span_context

+ 51 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/context.py

@@ -0,0 +1,51 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+import opentracing
+
+
+class SpanContext(opentracing.SpanContext):
+    """SpanContext satisfies the opentracing.SpanContext contract.
+
+    trace_id and span_id are uint64's, so their range is [1, 2^64).
+    """
+
+    def __init__(
+            self,
+            trace_id=None,
+            span_id=None,
+            baggage=None):
+        self.trace_id = trace_id
+        self.span_id = span_id
+        self._baggage = baggage or opentracing.SpanContext.EMPTY_BAGGAGE
+
+    @property
+    def baggage(self):
+        return self._baggage
+
+    def with_baggage_item(self, key, value):
+        new_baggage = self._baggage.copy()
+        new_baggage[key] = value
+        return SpanContext(
+            trace_id=self.trace_id,
+            span_id=self.span_id,
+            baggage=new_baggage)

+ 30 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/propagator.py

@@ -0,0 +1,30 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+
+class Propagator(object):
+
+    def inject(self, span_context, carrier):
+        pass
+
+    def extract(self, carrier):
+        pass

+ 94 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/span.py

@@ -0,0 +1,94 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from threading import Lock
+import time
+
+from opentracing import Span
+
+
+class MockSpan(Span):
+    """MockSpan is a thread-safe implementation of opentracing.Span.
+    """
+
+    def __init__(
+            self,
+            tracer,
+            operation_name=None,
+            context=None,
+            parent_id=None,
+            tags=None,
+            start_time=None):
+        super(MockSpan, self).__init__(tracer, context)
+        self._tracer = tracer
+        self._lock = Lock()
+
+        self.operation_name = operation_name
+        self.start_time = start_time
+        self.parent_id = parent_id
+        self.tags = tags if tags is not None else {}
+        self.finish_time = -1
+        self.finished = False
+        self.logs = []
+
+    def set_operation_name(self, operation_name):
+        with self._lock:
+            self.operation_name = operation_name
+        return super(MockSpan, self).set_operation_name(operation_name)
+
+    def set_tag(self, key, value):
+        with self._lock:
+            if self.tags is None:
+                self.tags = {}
+            self.tags[key] = value
+        return super(MockSpan, self).set_tag(key, value)
+
+    def log_kv(self, key_values, timestamp=None):
+        with self._lock:
+            self.logs.append(LogData(key_values, timestamp))
+        return super(MockSpan, self).log_kv(key_values, timestamp)
+
+    def finish(self, finish_time=None):
+        with self._lock:
+            finish_time = time.time() if finish_time is None else finish_time
+            self.finish_time = finish_time
+            self.finished = True
+            self._tracer._append_finished_span(self)
+
+    def set_baggage_item(self, key, value):
+        new_context = self._context.with_baggage_item(key, value)
+        with self._lock:
+            self._context = new_context
+        return self
+
+    def get_baggage_item(self, key):
+        with self._lock:
+            return self.context.baggage.get(key)
+
+
+class LogData(object):
+    def __init__(
+            self,
+            key_values,
+            timestamp=None):
+        self.key_values = key_values
+        self.timestamp = time.time() if timestamp is None else timestamp

+ 67 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/text_propagator.py

@@ -0,0 +1,67 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from opentracing import SpanContextCorruptedException
+
+from .context import SpanContext
+from .propagator import Propagator
+
+prefix_tracer_state = 'ot-tracer-'
+prefix_baggage = 'ot-baggage-'
+field_name_trace_id = prefix_tracer_state + 'traceid'
+field_name_span_id = prefix_tracer_state + 'spanid'
+field_count = 2
+
+
+class TextPropagator(Propagator):
+    """A MockTracer Propagator for Format.TEXT_MAP."""
+
+    def inject(self, span_context, carrier):
+        carrier[field_name_trace_id] = '{0:x}'.format(span_context.trace_id)
+        carrier[field_name_span_id] = '{0:x}'.format(span_context.span_id)
+        if span_context.baggage is not None:
+            for k in span_context.baggage:
+                carrier[prefix_baggage+k] = span_context.baggage[k]
+
+    def extract(self, carrier):  # noqa
+        count = 0
+        span_id, trace_id = (0, 0)
+        baggage = {}
+        for k in carrier:
+            v = carrier[k]
+            k = k.lower()
+            if k == field_name_span_id:
+                span_id = int(v, 16)
+                count += 1
+            elif k == field_name_trace_id:
+                trace_id = int(v, 16)
+                count += 1
+            elif k.startswith(prefix_baggage):
+                baggage[k[len(prefix_baggage):]] = v
+
+        if count != field_count:
+            raise SpanContextCorruptedException()
+
+        return SpanContext(
+            span_id=span_id,
+            trace_id=trace_id,
+            baggage=baggage)

+ 187 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/mocktracer/tracer.py

@@ -0,0 +1,187 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from threading import Lock
+import time
+
+import opentracing
+from opentracing import Format, Tracer
+from opentracing import UnsupportedFormatException
+from opentracing.scope_managers import ThreadLocalScopeManager
+
+from .context import SpanContext
+from .span import MockSpan
+
+
+class MockTracer(Tracer):
+    """MockTracer makes it easy to test the semantics of OpenTracing
+    instrumentation.
+
+    By using a MockTracer as a :class:`~opentracing.Tracer` implementation
+    for tests, a developer can assert that :class:`~opentracing.Span`
+    properties and relationships with other
+    **Spans** are defined as expected by instrumentation code.
+
+    By default, MockTracer registers propagators for :attr:`Format.TEXT_MAP`,
+    :attr:`Format.HTTP_HEADERS` and :attr:`Format.BINARY`. The user should
+    call :func:`register_propagator()` for each additional inject/extract
+    format.
+    """
+
+    def __init__(self, scope_manager=None):
+        """Initialize a MockTracer instance."""
+
+        scope_manager = ThreadLocalScopeManager() \
+            if scope_manager is None else scope_manager
+        super(MockTracer, self).__init__(scope_manager)
+
+        self._propagators = {}
+        self._finished_spans = []
+        self._spans_lock = Lock()
+
+        # Simple-as-possible (consecutive for repeatability) id generation.
+        self._next_id = 0
+        self._next_id_lock = Lock()
+
+        self._register_required_propagators()
+
+    def register_propagator(self, format, propagator):
+        """Register a propagator with this MockTracer.
+
+        :param string format: a :class:`~opentracing.Format`
+            identifier like :attr:`~opentracing.Format.TEXT_MAP`
+        :param **Propagator** propagator: a **Propagator** instance to handle
+            inject/extract calls involving `format`
+        """
+        self._propagators[format] = propagator
+
+    def _register_required_propagators(self):
+        from .text_propagator import TextPropagator
+        from .binary_propagator import BinaryPropagator
+        self.register_propagator(Format.TEXT_MAP, TextPropagator())
+        self.register_propagator(Format.HTTP_HEADERS, TextPropagator())
+        self.register_propagator(Format.BINARY, BinaryPropagator())
+
+    def finished_spans(self):
+        """Return a copy of all finished **Spans** started by this MockTracer
+        (since construction or the last call to :meth:`~MockTracer.reset()`)
+
+        :rtype: list
+        :return: a copy of the finished **Spans**.
+        """
+        with self._spans_lock:
+            return list(self._finished_spans)
+
+    def reset(self):
+        """Clear the finished **Spans** queue.
+
+        Note that this does **not** have any effect on **Spans** created by
+        MockTracer that have not finished yet; those
+        will still be enqueued in :meth:`~MockTracer.finished_spans()`
+        when they :func:`finish()`.
+        """
+        with self._spans_lock:
+            self._finished_spans = []
+
+    def _append_finished_span(self, span):
+        with self._spans_lock:
+            self._finished_spans.append(span)
+
+    def _generate_id(self):
+        with self._next_id_lock:
+            self._next_id += 1
+            return self._next_id
+
+    def start_active_span(self,
+                          operation_name,
+                          child_of=None,
+                          references=None,
+                          tags=None,
+                          start_time=None,
+                          ignore_active_span=False,
+                          finish_on_close=True):
+
+        # create a new Span
+        span = self.start_span(
+            operation_name=operation_name,
+            child_of=child_of,
+            references=references,
+            tags=tags,
+            start_time=start_time,
+            ignore_active_span=ignore_active_span,
+        )
+
+        return self.scope_manager.activate(span, finish_on_close)
+
+    def start_span(self,
+                   operation_name=None,
+                   child_of=None,
+                   references=None,
+                   tags=None,
+                   start_time=None,
+                   ignore_active_span=False):
+
+        start_time = time.time() if start_time is None else start_time
+
+        # See if we have a parent_ctx in `references`
+        parent_ctx = None
+        if child_of is not None:
+            parent_ctx = (
+                child_of if isinstance(child_of, opentracing.SpanContext)
+                else child_of.context)
+        elif references is not None and len(references) > 0:
+            # TODO only the first reference is currently used
+            parent_ctx = references[0].referenced_context
+
+        # retrieve the active SpanContext
+        if not ignore_active_span and parent_ctx is None:
+            scope = self.scope_manager.active
+            if scope is not None:
+                parent_ctx = scope.span.context
+
+        # Assemble the child ctx
+        ctx = SpanContext(span_id=self._generate_id())
+        if parent_ctx is not None:
+            if parent_ctx._baggage is not None:
+                ctx._baggage = parent_ctx._baggage.copy()
+            ctx.trace_id = parent_ctx.trace_id
+        else:
+            ctx.trace_id = self._generate_id()
+
+        # Tie it all together
+        return MockSpan(
+            self,
+            operation_name=operation_name,
+            context=ctx,
+            parent_id=(None if parent_ctx is None else parent_ctx.span_id),
+            tags=tags,
+            start_time=start_time)
+
+    def inject(self, span_context, format, carrier):
+        if format in self._propagators:
+            self._propagators[format].inject(span_context, carrier)
+        else:
+            raise UnsupportedFormatException()
+
+    def extract(self, format, carrier):
+        if format in self._propagators:
+            return self._propagators[format].extract(carrier)
+        else:
+            raise UnsupportedFormatException()

+ 93 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/propagation.py

@@ -0,0 +1,93 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+
+
+class UnsupportedFormatException(Exception):
+    """UnsupportedFormatException should be used when the provided format
+    value is unknown or disallowed by the :class:`Tracer`.
+
+    See :meth:`Tracer.inject()` and :meth:`Tracer.extract()`.
+    """
+    pass
+
+
+class InvalidCarrierException(Exception):
+    """InvalidCarrierException should be used when the provided carrier
+    instance does not match what the `format` argument requires.
+
+    See :meth:`Tracer.inject()` and :meth:`Tracer.extract()`.
+    """
+    pass
+
+
+class SpanContextCorruptedException(Exception):
+    """SpanContextCorruptedException should be used when the underlying
+    :class:`SpanContext` state is seemingly present but not well-formed.
+
+    See :meth:`Tracer.inject()` and :meth:`Tracer.extract()`.
+    """
+    pass
+
+
+class Format(object):
+    """A namespace for builtin carrier formats.
+
+    These static constants are intended for use in the :meth:`Tracer.inject()`
+    and :meth:`Tracer.extract()` methods. E.g.::
+
+        tracer.inject(span.context, Format.BINARY, binary_carrier)
+
+    """
+
+    BINARY = 'binary'
+    """
+    The BINARY format represents SpanContexts in an opaque bytearray carrier.
+
+    For both :meth:`Tracer.inject()` and :meth:`Tracer.extract()` the carrier
+    should be a bytearray instance. :meth:`Tracer.inject()` must append to the
+    bytearray carrier (rather than replace its contents).
+    """
+
+    TEXT_MAP = 'text_map'
+    """
+    The TEXT_MAP format represents :class:`SpanContext`\\ s in a python
+    ``dict`` mapping from strings to strings.
+
+    Both the keys and the values have unrestricted character sets (unlike the
+    HTTP_HEADERS format).
+
+    NOTE: The TEXT_MAP carrier ``dict`` may contain unrelated data (e.g.,
+    arbitrary gRPC metadata). As such, the :class:`Tracer` implementation
+    should use a prefix or other convention to distinguish tracer-specific
+    key:value pairs.
+    """
+
+    HTTP_HEADERS = 'http_headers'
+    """
+    The HTTP_HEADERS format represents :class:`SpanContext`\\ s in a python
+    ``dict`` mapping from character-restricted strings to strings.
+
+    Keys and values in the HTTP_HEADERS carrier must be suitable for use as
+    HTTP headers (without modification or further escaping). That is, the
+    keys have a greatly restricted character set, casing for the keys may not
+    be preserved by various intermediaries, and the values should be
+    URL-escaped.
+
+    NOTE: The HTTP_HEADERS carrier ``dict`` may contain unrelated data (e.g.,
+    arbitrary gRPC metadata). As such, the :class:`Tracer` implementation
+    should use a prefix or other convention to distinguish tracer-specific
+    key:value pairs.
+    """

+ 84 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/scope.py

@@ -0,0 +1,84 @@
+# Copyright (c) 2017-2019 The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from .span import Span
+
+
+class Scope(object):
+    """A scope formalizes the activation and deactivation of a :class:`Span`,
+    usually from a CPU standpoint. Many times a :class:`Span` will be extant
+    (in that :meth:`Span.finish()` has not been called) despite being in a
+    non-runnable state from a CPU/scheduler standpoint. For instance, a
+    :class:`Span` representing the client side of an RPC will be unfinished but
+    blocked on IO while the RPC is still outstanding. A scope defines when a
+    given :class:`Span` is scheduled and on the path.
+
+    :param manager: the :class:`ScopeManager` that created this :class:`Scope`.
+    :type manager: ScopeManager
+
+    :param span: the :class:`Span` used for this :class:`Scope`.
+    :type span: Span
+    """
+    def __init__(self, manager, span):
+        """Initializes a scope for *span*."""
+        self._manager = manager
+        self._span = span
+
+    @property
+    def span(self):
+        """Returns the :class:`Span` wrapped by this :class:`Scope`.
+
+        :rtype: Span
+        """
+        return self._span
+
+    @property
+    def manager(self):
+        """Returns the :class:`ScopeManager` that created this :class:`Scope`.
+
+        :rtype: ScopeManager
+        """
+        return self._manager
+
+    def close(self):
+        """Marks the end of the active period for this :class:`Scope`, updating
+        :attr:`ScopeManager.active` in the process.
+
+        NOTE: Calling this method more than once on a single :class:`Scope`
+        leads to undefined behavior.
+        """
+        pass
+
+    def __enter__(self):
+        """Allows :class:`Scope` to be used inside a Python Context Manager."""
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        """Calls :meth:`close()` when the execution is outside the Python
+        Context Manager.
+
+        If exception has occurred during execution, it is automatically logged
+        and added as a tag to the :class:`Span`.
+        :attr:`~operation.ext.tags.ERROR` will also be set to `True`.
+        """
+        Span._on_error(self.span, exc_type, exc_val, exc_tb)
+        self.close()

+ 65 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_manager.py

@@ -0,0 +1,65 @@
+# Copyright (c) 2017 The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from .span import Span, SpanContext
+from .scope import Scope
+
+
+class ScopeManager(object):
+    """The :class:`ScopeManager` interface abstracts both the activation of
+    a :class:`Span` and access to an active :class:`Span`/:class:`Scope`.
+    """
+    def __init__(self):
+        # TODO: `tracer` should not be None, but we don't have a reference;
+        # should we move the NOOP SpanContext, Span, Scope to somewhere
+        # else so that they're globally reachable?
+        self._noop_span = Span(tracer=None, context=SpanContext())
+        self._noop_scope = Scope(self, self._noop_span)
+
+    def activate(self, span, finish_on_close):
+        """Makes a :class:`Span` active.
+
+        :param span: the :class:`Span` that should become active.
+        :param finish_on_close: whether :class:`Span` should be automatically
+            finished when :meth:`Scope.close()` is called.
+
+        :rtype: Scope
+        :return: a :class:`Scope` to control the end of the active period for
+            *span*. It is a programming error to neglect to call
+            :meth:`Scope.close()` on the returned instance.
+        """
+        return self._noop_scope
+
+    @property
+    def active(self):
+        """Returns the currently active :class:`Scope` which can be used to access the
+        currently active :attr:`Scope.span`.
+
+        If there is a non-null :class:`Scope`, its wrapped :class:`Span`
+        becomes an implicit parent of any newly-created :class:`Span` at
+        :meth:`Tracer.start_active_span()` time.
+
+        :rtype: Scope
+        :return: the :class:`Scope` that is active, or ``None`` if not
+            available.
+        """
+        return self._noop_scope

+ 79 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/__init__.py

@@ -0,0 +1,79 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+import threading
+
+from opentracing import Scope, ScopeManager
+
+
+class ThreadLocalScopeManager(ScopeManager):
+    """
+    :class:`~opentracing.ScopeManager` implementation that stores the
+    current active :class:`~opentracing.Scope` using thread-local storage.
+    """
+    def __init__(self):
+        self._tls_scope = threading.local()
+
+    def activate(self, span, finish_on_close):
+        """
+        Make a :class:`~opentracing.Span` instance active.
+
+        :param span: the :class:`~opentracing.Span` that should become active.
+        :param finish_on_close: whether *span* should automatically be
+            finished when :meth:`Scope.close()` is called.
+
+        :return: a :class:`~opentracing.Scope` instance to control the end
+            of the active period for the :class:`~opentracing.Span`.
+            It is a programming error to neglect to call :meth:`Scope.close()`
+            on the returned instance.
+        """
+        scope = _ThreadLocalScope(self, span, finish_on_close)
+        setattr(self._tls_scope, 'active', scope)
+        return scope
+
+    @property
+    def active(self):
+        """
+        Return the currently active :class:`~opentracing.Scope` which
+        can be used to access the currently active
+        :attr:`Scope.span`.
+
+        :return: the :class:`~opentracing.Scope` that is active,
+            or ``None`` if not available.
+        """
+        return getattr(self._tls_scope, 'active', None)
+
+
+class _ThreadLocalScope(Scope):
+    def __init__(self, manager, span, finish_on_close):
+        super(_ThreadLocalScope, self).__init__(manager, span)
+        self._finish_on_close = finish_on_close
+        self._to_restore = manager.active
+
+    def close(self):
+        if self.manager.active is not self:
+            return
+
+        if self._finish_on_close:
+            self.span.finish()
+
+        setattr(self._manager._tls_scope, 'active', self._to_restore)

+ 138 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/asyncio.py

@@ -0,0 +1,138 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+import asyncio
+
+from opentracing import Scope
+from opentracing.scope_managers import ThreadLocalScopeManager
+from .constants import ACTIVE_ATTR
+
+
+class AsyncioScopeManager(ThreadLocalScopeManager):
+    """
+    :class:`~opentracing.ScopeManager` implementation for **asyncio**
+    that stores the :class:`~opentracing.Scope` in the current
+    :class:`Task` (:meth:`Task.current_task()`), falling back to
+    thread-local storage if none was being executed.
+
+    Automatic :class:`~opentracing.Span` propagation from
+    parent coroutines to their children is not provided, which needs to be
+    done manually:
+
+    .. code-block:: python
+
+        async def child_coroutine(span):
+            # activate the parent Span, but do not finish it upon
+            # deactivation. That will be done by the parent coroutine.
+            with tracer.scope_manager.activate(span, finish_on_close=False):
+                with tracer.start_active_span('child') as scope:
+                    ...
+
+        async def parent_coroutine():
+            with tracer.start_active_span('parent') as scope:
+                ...
+                await child_coroutine(span)
+                ...
+
+    """
+
+    def activate(self, span, finish_on_close):
+        """
+        Make a :class:`~opentracing.Span` instance active.
+
+        :param span: the :class:`~opentracing.Span` that should become active.
+        :param finish_on_close: whether *span* should automatically be
+            finished when :meth:`Scope.close()` is called.
+
+        If no :class:`Task` is being executed, thread-local
+        storage will be used to store the :class:`~opentracing.Scope`.
+
+        :return: a :class:`~opentracing.Scope` instance to control the end
+            of the active period for the :class:`~opentracing.Span`.
+            It is a programming error to neglect to call :meth:`Scope.close()`
+            on the returned instance.
+        """
+
+        task = self._get_task()
+        if not task:
+            return super(AsyncioScopeManager, self).activate(span,
+                                                             finish_on_close)
+
+        scope = _AsyncioScope(self, span, finish_on_close)
+        self._set_task_scope(scope, task)
+
+        return scope
+
+    @property
+    def active(self):
+        """
+        Return the currently active :class:`~opentracing.Scope` which
+        can be used to access the currently active
+        :attr:`Scope.span`.
+
+        :return: the :class:`~opentracing.Scope` that is active,
+            or ``None`` if not available.
+        """
+
+        task = self._get_task()
+        if not task:
+            return super(AsyncioScopeManager, self).active
+
+        return self._get_task_scope(task)
+
+    def _get_task(self):
+        try:
+            # Prevent failure when run from a thread
+            # without an event loop.
+            loop = asyncio.get_event_loop()
+        except RuntimeError:
+            return None
+
+        return asyncio.Task.current_task(loop=loop)
+
+    def _set_task_scope(self, scope, task=None):
+        if task is None:
+            task = self._get_task()
+
+        setattr(task, ACTIVE_ATTR, scope)
+
+    def _get_task_scope(self, task=None):
+        if task is None:
+            task = self._get_task()
+
+        return getattr(task, ACTIVE_ATTR, None)
+
+
+class _AsyncioScope(Scope):
+    def __init__(self, manager, span, finish_on_close):
+        super(_AsyncioScope, self).__init__(manager, span)
+        self._finish_on_close = finish_on_close
+        self._to_restore = manager.active
+
+    def close(self):
+        if self.manager.active is not self:
+            return
+
+        self.manager._set_task_scope(self._to_restore)
+
+        if self._finish_on_close:
+            self.span.finish()

+ 26 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/constants.py

@@ -0,0 +1,26 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+from __future__ import absolute_import
+
+# ---------------------------------------------------------------------------
+# ACTIVE_ATTR (string) is the name of the attribute storing the active Scope
+# in an external object, e.g. a coroutine or greenlet.
+# ---------------------------------------------------------------------------
+ACTIVE_ATTR = '__ot_active'

+ 114 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/gevent.py

@@ -0,0 +1,114 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+import gevent
+
+from opentracing import Scope, ScopeManager
+from .constants import ACTIVE_ATTR
+
+
+class GeventScopeManager(ScopeManager):
+    """
+    :class:`~opentracing.ScopeManager` implementation for **gevent**
+    that stores the :class:`~opentracing.Scope` in the current greenlet
+    (:func:`gevent.getcurrent()`).
+
+    Automatic :class:`~opentracing.Span` propagation from parent greenlets to
+    their children is not provided, which needs to be
+    done manually:
+
+    .. code-block:: python
+
+        def child_greenlet(span):
+            # activate the parent Span, but do not finish it upon
+            # deactivation. That will be done by the parent greenlet.
+            with tracer.scope_manager.activate(span, finish_on_close=False):
+                with tracer.start_active_span('child') as scope:
+                    ...
+
+        def parent_greenlet():
+            with tracer.start_active_span('parent') as scope:
+                ...
+                gevent.spawn(child_greenlet, span).join()
+                ...
+
+    """
+
+    def activate(self, span, finish_on_close):
+        """
+        Make a :class:`~opentracing.Span` instance active.
+
+        :param span: the :class:`~opentracing.Span` that should become active.
+        :param finish_on_close: whether *span* should automatically be
+            finished when :meth:`Scope.close()` is called.
+
+        :return: a :class:`~opentracing.Scope` instance to control the end
+            of the active period for the :class:`~opentracing.Span`.
+            It is a programming error to neglect to call :meth:`Scope.close()`
+            on the returned instance.
+        """
+
+        scope = _GeventScope(self, span, finish_on_close)
+        self._set_greenlet_scope(scope)
+
+        return scope
+
+    @property
+    def active(self):
+        """
+        Return the currently active :class:`~opentracing.Scope` which
+        can be used to access the currently active
+        :attr:`Scope.span`.
+
+        :return: the :class:`~opentracing.Scope` that is active,
+            or ``None`` if not available.
+        """
+
+        return self._get_greenlet_scope()
+
+    def _get_greenlet_scope(self, greenlet=None):
+        if greenlet is None:
+            greenlet = gevent.getcurrent()
+
+        return getattr(greenlet, ACTIVE_ATTR, None)
+
+    def _set_greenlet_scope(self, scope, greenlet=None):
+        if greenlet is None:
+            greenlet = gevent.getcurrent()
+
+        setattr(greenlet, ACTIVE_ATTR, scope)
+
+
+class _GeventScope(Scope):
+    def __init__(self, manager, span, finish_on_close):
+        super(_GeventScope, self).__init__(manager, span)
+        self._finish_on_close = finish_on_close
+        self._to_restore = manager.active
+
+    def close(self):
+        if self.manager.active is not self:
+            return
+
+        self.manager._set_greenlet_scope(self._to_restore)
+
+        if self._finish_on_close:
+            self.span.finish()

+ 280 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/scope_managers/tornado.py

@@ -0,0 +1,280 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+import threading
+import tornado.stack_context
+
+from opentracing import Scope
+from opentracing.scope_managers import ThreadLocalScopeManager
+
+
+# Implementation based on
+# github.com/uber-common/opentracing-python-instrumentation/
+
+class TornadoScopeManager(ThreadLocalScopeManager):
+    """
+    :class:`~opentracing.ScopeManager` implementation for **Tornado**
+    that stores the :class:`~opentracing.Scope` using a custom
+    :class:`StackContext`, falling back to thread-local storage if
+    none was found.
+
+    Using it under :func:`tracer_stack_context()` will
+    also automatically propagate the active :class:`~opentracing.Span`
+    from parent coroutines to their children:
+
+    .. code-block:: python
+
+        @tornado.gen.coroutine
+        def child_coroutine():
+            # No need to pass 'parent' and activate it here,
+            # as it is automatically propagated.
+            with tracer.start_active_span('child') as scope:
+                ...
+
+        @tornado.gen.coroutine
+        def parent_coroutine():
+            with tracer.start_active_span('parent') as scope:
+                ...
+                yield child_coroutine()
+                ...
+
+        with tracer_stack_context():
+            loop.add_callback(parent_coroutine)
+
+
+    .. note::
+        The current version does not support :class:`~opentracing.Span`
+        activation in children coroutines when the parent yields over
+        **multiple** of them, as the context is effectively shared by all,
+        and the active :class:`~opentracing.Span` state is messed up:
+
+        .. code-block:: python
+
+            @tornado.gen.coroutine
+            def coroutine(input):
+                # No span should be activated here.
+                # The parent Span will remain active, though.
+                with tracer.start_span('child', child_of=tracer.active_span):
+                    ...
+
+            @tornado.gen.coroutine
+            def handle_request_wrapper():
+                res1 = coroutine('A')
+                res2 = coroutine('B')
+
+                yield [res1, res2]
+    """
+
+    def activate(self, span, finish_on_close):
+        """
+        Make a :class:`~opentracing.Span` instance active.
+
+        :param span: the :class:`~opentracing.Span` that should become active.
+        :param finish_on_close: whether *span* should automatically be
+            finished when :meth:`Scope.close()` is called.
+
+        If no :func:`tracer_stack_context()` is detected, thread-local
+        storage will be used to store the :class:`~opentracing.Scope`.
+        Observe that in this case the active :class:`~opentracing.Span`
+        will not be automatically propagated to the child corotuines.
+
+        :return: a :class:`~opentracing.Scope` instance to control the end
+            of the active period for the :class:`~opentracing.Span`.
+            It is a programming error to neglect to call :meth:`Scope.close()`
+            on the returned instance.
+        """
+
+        context = self._get_context()
+        if context is None:
+            return super(TornadoScopeManager, self).activate(span,
+                                                             finish_on_close)
+
+        scope = _TornadoScope(self, span, finish_on_close)
+        context.active = scope
+
+        return scope
+
+    @property
+    def active(self):
+        """
+        Return the currently active :class:`~opentracing.Scope` which
+        can be used to access the currently active
+        :attr:`Scope.span`.
+
+        :return: the :class:`~opentracing.Scope` that is active,
+            or ``None`` if not available.
+        """
+
+        context = self._get_context()
+        if not context:
+            return super(TornadoScopeManager, self).active
+
+        return context.active
+
+    def _get_context(self):
+        return _TracerRequestContextManager.current_context()
+
+
+class _TornadoScope(Scope):
+    def __init__(self, manager, span, finish_on_close):
+        super(_TornadoScope, self).__init__(manager, span)
+        self._finish_on_close = finish_on_close
+        self._to_restore = manager.active
+
+    def close(self):
+        context = self.manager._get_context()
+        if context is None or context.active is not self:
+            return
+
+        context.active = self._to_restore
+
+        if self._finish_on_close:
+            self.span.finish()
+
+
+class ThreadSafeStackContext(tornado.stack_context.StackContext):
+    """
+    Thread safe version of Tornado's StackContext (up to 4.3)
+    Copy of implementation by caspersj@, until tornado-extras is open-sourced.
+    Tornado's StackContext works as follows:
+    - When entering a context, create an instance of StackContext and
+      add add this instance to the current "context stack"
+    - If execution transfers to another thread (using the wraps helper
+      method),  copy the current "context stack" and apply that in the new
+      thread when execution starts
+    - A context stack can be entered/exited by traversing the stack and
+      calling enter/exit on all elements. This is how the `wraps` helper
+      method enters/exits in new threads.
+    - StackContext has an internal pointer to a context factory (i.e.
+      RequestContext), and an internal stack of applied contexts (instances
+      of RequestContext) for each instance of StackContext. RequestContext
+      instances are entered/exited from the stack as the StackContext
+      is entered/exited
+    - However, the enter/exit logic and maintenance of this stack of
+      RequestContext instances is not thread safe.
+    ```
+    def __init__(self, context_factory):
+        self.context_factory = context_factory
+        self.contexts = []
+        self.active = True
+    def enter(self):
+        context = self.context_factory()
+        self.contexts.append(context)
+        context.__enter__()
+    def exit(self, type, value, traceback):
+        context = self.contexts.pop()
+        context.__exit__(type, value, traceback)
+    ```
+    Unexpected semantics of Tornado's default StackContext implementation:
+    - There exist a race on `self.contexts`, where thread A enters a
+      context, thread B enters a context, and thread A exits its context.
+      In this case, the exit by thread A pops the instance created by
+      thread B and calls exit on this instance.
+    - There exists a race between `enter` and `exit` where thread A
+      executes the two first statements of enter (create instance and
+      add to contexts) and thread B executes exit, calling exit on an
+      instance that has been initialized but not yet exited (and
+      subsequently this instance will then be entered).
+    The ThreadSafeStackContext changes the internal contexts stack to be
+    thread local, fixing both of the above issues.
+    """
+
+    def __init__(self, *args, **kwargs):
+        class LocalContexts(threading.local):
+            def __init__(self):
+                super(LocalContexts, self).__init__()
+                self._contexts = []
+
+            def append(self, item):
+                self._contexts.append(item)
+
+            def pop(self):
+                return self._contexts.pop()
+
+        super(ThreadSafeStackContext, self).__init__(*args, **kwargs)
+
+        if hasattr(self, 'contexts'):
+            # only patch if context exists
+            self.contexts = LocalContexts()
+
+
+class _TracerRequestContext(object):
+    __slots__ = ('active', )
+
+    def __init__(self, active=None):
+        self.active = active
+
+
+class _TracerRequestContextManager(object):
+    _state = threading.local()
+    _state.context = None
+
+    @classmethod
+    def current_context(cls):
+        return getattr(cls._state, 'context', None)
+
+    def __init__(self, context):
+        self._context = context
+
+    def __enter__(self):
+        self._prev_context = self.__class__.current_context()
+        self.__class__._state.context = self._context
+        return self._context
+
+    def __exit__(self, *_):
+        self.__class__._state.context = self._prev_context
+        self._prev_context = None
+        return False
+
+
+def tracer_stack_context():
+    """
+    Create a custom Tornado's :class:`StackContext` that allows
+    :class:`TornadoScopeManager` to store the active
+    :class:`~opentracing.Span` in the thread-local request context.
+
+    Suppose you have a method ``handle_request(request)`` in the
+    http server. Instead of calling it directly, use a wrapper:
+
+    .. code-block:: python
+
+        from opentracing.scope_managers.tornado import tracer_stack_context
+
+        @tornado.gen.coroutine
+        def handle_request_wrapper(request, actual_handler, *args, **kwargs)
+
+            request_wrapper = TornadoRequestWrapper(request=request)
+            span = http_server.before_request(request=request_wrapper)
+
+            with tracer_stack_context():
+                with tracer.scope_manager.activate(span, True):
+                    return actual_handler(*args, **kwargs)
+
+    :return:
+        Return a custom :class:`StackContext` that allows
+        :class:`TornadoScopeManager` to activate and propagate
+        :class:`~opentracing.Span` instances.
+    """
+    context = _TracerRequestContext()
+    return ThreadSafeStackContext(
+            lambda: _TracerRequestContextManager(context)
+    )

+ 252 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/span.py

@@ -0,0 +1,252 @@
+# Copyright The OpenTracing Authors
+# Copyright Uber Technologies, Inc
+#
+# 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.
+
+from __future__ import absolute_import
+from . import logs
+
+from opentracing.ext import tags
+
+
+class SpanContext(object):
+    """SpanContext represents :class:`Span` state that must propagate to
+    descendant :class:`Span`\\ s and across process boundaries.
+
+    SpanContext is logically divided into two pieces: the user-level "Baggage"
+    (see :meth:`Span.set_baggage_item` and :meth:`Span.get_baggage_item`) that
+    propagates across :class:`Span` boundaries and any
+    tracer-implementation-specific fields that are needed to identify or
+    otherwise contextualize the associated :class:`Span` (e.g., a ``(trace_id,
+    span_id, sampled)`` tuple).
+    """
+
+    EMPTY_BAGGAGE = {}  # TODO would be nice to make this immutable
+
+    @property
+    def baggage(self):
+        """
+        Return baggage associated with this :class:`SpanContext`.
+        If no baggage has been added to the :class:`Span`, returns an empty
+        dict.
+
+        The caller must not modify the returned dictionary.
+
+        See also: :meth:`Span.set_baggage_item()` /
+        :meth:`Span.get_baggage_item()`
+
+        :rtype: dict
+        :return: baggage associated with this :class:`SpanContext` or ``{}``.
+        """
+        return SpanContext.EMPTY_BAGGAGE
+
+
+class Span(object):
+    """
+    Span represents a unit of work executed on behalf of a trace. Examples of
+    spans include a remote procedure call, or a in-process method call to a
+    sub-component. Every span in a trace may have zero or more causal parents,
+    and these relationships transitively form a DAG. It is common for spans to
+    have at most one parent, and thus most traces are merely tree structures.
+
+    Span implements a context manager API that allows the following usage::
+
+        with tracer.start_span(operation_name='go_fishing') as span:
+            call_some_service()
+
+    In the context manager syntax it's not necessary to call
+    :meth:`Span.finish()`
+    """
+
+    def __init__(self, tracer, context):
+        self._tracer = tracer
+        self._context = context
+
+    @property
+    def context(self):
+        """Provides access to the :class:`SpanContext` associated with this
+        :class:`Span`.
+
+        The :class:`SpanContext` contains state that propagates from
+        :class:`Span` to :class:`Span` in a larger trace.
+
+        :rtype: SpanContext
+        :return: the :class:`SpanContext` associated with this :class:`Span`.
+        """
+        return self._context
+
+    @property
+    def tracer(self):
+        """Provides access to the :class:`Tracer` that created this
+        :class:`Span`.
+
+        :rtype: Tracer
+        :return: the :class:`Tracer` that created this :class:`Span`.
+        """
+        return self._tracer
+
+    def set_operation_name(self, operation_name):
+        """Changes the operation name.
+
+        :param operation_name: the new operation name
+        :type operation_name: str
+
+        :rtype: Span
+        :return: the :class:`Span` itself, for call chaining.
+        """
+        return self
+
+    def finish(self, finish_time=None):
+        """Indicates that the work represented by this :class:`Span` has completed or
+        terminated.
+
+        With the exception of the :attr:`Span.context` property, the semantics
+        of all other :class:`Span` methods are undefined after
+        :meth:`Span.finish()` has been invoked.
+
+        :param finish_time: an explicit :class:`Span` finish timestamp as a
+            unix timestamp per :meth:`time.time()`
+        :type finish_time: float
+        """
+        pass
+
+    def set_tag(self, key, value):
+        """Attaches a key/value pair to the :class:`Span`.
+
+        The value must be a string, a bool, or a numeric type.
+
+        If the user calls set_tag multiple times for the same key,
+        the behavior of the :class:`Tracer` is undefined, i.e. it is
+        implementation specific whether the :class:`Tracer` will retain the
+        first value, or the last value, or pick one randomly, or even keep all
+        of them.
+
+        :param key: key or name of the tag. Must be a string.
+        :type key: str
+
+        :param value: value of the tag.
+        :type value: string or bool or int or float
+
+        :rtype: Span
+        :return: the :class:`Span` itself, for call chaining.
+        """
+        return self
+
+    def log_kv(self, key_values, timestamp=None):
+        """Adds a log record to the :class:`Span`.
+
+        For example::
+
+            span.log_kv({
+                "event": "time to first byte",
+                "packet.size": packet.size()})
+
+            span.log_kv({"event": "two minutes ago"}, time.time() - 120)
+
+        :param key_values: A dict of string keys and values of any type
+        :type key_values: dict
+
+        :param timestamp: A unix timestamp per :meth:`time.time()`; current
+            time if ``None``
+        :type timestamp: float
+
+        :rtype: Span
+        :return: the :class:`Span` itself, for call chaining.
+        """
+        return self
+
+    def set_baggage_item(self, key, value):
+        """Stores a Baggage item in the :class:`Span` as a key/value pair.
+
+        Enables powerful distributed context propagation functionality where
+        arbitrary application data can be carried along the full path of
+        request execution throughout the system.
+
+        Note 1: Baggage is only propagated to the future (recursive) children
+        of this :class:`Span`.
+
+        Note 2: Baggage is sent in-band with every subsequent local and remote
+        calls, so this feature must be used with care.
+
+        :param key: Baggage item key
+        :type key: str
+
+        :param value: Baggage item value
+        :type value: str
+
+        :rtype: Span
+        :return: itself, for chaining the calls.
+        """
+        return self
+
+    def get_baggage_item(self, key):
+        """Retrieves value of the baggage item with the given key.
+
+        :param key: key of the baggage item
+        :type key: str
+
+        :rtype: str
+        :return: value of the baggage item with given key, or ``None``.
+        """
+        return None
+
+    def __enter__(self):
+        """Invoked when :class:`Span` is used as a context manager.
+
+        :rtype: Span
+        :return: the :class:`Span` itself
+        """
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        """Ends context manager and calls finish() on the :class:`Span`.
+
+        If exception has occurred during execution, it is automatically logged
+        and added as a tag. :attr:`~operation.ext.tags.ERROR` will also be set
+        to `True`.
+        """
+        Span._on_error(self, exc_type, exc_val, exc_tb)
+        self.finish()
+
+    @staticmethod
+    def _on_error(span, exc_type, exc_val, exc_tb):
+        if not span or not exc_val:
+            return
+
+        span.set_tag(tags.ERROR, True)
+        span.log_kv({
+            logs.EVENT: tags.ERROR,
+            logs.MESSAGE: str(exc_val),
+            logs.ERROR_OBJECT: exc_val,
+            logs.ERROR_KIND: exc_type,
+            logs.STACK: exc_tb,
+        })
+
+    def log_event(self, event, payload=None):
+        """DEPRECATED"""
+        if payload is None:
+            return self.log_kv({logs.EVENT: event})
+        else:
+            return self.log_kv({logs.EVENT: event, 'payload': payload})
+
+    def log(self, **kwargs):
+        """DEPRECATED"""
+        key_values = {}
+        if logs.EVENT in kwargs:
+            key_values[logs.EVENT] = kwargs[logs.EVENT]
+        if 'payload' in kwargs:
+            key_values['payload'] = kwargs['payload']
+        timestamp = None
+        if 'timestamp' in kwargs:
+            timestamp = kwargs['timestamp']
+        return self.log_kv(key_values, timestamp)

+ 142 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/tags.py

@@ -0,0 +1,142 @@
+# Copyright The OpenTracing Authors
+# Copyright Uber Technologies, Inc
+#
+# 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.
+
+from __future__ import absolute_import
+
+# The following tags are described in greater detail at the following url:
+# https://github.com/opentracing/specification/blob/master/semantic_conventions.md
+
+# Here we define standard names for tags that can be added to spans by the
+# instrumentation code. The actual tracing systems are not required to
+# retain these as tags in the stored spans if they have other means of
+# representing the same data. For example, the SPAN_KIND='server' can be
+# inferred from a Zipkin span by the presence of ss/sr annotations.
+
+# ---------------------------------------------------------------------------
+# SPAN_KIND hints at relationship between spans, e.g. client/server
+# ---------------------------------------------------------------------------
+SPAN_KIND = 'span.kind'
+
+# Marks a span representing the client-side of an RPC or other remote call
+SPAN_KIND_RPC_CLIENT = 'client'
+
+# Marks a span representing the server-side of an RPC or other remote call
+SPAN_KIND_RPC_SERVER = 'server'
+
+# Marks a span representing the consumer-side of a messaging call
+SPAN_KIND_CONSUMER = 'consumer'
+
+# Marks a span representing the producer-side of a messaging call
+SPAN_KIND_PRODUCER = 'producer'
+
+# ---------------------------------------------------------------------------
+# SERVICE indicates the service name for a span, which overrides any default
+# "service name" property defined in a tracer's config. The meaning of
+# service should correspond to the value set in peer.service, except it is
+# applied to the current span. This tag is meant to only be used when a
+# tracer is reporting spans on behalf of another service. This tag does not
+# need to be used when reporting spans for the service the tracer is running
+# in.
+# ---------------------------------------------------------------------------
+SERVICE = 'service'
+
+# ---------------------------------------------------------------------------
+# ERROR indicates whether a Span ended in an error state.
+# ---------------------------------------------------------------------------
+ERROR = 'error'
+
+# ---------------------------------------------------------------------------
+# COMPONENT (string) ia s low-cardinality identifier of the module, library,
+# or package that is generating a span.
+# ---------------------------------------------------------------------------
+COMPONENT = 'component'
+
+# ---------------------------------------------------------------------------
+# SAMPLING_PRIORITY (uint16) determines the priority of sampling this Span.
+# ---------------------------------------------------------------------------
+SAMPLING_PRIORITY = 'sampling.priority'
+
+# ---------------------------------------------------------------------------
+# PEER_* tags can be emitted by either client-side of server-side to describe
+# the other side/service in a peer-to-peer communications, like an RPC call.
+# ---------------------------------------------------------------------------
+
+# PEER_SERVICE (string) records the service name of the peer
+PEER_SERVICE = 'peer.service'
+
+# PEER_HOSTNAME (string) records the host name of the peer
+PEER_HOSTNAME = 'peer.hostname'
+
+# PEER_ADDRESS (string) suitable for use in a networking client library.
+# This may be a "ip:port", a bare "hostname", a FQDN, or even a
+# JDBC substring like "mysql://prod-db:3306"
+PEER_ADDRESS = 'peer.address'
+
+# PEER_HOST_IPV4 (uint32) records IP v4 host address of the peer
+PEER_HOST_IPV4 = 'peer.ipv4'
+
+# PEER_HOST_IPV6 (string) records IP v6 host address of the peer
+PEER_HOST_IPV6 = 'peer.ipv6'
+
+# PEER_PORT (uint16) records port number of the peer
+PEER_PORT = 'peer.port'
+
+# ---------------------------------------------------------------------------
+# HTTP tags
+# ---------------------------------------------------------------------------
+
+# HTTP_URL (string) should be the URL of the request being handled in this
+# segment of the trace, in standard URI format. The protocol is optional.
+HTTP_URL = 'http.url'
+
+# HTTP_METHOD (string) is the HTTP method of the request.
+# Both upper/lower case values are allowed.
+HTTP_METHOD = 'http.method'
+
+# HTTP_STATUS_CODE (int) is the numeric HTTP status code (200, 404, etc)
+# of the HTTP response.
+HTTP_STATUS_CODE = 'http.status_code'
+
+# ---------------------------------------------------------------------------
+# DATABASE tags
+# ---------------------------------------------------------------------------
+
+# DATABASE_INSTANCE (string) The database instance name. E.g., In java, if
+# the jdbc.url="jdbc:mysql://127.0.0.1:3306/customers", the instance
+# name is "customers"
+DATABASE_INSTANCE = 'db.instance'
+
+# DATABASE_STATEMENT (string) A database statement for the given database
+# type. E.g., for db.type="SQL", "SELECT * FROM user_table";
+# for db.type="redis", "SET mykey 'WuValue'".
+DATABASE_STATEMENT = 'db.statement'
+
+# DATABASE_TYPE (string) For any SQL database, "sql". For others,
+# the lower-case database category, e.g. "cassandra", "hbase", or "redis".
+DATABASE_TYPE = 'db.type'
+
+# DATABASE_USER (string) Username for accessing database. E.g.,
+# "readonly_user" or "reporting_user"
+DATABASE_USER = 'db.user'
+
+# ---------------------------------------------------------------------------
+# MESSAGE_BUS tags
+# ---------------------------------------------------------------------------
+
+# MESSAGE_BUS_DESTINATION (string) An address at which messages can be
+# exchanged. E.g. A Kafka record has an associated "topic name" that can
+# be extracted by the instrumented producer or consumer and stored
+# using this tag.
+MESSAGE_BUS_DESTINATION = 'message_bus.destination'

+ 348 - 0
desktop/core/ext-py/opentracing-2.2.0/opentracing/tracer.py

@@ -0,0 +1,348 @@
+# Copyright The OpenTracing Authors
+# Copyright Uber Technologies, Inc
+#
+# 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.
+
+from __future__ import absolute_import
+from collections import namedtuple
+from .span import Span
+from .span import SpanContext
+from .scope import Scope
+from .scope_manager import ScopeManager
+from .propagation import Format, UnsupportedFormatException
+
+
+class Tracer(object):
+    """Tracer is the entry point API between instrumentation code and the
+    tracing implementation.
+
+    This implementation both defines the public Tracer API, and provides
+    a default no-op behavior.
+    """
+
+    _supported_formats = [Format.TEXT_MAP, Format.BINARY, Format.HTTP_HEADERS]
+
+    def __init__(self, scope_manager=None):
+        self._scope_manager = ScopeManager() if scope_manager is None \
+                else scope_manager
+        self._noop_span_context = SpanContext()
+        self._noop_span = Span(tracer=self, context=self._noop_span_context)
+        self._noop_scope = Scope(self._scope_manager, self._noop_span)
+
+    @property
+    def scope_manager(self):
+        """Provides access to the current :class:`~opentracing.ScopeManager`.
+
+        :rtype: :class:`~opentracing.ScopeManager`
+        """
+        return self._scope_manager
+
+    @property
+    def active_span(self):
+        """Provides access to the the active :class:`Span`. This is a shorthand for
+        :attr:`Tracer.scope_manager.active.span`, and ``None`` will be
+        returned if :attr:`Scope.span` is ``None``.
+
+        :rtype: :class:`~opentracing.Span`
+        :return: the active :class:`Span`.
+        """
+        scope = self._scope_manager.active
+        return None if scope is None else scope.span
+
+    def start_active_span(self,
+                          operation_name,
+                          child_of=None,
+                          references=None,
+                          tags=None,
+                          start_time=None,
+                          ignore_active_span=False,
+                          finish_on_close=True):
+        """Returns a newly started and activated :class:`Scope`.
+
+        The returned :class:`Scope` supports with-statement contexts. For
+        example::
+
+            with tracer.start_active_span('...') as scope:
+                scope.span.set_tag('http.method', 'GET')
+                do_some_work()
+            # Span.finish() is called as part of scope deactivation through
+            # the with statement.
+
+        It's also possible to not finish the :class:`Span` when the
+        :class:`Scope` context expires::
+
+            with tracer.start_active_span('...',
+                                          finish_on_close=False) as scope:
+                scope.span.set_tag('http.method', 'GET')
+                do_some_work()
+            # Span.finish() is not called as part of Scope deactivation as
+            # `finish_on_close` is `False`.
+
+        :param operation_name: name of the operation represented by the new
+            :class:`Span` from the perspective of the current service.
+        :type operation_name: str
+
+        :param child_of: (optional) a :class:`Span` or :class:`SpanContext`
+            instance representing the parent in a REFERENCE_CHILD_OF reference.
+            If specified, the `references` parameter must be omitted.
+        :type child_of: Span or SpanContext
+
+        :param references: (optional) references that identify one or more
+            parent :class:`SpanContext`\\ s. (See the Reference documentation
+            for detail).
+        :type references: :obj:`list` of :class:`Reference`
+
+        :param tags: an optional dictionary of :class:`Span` tags. The caller
+            gives up ownership of that dictionary, because the :class:`Tracer`
+            may use it as-is to avoid extra data copying.
+        :type tags: dict
+
+        :param start_time: an explicit :class:`Span` start time as a unix
+            timestamp per :meth:`time.time()`.
+        :type start_time: float
+
+        :param ignore_active_span: (optional) an explicit flag that ignores
+            the current active :class:`Scope` and creates a root :class:`Span`.
+        :type ignore_active_span: bool
+
+        :param finish_on_close: whether :class:`Span` should automatically be
+            finished when :meth:`Scope.close()` is called.
+        :type finish_on_close: bool
+
+        :rtype: Scope
+        :return: a :class:`Scope`, already registered via the
+            :class:`ScopeManager`.
+        """
+        return self._noop_scope
+
+    def start_span(self,
+                   operation_name=None,
+                   child_of=None,
+                   references=None,
+                   tags=None,
+                   start_time=None,
+                   ignore_active_span=False):
+        """Starts and returns a new :class:`Span` representing a unit of work.
+
+
+        Starting a root :class:`Span` (a :class:`Span` with no causal
+        references)::
+
+            tracer.start_span('...')
+
+
+        Starting a child :class:`Span` (see also :meth:`start_child_span()`)::
+
+            tracer.start_span(
+                '...',
+                child_of=parent_span)
+
+
+        Starting a child :class:`Span` in a more verbose way::
+
+            tracer.start_span(
+                '...',
+                references=[opentracing.child_of(parent_span)])
+
+
+        :param operation_name: name of the operation represented by the new
+            :class:`Span` from the perspective of the current service.
+        :type operation_name: str
+
+        :param child_of: (optional) a :class:`Span` or :class:`SpanContext`
+            representing the parent in a REFERENCE_CHILD_OF reference.  If
+            specified, the `references` parameter must be omitted.
+        :type child_of: Span or SpanContext
+
+        :param references: (optional) references that identify one or more
+            parent :class:`SpanContext`\\ s. (See the Reference documentation
+            for detail).
+        :type references: :obj:`list` of :class:`Reference`
+
+        :param tags: an optional dictionary of :class:`Span` tags. The caller
+            gives up ownership of that dictionary, because the :class:`Tracer`
+            may use it as-is to avoid extra data copying.
+        :type tags: dict
+
+        :param start_time: an explicit Span start time as a unix timestamp per
+            :meth:`time.time()`
+        :type start_time: float
+
+        :param ignore_active_span: an explicit flag that ignores the current
+            active :class:`Scope` and creates a root :class:`Span`.
+        :type ignore_active_span: bool
+
+        :rtype: Span
+        :return: an already-started :class:`Span` instance.
+        """
+        return self._noop_span
+
+    def inject(self, span_context, format, carrier):
+        """Injects `span_context` into `carrier`.
+
+        The type of `carrier` is determined by `format`. See the
+        :class:`Format` class/namespace for the built-in OpenTracing formats.
+
+        Implementations *must* raise :exc:`UnsupportedFormatException` if
+        `format` is unknown or disallowed.
+
+        :param span_context: the :class:`SpanContext` instance to inject
+        :type span_context: SpanContext
+
+        :param format: a python object instance that represents a given
+            carrier format. `format` may be of any type, and `format` equality
+            is defined by python ``==`` equality.
+        :type format: Format
+        :param carrier: the format-specific carrier object to inject into
+        """
+        if format in Tracer._supported_formats:
+            return
+        raise UnsupportedFormatException(format)
+
+    def extract(self, format, carrier):
+        """Returns a :class:`SpanContext` instance extracted from a `carrier` of the
+        given `format`, or ``None`` if no such :class:`SpanContext` could be
+        found.
+
+        The type of `carrier` is determined by `format`. See the
+        :class:`Format` class/namespace for the built-in OpenTracing formats.
+
+        Implementations *must* raise :exc:`UnsupportedFormatException` if
+        `format` is unknown or disallowed.
+
+        Implementations may raise :exc:`InvalidCarrierException`,
+        :exc:`SpanContextCorruptedException`, or implementation-specific errors
+        if there are problems with `carrier`.
+
+
+        :param format: a python object instance that represents a given
+            carrier format. `format` may be of any type, and `format` equality
+            is defined by python ``==`` equality.
+
+        :param carrier: the format-specific carrier object to extract from
+
+        :rtype: SpanContext
+        :return: a :class:`SpanContext` extracted from `carrier` or ``None`` if
+            no such :class:`SpanContext` could be found.
+        """
+        if format in Tracer._supported_formats:
+            return self._noop_span_context
+        raise UnsupportedFormatException(format)
+
+
+class ReferenceType(object):
+    """A namespace for OpenTracing reference types.
+
+    See http://opentracing.io/spec for more detail about references,
+    reference types, and CHILD_OF and FOLLOWS_FROM in particular.
+    """
+    CHILD_OF = 'child_of'
+    FOLLOWS_FROM = 'follows_from'
+
+
+# We use namedtuple since references are meant to be immutable.
+# We subclass it to expose a standard docstring.
+class Reference(namedtuple('Reference', ['type', 'referenced_context'])):
+    """A Reference pairs a reference type with a referenced :class:`SpanContext`.
+
+    References are used by :meth:`Tracer.start_span()` to describe the
+    relationships between :class:`Span`\\ s.
+
+    :class:`Tracer` implementations must ignore references where
+    referenced_context is ``None``.  This behavior allows for simpler code when
+    an inbound RPC request contains no tracing information and as a result
+    :meth:`Tracer.extract()` returns ``None``::
+
+        parent_ref = tracer.extract(opentracing.HTTP_HEADERS, request.headers)
+        span = tracer.start_span(
+            'operation', references=child_of(parent_ref)
+        )
+
+    See :meth:`child_of` and :meth:`follows_from` helpers for creating these
+    references.
+    """
+    pass
+
+
+def child_of(referenced_context=None):
+    """child_of is a helper that creates CHILD_OF References.
+
+    :param referenced_context: the (causal parent) :class:`SpanContext` to
+        reference. If ``None`` is passed, this reference must be ignored by
+        the :class:`Tracer`.
+    :type referenced_context: SpanContext
+
+    :rtype: Reference
+    :return: A reference suitable for ``Tracer.start_span(...,
+        references=...)``
+    """
+    return Reference(
+        type=ReferenceType.CHILD_OF,
+        referenced_context=referenced_context)
+
+
+def follows_from(referenced_context=None):
+    """follows_from is a helper that creates FOLLOWS_FROM References.
+
+    :param referenced_context: the (causal parent) :class:`SpanContext` to
+        reference. If ``None`` is passed, this reference must be ignored by the
+        :class:`Tracer`.
+    :type referenced_context: SpanContext
+
+    :rtype: Reference
+    :return: A Reference suitable for ``Tracer.start_span(...,
+        references=...)``
+    """
+    return Reference(
+        type=ReferenceType.FOLLOWS_FROM,
+        referenced_context=referenced_context)
+
+
+def start_child_span(parent_span, operation_name, tags=None, start_time=None):
+    """A shorthand method that starts a `child_of` :class:`Span` for a given
+    parent :class:`Span`.
+
+    Equivalent to calling::
+
+        parent_span.tracer().start_span(
+            operation_name,
+            references=opentracing.child_of(parent_span.context),
+            tags=tags,
+            start_time=start_time)
+
+    :param parent_span: the :class:`Span` which will act as the parent in the
+        returned :class:`Span`\\ s child_of reference.
+    :type parent_span: Span
+
+    :param operation_name: the operation name for the child :class:`Span`
+        instance
+    :type operation_name: str
+
+    :param tags: optional dict of :class:`Span` tags. The caller gives up
+        ownership of that dict, because the :class:`Tracer` may use it as-is to
+        avoid extra data copying.
+    :type tags: dict
+
+    :param start_time: an explicit :class:`Span` start time as a unix timestamp
+        per :meth:`time.time()`.
+    :type start_time: float
+
+    :rtype: Span
+    :return: an already-started :class:`Span` instance.
+    """
+    return parent_span.tracer.start_span(
+        operation_name=operation_name,
+        child_of=parent_span,
+        tags=tags,
+        start_time=start_time
+    )

+ 5 - 0
desktop/core/ext-py/opentracing-2.2.0/requirements-test.txt

@@ -0,0 +1,5 @@
+# add dependencies in setup.py
+
+-r requirements.txt
+
+-e .[tests]

+ 3 - 0
desktop/core/ext-py/opentracing-2.2.0/requirements.txt

@@ -0,0 +1,3 @@
+# add dependencies in setup.py
+
+-e .

+ 19 - 0
desktop/core/ext-py/opentracing-2.2.0/setup.cfg

@@ -0,0 +1,19 @@
+[metadata]
+description-file = README.rst
+
+[flake8]
+max-line-length = 79
+max-complexity = 8
+exclude = ./docs/
+
+[zest.releaser]
+release = no
+history_file = CHANGELOG.rst
+
+[upload_docs]
+upload-dir = docs/_build/html
+
+[egg_info]
+tag_build = 
+tag_date = 0
+

+ 47 - 0
desktop/core/ext-py/opentracing-2.2.0/setup.py

@@ -0,0 +1,47 @@
+from setuptools import setup
+
+
+setup(
+    name='opentracing',
+    version='2.2.0',
+    author='The OpenTracing Authors',
+    author_email='opentracing@googlegroups.com',
+    description='OpenTracing API for Python. See documentation at http://opentracing.io',
+    long_description='\n'+open('README.rst').read(),
+    license='Apache License 2.0',
+    url='https://github.com/opentracing/opentracing-python',
+    keywords=['opentracing'],
+    classifiers=[
+        'Development Status :: 5 - Production/Stable',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: Apache Software License',
+        'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: Implementation :: PyPy',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+    ],
+    packages=['opentracing'],
+    include_package_data=True,
+    zip_safe=False,
+    platforms='any',
+    extras_require={
+        'tests': [
+            'doubles',
+            'flake8',
+            'flake8-quotes',
+            'mock',
+            'pytest',
+            'pytest-cov',
+            'pytest-mock',
+            'Sphinx',
+            'sphinx_rtd_theme',
+
+            'six>=1.10.0,<2.0',
+            'gevent',
+            'tornado<6',
+        ],
+        ':python_version == "2.7"': ['futures'],
+    },
+)

+ 0 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/__init__.py


+ 29 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/conftest.py

@@ -0,0 +1,29 @@
+# Copyright (c) 2016 The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+from __future__ import absolute_import
+
+import six
+
+PYTHON3_FILES = [
+    'scope_managers/test_asyncio.py',
+]
+
+if six.PY2:
+    collect_ignore = PYTHON3_FILES

+ 0 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/ext/__init__.py


+ 0 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/__init__.py


+ 36 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_api.py

@@ -0,0 +1,36 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+from __future__ import absolute_import
+import unittest
+
+from opentracing.harness.api_check import APICompatibilityCheckMixin
+from opentracing.mocktracer import MockTracer
+
+
+class APICheckMockTracer(unittest.TestCase, APICompatibilityCheckMixin):
+    def tracer(self):
+        return MockTracer()
+
+    def is_parent(self, parent, span):
+        # use `Span` ids to check parenting
+        if parent is None:
+            return span.parent_id is None
+
+        return parent.context.span_id == span.parent_id

+ 69 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_propagation.py

@@ -0,0 +1,69 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import pytest
+from opentracing import Format, SpanContextCorruptedException, \
+        UnsupportedFormatException
+from opentracing.mocktracer import MockTracer
+
+
+def test_propagation():
+    tracer = MockTracer()
+    sp = tracer.start_span(operation_name='test')
+    sp.set_baggage_item('foo', 'bar')
+
+    # Test invalid types
+    with pytest.raises(UnsupportedFormatException):
+        tracer.inject(sp.context, 'invalid', {})
+    with pytest.raises(UnsupportedFormatException):
+        tracer.extract('invalid', {})
+
+    tests = [(Format.BINARY, bytearray()),
+             (Format.TEXT_MAP, {})]
+    for format, carrier in tests:
+        tracer.inject(sp.context, format, carrier)
+        extracted_ctx = tracer.extract(format, carrier)
+
+        assert extracted_ctx.trace_id == sp.context.trace_id
+        assert extracted_ctx.span_id == sp.context.span_id
+        assert extracted_ctx.baggage == sp.context.baggage
+
+
+def test_propagation_extract_corrupted_data():
+    tracer = MockTracer()
+
+    tests = [(Format.BINARY, bytearray()),
+             (Format.TEXT_MAP, {})]
+    for format, carrier in tests:
+        with pytest.raises(SpanContextCorruptedException):
+            tracer.extract(format, carrier)
+
+
+def test_start_span():
+    """ Test in process child span creation."""
+    tracer = MockTracer()
+    sp = tracer.start_span(operation_name='test')
+    sp.set_baggage_item('foo', 'bar')
+
+    child = tracer.start_span(
+        operation_name='child', child_of=sp.context)
+    assert child.context.trace_id == sp.context.trace_id
+    assert child.context.baggage == sp.context.baggage
+    assert child.parent_id == sp.context.span_id

+ 39 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_span.py

@@ -0,0 +1,39 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from opentracing.mocktracer import MockTracer
+
+
+def test_span_log_kv():
+    tracer = MockTracer()
+
+    span = tracer.start_span('x')
+    span.log_kv({
+        'foo': 'bar',
+        'baz': 42,
+        })
+    span.finish()
+
+    finished_spans = tracer.finished_spans()
+    assert len(finished_spans) == 1
+    assert len(finished_spans[0].logs) == 1
+    assert len(finished_spans[0].logs[0].key_values) == 2
+    assert finished_spans[0].logs[0].key_values['foo'] == 'bar'
+    assert finished_spans[0].logs[0].key_values['baz'] == 42

+ 46 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/mocktracer/test_tracer.py

@@ -0,0 +1,46 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from opentracing.mocktracer import MockTracer
+
+
+def test_tracer_finished_spans():
+    tracer = MockTracer()
+
+    span_x = tracer.start_span('x')
+    span_x.finish()
+
+    span_y = tracer.start_span('y')
+    span_y.finish()
+
+    finished_spans = tracer.finished_spans()
+    assert len(finished_spans) == 2
+    assert finished_spans[0] == span_x
+    assert finished_spans[1] == span_y
+
+    # A copy per invocation.
+    assert tracer.finished_spans() is not finished_spans
+
+
+def test_tracer_reset():
+    tracer = MockTracer()
+    tracer.start_span('x').finish()
+    tracer.reset()
+    assert len(tracer.finished_spans()) == 0

+ 0 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/__init__.py


+ 51 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_asyncio.py

@@ -0,0 +1,51 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from concurrent.futures import ThreadPoolExecutor
+from unittest import TestCase
+
+import asyncio
+
+from opentracing.scope_managers.asyncio import AsyncioScopeManager
+from opentracing.harness.scope_check import ScopeCompatibilityCheckMixin
+
+
+class AsyncioCompabilityCheck(TestCase, ScopeCompatibilityCheckMixin):
+
+    def scope_manager(self):
+        return AsyncioScopeManager()
+
+    def run_test(self, test_fn):
+        @asyncio.coroutine
+        def async_test_fn():
+            test_fn()
+        asyncio.get_event_loop().run_until_complete(async_test_fn())
+
+    def test_no_event_loop(self):
+        # no event loop exists by default in
+        # new threads, so make sure we don't fail there.
+        def test_fn():
+            manager = self.scope_manager()
+            assert manager.active is None
+
+        executor = ThreadPoolExecutor(max_workers=1)
+        executor.submit(test_fn).result()

+ 36 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_gevent.py

@@ -0,0 +1,36 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from unittest import TestCase
+
+import gevent
+
+from opentracing.scope_managers.gevent import GeventScopeManager
+from opentracing.harness.scope_check import ScopeCompatibilityCheckMixin
+
+
+class GeventCompabilityCheck(TestCase, ScopeCompatibilityCheckMixin):
+    def scope_manager(self):
+        return GeventScopeManager()
+
+    def run_test(self, test_fn):
+        gevent.spawn(test_fn).get()

+ 30 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_threadlocal.py

@@ -0,0 +1,30 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+from unittest import TestCase
+
+from opentracing.scope_managers import ThreadLocalScopeManager
+from opentracing.harness.scope_check import ScopeCompatibilityCheckMixin
+
+
+class ThreadLocalCompabilityCheck(TestCase, ScopeCompatibilityCheckMixin):
+    def scope_manager(self):
+        return ThreadLocalScopeManager()

+ 38 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/scope_managers/test_tornado.py

@@ -0,0 +1,38 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from unittest import TestCase
+
+from tornado import ioloop
+
+from opentracing.scope_managers.tornado import TornadoScopeManager
+from opentracing.scope_managers.tornado import tracer_stack_context
+from opentracing.harness.scope_check import ScopeCompatibilityCheckMixin
+
+
+class TornadoCompabilityCheck(TestCase, ScopeCompatibilityCheckMixin):
+    def scope_manager(self):
+        return TornadoScopeManager()
+
+    def run_test(self, test_fn):
+        with tracer_stack_context():
+            ioloop.IOLoop.current().run_sync(test_fn)

+ 33 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_api.py

@@ -0,0 +1,33 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+import unittest
+from opentracing import Tracer
+from opentracing.harness.api_check import APICompatibilityCheckMixin
+
+
+class APICheckNoopTracer(unittest.TestCase, APICompatibilityCheckMixin):
+    """
+    Run tests from APICompatibilityCheckMixin against default No-op Tracer.
+    """
+
+    def tracer(self):
+        return Tracer()
+
+    def check_baggage_values(self):
+        return False
+
+    def check_scope_manager(self):
+        return False

+ 75 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_api_check_mixin.py

@@ -0,0 +1,75 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+import unittest
+from opentracing import Tracer
+from opentracing.harness.api_check import APICompatibilityCheckMixin
+
+
+class VerifyAPICompatibilityCheck(unittest.TestCase):
+    def test_tracer_exception(self):
+        api_check = APICompatibilityCheckMixin()
+        with self.assertRaises(NotImplementedError):
+            api_check.tracer()
+
+    def test_default_baggage_check_mode(self):
+        api_check = APICompatibilityCheckMixin()
+        assert api_check.check_baggage_values() is True
+
+    def test_default_scope_manager_check_mode(self):
+        api_check = APICompatibilityCheckMixin()
+        assert api_check.check_scope_manager() is True
+
+    def test_baggage_check_works(self):
+        api_check = APICompatibilityCheckMixin()
+        setattr(api_check, 'tracer', lambda: Tracer())
+
+        # no-op tracer does not store baggage, so the test with default
+        # value of `check_baggage_values()` should fail.
+        with self.assertRaises(AssertionError):
+            api_check.test_span_baggage()
+
+        # second check that assert on empty baggage will fail too
+        with self.assertRaises(AssertionError):
+            api_check.test_context_baggage()
+
+    def test_scope_manager_check_works(self):
+        api_check = APICompatibilityCheckMixin()
+        setattr(api_check, 'tracer', lambda: Tracer())
+
+        # these tests are expected to succeed
+        api_check.test_start_active_span_ignore_active_span()
+        api_check.test_start_span_propagation_ignore_active_span()
+
+        # no-op tracer has a no-op ScopeManager implementation,
+        # which means no *actual* propagation is done,
+        # so these tests are expected to work, but asserts to fail
+        with self.assertRaises(AssertionError):
+            api_check.test_start_active_span()
+
+        with self.assertRaises(AssertionError):
+            api_check.test_start_active_span_parent()
+
+        with self.assertRaises(AssertionError):
+            api_check.test_start_span_propagation()
+
+        with self.assertRaises(AssertionError):
+            api_check.test_tracer_start_active_span_scope()
+
+        with self.assertRaises(AssertionError):
+            api_check.test_tracer_start_span_scope()
+
+        with self.assertRaises(AssertionError):
+            api_check.test_start_active_span_finish_on_close()

+ 49 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_globaltracer.py

@@ -0,0 +1,49 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+import pytest
+import mock
+import opentracing
+
+
+def teardown_function(function):
+    opentracing._reset_global_tracer()
+
+
+def test_opentracing_tracer():
+    assert opentracing.tracer is opentracing.global_tracer()
+    assert isinstance(opentracing.global_tracer(), opentracing.Tracer)
+
+
+def test_is_global_tracer_registered():
+    assert opentracing.is_global_tracer_registered() is False
+
+
+def test_set_global_tracer():
+    tracer = mock.Mock()
+    opentracing.set_global_tracer(tracer)
+    assert opentracing.global_tracer() is tracer
+    assert opentracing.is_global_tracer_registered()
+
+    # Register another value.
+    tracer = mock.Mock()
+    opentracing.set_global_tracer(tracer)
+    assert opentracing.global_tracer() is tracer
+    assert opentracing.is_global_tracer_registered()
+
+
+def test_register_none():
+    with pytest.raises(ValueError):
+        opentracing.set_global_tracer(None)

+ 121 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_noop_span.py

@@ -0,0 +1,121 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+import mock
+import time
+import types
+from opentracing import child_of
+from opentracing import Format
+from opentracing import Tracer
+from opentracing import logs
+from opentracing import tags
+
+
+def test_span():
+    tracer = Tracer()
+    parent = tracer.start_span('parent')
+    child = tracer.start_span('test', references=child_of(parent.context))
+    assert parent == child
+    child.log_kv({'event': 'cache_hit', 'size.bytes': 42})
+    child.log_kv({'event': 'cache_miss'}, time.time())
+    child.log_event('cache_hit', ['arg1', 'arg2'])
+
+    with mock.patch.object(parent, 'finish') as finish:
+        with mock.patch.object(parent, 'log_event') as log_event:
+            with mock.patch.object(parent, 'log_kv') as log_kv:
+                with mock.patch.object(parent, 'set_tag') as set_tag:
+                    try:
+                        with parent:
+                            raise ValueError()
+                    except ValueError:
+                        pass
+                    assert finish.call_count == 1
+                    assert log_event.call_count == 0
+                    assert log_kv.call_count == 1
+                    assert set_tag.call_count == 1
+
+    with mock.patch.object(parent, 'finish') as finish:
+        with mock.patch.object(parent, 'log_event') as log_kv:
+            with parent:
+                pass
+            assert finish.call_count == 1
+            assert log_kv.call_count == 0
+
+    parent.set_tag('x', 'y').set_tag('z', 1)  # test chaining
+    parent.set_tag(tags.PEER_SERVICE, 'test-service')
+    parent.set_tag(tags.PEER_HOST_IPV4, 127 << 24 + 1)
+    parent.set_tag(tags.PEER_HOST_IPV6, '::')
+    parent.set_tag(tags.PEER_HOSTNAME, 'uber.com')
+    parent.set_tag(tags.PEER_PORT, 123)
+    parent.finish()
+
+
+def test_span_error_report():
+    tracer = Tracer()
+    span = tracer.start_span('foo')
+    error_message = 'unexpected_situation'
+
+    with mock.patch.object(span, 'log_kv') as log_kv:
+        with mock.patch.object(span, 'set_tag') as set_tag:
+            try:
+                with span:
+                    raise ValueError(error_message)
+            except ValueError:
+                pass
+
+            assert set_tag.call_count == 1
+            assert set_tag.call_args[0] == (tags.ERROR, True)
+
+            assert log_kv.call_count == 1
+            log_kv_args = log_kv.call_args[0][0]
+            assert log_kv_args.get(logs.EVENT, None) is tags.ERROR
+            assert log_kv_args.get(logs.MESSAGE, None) is error_message
+            assert log_kv_args.get(logs.ERROR_KIND, None) is ValueError
+            assert isinstance(log_kv_args.get(logs.ERROR_OBJECT, None),
+                              ValueError)
+            assert isinstance(log_kv_args.get(logs.STACK, None),
+                              types.TracebackType)
+
+
+def test_inject():
+    tracer = Tracer()
+    span = tracer.start_span()
+
+    bin_carrier = bytearray()
+    tracer.inject(
+        span_context=span.context,
+        format=Format.BINARY,
+        carrier=bin_carrier)
+    assert bin_carrier == bytearray()
+
+    text_carrier = {}
+    tracer.inject(
+        span_context=span.context,
+        format=Format.TEXT_MAP,
+        carrier=text_carrier)
+    assert text_carrier == {}
+
+
+def test_extract():
+    tracer = Tracer()
+    noop_span = tracer._noop_span
+
+    bin_carrier = bytearray()
+    span_ctx = tracer.extract(Format.BINARY, carrier=bin_carrier)
+    assert noop_span.context == span_ctx
+
+    text_carrier = {}
+    span_ctx = tracer.extract(Format.TEXT_MAP, carrier=text_carrier)
+    assert noop_span.context == span_ctx

+ 30 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_noop_tracer.py

@@ -0,0 +1,30 @@
+# Copyright The OpenTracing Authors
+#
+# 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.
+
+from __future__ import absolute_import
+from opentracing import child_of
+from opentracing import Tracer
+
+
+def test_tracer():
+    tracer = Tracer()
+    span = tracer.start_span(operation_name='root')
+    child = tracer.start_span(operation_name='child',
+                              references=child_of(span))
+    assert span == child
+
+
+def test_tracer_active_span():
+    tracer = Tracer()
+    assert tracer.active_span is tracer.scope_manager.active.span

+ 85 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_scope.py

@@ -0,0 +1,85 @@
+# Copyright (c) 2017 The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+import mock
+import types
+
+from opentracing.scope_manager import ScopeManager
+from opentracing.tracer import Tracer
+from opentracing.scope import Scope
+from opentracing.span import Span, SpanContext
+from opentracing import tags
+from opentracing import logs
+
+
+def test_scope_wrapper():
+    # ensure `Scope` wraps the `Span` argument
+    span = Span(tracer=Tracer(), context=SpanContext())
+    scope = Scope(ScopeManager, span)
+    assert scope.span == span
+
+
+def test_scope_context_manager():
+    # ensure `Scope` can be used in a Context Manager that
+    # calls the `close()` method
+    span = Span(tracer=Tracer(), context=SpanContext())
+    scope = Scope(ScopeManager(), span)
+    with mock.patch.object(scope, 'close') as close:
+        with scope:
+            pass
+        assert close.call_count == 1
+
+
+def test_scope_error_report():
+    tracer = Tracer()
+    scope = tracer.start_active_span('foo')
+    error_message = 'unexpected_situation'
+
+    with mock.patch.object(scope.span, 'log_kv') as log_kv:
+        with mock.patch.object(scope.span, 'set_tag') as set_tag:
+            try:
+                with scope:
+                    raise ValueError(error_message)
+            except ValueError:
+                pass
+
+            assert set_tag.call_count == 1
+            assert set_tag.call_args[0] == (tags.ERROR, True)
+
+            assert log_kv.call_count == 1
+            log_kv_args = log_kv.call_args[0][0]
+            assert log_kv_args.get(logs.EVENT, None) is tags.ERROR
+            assert log_kv_args.get(logs.MESSAGE, None) is error_message
+            assert log_kv_args.get(logs.ERROR_KIND, None) is ValueError
+            assert isinstance(log_kv_args.get(logs.ERROR_OBJECT, None),
+                              ValueError)
+            assert isinstance(log_kv_args.get(logs.STACK, None),
+                              types.TracebackType)
+
+
+def test_scope_exit_with_no_span():
+    # ensure `Scope.__exit__` doesn't fail with `AttributeError`
+    try:
+        with Scope(None, None):
+            raise ValueError
+    except ValueError:
+        pass

+ 66 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_scope_check_mixin.py

@@ -0,0 +1,66 @@
+# Copyright (c) The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+from __future__ import absolute_import
+import unittest
+from opentracing import ScopeManager
+from opentracing.harness.scope_check import ScopeCompatibilityCheckMixin
+
+
+class VerifyScopeCompatibilityCheck(unittest.TestCase):
+    def test_scope_manager_exception(self):
+        scope_check = ScopeCompatibilityCheckMixin()
+        with self.assertRaises(NotImplementedError):
+            scope_check.scope_manager()
+
+    def test_missing_active_works(self):
+        scope_check = ScopeCompatibilityCheckMixin()
+        setattr(scope_check, 'scope_manager', lambda: ScopeManager())
+
+        with self.assertRaises(AssertionError):
+            scope_check.test_missing_active()
+
+        with self.assertRaises(AssertionError):
+            scope_check.test_missing_active_external()
+
+    def test_activate_works(self):
+        scope_check = ScopeCompatibilityCheckMixin()
+        setattr(scope_check, 'scope_manager', lambda: ScopeManager())
+
+        with self.assertRaises(AssertionError):
+            scope_check.test_activate()
+
+        with self.assertRaises(AssertionError):
+            scope_check.test_activate_external()
+
+        with self.assertRaises(AssertionError):
+            scope_check.test_activate_finish_on_close()
+
+        with self.assertRaises(AssertionError):
+            scope_check.test_activate_nested()
+
+        with self.assertRaises(AssertionError):
+            scope_check.test_activate_finish_on_close_nested()
+
+    def test_close_wrong_order(self):
+        scope_check = ScopeCompatibilityCheckMixin()
+        setattr(scope_check, 'scope_manager', lambda: ScopeManager())
+
+        # this test is expected to succeed.
+        scope_check.test_close_wrong_order()

+ 34 - 0
desktop/core/ext-py/opentracing-2.2.0/tests/test_scope_manager.py

@@ -0,0 +1,34 @@
+# Copyright (c) 2017 The OpenTracing Authors.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from __future__ import absolute_import
+
+from opentracing.scope_manager import ScopeManager
+from opentracing.tracer import Tracer
+from opentracing.span import Span, SpanContext
+
+
+def test_scope_manager():
+    # ensure the activation returns the noop `Scope` that is always active
+    scope_manager = ScopeManager()
+    span = Span(tracer=Tracer(), context=SpanContext())
+    scope = scope_manager.activate(span, False)
+    assert scope == scope_manager._noop_scope
+    assert scope == scope_manager.active

+ 7 - 0
desktop/core/ext-py/opentracing-2.2.0/tox.ini

@@ -0,0 +1,7 @@
+[tox]
+envlist = py27,py35,py36,py37
+
+[testenv]
+install_command = pip install {opts} {packages} {env:PWD}[tests]
+whitelist_externals = make
+commands =  make test testbed lint