From 5f4a12c5d6fdbf533a505f15924c2443c85bed58 Mon Sep 17 00:00:00 2001 From: Laurent Mazuel Date: Mon, 10 Jun 2019 10:15:46 -0700 Subject: [PATCH] Devtools (#5759) * Initial commit * Initial commit * Initial commit * wip: initial work - incomplete * Copy code from https://github.com/Azure/azure-cli/tree/master/src/azure-cli-testsdk * Add vcrpy version from azure-cli * Add VSCode ignores * Add Azure imports * Start converting CLI commands to SDK calls * Minor proofreading * Add required common and mock modules * Add deps, update pkgs and url * Package structure * Add more editor ignores * Remove azure deps and nonexistent HISTORY ref * Remove Azure mgmt dependencies * Remove azure.common dependency * Add dependency on six * Remove CLI-specific stuff * Remove CLI exception * Remove most CLI-centric patches * Remove older CLI-centric base class * Add sleep patch back in * First steps toward a unified config * Config and no-record headers Add config object to ScenarioTest Add fake header for deactivating recording Align cmdline options with vcr.py options * Move recording-deactivation header detection to right place * Add way to set default config file from scenario test * Remove 'CLI' from env vars * Reinstate patch_long_run_operation_delay * New record disabling mechanism * Modify config options for better backwards compatibility * Ignore more VS stuff * Remove jmespath dependency, update vcrpy * Remove checkers * Remove unuseds, make patches/processors kwargs * Remove checkers, used only for CLI * Update import and instance var name * Remove unused imports * line organization * Update version number and vcrpy version * Add a little more to README, add setup.cfg * Add unit tests for TestConfig * Add travis.yml and update dependencies * Update author email * Dummy push to try to trigger a Travis build * Another dummy commit for Travis * Switch to README.rst * Update Travis tag pointer * Use io to get encoding arg when reading README * Remove unnecessary import * Expose most everything in top-level namespace * ScenarioTest -> ReplayableTest; update version * Update version * Remove unused os.path import * Fix super call * Fix super call in setUp * Update ReplayableTest import * Use earlier vcrpy, update version num * Don't fix vcrpy version * Drop "cli" from default random name prefix * Add deployment to Travis * Specify universal wheel * Bump version to 0.2.2 for testing CI release process * Let preparer subclasses override create_random_name * De-"privatize" mock_in_unit_test and expose it * Bump version to 0.3.0 * Set disable_recording from kwarg * Don't treat mock_in_unit_test as a unittest * Remove skip for mock_in_unit_test, specify test dir * Update version numbers * Remove extraneous requirements * Remove outdated README.md stuff * Update install for new requirements.txt * Add 3.6-dev to pythons * Update code style and run pylint in Travis * Integrate with codecov.io * Add test cover IntegrationTestBase Also check in IntelliJ IDEA workspace configuration just in case someone else is using PyCharm * Add test case for LiveTest constructor * Add tests cover create_random_name * Add test covering get_sha1_hash * Add test cover RecordingProcessor base class * Add test covering SubscriptionRecordingProcessor * Configure code coverage using configuration file * Use unittest instead of nosetests to drive the automation * Fix a few code style issues * Rename coveragerc file * Add AccessTokenProcessor * Split intro and overview into clauses * Back to paragraphs * Update intro, add vcr link * Update intro paragraph to be more general * Remove reference to command modules * Update test and module refs; clarify VCR.py role * Remove outdated reference to class with builtin preparer * Replace intro text Use intro stolen from defunct recording_vcr_tests.md * s/ScenarioTest/ReplayableTest/ * Add note about semantic linefeeds * Make semantic linefeeds note an HTML comment * Remove CLI examples and add links to consumers * Remove doc for legacy test case class * Finish sentence * Add subclass kwarg information * Fix subscription ID removal and test new cases * Fix no-self-use linter complaint * Downgrade the version of vcrpy dependency from 1.11.1 to 1.11.0 due to a sympton similar to this https://github.com/kevin1024/vcrpy/issues/318 * Bump version to 0.5.0 to prepare for release * Fix import on Py3 not-TravisCI * Fix recordmode * Tight config test * url parsing fix * fixed pylint import order * pylint import fix * added record processor for slashes * changed processor name * Bump version 0.5.0 => 0.5.1 * Fix SubscriptionIdReplacer * Update version 0.5.1 => 0.5.2 * Update __init__.py * Detect leaked LRO poller * PyLint happiness * Improve error message * wip * fix error * use base 64 * simplify * add comments * fix tests * fix lint error * use newer pylint to avoid invalid line errors * add a new test * address review feedback * address review feedback * support large response payload * remove useless single quots from the error message * setup: update version * do not use preparer model for allowing large payload * address review feedback * Support Autorest.Python 3.x LRO leak (#42) * Support Autorest.Python 3.x LRO leak * PyLint happyness * Bump version to 0.5.5 * Update the resource removal sequence Also: 1. Adopt py.test over nosetest 2. Cleanup some test code * remove x-ms-authorization-auxiliary header * fix lint error * update version * Add some CI tools to devtools * Readme update * Some tests configuration * Use Pytest as test launcher * PyLint fixes * CI tools tests are Py3.6 only * PyLint CI tools only if 3.6 * CI tools tests recording * Dont't Pylint the tests * Fix incorrect usage of os.environ * Make tests X-platform valid * Fix test dependent of traceback * Robust preparer testing * PyGithub 1.40 * Release 1.1.0 * Allow clone_to_path to have both PR and SHA1 (#49) * Allow clone_to_path to have both PR and SHA1 * Fix test * Update github_tools.py (#55) * SingleValueReplacer.process_request properly decodes request.body if its type is byte. (#56) * Remove pointless files * Move to tools * Update dev_requirement file * Don't record requests to AAD OAuth2 v2.0 endpoint * Use devtools from repo, not from PyPI * Fix mock dep --- scripts/dev_setup.py | 16 +- tools/azure-devtools/LICENSE | 21 + tools/azure-devtools/README.rst | 32 ++ tools/azure-devtools/dev_requirements.txt | 4 + .../azure-devtools/doc/scenario_base_tests.md | 101 +++++ tools/azure-devtools/scripts/ci.sh | 4 + tools/azure-devtools/setup.cfg | 2 + tools/azure-devtools/setup.py | 63 +++ .../src/azure_devtools/__init__.py | 0 .../src/azure_devtools/ci_tools/__init__.py | 4 + .../azure_devtools/ci_tools/bot_framework.py | 121 ++++++ .../src/azure_devtools/ci_tools/git_tools.py | 90 +++++ .../azure_devtools/ci_tools/github_tools.py | 374 +++++++++++++++++ ...otFrameworkTest.test_bot_basic_command.txt | 77 ++++ ...otFrameworkTest.test_bot_basic_failure.txt | 77 ++++ .../BotFrameworkTest.test_bot_help.txt | 66 +++ ...FrameworkTest.test_bot_unknown_command.txt | 66 +++ .../BotFrameworkTest.test_webhook_data.txt | 66 +++ .../GithubTools.test_clone_path.txt | 99 +++++ .../ReplayData/GithubTools.test_configure.txt | 11 + .../GithubTools.test_create_comment.txt | 66 +++ .../ReplayData/GithubTools.test_dashboard.txt | 110 +++++ .../GithubTools.test_exception_to_github.txt | 99 +++++ .../ReplayData/GithubTools.test_get_files.txt | 33 ++ .../GithubTools.test_get_or_create_pull.txt | 22 + .../ReplayData/GithubTools.test_get_user.txt | 11 + .../GithubTools.test_manage_git_folder.txt | 33 ++ .../azure_devtools/ci_tools/tests/__init__.py | 0 .../azure_devtools/ci_tools/tests/conftest.py | 44 ++ .../ci_tools/tests/test_bot_framework.py | 215 ++++++++++ .../ci_tools/tests/test_git_tools.py | 72 ++++ .../ci_tools/tests/test_github_tools.py | 382 ++++++++++++++++++ .../azure_devtools/scenario_tests/__init__.py | 28 ++ .../src/azure_devtools/scenario_tests/base.py | 214 ++++++++++ .../azure_devtools/scenario_tests/config.py | 28 ++ .../azure_devtools/scenario_tests/const.py | 14 + .../scenario_tests/decorators.py | 44 ++ .../scenario_tests/exceptions.py | 10 + .../azure_devtools/scenario_tests/patches.py | 37 ++ .../scenario_tests/preparers.py | 122 ++++++ .../scenario_tests/recording_processors.py | 200 +++++++++ .../scenario_tests/tests/__init__.py | 4 + .../scenario_tests/tests/test_config.py | 36 ++ .../tests/test_integration_test_base.py | 58 +++ .../tests/test_preparer_order.py | 42 ++ .../tests/test_recording_processor.py | 141 +++++++ .../scenario_tests/tests/test_utilities.py | 121 ++++++ .../scenario_tests/utilities.py | 81 ++++ tools/azure-sdk-tools/dev_requirements.txt | 1 + 49 files changed, 3557 insertions(+), 5 deletions(-) create mode 100644 tools/azure-devtools/LICENSE create mode 100644 tools/azure-devtools/README.rst create mode 100644 tools/azure-devtools/dev_requirements.txt create mode 100644 tools/azure-devtools/doc/scenario_base_tests.md create mode 100755 tools/azure-devtools/scripts/ci.sh create mode 100644 tools/azure-devtools/setup.cfg create mode 100644 tools/azure-devtools/setup.py create mode 100644 tools/azure-devtools/src/azure_devtools/__init__.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/__init__.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/bot_framework.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/git_tools.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/github_tools.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_command.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_failure.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_help.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_unknown_command.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_webhook_data.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_clone_path.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_configure.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_create_comment.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_dashboard.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_exception_to_github.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_files.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_or_create_pull.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_user.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_manage_git_folder.txt create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/__init__.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/conftest.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_bot_framework.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_git_tools.py create mode 100644 tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_github_tools.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/__init__.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/base.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/config.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/const.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/decorators.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/exceptions.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/patches.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/preparers.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/recording_processors.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/tests/__init__.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/tests/test_config.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/tests/test_integration_test_base.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/tests/test_preparer_order.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/tests/test_recording_processor.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/tests/test_utilities.py create mode 100644 tools/azure-devtools/src/azure_devtools/scenario_tests/utilities.py create mode 100644 tools/azure-sdk-tools/dev_requirements.txt diff --git a/scripts/dev_setup.py b/scripts/dev_setup.py index d484a0a4eae6..eda83ccd80a8 100644 --- a/scripts/dev_setup.py +++ b/scripts/dev_setup.py @@ -74,15 +74,20 @@ def pip_command(command, additional_dir=".", error_ok=False): ] ) -# Put azure-common in front -if "azure-common" in content_packages: - content_packages.remove("azure-common") -content_packages.insert(0, "azure-common") +# Install tests dep first +if "azure-devtools" in content_packages: + content_packages.remove("azure-devtools") +content_packages.insert(0, "azure-devtools") if "azure-sdk-tools" in content_packages: content_packages.remove("azure-sdk-tools") content_packages.insert(1, "azure-sdk-tools") +# Put azure-common in front of content package +if "azure-common" in content_packages: + content_packages.remove("azure-common") +content_packages.insert(2, "azure-common") + print("Running dev setup...") print("Root directory '{}'\n".format(root_dir)) @@ -100,8 +105,9 @@ def pip_command(command, additional_dir=".", error_ok=False): pip_command("install {}/{}/".format(packages[package_name], package_name)) # install packages +print("Packages to install: {}".format(content_packages)) for package_name in content_packages: - print("Installing {}".format(package_name)) + print("\nInstalling {}".format(package_name)) # if we are running dev_setup with no arguments. going after dev_requirements will be a pointless exercise # and waste of cycles as all the dependencies will be installed regardless. if os.path.isfile( diff --git a/tools/azure-devtools/LICENSE b/tools/azure-devtools/LICENSE new file mode 100644 index 000000000000..4b1ad51b2f0e --- /dev/null +++ b/tools/azure-devtools/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + 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 diff --git a/tools/azure-devtools/README.rst b/tools/azure-devtools/README.rst new file mode 100644 index 000000000000..bdf397897d71 --- /dev/null +++ b/tools/azure-devtools/README.rst @@ -0,0 +1,32 @@ +.. image:: https://travis-ci.org/Azure/azure-python-devtools.svg?branch=master + :target: https://travis-ci.org/Azure/azure-python-devtools + +Development tools for Python-based Azure tools +============================================== + +This package contains tools to aid in developing Python-based Azure code. + +This includes the following components: + +scenario_tests +-------------- + +A testing framework to handle much of the busywork +associated with testing code that interacts with Azure. + +ci_tools +-------- + +Some tooling to help developing CI tools. This includes some Git helpers, +Github RestAPI wrapper and a Bot framework for Github issues. + +Contributing +============ + +This project has adopted the +`Microsoft Open Source Code of Conduct `__. +For more information see the +`Code of Conduct FAQ `__ +or contact +`opencode@microsoft.com `__ +with any additional questions or comments. diff --git a/tools/azure-devtools/dev_requirements.txt b/tools/azure-devtools/dev_requirements.txt new file mode 100644 index 000000000000..9ab230d71c73 --- /dev/null +++ b/tools/azure-devtools/dev_requirements.txt @@ -0,0 +1,4 @@ +-e .[ci_tools] + +mock;python_version<="2.7" +pytest diff --git a/tools/azure-devtools/doc/scenario_base_tests.md b/tools/azure-devtools/doc/scenario_base_tests.md new file mode 100644 index 000000000000..945b9eadeed8 --- /dev/null +++ b/tools/azure-devtools/doc/scenario_base_tests.md @@ -0,0 +1,101 @@ +# How to write ReplayableTest based VCR tests + +The `scenario_tests` package uses the [VCR.py](https://pypi.python.org/pypi/vcrpy) library +to record the HTTP messages exchanged during a program run +and play them back at a later time, +making it useful for creating "scenario tests" +that interact with Azure (or other) services. +These tests can be replayed at a later time without any network activity, +allowing us to detect changes in the Python layers +between the code being tested and the underlying REST API. + + +## Overview + +Tests all derive from the `ReplayableTest` class +found in `azure_devtools.scenario_tests.base`. +This class exposes the VCR tests using the standard Python `unittest` framework +and allows the tests to be discovered by and debugged in Visual Studio. + +When you run a test, +the test driver will automatically detect the test is unrecorded +and record the HTTP requests and responses in a .yaml file +(referred to by VCR.py as a "cassette"). +If the test succeeds, the cassette will be preserved +and future playthroughs of the test will come from the cassette +rather than using actual network communication. + +If the tests are run on TravisCI, +any tests which cannot be replayed will automatically fail. + +`ReplayableTest` itself derives from `IntegrationTestBase`, +which provides some helpful methods for use in more general unit tests +but no functionality pertaining to network communication. + + +## Configuring ReplayableTest + +The only configuration of `ReplayableTest` that is "exposed" +(in the sense of being accessible other than through subclassing) +is whether tests should be run in "live" or "playback" mode. +This can be set in the following two ways, +of which the first takes precedence: +* Set the environment variable `AZURE_TEST_RUN_LIVE`. + Any value will cause the tests to run in live mode; + if the variable is unset the default of playback mode will be used. +* Specify a boolean value for `live-mode` in a configuration file, + the path to which must be specified by a `ReplayableTest` subclass as described below + (i.e. by default no config file will be read). + True values mean "live" mode; false ones mean "playback." + +"Live" and "playback" mode are actually just shorthand for recording modes +in the underlying VCR.py package; +they correspond to "all" and "once" +as described in the [VCR.py documentation](http://vcrpy.readthedocs.io/en/latest/usage.html#record-modes). + +### Subclassing ReplayableTest and features + +Most customization of `ReplayableTest` is accessible only through subclassing. + +The two main users of `ReplayableTest` are +[azure-cli](https://github.com/Azure/azure-cli) +and [azure-sdk-for-python](https://github.com/Azure/azure-sdk-for-python). +Each uses a subclass of `ReplayableTest` to add context-specific functionality +and preserve backward compatibility with test code +prior to the existence of `azure-devtools`. +For example, azure-cli's [compatibility layer](https://github.com/Azure/azure-cli/tree/master/src/azure-cli-testsdk) +adds methods for running CLI commands and evaluating their output. + +Subclasses of `ReplayableTest` can configure its behavior +by passing the following keyword arguments when they call +its `__init__` method (probably using `super`): + +* `config_file`: Path to a configuration file. + It should be in the format described in Python's + [ConfigParser](https://docs.python.org/3/library/configparser.html) docs + and currently allows only the boolean option `live-mode`. +* `recording_dir` and `recording_name`: + Directory path and file name, respectively, + for the recording that should be used for a given test case. + By default, the directory will be a `recordings` directory + in the same location as the file containing the test case, + and the file name will be the same as the test method name. + A `.yaml` extension will be appended to whatever is used for `recording_name`. +* `recording_processors` and `replay_processors`: + Lists of `RecordingProcessor` instances for making changes to requests and responses + during test recording and test playback, respectively. + See [recording_processors.py](src/azure_devtools/scenario_tests/recording_processors.py) + for some examples and how to implement them. +* `recording_patches` and `replay_patches`: + Lists of patches to apply to functions, methods, etc. + during test recording and playback, respectively. + See [patches.py](src/azure_devtools/scenario_tests/patches.py) + for some examples. Note the `mock_in_unit_test` function + which abstracts out some boilerplate for applying a patch. + + + \ No newline at end of file diff --git a/tools/azure-devtools/scripts/ci.sh b/tools/azure-devtools/scripts/ci.sh new file mode 100755 index 000000000000..7fec520d06f8 --- /dev/null +++ b/tools/azure-devtools/scripts/ci.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +pylint src/azure_devtools +pytest src/azure_devtools/scenario_tests/tests --cov=./ \ No newline at end of file diff --git a/tools/azure-devtools/setup.cfg b/tools/azure-devtools/setup.cfg new file mode 100644 index 000000000000..3c6e79cf31da --- /dev/null +++ b/tools/azure-devtools/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal=1 diff --git a/tools/azure-devtools/setup.py b/tools/azure-devtools/setup.py new file mode 100644 index 000000000000..7a332ffb384a --- /dev/null +++ b/tools/azure-devtools/setup.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import io +from setuptools import setup + + +VERSION = "1.1.1" + + +CLASSIFIERS = [ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Developers', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'License :: OSI Approved :: MIT License', +] + + +DEPENDENCIES = [ + 'ConfigArgParse>=0.12.0', + 'six>=1.10.0', + 'vcrpy>=1.11.0', +] + +with io.open('README.rst', 'r', encoding='utf-8') as f: + README = f.read() + +setup( + name='azure-devtools', + version=VERSION, + description='Microsoft Azure Development Tools for SDK', + long_description=README, + license='MIT', + author='Microsoft Corporation', + author_email='ptvshelp@microsoft.com', + url='https://github.com/Azure/azure-python-devtools', + zip_safe=False, + classifiers=CLASSIFIERS, + packages=[ + 'azure_devtools', + 'azure_devtools.scenario_tests', + 'azure_devtools.ci_tools', + ], + extras_require={ + 'ci_tools':[ + "PyGithub>=1.40", # Can Merge PR after 1.36, "requests" and tests after 1.40 + "GitPython", + "requests>=2.0" + ] + }, + package_dir={'': 'src'}, + install_requires=DEPENDENCIES, +) diff --git a/tools/azure-devtools/src/azure_devtools/__init__.py b/tools/azure-devtools/src/azure_devtools/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/__init__.py b/tools/azure-devtools/src/azure_devtools/ci_tools/__init__.py new file mode 100644 index 000000000000..34913fb394d7 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/__init__.py @@ -0,0 +1,4 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/bot_framework.py b/tools/azure-devtools/src/azure_devtools/ci_tools/bot_framework.py new file mode 100644 index 000000000000..13fb436b20f5 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/bot_framework.py @@ -0,0 +1,121 @@ +from collections import namedtuple +from functools import lru_cache +import logging +import os +import re + +from github import Github, GithubException, UnknownObjectException + +from .github_tools import ( + exception_to_github, +) + +_LOGGER = logging.getLogger(__name__) + + +def order(function): + function.bot_order = True + return function + +WebhookMetadata = namedtuple( + 'WebhookMetadata', + ['repo', 'issue', 'text', 'comment'] +) + +def build_from_issue_comment(gh_token, body): + """Create a WebhookMetadata from a comment added to an issue. + """ + if body["action"] in ["created", "edited"]: + github_con = Github(gh_token) + repo = github_con.get_repo(body['repository']['full_name']) + issue = repo.get_issue(body['issue']['number']) + text = body['comment']['body'] + try: + comment = issue.get_comment(body['comment']['id']) + except UnknownObjectException: + # If the comment has already disapeared, skip the command + return None + return WebhookMetadata(repo, issue, text, comment) + return None + +def build_from_issues(gh_token, body): + """Create a WebhookMetadata from an opening issue text. + """ + if body["action"] in ["opened", "edited"]: + github_con = Github(gh_token) + repo = github_con.get_repo(body['repository']['full_name']) + issue = repo.get_issue(body['issue']['number']) + text = body['issue']['body'] + comment = issue # It's where we update the comment: in the issue itself + return WebhookMetadata(repo, issue, text, comment) + return None + +@lru_cache() +def robot_name_from_env_variable(): + github_con = Github(os.environ["GH_TOKEN"]) + return github_con.get_user().login + + +class BotHandler: + def __init__(self, handler, robot_name=None, gh_token=None): + self.handler = handler + self.gh_token = gh_token or os.environ["GH_TOKEN"] + self.robot_name = robot_name or robot_name_from_env_variable() + + def _is_myself(self, body): + return body['sender']['login'].lower() == self.robot_name.lower() + + def issue_comment(self, body): + if self._is_myself(body): + return {'message': 'I don\'t talk to myself, I\'m not schizo'} + webhook_data = build_from_issue_comment(self.gh_token, body) + return self.manage_comment(webhook_data) + + def issues(self, body): + if self._is_myself(body): + return {'message': 'I don\'t talk to myself, I\'m not schizo'} + webhook_data = build_from_issues(self.gh_token, body) + return self.manage_comment(webhook_data) + + def orders(self): + """Return method tagged "order" in the handler. + """ + return [order_cmd for order_cmd in dir(self.handler) + if getattr(getattr(self.handler, order_cmd), "bot_order", False)] + + def manage_comment(self, webhook_data): + if webhook_data is None: + return {'message': 'Nothing for me'} + # Is someone talking to me: + message = re.search("@{} (.*)".format(self.robot_name), webhook_data.text, re.I) + response = None + if message: + command = message.group(1) + split_text = command.lower().split() + orderstr = split_text.pop(0) + if orderstr == "help": + response = self.help_order() + elif orderstr in self.orders(): + try: # Reaction is fun, but it's preview not prod. + # Be careful, don't fail the command if we can't thumbs up... + webhook_data.comment.create_reaction("+1") + except GithubException: + pass + with exception_to_github(webhook_data.issue): # Just in case + response = getattr(self.handler, orderstr)(webhook_data.issue, *split_text) + else: + response = "I didn't understand your command:\n```bash\n{}\n```\nin this context, sorry :(\n".format( + command + ) + response += self.help_order() + if response: + webhook_data.issue.create_comment(response) + return {'message': response} + return {'message': 'Nothing for me or exception'} + + def help_order(self): + orders = ["This is what I can do:"] + for orderstr in self.orders(): + orders.append("- `{}`".format(orderstr)) + orders.append("- `help` : this help message") + return "\n".join(orders) diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/git_tools.py b/tools/azure-devtools/src/azure_devtools/ci_tools/git_tools.py new file mode 100644 index 000000000000..8c29dd842dc8 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/git_tools.py @@ -0,0 +1,90 @@ +"""Pure git tools for managing local folder Git. +""" +import logging + +from git import Repo, GitCommandError + +_LOGGER = logging.getLogger(__name__) + +def checkout_and_create_branch(repo, name): + """Checkout branch. Create it if necessary""" + local_branch = repo.branches[name] if name in repo.branches else None + if not local_branch: + if name in repo.remotes.origin.refs: + # If origin branch exists but not local, git.checkout is the fatest way + # to create local branch with origin link automatically + msg = repo.git.checkout(name) + _LOGGER.debug(msg) + return + # Create local branch, will be link to origin later + local_branch = repo.create_head(name) + local_branch.checkout() + +def checkout_create_push_branch(repo, name): + """Checkout this branch. Create it if necessary, and push it to origin. + """ + try: + repo.git.checkout(name) + _LOGGER.info("Checkout %s success", name) + except GitCommandError: + _LOGGER.info("Checkout %s was impossible (branch does not exist). Creating it and push it.", name) + checkout_and_create_branch(repo, name) + repo.git.push('origin', name, set_upstream=True) + + +def do_commit(repo, message_template, branch_name, hexsha): + "Do a commit if modified/untracked files" + repo.git.add(repo.working_tree_dir) + + if not repo.git.diff(staged=True): + _LOGGER.warning('No modified files in this Autorest run') + return False + + checkout_and_create_branch(repo, branch_name) + msg = message_template.format(hexsha=hexsha) + commit = repo.index.commit(msg) + _LOGGER.info("Commit done: %s", msg) + return commit.hexsha + +def get_repo_hexsha(git_folder): + """Get the SHA1 of the current repo""" + repo = Repo(str(git_folder)) + if repo.bare: + not_git_hexsha = "notgitrepo" + _LOGGER.warning("Not a git repo, SHA1 used will be: %s", not_git_hexsha) + return not_git_hexsha + hexsha = repo.head.commit.hexsha + _LOGGER.info("Found REST API repo SHA1: %s", hexsha) + return hexsha + +def checkout_with_fetch(git_folder, refspec, repository="origin"): + """Fetch the refspec, and checkout FETCH_HEAD. + Beware that you will ne in detached head mode. + """ + _LOGGER.info("Trying to fetch and checkout %s", refspec) + repo = Repo(str(git_folder)) + repo.git.fetch(repository, refspec) # FETCH_HEAD should be set + repo.git.checkout("FETCH_HEAD") + _LOGGER.info("Fetch and checkout success for %s", refspec) + +def clone_to_path(https_authenticated_url, folder, branch_or_commit=None): + """Clone the given URL to the folder. + + :param str branch_or_commit: If specified, switch to this branch. Branch must exist. + """ + _LOGGER.info("Cloning repo") + repo = Repo.clone_from(https_authenticated_url, str(folder)) + # Do NOT clone and set branch at the same time, since we allow branch to be a SHA1 + # And you can't clone a SHA1 + if branch_or_commit: + _LOGGER.info("Checkout branch_or_commit %s", branch_or_commit) + repo.git.checkout(branch_or_commit) + + _LOGGER.info("Clone success") + +def get_files_in_commit(git_folder, commit_id="HEAD"): + """List of files in HEAD commit. + """ + repo = Repo(str(git_folder)) + output = repo.git.diff("--name-only", commit_id+"^", commit_id) + return output.splitlines() diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/github_tools.py b/tools/azure-devtools/src/azure_devtools/ci_tools/github_tools.py new file mode 100644 index 000000000000..530d4690fe87 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/github_tools.py @@ -0,0 +1,374 @@ +"""Github tools. +""" +from contextlib import contextmanager +import logging +import os +from pathlib import Path +import shutil +import stat +from subprocess import CalledProcessError +import traceback +from urllib.parse import urlsplit, urlunsplit + +from github import Github, GithubException +from git import Repo + +from .git_tools import ( + clone_to_path as _git_clone_to_path, + checkout_with_fetch +) + +_LOGGER = logging.getLogger(__name__) + +class ExceptionContext: # pylint: disable=too-few-public-methods + def __init__(self): + self.comment = None + +@contextmanager +def exception_to_github(github_obj_to_comment, summary=""): + """If any exception comes, log them in the given Github obj. + """ + context = ExceptionContext() + try: + yield context + except Exception: # pylint: disable=broad-except + if summary: + summary = ": ({})".format(summary) + error_type = "an unknown error" + try: + raise + except CalledProcessError as err: + error_type = "a Subprocess error" + content = "Command: {}\n".format(err.cmd) + content += "Finished with return code {}\n".format(err.returncode) + if err.output: + content += "and output:\n```shell\n{}\n```".format(err.output) + else: + content += "and no output" + except Exception: # pylint: disable=broad-except + content = "```python\n{}\n```".format(traceback.format_exc()) + response = "
Encountered {}{}

\n\n".format( + error_type, + summary + ) + response += content + response += "\n\n

" + context.comment = create_comment(github_obj_to_comment, response) + +def user_from_token(gh_token): + """Get user login from GitHub token""" + github_con = Github(gh_token) + return github_con.get_user() + +def create_comment(github_object, body): + """Create a comment, whatever the object is a PR, a commit or an issue. + """ + try: + return github_object.create_issue_comment(body) # It's a PR + except AttributeError: + return github_object.create_comment(body) # It's a commit/issue + +def get_comments(github_object): + """Get a list of comments, whater the object is a PR, a commit or an issue. + """ + try: + return github_object.get_issue_comments() # It's a PR + except AttributeError: + return github_object.get_comments() # It's a commit/issue + +def get_files(github_object): + """Get files from a PR or a commit. + """ + try: + return github_object.get_files() # Try as a PR object + except AttributeError: + return github_object.files # Try as a commit object + +def configure_user(gh_token, repo): + """git config --global user.email "you@example.com" + git config --global user.name "Your Name" + """ + user = user_from_token(gh_token) + repo.git.config('user.email', user.email or 'adxpysdk@microsoft.com') + repo.git.config('user.name', user.name or 'SwaggerToSDK Automation') + +def get_full_sdk_id(gh_token, sdk_git_id): + """If the SDK git id is incomplete, try to complete it with user login""" + if not '/' in sdk_git_id: + login = user_from_token(gh_token).login + return '{}/{}'.format(login, sdk_git_id) + return sdk_git_id + +def sync_fork(gh_token, github_repo_id, repo, push=True): + """Sync the current branch in this fork against the direct parent on Github""" + if not gh_token: + _LOGGER.warning('Skipping the upstream repo sync, no token') + return + _LOGGER.info('Check if repo has to be sync with upstream') + github_con = Github(gh_token) + github_repo = github_con.get_repo(github_repo_id) + + if not github_repo.parent: + _LOGGER.warning('This repo has no upstream') + return + + upstream_url = 'https://github.com/{}.git'.format(github_repo.parent.full_name) + upstream = repo.create_remote('upstream', url=upstream_url) + upstream.fetch() + active_branch_name = repo.active_branch.name + if not active_branch_name in repo.remotes.upstream.refs: + _LOGGER.info('Upstream has no branch %s to merge from', active_branch_name) + return + else: + _LOGGER.info('Merge from upstream') + msg = repo.git.rebase('upstream/{}'.format(repo.active_branch.name)) + _LOGGER.debug(msg) + if push: + msg = repo.git.push() + _LOGGER.debug(msg) + +def get_or_create_pull(github_repo, title, body, head, base, *, none_if_no_commit=False): + """Try to create the PR. If the PR exists, try to find it instead. Raises otherwise. + + You should always use the complete head syntax "org:branch", since the syntax is required + in case of listing. + + if "none_if_no_commit" is set, return None instead of raising exception if the problem + is that head and base are the same. + """ + try: # Try to create or get a PR + return github_repo.create_pull( + title=title, + body=body, + head=head, + base=base + ) + except GithubException as err: + err_message = err.data['errors'][0].get('message', '') + if err.status == 422 and err_message.startswith('A pull request already exists'): + _LOGGER.info('PR already exists, get this PR') + return list(github_repo.get_pulls( + head=head, + base=base + ))[0] + elif none_if_no_commit and err.status == 422 and err_message.startswith('No commits between'): + _LOGGER.info('No PR possible since head %s and base %s are the same', + head, + base) + return None + else: + _LOGGER.warning("Unable to create PR:\n%s", err.data) + raise + except Exception as err: + response = traceback.format_exc() + _LOGGER.warning("Unable to create PR:\n%s", response) + raise + +def clone_to_path(gh_token, folder, sdk_git_id, branch_or_commit=None, *, pr_number=None): + """Clone the given repo_id to the folder. + + If PR number is specified fetch the magic branches + pull//head or pull//merge from Github. "merge" is tried first, and fallback to "head". + Beware that pr_number implies detached head, and then no push is possible. + + If branch is specified, checkout this branch or commit finally. + + :param str branch_or_commit: If specified, switch to this branch/commit. + :param int pr_number: PR number. + """ + _LOGGER.info("Clone SDK repository %s", sdk_git_id) + url_parsing = urlsplit(sdk_git_id) + sdk_git_id = url_parsing.path + if sdk_git_id.startswith("/"): + sdk_git_id = sdk_git_id[1:] + + credentials_part = '' + if gh_token: + login = user_from_token(gh_token).login + credentials_part = '{user}:{token}@'.format( + user=login, + token=gh_token + ) + else: + _LOGGER.warning('Will clone the repo without writing credentials') + + https_authenticated_url = 'https://{credentials}github.com/{sdk_git_id}.git'.format( + credentials=credentials_part, + sdk_git_id=sdk_git_id + ) + # Clone the repo + _git_clone_to_path(https_authenticated_url, folder) + # If this is a PR, do some fetch to improve the number of SHA1 available + if pr_number: + try: + checkout_with_fetch(folder, "pull/{}/merge".format(pr_number)) + return + except Exception: # pylint: disable=broad-except + pass # Assume "merge" doesn't exist anymore, fetch "head" + checkout_with_fetch(folder, "pull/{}/head".format(pr_number)) + # If there is SHA1, checkout it. If PR number was given, SHA1 could be inside that PR. + if branch_or_commit: + repo = Repo(str(folder)) + repo.git.checkout(branch_or_commit) + +def do_pr(gh_token, sdk_git_id, sdk_pr_target_repo_id, branch_name, base_branch, pr_body=""): # pylint: disable=too-many-arguments + "Do the PR" + if not gh_token: + _LOGGER.info('Skipping the PR, no token found') + return None + if not sdk_pr_target_repo_id: + _LOGGER.info('Skipping the PR, no target repo id') + return None + + github_con = Github(gh_token) + sdk_pr_target_repo = github_con.get_repo(sdk_pr_target_repo_id) + + if '/' in sdk_git_id: + sdk_git_owner = sdk_git_id.split('/')[0] + _LOGGER.info("Do the PR from %s", sdk_git_owner) + head_name = "{}:{}".format(sdk_git_owner, branch_name) + else: + head_name = branch_name + sdk_git_repo = github_con.get_repo(sdk_git_id) + sdk_git_owner = sdk_git_repo.owner.login + + try: + github_pr = sdk_pr_target_repo.create_pull( + title='Automatic PR from {}'.format(branch_name), + body=pr_body, + head=head_name, + base=base_branch + ) + except GithubException as err: + if err.status == 422 and err.data['errors'][0].get('message', '').startswith('A pull request already exists'): + matching_pulls = sdk_pr_target_repo.get_pulls(base=base_branch, head=sdk_git_owner+":"+head_name) + matching_pull = matching_pulls[0] + _LOGGER.info('PR already exists: %s', matching_pull.html_url) + return matching_pull + raise + _LOGGER.info("Made PR %s", github_pr.html_url) + return github_pr + + +def remove_readonly(func, path, _): + "Clear the readonly bit and reattempt the removal" + os.chmod(path, stat.S_IWRITE) + func(path) + +@contextmanager +def manage_git_folder(gh_token, temp_dir, git_id, *, pr_number=None): + """Context manager to avoid readonly problem while cleanup the temp dir. + + If PR number is given, use magic branches "pull" from Github. + """ + _LOGGER.debug("Git ID %s", git_id) + if Path(git_id).exists(): + yield git_id + return # Do not erase a local folder, just skip here + + # Clone the specific branch + split_git_id = git_id.split("@") + branch = split_git_id[1] if len(split_git_id) > 1 else None + clone_to_path(gh_token, temp_dir, split_git_id[0], branch_or_commit=branch, pr_number=pr_number) + try: + yield temp_dir + # Pre-cleanup for Windows http://bugs.python.org/issue26660 + finally: + _LOGGER.debug("Preclean Rest folder") + shutil.rmtree(temp_dir, onerror=remove_readonly) + + +class GithubLink: + def __init__(self, gitid, link_type, branch_or_commit, path, token=None): # pylint: disable=too-many-arguments + self.gitid = gitid + self.link_type = link_type + self.branch_or_commit = branch_or_commit + self.path = path + self.token = token + + @classmethod + def from_string(cls, github_url): + parsed = urlsplit(github_url) + netloc = parsed.netloc + if "@" in netloc: + token, netloc = netloc.split("@") + else: + token = None + + split_path = parsed.path.split("/") + split_path.pop(0) # First is always empty + gitid = split_path.pop(0) + "/" + split_path.pop(0) + link_type = split_path.pop(0) if netloc != "raw.githubusercontent.com" else "raw" + branch_or_commit = split_path.pop(0) + path = "/".join(split_path) + return cls(gitid, link_type, branch_or_commit, path, token) + + def __repr__(self): + if self.link_type == "raw": + netloc = "raw.githubusercontent.com" + path = "/".join(["", self.gitid, self.branch_or_commit, self.path]) + # If raw and token, needs to be passed with "Authorization: token ", so nothing to do here + else: + netloc = "github.com" if not self.token else self.token + "@github.com" + path = "/".join(["", self.gitid, self.link_type, self.branch_or_commit, self.path]) + return urlunsplit(("https", netloc, path, '', '')) + + def as_raw_link(self): + """Returns a GithubLink to a raw content. + """ + if self.link_type == "raw": + return self # Can be discussed if we need an hard copy, or fail + if self.link_type != "blob": + raise ValueError("Cannot get a download link from a tree link") + return self.__class__( + self.gitid, + "raw", + self.branch_or_commit, + self.path, + self.token + ) + +class DashboardCommentableObject: # pylint: disable=too-few-public-methods + def __init__(self, issue_or_pr, header): + self._issue_or_pr = issue_or_pr + self._header = header + + def create_comment(self, text): + """Mimic issue API, so we can use it everywhere. + Return dashboard comment. + """ + return DashboardComment.get_or_create(self._issue_or_pr, self._header, text) + +class DashboardComment: + def __init__(self, github_comment, header): + self.github_comment = github_comment + self._header = header + + @classmethod + def get_or_create(cls, issue, header, text=None): + """Get or create the dashboard comment in this issue. + """ + for comment in get_comments(issue): + try: + if comment.body.splitlines()[0] == header: + obj = cls(comment, header) + break + except IndexError: # The comment body is empty + pass + # Hooooooo, no dashboard comment, let's create one + else: + comment = create_comment(issue, header) + obj = cls(comment, header) + if text: + obj.edit(text) + return obj + + def edit(self, text): + self.github_comment.edit(self._header+"\n"+text) + + @property + def body(self): + return self.github_comment.body[len(self._header+"\n"):] + + def delete(self): + self.github_comment.delete() diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_command.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_command.txt new file mode 100644 index 000000000000..fec50c88c687 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_command.txt @@ -0,0 +1,77 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/17 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:19 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4868'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"98b4fc509c1be25d2318a54b8c92958d"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:24 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.067750'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1584:97BA:C8520B:103DCD4:5AFDF1D7')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/17","id":296837951,"number":17,"title":"Bot testing test_bot_basic_command","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-13T18:21:32Z","updated_at":"2018-05-17T21:17:24Z","closed_at":null,"author_association":"OWNER","body":"Issue for test test_bot_basic_command","closed_by":null} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:19 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4867'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"725d5cec4f2c42be4592ff68c6cde59c"'), ('Last-Modified', 'Thu, 21 Apr 2016 17:29:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.068194'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1585:97AE:D648:1542E:5AFDF1D7')] +{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":1,"subscribers_count":1} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/17 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:19 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4866'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"98b4fc509c1be25d2318a54b8c92958d"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:24 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.056033'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1586:97B6:619CDF:7E742E:5AFDF1D7')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/17","id":296837951,"number":17,"title":"Bot testing test_bot_basic_command","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-13T18:21:32Z","updated_at":"2018-05-17T21:17:24Z","closed_at":null,"author_association":"OWNER","body":"Issue for test test_bot_basic_command","closed_by":null} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/17/reactions +{'Accept': 'application/vnd.github.squirrel-girl-preview', 'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"content": "+1"} +200 +[('Date', 'Thu, 17 May 2018 21:19:19 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4865'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"830905522c930d77c944e2465cbf79e3"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.squirrel-girl-preview'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.049763'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1587:97BA:C85240:103DD1C:5AFDF1D7')] +{"id":19647639,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"content":"+1","created_at":"2018-02-15T16:48:56Z"} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/17/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "I did something with myparameter"} +201 +[('Date', 'Thu, 17 May 2018 21:19:20 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1269'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4864'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"3c8c70479a1f9d4bd626e25a0fb202d5"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015300'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.235969'), ('X-GitHub-Request-Id', '1589:97BA:C8524D:103DD2D:5AFDF1D7')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015300","html_url":"https://github.com/lmazuel/TestingRepo/issues/17#issuecomment-390015300","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17","id":390015300,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:19Z","updated_at":"2018-05-17T21:19:19Z","author_association":"OWNER","body":"I did something with myparameter"} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/17/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:20 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4863'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"74c8cfcaef98bcea9d03825eaf8e8bcb"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.075117'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '158A:97B8:C19E00:FA7576:5AFDF1D8')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015300","html_url":"https://github.com/lmazuel/TestingRepo/issues/17#issuecomment-390015300","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/17","id":390015300,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:19Z","updated_at":"2018-05-17T21:19:19Z","author_association":"OWNER","body":"I did something with myparameter"}] + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390015300 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:19:20 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4862'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.153464'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '158B:97B4:2A9DDC:371568:5AFDF1D8')] + + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_failure.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_failure.txt new file mode 100644 index 000000000000..47387cd8dd4a --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_basic_failure.txt @@ -0,0 +1,77 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/18 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:20 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4861'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"927f79403c0b19d9941c1f9971554c97"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:25 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.091675'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '158C:97B8:C19E27:FA75AE:5AFDF1D8')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/18","id":296839107,"number":18,"title":"Bot testing test_bot_basic_failure","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-02-13T18:25:38Z","updated_at":"2018-05-17T21:17:25Z","closed_at":null,"author_association":"OWNER","body":"Test test_bot_basic_failure","closed_by":null} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:21 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4860'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"725d5cec4f2c42be4592ff68c6cde59c"'), ('Last-Modified', 'Thu, 21 Apr 2016 17:29:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.071013'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '158D:97B8:C19E34:FA75C6:5AFDF1D8')] +{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":1,"subscribers_count":1} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/18 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:21 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4859'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"927f79403c0b19d9941c1f9971554c97"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:25 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.077929'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '158E:97B6:619D50:7E74CE:5AFDF1D9')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/18","id":296839107,"number":18,"title":"Bot testing test_bot_basic_failure","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-02-13T18:25:38Z","updated_at":"2018-05-17T21:17:25Z","closed_at":null,"author_association":"OWNER","body":"Test test_bot_basic_failure","closed_by":null} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/18/reactions +{'Accept': 'application/vnd.github.squirrel-girl-preview', 'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"content": "+1"} +200 +[('Date', 'Thu, 17 May 2018 21:19:21 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4858'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"f35e383770b095bc94f549fe44edc2fe"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.squirrel-girl-preview'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.068572'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '158F:97BA:C852D8:103DDF9:5AFDF1D9')] +{"id":19647644,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"content":"+1","created_at":"2018-02-15T16:48:58Z"} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/18/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "
Encountered an unknown error

\n\n```python\nsomething to do with an exception\n```\n\n

"} +201 +[('Date', 'Thu, 17 May 2018 21:19:21 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1367'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4857'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"06822f58759ca9c9cd53dc2e99a93569"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015309'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.233947'), ('X-GitHub-Request-Id', '1590:97BA:C852EB:103DE13:5AFDF1D9')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015309","html_url":"https://github.com/lmazuel/TestingRepo/issues/18#issuecomment-390015309","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18","id":390015309,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:21Z","updated_at":"2018-05-17T21:19:21Z","author_association":"OWNER","body":"
Encountered an unknown error

\n\n```python\nsomething to do with an exception\n```\n\n

"} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/18/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:22 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4856'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"a5b1ec4e91e863af61c812af3c2a3308"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.052239'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1591:97BA:C85304:103DE35:5AFDF1D9')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/378008509","html_url":"https://github.com/lmazuel/TestingRepo/issues/18#issuecomment-378008509","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18","id":378008509,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-04-02T18:49:03Z","updated_at":"2018-04-02T18:49:03Z","author_association":"OWNER","body":"
Encountered an unknown error

\n\n```python\nTraceback (most recent call last):\n File \"/home/travis/build/lmazuel/swagger-to-sdk/swaggertosdk/github_tools.py\", line 32, in exception_to_github\n yield context\n File \"/home/travis/build/lmazuel/swagger-to-sdk/swaggertosdk/restapi/bot_framework.py\", line 104, in manage_comment\n response = getattr(self.handler, orderstr)(webhook_data.issue, *split_text)\n File \"/home/travis/build/lmazuel/swagger-to-sdk/tests/test_bot_framework.py\", line 134, in command1\n raise ValueError(\"Not happy\")\nValueError: Not happy\n\n```\n\n

"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390014728","html_url":"https://github.com/lmazuel/TestingRepo/issues/18#issuecomment-390014728","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18","id":390014728,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:17:25Z","updated_at":"2018-05-17T21:17:25Z","author_association":"OWNER","body":"
Encountered an unknown error

\n\n```python\nsomething to do with an exception\n```\n\n

"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015309","html_url":"https://github.com/lmazuel/TestingRepo/issues/18#issuecomment-390015309","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/18","id":390015309,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:21Z","updated_at":"2018-05-17T21:19:21Z","author_association":"OWNER","body":"
Encountered an unknown error

\n\n```python\nsomething to do with an exception\n```\n\n

"}] + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390015309 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:19:22 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4855'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.105747'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '1592:97BA:C85310:103DE44:5AFDF1DA')] + + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_help.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_help.txt new file mode 100644 index 000000000000..c597b5fd77ae --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_help.txt @@ -0,0 +1,66 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/16 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:22 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4854'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"dbdbf224af844ba6fe3d35549fe06d65"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:27 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.086366'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1593:97B8:C19EA6:FA766A:5AFDF1DA')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/16","id":296581533,"number":16,"title":"Bot testing test_bot_help","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2018-02-13T01:16:25Z","updated_at":"2018-05-17T21:17:27Z","closed_at":null,"author_association":"OWNER","body":"This is bot testing. Test framework will use this issue to test if bot can understand what we are saying. Webhook will be faked.","closed_by":null} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:22 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4853'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"725d5cec4f2c42be4592ff68c6cde59c"'), ('Last-Modified', 'Thu, 21 Apr 2016 17:29:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.067798'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1594:97B6:619DAB:7E754C:5AFDF1DA')] +{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":1,"subscribers_count":1} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/16 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:22 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4852'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"dbdbf224af844ba6fe3d35549fe06d65"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:27 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.069684'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1595:97B8:C19EC5:FA7690:5AFDF1DA')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/16","id":296581533,"number":16,"title":"Bot testing test_bot_help","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2018-02-13T01:16:25Z","updated_at":"2018-05-17T21:17:27Z","closed_at":null,"author_association":"OWNER","body":"This is bot testing. Test framework will use this issue to test if bot can understand what we are saying. Webhook will be faked.","closed_by":null} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/16/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "This is what I can do:\n- `command1`\n- `command2`\n- `help` : this help message"} +201 +[('Date', 'Thu, 17 May 2018 21:19:23 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1317'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4851'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"c2544608584665dd2942321d6aab107f"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015316'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.261789'), ('X-GitHub-Request-Id', '1596:97BA:C8533D:103DE8D:5AFDF1DA')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015316","html_url":"https://github.com/lmazuel/TestingRepo/issues/16#issuecomment-390015316","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","id":390015316,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:23Z","updated_at":"2018-05-17T21:19:23Z","author_association":"OWNER","body":"This is what I can do:\n- `command1`\n- `command2`\n- `help` : this help message"} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/16/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:23 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4850'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"9becdc0c2a9bd3482c6eca5b01416246"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.073664'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1597:97BA:C85357:103DEB6:5AFDF1DB')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/365120206","html_url":"https://github.com/lmazuel/TestingRepo/issues/16#issuecomment-365120206","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","id":365120206,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-13T01:24:00Z","updated_at":"2018-02-13T01:24:00Z","author_association":"OWNER","body":"This is what I can do:\n - `help` : this help message\n - `generate ` : create a PR for this README\n "},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/365120680","html_url":"https://github.com/lmazuel/TestingRepo/issues/16#issuecomment-365120680","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","id":365120680,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-13T01:26:35Z","updated_at":"2018-02-13T01:26:35Z","author_association":"OWNER","body":"This is what I can do:\n- `help` : this help message"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/365343119","html_url":"https://github.com/lmazuel/TestingRepo/issues/16#issuecomment-365343119","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","id":365343119,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-13T17:35:27Z","updated_at":"2018-02-13T17:35:27Z","author_association":"OWNER","body":"This is what I can do:\n- `command1`\n- `command2`\n- `help` : this help message"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/365350586","html_url":"https://github.com/lmazuel/TestingRepo/issues/16#issuecomment-365350586","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","id":365350586,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-13T17:59:45Z","updated_at":"2018-02-13T17:59:45Z","author_association":"OWNER","body":"End message for tests"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015316","html_url":"https://github.com/lmazuel/TestingRepo/issues/16#issuecomment-390015316","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","id":390015316,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:23Z","updated_at":"2018-05-17T21:19:23Z","author_association":"OWNER","body":"This is what I can do:\n- `command1`\n- `command2`\n- `help` : this help message"}] + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390015316 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:19:24 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4849'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.543403'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '1598:97B8:C19F06:FA76E1:5AFDF1DB')] + + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_unknown_command.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_unknown_command.txt new file mode 100644 index 000000000000..2b05c1c97257 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_bot_unknown_command.txt @@ -0,0 +1,66 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/19 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:24 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4848'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"817b6384493b05bdc635dcb4b3ed97e9"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:28 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.072901'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1599:97B6:619DF4:7E75B2:5AFDF1DC')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/19","id":296841237,"number":19,"title":"Bot testing test_bot_unknown_command","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-13T18:32:59Z","updated_at":"2018-05-17T21:17:28Z","closed_at":null,"author_association":"OWNER","body":"Test test_bot_unknown_command","closed_by":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false}} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:24 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4847'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"725d5cec4f2c42be4592ff68c6cde59c"'), ('Last-Modified', 'Thu, 21 Apr 2016 17:29:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.075721'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '159A:97B8:C19F3B:FA772C:5AFDF1DC')] +{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":1,"subscribers_count":1} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/19 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:24 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4846'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"817b6384493b05bdc635dcb4b3ed97e9"'), ('Last-Modified', 'Thu, 17 May 2018 21:17:28 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.054579'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '159B:97BA:C853B6:103DF3D:5AFDF1DC')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/19","id":296841237,"number":19,"title":"Bot testing test_bot_unknown_command","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-13T18:32:59Z","updated_at":"2018-05-17T21:17:28Z","closed_at":null,"author_association":"OWNER","body":"Test test_bot_unknown_command","closed_by":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false}} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/19/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "I didn't understand your command:\n```bash\ncommand1 myparameter\n```\nin this context, sorry :(\nThis is what I can do:\n- `help` : this help message"} +201 +[('Date', 'Thu, 17 May 2018 21:19:25 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1387'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4845'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"7e5e5bc1d93fe17033b3690c64d1de5c"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015326'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.287623'), ('X-GitHub-Request-Id', '159C:97BA:C853C6:103DF50:5AFDF1DC')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015326","html_url":"https://github.com/lmazuel/TestingRepo/issues/19#issuecomment-390015326","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19","id":390015326,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:24Z","updated_at":"2018-05-17T21:19:24Z","author_association":"OWNER","body":"I didn't understand your command:\n```bash\ncommand1 myparameter\n```\nin this context, sorry :(\nThis is what I can do:\n- `help` : this help message"} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/19/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:25 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4844'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"2f96a1efc55bec5c0d05b8eb07192251"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.061455'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '159D:97B8:C19F68:FA7775:5AFDF1DD')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390015326","html_url":"https://github.com/lmazuel/TestingRepo/issues/19#issuecomment-390015326","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/19","id":390015326,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:19:24Z","updated_at":"2018-05-17T21:19:24Z","author_association":"OWNER","body":"I didn't understand your command:\n```bash\ncommand1 myparameter\n```\nin this context, sorry :(\nThis is what I can do:\n- `help` : this help message"}] + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390015326 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:19:25 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4843'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.119982'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '159F:97BA:C853F6:103DF8C:5AFDF1DD')] + + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_webhook_data.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_webhook_data.txt new file mode 100644 index 000000000000..7fdc948de8d1 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/BotFrameworkTest.test_webhook_data.txt @@ -0,0 +1,66 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:25 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4842'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"725d5cec4f2c42be4592ff68c6cde59c"'), ('Last-Modified', 'Thu, 21 Apr 2016 17:29:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.053636'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '15A0:97B6:619E2D:7E75FD:5AFDF1DD')] +{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":1,"subscribers_count":1} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/16 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:25 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4841'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"7d2748617881607a7850e67e06267e71"'), ('Last-Modified', 'Thu, 17 May 2018 21:19:23 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.076099'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '15A1:97BA:C8540D:103DFB0:5AFDF1DD')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/16","id":296581533,"number":16,"title":"Bot testing test_bot_help","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2018-02-13T01:16:25Z","updated_at":"2018-05-17T21:19:23Z","closed_at":null,"author_association":"OWNER","body":"This is bot testing. Test framework will use this issue to test if bot can understand what we are saying. Webhook will be faked.","closed_by":null} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:25 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4840'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"725d5cec4f2c42be4592ff68c6cde59c"'), ('Last-Modified', 'Thu, 21 Apr 2016 17:29:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.069166'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '15A2:97BA:C8541C:103DFC4:5AFDF1DD')] +{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":1,"subscribers_count":1} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/16 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:26 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4839'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"7d2748617881607a7850e67e06267e71"'), ('Last-Modified', 'Thu, 17 May 2018 21:19:23 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.070185'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '15A3:97B4:2A9E5A:37161B:5AFDF1DD')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/16","id":296581533,"number":16,"title":"Bot testing test_bot_help","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2018-02-13T01:16:25Z","updated_at":"2018-05-17T21:19:23Z","closed_at":null,"author_association":"OWNER","body":"This is bot testing. Test framework will use this issue to test if bot can understand what we are saying. Webhook will be faked.","closed_by":null} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/365120206 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:26 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4838'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"9ae58cc064227ab7ba03d6700bc43271"'), ('Last-Modified', 'Tue, 08 May 2018 04:10:43 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.060661'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '15A4:97B6:619E50:7E7635:5AFDF1DE')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/365120206","html_url":"https://github.com/lmazuel/TestingRepo/issues/16#issuecomment-365120206","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/16","id":365120206,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-13T01:24:00Z","updated_at":"2018-02-13T01:24:00Z","author_association":"OWNER","body":"This is what I can do:\n - `help` : this help message\n - `generate ` : create a PR for this README\n "} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:19:26 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4837'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"725d5cec4f2c42be4592ff68c6cde59c"'), ('Last-Modified', 'Thu, 21 Apr 2016 17:29:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.059502'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '15A5:97BA:C85441:103DFF5:5AFDF1DE')] +{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master","permissions":{"admin":true,"push":true,"pull":true},"allow_squash_merge":true,"allow_merge_commit":true,"allow_rebase_merge":true,"network_count":1,"subscribers_count":1} + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_clone_path.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_clone_path.txt new file mode 100644 index 000000000000..a207132972d7 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_clone_path.txt @@ -0,0 +1,99 @@ +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:18 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4991'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.048085'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFBC:85AB:4441C25:57B4B8B:5B3FE41A')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:20 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4990'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.093382'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFBE:85A8:208C8EA:29398CF:5B3FE41C')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:22 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4989'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.042008'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFC1:85A8:208C923:2939909:5B3FE41E')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:24 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4988'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.058983'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFC3:85A8:208C95A:2939952:5B3FE41F')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:25 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4987'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.054447'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFC7:85AA:3E20F9D:4F32AB0:5B3FE421')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:29 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4986'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.053094'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFCC:85AB:44420F3:57B51B8:5B3FE424')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/pulls/2 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4985'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"8a6ef82b7dcdf6548b23e3a686b38341"'), ('Last-Modified', 'Thu, 05 Jul 2018 16:03:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.114799'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFD1:85AB:44422E1:57B544C:5B3FE429')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2","id":70768598,"node_id":"MDExOlB1bGxSZXF1ZXN0NzA3Njg1OTg=","html_url":"https://github.com/lmazuel/TestingRepo/pull/2","diff_url":"https://github.com/lmazuel/TestingRepo/pull/2.diff","patch_url":"https://github.com/lmazuel/TestingRepo/pull/2.patch","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2","number":2,"state":"open","locked":false,"title":"Update README.md","user":{"login":"AutorestCI","id":18218145,"node_id":"MDQ6VXNlcjE4MjE4MTQ1","avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-05-19T21:29:49Z","updated_at":"2018-07-05T16:03:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1d020a4d8788aa40753ca326f0818a8cd805ac93","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/commits","review_comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/comments","review_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2/comments","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/40d2028637a6b5f8f6ae6e595e772d6fc33b93bb","head":{"label":"AutorestCI:AutorestCI-patch-1","ref":"AutorestCI-patch-1","sha":"40d2028637a6b5f8f6ae6e595e772d6fc33b93bb","user":{"login":"AutorestCI","id":18218145,"node_id":"MDQ6VXNlcjE4MjE4MTQ1","avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"repo":{"id":59243826,"node_id":"MDEwOlJlcG9zaXRvcnk1OTI0MzgyNg==","name":"TestingRepo","full_name":"AutorestCI/TestingRepo","owner":{"login":"AutorestCI","id":18218145,"node_id":"MDQ6VXNlcjE4MjE4MTQ1","avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/AutorestCI/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":true,"url":"https://api.github.com/repos/AutorestCI/TestingRepo","forks_url":"https://api.github.com/repos/AutorestCI/TestingRepo/forks","keys_url":"https://api.github.com/repos/AutorestCI/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/AutorestCI/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/AutorestCI/TestingRepo/teams","hooks_url":"https://api.github.com/repos/AutorestCI/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/AutorestCI/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/AutorestCI/TestingRepo/events","assignees_url":"https://api.github.com/repos/AutorestCI/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/AutorestCI/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/AutorestCI/TestingRepo/tags","blobs_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/AutorestCI/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/AutorestCI/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/AutorestCI/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/AutorestCI/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/AutorestCI/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/AutorestCI/TestingRepo/subscription","commits_url":"https://api.github.com/repos/AutorestCI/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/AutorestCI/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/AutorestCI/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/AutorestCI/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/AutorestCI/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/AutorestCI/TestingRepo/merges","archive_url":"https://api.github.com/repos/AutorestCI/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/AutorestCI/TestingRepo/downloads","issues_url":"https://api.github.com/repos/AutorestCI/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/AutorestCI/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/AutorestCI/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/AutorestCI/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/AutorestCI/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/AutorestCI/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/AutorestCI/TestingRepo/deployments","created_at":"2016-05-19T21:26:35Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2016-05-19T21:28:13Z","git_url":"git://github.com/AutorestCI/TestingRepo.git","ssh_url":"git@github.com:AutorestCI/TestingRepo.git","clone_url":"https://github.com/AutorestCI/TestingRepo.git","svn_url":"https://github.com/AutorestCI/TestingRepo","homepage":null,"size":1,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"lmazuel:master","ref":"master","sha":"dd82f65f1b6314b18609b8572464b6d328ea70d4","user":{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"repo":{"id":56793153,"node_id":"MDEwOlJlcG9zaXRvcnk1Njc5MzE1Mw==","name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2"},"html":{"href":"https://github.com/lmazuel/TestingRepo/pull/2"},"issue":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2"},"comments":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/40d2028637a6b5f8f6ae6e595e772d6fc33b93bb"}},"author_association":"COLLABORATOR","merged":false,"mergeable":true,"rebaseable":false,"mergeable_state":"clean","merged_by":null,"comments":3,"review_comments":0,"maintainer_can_modify":false,"commits":1,"additions":2,"deletions":0,"changed_files":1} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4984'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.039463'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFD3:85A8:208CA76:2939AE7:5B3FE429')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Fri, 06 Jul 2018 21:50:36 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4983'), ('X-RateLimit-Reset', '1530917381'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"10b653fde1e6d20073ad0d69f59b2c3f"'), ('Last-Modified', 'Fri, 08 Jun 2018 04:11:06 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.042491'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'DFDB:85A5:50C84B:6722D2:5B3FE42C')] +{"login":"lmazuel","id":1050156,"node_id":"MDQ6VXNlcjEwNTAxNTY=","avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":47,"public_gists":14,"followers":40,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-06-08T04:11:06Z","private_gists":2,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41453,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_configure.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_configure.txt new file mode 100644 index 000000000000..c59238163ea6 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_configure.txt @@ -0,0 +1,11 @@ +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:30 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4801'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"77a0c498bc6360506f9e7a4dd33857df"'), ('Last-Modified', 'Tue, 08 May 2018 04:10:43 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.050830'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '16F8:97BA:C9220B:104EE7D:5AFDF3C2')] +{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":46,"public_gists":14,"followers":30,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-05-08T04:10:43Z","private_gists":1,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41216,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_create_comment.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_create_comment.txt new file mode 100644 index 000000000000..d43df7590331 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_create_comment.txt @@ -0,0 +1,66 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/14 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:31 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4800'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"8bb2ec36d3e6380bc0eabd5bd44e96eb"'), ('Last-Modified', 'Thu, 17 May 2018 21:15:04 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.064500'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '16F9:97BA:C92251:104EED1:5AFDF3C3')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/14","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/14/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/14/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/14/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/14","id":291717104,"number":14,"title":"Testing comment","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-01-25T21:12:00Z","updated_at":"2018-05-17T21:15:04Z","closed_at":null,"author_association":"OWNER","body":"","closed_by":null} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/14/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "This is a test"} +201 +[('Date', 'Thu, 17 May 2018 21:27:31 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1251'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4799'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"d2dfbb8c026a93b366703c2905dd6477"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017673'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.445487'), ('X-GitHub-Request-Id', '16FA:97B8:C2461E:FB54DF:5AFDF3C3')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017673","html_url":"https://github.com/lmazuel/TestingRepo/issues/14#issuecomment-390017673","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/14","id":390017673,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:31Z","updated_at":"2018-05-17T21:27:31Z","author_association":"OWNER","body":"This is a test"} + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017673 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:27:32 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4798'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.141787'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '16FB:97BA:C9227D:104EF10:5AFDF3C3')] + + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/pulls/2 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:32 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4797'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"e0597269209bdeaf65893e74635ff339"'), ('Last-Modified', 'Thu, 17 May 2018 21:15:05 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.132533'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '16FC:97B8:C24657:FB552C:5AFDF3C4')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2","id":70768598,"html_url":"https://github.com/lmazuel/TestingRepo/pull/2","diff_url":"https://github.com/lmazuel/TestingRepo/pull/2.diff","patch_url":"https://github.com/lmazuel/TestingRepo/pull/2.patch","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2","number":2,"state":"open","locked":false,"title":"Update README.md","user":{"login":"AutorestCI","id":18218145,"avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-05-19T21:29:49Z","updated_at":"2018-05-17T21:15:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1d020a4d8788aa40753ca326f0818a8cd805ac93","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/commits","review_comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/comments","review_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2/comments","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/40d2028637a6b5f8f6ae6e595e772d6fc33b93bb","head":{"label":"AutorestCI:AutorestCI-patch-1","ref":"AutorestCI-patch-1","sha":"40d2028637a6b5f8f6ae6e595e772d6fc33b93bb","user":{"login":"AutorestCI","id":18218145,"avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"repo":{"id":59243826,"name":"TestingRepo","full_name":"AutorestCI/TestingRepo","owner":{"login":"AutorestCI","id":18218145,"avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/AutorestCI/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":true,"url":"https://api.github.com/repos/AutorestCI/TestingRepo","forks_url":"https://api.github.com/repos/AutorestCI/TestingRepo/forks","keys_url":"https://api.github.com/repos/AutorestCI/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/AutorestCI/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/AutorestCI/TestingRepo/teams","hooks_url":"https://api.github.com/repos/AutorestCI/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/AutorestCI/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/AutorestCI/TestingRepo/events","assignees_url":"https://api.github.com/repos/AutorestCI/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/AutorestCI/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/AutorestCI/TestingRepo/tags","blobs_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/AutorestCI/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/AutorestCI/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/AutorestCI/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/AutorestCI/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/AutorestCI/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/AutorestCI/TestingRepo/subscription","commits_url":"https://api.github.com/repos/AutorestCI/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/AutorestCI/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/AutorestCI/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/AutorestCI/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/AutorestCI/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/AutorestCI/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/AutorestCI/TestingRepo/merges","archive_url":"https://api.github.com/repos/AutorestCI/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/AutorestCI/TestingRepo/downloads","issues_url":"https://api.github.com/repos/AutorestCI/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/AutorestCI/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/AutorestCI/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/AutorestCI/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/AutorestCI/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/AutorestCI/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/AutorestCI/TestingRepo/deployments","created_at":"2016-05-19T21:26:35Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2016-05-19T21:28:13Z","git_url":"git://github.com/AutorestCI/TestingRepo.git","ssh_url":"git@github.com:AutorestCI/TestingRepo.git","clone_url":"https://github.com/AutorestCI/TestingRepo.git","svn_url":"https://github.com/AutorestCI/TestingRepo","homepage":null,"size":1,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"lmazuel:master","ref":"master","sha":"dd82f65f1b6314b18609b8572464b6d328ea70d4","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"repo":{"id":56793153,"name":"TestingRepo","full_name":"lmazuel/TestingRepo","owner":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lmazuel/TestingRepo","description":"To test to Python Github SDK. Nothing interesting here.","fork":false,"url":"https://api.github.com/repos/lmazuel/TestingRepo","forks_url":"https://api.github.com/repos/lmazuel/TestingRepo/forks","keys_url":"https://api.github.com/repos/lmazuel/TestingRepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lmazuel/TestingRepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lmazuel/TestingRepo/teams","hooks_url":"https://api.github.com/repos/lmazuel/TestingRepo/hooks","issue_events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/events{/number}","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/events","assignees_url":"https://api.github.com/repos/lmazuel/TestingRepo/assignees{/user}","branches_url":"https://api.github.com/repos/lmazuel/TestingRepo/branches{/branch}","tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/tags","blobs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/{sha}","languages_url":"https://api.github.com/repos/lmazuel/TestingRepo/languages","stargazers_url":"https://api.github.com/repos/lmazuel/TestingRepo/stargazers","contributors_url":"https://api.github.com/repos/lmazuel/TestingRepo/contributors","subscribers_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscribers","subscription_url":"https://api.github.com/repos/lmazuel/TestingRepo/subscription","commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/lmazuel/TestingRepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/lmazuel/TestingRepo/contents/{+path}","compare_url":"https://api.github.com/repos/lmazuel/TestingRepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lmazuel/TestingRepo/merges","archive_url":"https://api.github.com/repos/lmazuel/TestingRepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lmazuel/TestingRepo/downloads","issues_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues{/number}","pulls_url":"https://api.github.com/repos/lmazuel/TestingRepo/pulls{/number}","milestones_url":"https://api.github.com/repos/lmazuel/TestingRepo/milestones{/number}","notifications_url":"https://api.github.com/repos/lmazuel/TestingRepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/labels{/name}","releases_url":"https://api.github.com/repos/lmazuel/TestingRepo/releases{/id}","deployments_url":"https://api.github.com/repos/lmazuel/TestingRepo/deployments","created_at":"2016-04-21T17:29:04Z","updated_at":"2016-04-21T17:29:04Z","pushed_at":"2018-02-14T21:55:42Z","git_url":"git://github.com/lmazuel/TestingRepo.git","ssh_url":"git@github.com:lmazuel/TestingRepo.git","clone_url":"https://github.com/lmazuel/TestingRepo.git","svn_url":"https://github.com/lmazuel/TestingRepo","homepage":null,"size":43,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":1,"open_issues":10,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2"},"html":{"href":"https://github.com/lmazuel/TestingRepo/pull/2"},"issue":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2"},"comments":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/lmazuel/TestingRepo/statuses/40d2028637a6b5f8f6ae6e595e772d6fc33b93bb"}},"author_association":"COLLABORATOR","merged":false,"mergeable":true,"rebaseable":false,"mergeable_state":"clean","merged_by":null,"comments":3,"review_comments":0,"maintainer_can_modify":false,"commits":1,"additions":2,"deletions":0,"changed_files":1} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/2/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "This is a test"} +201 +[('Date', 'Thu, 17 May 2018 21:27:32 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1247'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4796'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"b3aba802534abbc06eb4cee35eca6eac"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017676'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.233537'), ('X-GitHub-Request-Id', '16FD:97B8:C2466C:FB5542:5AFDF3C4')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017676","html_url":"https://github.com/lmazuel/TestingRepo/pull/2#issuecomment-390017676","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/2","id":390017676,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:32Z","updated_at":"2018-05-17T21:27:32Z","author_association":"OWNER","body":"This is a test"} + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017676 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:27:33 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4795'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.189453'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '16FE:97BA:C922C2:104EF68:5AFDF3C4')] + + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_dashboard.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_dashboard.txt new file mode 100644 index 000000000000..8b62646b0d02 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_dashboard.txt @@ -0,0 +1,110 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/15 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4794'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"f7880303c57eae4c85d647cee834e3f6"'), ('Last-Modified', 'Thu, 17 May 2018 21:15:07 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.054964'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '16FF:97BA:C922DA:104EF8A:5AFDF3C5')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/15","id":293729231,"number":15,"title":"Dashboard testing","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-02-02T00:09:29Z","updated_at":"2018-05-17T21:15:07Z","closed_at":null,"author_association":"OWNER","body":"","closed_by":null} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/15/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4793'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"394698f297e36caa81023c22d91e8f84"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.106485'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1700:97BA:C922E8:104EF9A:5AFDF3C5')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/362444226","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-362444226","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":362444226,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-02T00:10:56Z","updated_at":"2018-02-02T00:59:46Z","author_association":"OWNER","body":"klsfjdlkjflksd\nlskjflkdjf\n"}] + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/15/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4792'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"394698f297e36caa81023c22d91e8f84"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.066016'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1701:97B8:C246C0:FB55B0:5AFDF3C5')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/362444226","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-362444226","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":362444226,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-02T00:10:56Z","updated_at":"2018-02-02T00:59:46Z","author_association":"OWNER","body":"klsfjdlkjflksd\nlskjflkdjf\n"}] + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/15/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "# MYHEADER"} +201 +[('Date', 'Thu, 17 May 2018 21:27:33 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1247'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4791'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"772f2729f150f5896d0a03475c5dd0c5"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017687'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.190633'), ('X-GitHub-Request-Id', '1702:97B8:C246D0:FB55C5:5AFDF3C5')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017687","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-390017687","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":390017687,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:33Z","updated_at":"2018-05-17T21:27:33Z","author_association":"OWNER","body":"# MYHEADER"} + +https +PATCH +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017687 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "# MYHEADER\n
Encountered an unknown error: (Python bot)

\n\n```python\nsomething to do with an exception\n```\n\n

"} +200 +[('Date', 'Thu, 17 May 2018 21:27:34 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4790'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"bd0982c93a87b03a313876721ccc76a4"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.191203'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1703:97B8:C246F0:FB55EC:5AFDF3C5')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017687","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-390017687","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":390017687,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:33Z","updated_at":"2018-05-17T21:27:34Z","author_association":"OWNER","body":"# MYHEADER\n
Encountered an unknown error: (Python bot)

\n\n```python\nsomething to do with an exception\n```\n\n

"} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/15/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:34 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4789'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"b91f459a1d0337ede82a9105fa62ce19"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.075426'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1704:97BA:C92330:104F002:5AFDF3C6')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/362444226","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-362444226","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":362444226,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-02T00:10:56Z","updated_at":"2018-02-02T00:59:46Z","author_association":"OWNER","body":"klsfjdlkjflksd\nlskjflkdjf\n"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017687","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-390017687","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":390017687,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:33Z","updated_at":"2018-05-17T21:27:34Z","author_association":"OWNER","body":"# MYHEADER\n
Encountered an unknown error: (Python bot)

\n\n```python\nsomething to do with an exception\n```\n\n

"}] + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/15/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:34 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4788'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"b91f459a1d0337ede82a9105fa62ce19"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.070095'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1705:97BA:C92342:104F012:5AFDF3C6')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/362444226","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-362444226","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":362444226,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-02T00:10:56Z","updated_at":"2018-02-02T00:59:46Z","author_association":"OWNER","body":"klsfjdlkjflksd\nlskjflkdjf\n"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017687","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-390017687","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":390017687,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:33Z","updated_at":"2018-05-17T21:27:34Z","author_association":"OWNER","body":"# MYHEADER\n
Encountered an unknown error: (Python bot)

\n\n```python\nsomething to do with an exception\n```\n\n

"}] + +https +PATCH +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017687 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "# MYHEADER\nNew text comment"} +200 +[('Date', 'Thu, 17 May 2018 21:27:34 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4787'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"7d8a8bf4af44d34c832747ad13a83446"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.218436'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1706:97B8:C24728:FB5638:5AFDF3C6')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017687","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-390017687","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":390017687,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:33Z","updated_at":"2018-05-17T21:27:34Z","author_association":"OWNER","body":"# MYHEADER\nNew text comment"} + +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/15/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:35 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4786'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"2765cea7edb0c5332910282095b1d4c1"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.061215'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1707:97B8:C2473C:FB5658:5AFDF3C6')] +[{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/362444226","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-362444226","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":362444226,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-02-02T00:10:56Z","updated_at":"2018-02-02T00:59:46Z","author_association":"OWNER","body":"klsfjdlkjflksd\nlskjflkdjf\n"},{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017687","html_url":"https://github.com/lmazuel/TestingRepo/issues/15#issuecomment-390017687","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/15","id":390017687,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:33Z","updated_at":"2018-05-17T21:27:34Z","author_association":"OWNER","body":"# MYHEADER\nNew text comment"}] + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017687 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:27:35 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4785'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.126890'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '1708:97B4:2AC8C4:374BDD:5AFDF3C7')] + + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_exception_to_github.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_exception_to_github.txt new file mode 100644 index 000000000000..935e64e2fc1f --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_exception_to_github.txt @@ -0,0 +1,99 @@ +https +GET +api.github.com +None +/repos/lmazuel/TestingRepo/issues/13 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:35 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4784'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"5d22339274e7041343287e3bfa73f758"'), ('Last-Modified', 'Thu, 17 May 2018 21:15:10 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', 'repo'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.057591'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1709:97B6:61F179:7EE505:5AFDF3C7')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13","repository_url":"https://api.github.com/repos/lmazuel/TestingRepo","labels_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13/labels{/name}","comments_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13/comments","events_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13/events","html_url":"https://github.com/lmazuel/TestingRepo/issues/13","id":290980764,"number":13,"title":"Testing exception","user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-01-23T20:24:40Z","updated_at":"2018-05-17T21:15:10Z","closed_at":null,"author_association":"OWNER","body":"This unittest is doing something stupid, to test I'm able to log in a generic way the stacktrace in Github","closed_by":null} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/13/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "
Encountered an unknown error

\n\n```python\nsomething to do with an exception\n```\n\n

"} +201 +[('Date', 'Thu, 17 May 2018 21:27:35 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1367'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4783'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"02c13ce01b48f85e423f4eaaa70ae776"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017694'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.207902'), ('X-GitHub-Request-Id', '170A:97BA:C923A8:104F0A2:5AFDF3C7')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017694","html_url":"https://github.com/lmazuel/TestingRepo/issues/13#issuecomment-390017694","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13","id":390017694,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:35Z","updated_at":"2018-05-17T21:27:35Z","author_association":"OWNER","body":"
Encountered an unknown error

\n\n```python\nsomething to do with an exception\n```\n\n

"} + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017694 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:27:36 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4782'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.137629'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '170B:97B6:61F19A:7EE52A:5AFDF3C7')] + + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/13/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "
Encountered an unknown error: (Python bot)

\n\n```python\nsomething to do with an exception\n```\n\n

"} +201 +[('Date', 'Thu, 17 May 2018 21:27:36 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1381'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4781'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"80a0e4c3cf7c8e5152378483fc9b6928"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017696'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.177832'), ('X-GitHub-Request-Id', '170C:97B4:2AC8D4:374BF5:5AFDF3C8')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017696","html_url":"https://github.com/lmazuel/TestingRepo/issues/13#issuecomment-390017696","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13","id":390017696,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:36Z","updated_at":"2018-05-17T21:27:36Z","author_association":"OWNER","body":"
Encountered an unknown error: (Python bot)

\n\n```python\nsomething to do with an exception\n```\n\n

"} + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017696 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:27:36 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4780'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.152868'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '170D:97BA:C923DA:104F0E5:5AFDF3C8')] + + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/13/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "
Encountered a Subprocess error: (Python bot)

\n\nCommand: ['autorest', 'readme.md']\nFinished with return code 2\nand output:\n```shell\nError line 1\nError line 2\n```\n\n

"} +201 +[('Date', 'Thu, 17 May 2018 21:27:36 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1453'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4779'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"1b1b351c9807c836fbc5facac7829561"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017699'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.193468'), ('X-GitHub-Request-Id', '170E:97B6:61F1CD:7EE566:5AFDF3C8')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017699","html_url":"https://github.com/lmazuel/TestingRepo/issues/13#issuecomment-390017699","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13","id":390017699,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:36Z","updated_at":"2018-05-17T21:27:36Z","author_association":"OWNER","body":"
Encountered a Subprocess error: (Python bot)

\n\nCommand: ['autorest', 'readme.md']\nFinished with return code 2\nand output:\n```shell\nError line 1\nError line 2\n```\n\n

"} + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017699 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:27:37 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4778'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.129749'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '170F:97BA:C92400:104F11E:5AFDF3C8')] + + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/issues/13/comments +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"body": "
Encountered a Subprocess error: (Python bot)

\n\nCommand: ['autorest', 'readme.md']\nFinished with return code 2\nand no output\n\n

"} +201 +[('Date', 'Thu, 17 May 2018 21:27:37 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1412'), ('Server', 'GitHub.com'), ('Status', '201 Created'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4777'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', '"c63186bf115722901d5391428f67a13b"'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('Location', 'https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017701'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.211042'), ('X-GitHub-Request-Id', '1710:97B8:C24810:FB5779:5AFDF3C9')] +{"url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/comments/390017701","html_url":"https://github.com/lmazuel/TestingRepo/issues/13#issuecomment-390017701","issue_url":"https://api.github.com/repos/lmazuel/TestingRepo/issues/13","id":390017701,"user":{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false},"created_at":"2018-05-17T21:27:37Z","updated_at":"2018-05-17T21:27:37Z","author_association":"OWNER","body":"
Encountered a Subprocess error: (Python bot)

\n\nCommand: ['autorest', 'readme.md']\nFinished with return code 2\nand no output\n\n

"} + +https +DELETE +api.github.com +None +/repos/lmazuel/TestingRepo/issues/comments/390017701 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +204 +[('Date', 'Thu, 17 May 2018 21:27:37 GMT'), ('Content-Type', 'application/octet-stream'), ('Server', 'GitHub.com'), ('Status', '204 No Content'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4776'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.150903'), ('Vary', 'Accept-Encoding'), ('X-GitHub-Request-Id', '1711:97BA:C92421:104F154:5AFDF3C9')] + + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_files.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_files.txt new file mode 100644 index 000000000000..5cc5b47e4f6a --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_files.txt @@ -0,0 +1,33 @@ +https +GET +api.github.com +None +/repos/Azure/azure-sdk-for-python/pulls/1833 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:38 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4775'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"efe380b23abd3372e84ff35dbd437a3c"'), ('Last-Modified', 'Thu, 29 Mar 2018 00:23:35 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.134239'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1712:97B8:C2483A:FB57AE:5AFDF3C9')] +{"url":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/1833","id":165209780,"html_url":"https://github.com/Azure/azure-sdk-for-python/pull/1833","diff_url":"https://github.com/Azure/azure-sdk-for-python/pull/1833.diff","patch_url":"https://github.com/Azure/azure-sdk-for-python/pull/1833.patch","issue_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/1833","number":1833,"state":"closed","locked":false,"title":"Automatic PR of restapi_auto_bgsky_master into master","user":{"login":"AutorestCI","id":18218145,"avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"body":"Created to sync https://github.com/Azure/azure-rest-api-specs/pull/2335","created_at":"2018-01-25T19:40:09Z","updated_at":"2018-02-06T18:26:44Z","closed_at":"2018-02-06T18:26:41Z","merged_at":null,"merge_commit_sha":"7a4bc4682149db0f88b1ad628b432fe90ae87786","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":803155593,"url":"https://api.github.com/repos/Azure/azure-sdk-for-python/labels/RestPRMerged","name":"RestPRMerged","color":"0e8a16","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/1833/commits","review_comments_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/1833/comments","review_comment_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/1833/comments","statuses_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/statuses/3d6c419cd2ade53c240c40db96dbe34957351244","head":{"label":"Azure:restapi_auto_bgsky_master","ref":"restapi_auto_bgsky_master","sha":"3d6c419cd2ade53c240c40db96dbe34957351244","user":{"login":"Azure","id":6844498,"avatar_url":"https://avatars0.githubusercontent.com/u/6844498?v=4","gravatar_id":"","url":"https://api.github.com/users/Azure","html_url":"https://github.com/Azure","followers_url":"https://api.github.com/users/Azure/followers","following_url":"https://api.github.com/users/Azure/following{/other_user}","gists_url":"https://api.github.com/users/Azure/gists{/gist_id}","starred_url":"https://api.github.com/users/Azure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Azure/subscriptions","organizations_url":"https://api.github.com/users/Azure/orgs","repos_url":"https://api.github.com/users/Azure/repos","events_url":"https://api.github.com/users/Azure/events{/privacy}","received_events_url":"https://api.github.com/users/Azure/received_events","type":"Organization","site_admin":false},"repo":{"id":4127088,"name":"azure-sdk-for-python","full_name":"Azure/azure-sdk-for-python","owner":{"login":"Azure","id":6844498,"avatar_url":"https://avatars0.githubusercontent.com/u/6844498?v=4","gravatar_id":"","url":"https://api.github.com/users/Azure","html_url":"https://github.com/Azure","followers_url":"https://api.github.com/users/Azure/followers","following_url":"https://api.github.com/users/Azure/following{/other_user}","gists_url":"https://api.github.com/users/Azure/gists{/gist_id}","starred_url":"https://api.github.com/users/Azure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Azure/subscriptions","organizations_url":"https://api.github.com/users/Azure/orgs","repos_url":"https://api.github.com/users/Azure/repos","events_url":"https://api.github.com/users/Azure/events{/privacy}","received_events_url":"https://api.github.com/users/Azure/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Azure/azure-sdk-for-python","description":"Microsoft Azure SDK for Python","fork":false,"url":"https://api.github.com/repos/Azure/azure-sdk-for-python","forks_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/forks","keys_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/teams","hooks_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/hooks","issue_events_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/events{/number}","events_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/events","assignees_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/assignees{/user}","branches_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/branches{/branch}","tags_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/tags","blobs_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/statuses/{sha}","languages_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/languages","stargazers_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/stargazers","contributors_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contributors","subscribers_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/subscribers","subscription_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/subscription","commits_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/{+path}","compare_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/merges","archive_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/downloads","issues_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues{/number}","pulls_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls{/number}","milestones_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/milestones{/number}","notifications_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/labels{/name}","releases_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/releases{/id}","deployments_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/deployments","created_at":"2012-04-24T16:46:12Z","updated_at":"2018-05-16T23:44:09Z","pushed_at":"2018-05-17T20:20:22Z","git_url":"git://github.com/Azure/azure-sdk-for-python.git","ssh_url":"git@github.com:Azure/azure-sdk-for-python.git","clone_url":"https://github.com/Azure/azure-sdk-for-python.git","svn_url":"https://github.com/Azure/azure-sdk-for-python","homepage":"","size":64485,"stargazers_count":536,"watchers_count":536,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":450,"mirror_url":null,"archived":false,"open_issues_count":176,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":450,"open_issues":176,"watchers":536,"default_branch":"master"}},"base":{"label":"Azure:master","ref":"master","sha":"f4715da4f929733b2b95c03142512f85ae8728a5","user":{"login":"Azure","id":6844498,"avatar_url":"https://avatars0.githubusercontent.com/u/6844498?v=4","gravatar_id":"","url":"https://api.github.com/users/Azure","html_url":"https://github.com/Azure","followers_url":"https://api.github.com/users/Azure/followers","following_url":"https://api.github.com/users/Azure/following{/other_user}","gists_url":"https://api.github.com/users/Azure/gists{/gist_id}","starred_url":"https://api.github.com/users/Azure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Azure/subscriptions","organizations_url":"https://api.github.com/users/Azure/orgs","repos_url":"https://api.github.com/users/Azure/repos","events_url":"https://api.github.com/users/Azure/events{/privacy}","received_events_url":"https://api.github.com/users/Azure/received_events","type":"Organization","site_admin":false},"repo":{"id":4127088,"name":"azure-sdk-for-python","full_name":"Azure/azure-sdk-for-python","owner":{"login":"Azure","id":6844498,"avatar_url":"https://avatars0.githubusercontent.com/u/6844498?v=4","gravatar_id":"","url":"https://api.github.com/users/Azure","html_url":"https://github.com/Azure","followers_url":"https://api.github.com/users/Azure/followers","following_url":"https://api.github.com/users/Azure/following{/other_user}","gists_url":"https://api.github.com/users/Azure/gists{/gist_id}","starred_url":"https://api.github.com/users/Azure/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Azure/subscriptions","organizations_url":"https://api.github.com/users/Azure/orgs","repos_url":"https://api.github.com/users/Azure/repos","events_url":"https://api.github.com/users/Azure/events{/privacy}","received_events_url":"https://api.github.com/users/Azure/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Azure/azure-sdk-for-python","description":"Microsoft Azure SDK for Python","fork":false,"url":"https://api.github.com/repos/Azure/azure-sdk-for-python","forks_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/forks","keys_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/teams","hooks_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/hooks","issue_events_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/events{/number}","events_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/events","assignees_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/assignees{/user}","branches_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/branches{/branch}","tags_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/tags","blobs_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/statuses/{sha}","languages_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/languages","stargazers_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/stargazers","contributors_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contributors","subscribers_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/subscribers","subscription_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/subscription","commits_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/{+path}","compare_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/merges","archive_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/downloads","issues_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues{/number}","pulls_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls{/number}","milestones_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/milestones{/number}","notifications_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/labels{/name}","releases_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/releases{/id}","deployments_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/deployments","created_at":"2012-04-24T16:46:12Z","updated_at":"2018-05-16T23:44:09Z","pushed_at":"2018-05-17T20:20:22Z","git_url":"git://github.com/Azure/azure-sdk-for-python.git","ssh_url":"git@github.com:Azure/azure-sdk-for-python.git","clone_url":"https://github.com/Azure/azure-sdk-for-python.git","svn_url":"https://github.com/Azure/azure-sdk-for-python","homepage":"","size":64485,"stargazers_count":536,"watchers_count":536,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":450,"mirror_url":null,"archived":false,"open_issues_count":176,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":450,"open_issues":176,"watchers":536,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/1833"},"html":{"href":"https://github.com/Azure/azure-sdk-for-python/pull/1833"},"issue":{"href":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/1833"},"comments":{"href":"https://api.github.com/repos/Azure/azure-sdk-for-python/issues/1833/comments"},"review_comments":{"href":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/1833/comments"},"review_comment":{"href":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Azure/azure-sdk-for-python/pulls/1833/commits"},"statuses":{"href":"https://api.github.com/repos/Azure/azure-sdk-for-python/statuses/3d6c419cd2ade53c240c40db96dbe34957351244"}},"author_association":"MEMBER","merged":false,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":null,"comments":1,"review_comments":0,"maintainer_can_modify":false,"commits":9,"additions":1941,"deletions":43,"changed_files":23} + +https +GET +api.github.com +None +/repos/Azure/azure-sdk-for-python/pulls/1833/files +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:38 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4774'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"974102d71c3b4d54ea78ae6faeddeb4d"'), ('Last-Modified', 'Thu, 29 Mar 2018 00:23:35 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.104289'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1713:97B6:61F208:7EE5BA:5AFDF3CA')] +[{"sha":"bf24d5ec847de2a0e8e63082550a5bcfeac05048","filename":"azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py","status":"modified","additions":33,"deletions":4,"changes":37,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -14,9 +14,12 @@\n from msrestazure import AzureConfiguration\n from .version import VERSION\n from .operations.usage_details_operations import UsageDetailsOperations\n+from .operations.marketplaces_operations import MarketplacesOperations\n from .operations.reservations_summaries_operations import ReservationsSummariesOperations\n from .operations.reservations_details_operations import ReservationsDetailsOperations\n+from .operations.budgets_operations import BudgetsOperations\n from .operations.operations import Operations\n+from .operations.price_sheet_operations import PriceSheetOperations\n from . import models\n \n \n@@ -30,16 +33,24 @@ class ConsumptionManagementClientConfiguration(AzureConfiguration):\n object`\n :param subscription_id: Azure Subscription ID.\n :type subscription_id: str\n+ :param resource_group_name: Azure Resource Group Name.\n+ :type resource_group_name: str\n+ :param budget_name: Budget Name.\n+ :type budget_name: str\n :param str base_url: Service URL\n \"\"\"\n \n def __init__(\n- self, credentials, subscription_id, base_url=None):\n+ self, credentials, subscription_id, resource_group_name, budget_name, base_url=None):\n \n if credentials is None:\n raise ValueError(\"Parameter 'credentials' must not be None.\")\n if subscription_id is None:\n raise ValueError(\"Parameter 'subscription_id' must not be None.\")\n+ if resource_group_name is None:\n+ raise ValueError(\"Parameter 'resource_group_name' must not be None.\")\n+ if budget_name is None:\n+ raise ValueError(\"Parameter 'budget_name' must not be None.\")\n if not base_url:\n base_url = 'https://management.azure.com'\n \n@@ -50,6 +61,8 @@ def __init__(\n \n self.credentials = credentials\n self.subscription_id = subscription_id\n+ self.resource_group_name = resource_group_name\n+ self.budget_name = budget_name\n \n \n class ConsumptionManagementClient(object):\n@@ -60,37 +73,53 @@ class ConsumptionManagementClient(object):\n \n :ivar usage_details: UsageDetails operations\n :vartype usage_details: azure.mgmt.consumption.operations.UsageDetailsOperations\n+ :ivar marketplaces: Marketplaces operations\n+ :vartype marketplaces: azure.mgmt.consumption.operations.MarketplacesOperations\n :ivar reservations_summaries: ReservationsSummaries operations\n :vartype reservations_summaries: azure.mgmt.consumption.operations.ReservationsSummariesOperations\n :ivar reservations_details: ReservationsDetails operations\n :vartype reservations_details: azure.mgmt.consumption.operations.ReservationsDetailsOperations\n+ :ivar budgets: Budgets operations\n+ :vartype budgets: azure.mgmt.consumption.operations.BudgetsOperations\n :ivar operations: Operations operations\n :vartype operations: azure.mgmt.consumption.operations.Operations\n+ :ivar price_sheet: PriceSheet operations\n+ :vartype price_sheet: azure.mgmt.consumption.operations.PriceSheetOperations\n \n :param credentials: Credentials needed for the client to connect to Azure.\n :type credentials: :mod:`A msrestazure Credentials\n object`\n :param subscription_id: Azure Subscription ID.\n :type subscription_id: str\n+ :param resource_group_name: Azure Resource Group Name.\n+ :type resource_group_name: str\n+ :param budget_name: Budget Name.\n+ :type budget_name: str\n :param str base_url: Service URL\n \"\"\"\n \n def __init__(\n- self, credentials, subscription_id, base_url=None):\n+ self, credentials, subscription_id, resource_group_name, budget_name, base_url=None):\n \n- self.config = ConsumptionManagementClientConfiguration(credentials, subscription_id, base_url)\n+ self.config = ConsumptionManagementClientConfiguration(credentials, subscription_id, resource_group_name, budget_name, base_url)\n self._client = ServiceClient(self.config.credentials, self.config)\n \n client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}\n- self.api_version = '2017-11-30'\n+ self.api_version = '2018-01-31'\n self._serialize = Serializer(client_models)\n self._deserialize = Deserializer(client_models)\n \n self.usage_details = UsageDetailsOperations(\n self._client, self.config, self._serialize, self._deserialize)\n+ self.marketplaces = MarketplacesOperations(\n+ self._client, self.config, self._serialize, self._deserialize)\n self.reservations_summaries = ReservationsSummariesOperations(\n self._client, self.config, self._serialize, self._deserialize)\n self.reservations_details = ReservationsDetailsOperations(\n self._client, self.config, self._serialize, self._deserialize)\n+ self.budgets = BudgetsOperations(\n+ self._client, self.config, self._serialize, self._deserialize)\n self.operations = Operations(\n self._client, self.config, self._serialize, self._deserialize)\n+ self.price_sheet = PriceSheetOperations(\n+ self._client, self.config, self._serialize, self._deserialize)"},{"sha":"d071f7f2e49d6159288f76e17b5cf2c52f900933","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py","status":"modified","additions":28,"deletions":0,"changes":28,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -11,34 +11,62 @@\n \n from .meter_details import MeterDetails\n from .usage_detail import UsageDetail\n+from .marketplace import Marketplace\n from .reservation_summaries import ReservationSummaries\n from .reservation_details import ReservationDetails\n+from .budget_time_period import BudgetTimePeriod\n+from .filters import Filters\n+from .current_spend import CurrentSpend\n+from .notification import Notification\n+from .budget import Budget\n from .error_details import ErrorDetails\n from .error_response import ErrorResponse, ErrorResponseException\n from .operation_display import OperationDisplay\n from .operation import Operation\n from .resource import Resource\n+from .proxy_resource import ProxyResource\n+from .price_sheet_list_result import PriceSheetListResult\n+from .price_sheet_model import PriceSheetModel\n from .usage_detail_paged import UsageDetailPaged\n+from .marketplace_paged import MarketplacePaged\n from .reservation_summaries_paged import ReservationSummariesPaged\n from .reservation_details_paged import ReservationDetailsPaged\n+from .budget_paged import BudgetPaged\n from .operation_paged import OperationPaged\n from .consumption_management_client_enums import (\n+ CategoryType,\n+ TimeGrainType,\n+ OperatorType,\n Datagrain,\n )\n \n __all__ = [\n 'MeterDetails',\n 'UsageDetail',\n+ 'Marketplace',\n 'ReservationSummaries',\n 'ReservationDetails',\n+ 'BudgetTimePeriod',\n+ 'Filters',\n+ 'CurrentSpend',\n+ 'Notification',\n+ 'Budget',\n 'ErrorDetails',\n 'ErrorResponse', 'ErrorResponseException',\n 'OperationDisplay',\n 'Operation',\n 'Resource',\n+ 'ProxyResource',\n+ 'PriceSheetListResult',\n+ 'PriceSheetModel',\n 'UsageDetailPaged',\n+ 'MarketplacePaged',\n 'ReservationSummariesPaged',\n 'ReservationDetailsPaged',\n+ 'BudgetPaged',\n 'OperationPaged',\n+ 'CategoryType',\n+ 'TimeGrainType',\n+ 'OperatorType',\n 'Datagrain',\n ]"},{"sha":"f6485d49266ddf2734c02ab55dceb9aba94bfe0a","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py","status":"added","additions":91,"deletions":0,"changes":91,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,91 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from .proxy_resource import ProxyResource\n+\n+\n+class Budget(ProxyResource):\n+ \"\"\"A budget resource.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar id: Resource Id.\n+ :vartype id: str\n+ :ivar name: Resource name.\n+ :vartype name: str\n+ :ivar type: Resource type.\n+ :vartype type: str\n+ :param e_tag: eTag of the resource. To handle concurrent update scenarion,\n+ this field will be used to determine whether the user is updating the\n+ latest version or not.\n+ :type e_tag: str\n+ :param category: The category of the budget, whether the budget tracks\n+ cost or usage. Possible values include: 'Cost', 'Usage'\n+ :type category: str or ~azure.mgmt.consumption.models.CategoryType\n+ :param amount: The total amount of cost to track with the budget\n+ :type amount: decimal.Decimal\n+ :param time_grain: The time covered by a budget. Tracking of the amount\n+ will be reset based on the time grain. Possible values include: 'Monthly',\n+ 'Quarterly', 'Annually'\n+ :type time_grain: str or ~azure.mgmt.consumption.models.TimeGrainType\n+ :param time_period: Has start and end date of the budget. The start date\n+ must be first of the month and should be less than the end date. Budget\n+ start date must be on or after June 1, 2017. Future start date should not\n+ be more than three months. Past start date should be selected within the\n+ timegrain preiod. There are no restrictions on the end date.\n+ :type time_period: ~azure.mgmt.consumption.models.BudgetTimePeriod\n+ :param filters: May be used to filter budgets by resource group, resource,\n+ or meter.\n+ :type filters: ~azure.mgmt.consumption.models.Filters\n+ :ivar current_spend: The current amount of cost which is being tracked for\n+ a budget.\n+ :vartype current_spend: ~azure.mgmt.consumption.models.CurrentSpend\n+ :param notifications: Dictionary of notifications associated with the\n+ budget. Budget can have up to five notifications.\n+ :type notifications: dict[str,\n+ ~azure.mgmt.consumption.models.Notification]\n+ \"\"\"\n+\n+ _validation = {\n+ 'id': {'readonly': True},\n+ 'name': {'readonly': True},\n+ 'type': {'readonly': True},\n+ 'category': {'required': True},\n+ 'amount': {'required': True},\n+ 'time_grain': {'required': True},\n+ 'time_period': {'required': True},\n+ 'current_spend': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'id': {'key': 'id', 'type': 'str'},\n+ 'name': {'key': 'name', 'type': 'str'},\n+ 'type': {'key': 'type', 'type': 'str'},\n+ 'e_tag': {'key': 'eTag', 'type': 'str'},\n+ 'category': {'key': 'properties.category', 'type': 'str'},\n+ 'amount': {'key': 'properties.amount', 'type': 'decimal'},\n+ 'time_grain': {'key': 'properties.timeGrain', 'type': 'str'},\n+ 'time_period': {'key': 'properties.timePeriod', 'type': 'BudgetTimePeriod'},\n+ 'filters': {'key': 'properties.filters', 'type': 'Filters'},\n+ 'current_spend': {'key': 'properties.currentSpend', 'type': 'CurrentSpend'},\n+ 'notifications': {'key': 'properties.notifications', 'type': '{Notification}'},\n+ }\n+\n+ def __init__(self, category, amount, time_grain, time_period, e_tag=None, filters=None, notifications=None):\n+ super(Budget, self).__init__(e_tag=e_tag)\n+ self.category = category\n+ self.amount = amount\n+ self.time_grain = time_grain\n+ self.time_period = time_period\n+ self.filters = filters\n+ self.current_spend = None\n+ self.notifications = notifications"},{"sha":"2668382253e2d7aaefb8665a466d2482193e0246","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py","status":"added","additions":27,"deletions":0,"changes":27,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,27 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.paging import Paged\n+\n+\n+class BudgetPaged(Paged):\n+ \"\"\"\n+ A paging container for iterating over a list of :class:`Budget ` object\n+ \"\"\"\n+\n+ _attribute_map = {\n+ 'next_link': {'key': 'nextLink', 'type': 'str'},\n+ 'current_page': {'key': 'value', 'type': '[Budget]'}\n+ }\n+\n+ def __init__(self, *args, **kwargs):\n+\n+ super(BudgetPaged, self).__init__(*args, **kwargs)"},{"sha":"2b1c0e78418a1deb6b6147fc90ea53f1a03256d0","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py","status":"added","additions":37,"deletions":0,"changes":37,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,37 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class BudgetTimePeriod(Model):\n+ \"\"\"The start and end date for a budget.\n+\n+ :param start_date: The start date for the budget.\n+ :type start_date: datetime\n+ :param end_date: The end date for the budget. If not provided, we default\n+ this to 10 years from the start date.\n+ :type end_date: datetime\n+ \"\"\"\n+\n+ _validation = {\n+ 'start_date': {'required': True},\n+ }\n+\n+ _attribute_map = {\n+ 'start_date': {'key': 'startDate', 'type': 'iso-8601'},\n+ 'end_date': {'key': 'endDate', 'type': 'iso-8601'},\n+ }\n+\n+ def __init__(self, start_date, end_date=None):\n+ super(BudgetTimePeriod, self).__init__()\n+ self.start_date = start_date\n+ self.end_date = end_date"},{"sha":"bb0db82f76b32c1d02cca1de69b0ecc49b3b548b","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py","status":"modified","additions":20,"deletions":0,"changes":20,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -12,6 +12,26 @@\n from enum import Enum\n \n \n+class CategoryType(Enum):\n+\n+ cost = \"Cost\"\n+ usage = \"Usage\"\n+\n+\n+class TimeGrainType(Enum):\n+\n+ monthly = \"Monthly\"\n+ quarterly = \"Quarterly\"\n+ annually = \"Annually\"\n+\n+\n+class OperatorType(Enum):\n+\n+ equal_to = \"EqualTo\"\n+ greater_than = \"GreaterThan\"\n+ greater_than_or_equal_to = \"GreaterThanOrEqualTo\"\n+\n+\n class Datagrain(Enum):\n \n daily_grain = \"daily\""},{"sha":"839c286b104079f531a4b130f3e01082d63d08ac","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py","status":"added","additions":41,"deletions":0,"changes":41,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,41 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class CurrentSpend(Model):\n+ \"\"\"The current amount of cost which is being tracked for a budget.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar amount: The total amount of cost which is being tracked by the\n+ budget.\n+ :vartype amount: decimal.Decimal\n+ :ivar unit: The unit of measure for the budget amount.\n+ :vartype unit: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'amount': {'readonly': True},\n+ 'unit': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'amount': {'key': 'amount', 'type': 'decimal'},\n+ 'unit': {'key': 'unit', 'type': 'str'},\n+ }\n+\n+ def __init__(self):\n+ super(CurrentSpend, self).__init__()\n+ self.amount = None\n+ self.unit = None"},{"sha":"dc010a065900621f02b77dfe1b389071e597fd73","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py","status":"added","additions":44,"deletions":0,"changes":44,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,44 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class Filters(Model):\n+ \"\"\"May be used to filter budgets by resource group, resource, or meter.\n+\n+ :param resource_groups: The list of filters on resource groups, allowed at\n+ subscription level only.\n+ :type resource_groups: list[str]\n+ :param resources: The list of filters on resources.\n+ :type resources: list[str]\n+ :param meters: The list of filters on meters, mandatory for budgets of\n+ usage category.\n+ :type meters: list[str]\n+ \"\"\"\n+\n+ _validation = {\n+ 'resource_groups': {'max_items': 10, 'min_items': 0},\n+ 'resources': {'max_items': 10, 'min_items': 0},\n+ 'meters': {'max_items': 10, 'min_items': 0},\n+ }\n+\n+ _attribute_map = {\n+ 'resource_groups': {'key': 'resourceGroups', 'type': '[str]'},\n+ 'resources': {'key': 'resources', 'type': '[str]'},\n+ 'meters': {'key': 'meters', 'type': '[str]'},\n+ }\n+\n+ def __init__(self, resource_groups=None, resources=None, meters=None):\n+ super(Filters, self).__init__()\n+ self.resource_groups = resource_groups\n+ self.resources = resources\n+ self.meters = meters"},{"sha":"d401f3fdc397e6aa0d40011f987917ef0984a8bc","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace.py","status":"added","additions":174,"deletions":0,"changes":174,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,174 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from .resource import Resource\n+\n+\n+class Marketplace(Resource):\n+ \"\"\"An marketplace resource.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar id: Resource Id.\n+ :vartype id: str\n+ :ivar name: Resource name.\n+ :vartype name: str\n+ :ivar type: Resource type.\n+ :vartype type: str\n+ :ivar tags: Resource tags.\n+ :vartype tags: dict[str, str]\n+ :ivar billing_period_id: The id of the billing period resource that the\n+ usage belongs to.\n+ :vartype billing_period_id: str\n+ :ivar usage_start: The start of the date time range covered by the usage\n+ detail.\n+ :vartype usage_start: datetime\n+ :ivar usage_end: The end of the date time range covered by the usage\n+ detail.\n+ :vartype usage_end: datetime\n+ :ivar resource_rate: The marketplace resource rate.\n+ :vartype resource_rate: decimal.Decimal\n+ :ivar offer_name: The type of offer.\n+ :vartype offer_name: str\n+ :ivar resource_group: The name of resource group.\n+ :vartype resource_group: str\n+ :ivar order_number: The order number.\n+ :vartype order_number: str\n+ :ivar instance_name: The name of the resource instance that the usage is\n+ about.\n+ :vartype instance_name: str\n+ :ivar instance_id: The uri of the resource instance that the usage is\n+ about.\n+ :vartype instance_id: str\n+ :ivar currency: The ISO currency in which the meter is charged, for\n+ example, USD.\n+ :vartype currency: str\n+ :ivar consumed_quantity: The quantity of usage.\n+ :vartype consumed_quantity: decimal.Decimal\n+ :ivar unit_of_measure: The unit of measure.\n+ :vartype unit_of_measure: str\n+ :ivar pretax_cost: The amount of cost before tax.\n+ :vartype pretax_cost: decimal.Decimal\n+ :ivar is_estimated: The estimated usage is subject to change.\n+ :vartype is_estimated: bool\n+ :ivar meter_id: The meter id.\n+ :vartype meter_id: str\n+ :ivar subscription_guid: Subscription guid.\n+ :vartype subscription_guid: str\n+ :ivar subscription_name: Subscription name.\n+ :vartype subscription_name: str\n+ :ivar account_name: Account name.\n+ :vartype account_name: str\n+ :ivar department_name: Department name.\n+ :vartype department_name: str\n+ :ivar consumed_service: Consumed service name.\n+ :vartype consumed_service: str\n+ :ivar cost_center: The cost center of this department if it is a\n+ department and a costcenter exists\n+ :vartype cost_center: str\n+ :ivar additional_properties: Additional details of this usage item. By\n+ default this is not populated, unless it's specified in $expand.\n+ :vartype additional_properties: str\n+ :ivar publisher_name: The name of publisher.\n+ :vartype publisher_name: str\n+ :ivar plan_name: The name of plan.\n+ :vartype plan_name: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'id': {'readonly': True},\n+ 'name': {'readonly': True},\n+ 'type': {'readonly': True},\n+ 'tags': {'readonly': True},\n+ 'billing_period_id': {'readonly': True},\n+ 'usage_start': {'readonly': True},\n+ 'usage_end': {'readonly': True},\n+ 'resource_rate': {'readonly': True},\n+ 'offer_name': {'readonly': True},\n+ 'resource_group': {'readonly': True},\n+ 'order_number': {'readonly': True},\n+ 'instance_name': {'readonly': True},\n+ 'instance_id': {'readonly': True},\n+ 'currency': {'readonly': True},\n+ 'consumed_quantity': {'readonly': True},\n+ 'unit_of_measure': {'readonly': True},\n+ 'pretax_cost': {'readonly': True},\n+ 'is_estimated': {'readonly': True},\n+ 'meter_id': {'readonly': True},\n+ 'subscription_guid': {'readonly': True},\n+ 'subscription_name': {'readonly': True},\n+ 'account_name': {'readonly': True},\n+ 'department_name': {'readonly': True},\n+ 'consumed_service': {'readonly': True},\n+ 'cost_center': {'readonly': True},\n+ 'additional_properties': {'readonly': True},\n+ 'publisher_name': {'readonly': True},\n+ 'plan_name': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'id': {'key': 'id', 'type': 'str'},\n+ 'name': {'key': 'name', 'type': 'str'},\n+ 'type': {'key': 'type', 'type': 'str'},\n+ 'tags': {'key': 'tags', 'type': '{str}'},\n+ 'billing_period_id': {'key': 'properties.billingPeriodId', 'type': 'str'},\n+ 'usage_start': {'key': 'properties.usageStart', 'type': 'iso-8601'},\n+ 'usage_end': {'key': 'properties.usageEnd', 'type': 'iso-8601'},\n+ 'resource_rate': {'key': 'properties.resourceRate', 'type': 'decimal'},\n+ 'offer_name': {'key': 'properties.offerName', 'type': 'str'},\n+ 'resource_group': {'key': 'properties.resourceGroup', 'type': 'str'},\n+ 'order_number': {'key': 'properties.orderNumber', 'type': 'str'},\n+ 'instance_name': {'key': 'properties.instanceName', 'type': 'str'},\n+ 'instance_id': {'key': 'properties.instanceId', 'type': 'str'},\n+ 'currency': {'key': 'properties.currency', 'type': 'str'},\n+ 'consumed_quantity': {'key': 'properties.consumedQuantity', 'type': 'decimal'},\n+ 'unit_of_measure': {'key': 'properties.unitOfMeasure', 'type': 'str'},\n+ 'pretax_cost': {'key': 'properties.pretaxCost', 'type': 'decimal'},\n+ 'is_estimated': {'key': 'properties.isEstimated', 'type': 'bool'},\n+ 'meter_id': {'key': 'properties.meterId', 'type': 'str'},\n+ 'subscription_guid': {'key': 'properties.subscriptionGuid', 'type': 'str'},\n+ 'subscription_name': {'key': 'properties.subscriptionName', 'type': 'str'},\n+ 'account_name': {'key': 'properties.accountName', 'type': 'str'},\n+ 'department_name': {'key': 'properties.departmentName', 'type': 'str'},\n+ 'consumed_service': {'key': 'properties.consumedService', 'type': 'str'},\n+ 'cost_center': {'key': 'properties.costCenter', 'type': 'str'},\n+ 'additional_properties': {'key': 'properties.additionalProperties', 'type': 'str'},\n+ 'publisher_name': {'key': 'properties.publisherName', 'type': 'str'},\n+ 'plan_name': {'key': 'properties.planName', 'type': 'str'},\n+ }\n+\n+ def __init__(self):\n+ super(Marketplace, self).__init__()\n+ self.billing_period_id = None\n+ self.usage_start = None\n+ self.usage_end = None\n+ self.resource_rate = None\n+ self.offer_name = None\n+ self.resource_group = None\n+ self.order_number = None\n+ self.instance_name = None\n+ self.instance_id = None\n+ self.currency = None\n+ self.consumed_quantity = None\n+ self.unit_of_measure = None\n+ self.pretax_cost = None\n+ self.is_estimated = None\n+ self.meter_id = None\n+ self.subscription_guid = None\n+ self.subscription_name = None\n+ self.account_name = None\n+ self.department_name = None\n+ self.consumed_service = None\n+ self.cost_center = None\n+ self.additional_properties = None\n+ self.publisher_name = None\n+ self.plan_name = None"},{"sha":"d360761aca550436c8a2be210180f36920169c06","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace_paged.py","status":"added","additions":27,"deletions":0,"changes":27,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace_paged.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace_paged.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/marketplace_paged.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,27 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.paging import Paged\n+\n+\n+class MarketplacePaged(Paged):\n+ \"\"\"\n+ A paging container for iterating over a list of :class:`Marketplace ` object\n+ \"\"\"\n+\n+ _attribute_map = {\n+ 'next_link': {'key': 'nextLink', 'type': 'str'},\n+ 'current_page': {'key': 'value', 'type': '[Marketplace]'}\n+ }\n+\n+ def __init__(self, *args, **kwargs):\n+\n+ super(MarketplacePaged, self).__init__(*args, **kwargs)"},{"sha":"61e1ca0ed34df63b0df71d2970b19f7fa8a866bd","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py","status":"added","additions":62,"deletions":0,"changes":62,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,62 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class Notification(Model):\n+ \"\"\"The notification associated with a budget.\n+\n+ :param enabled: The notification is enabled or not.\n+ :type enabled: bool\n+ :param operator: The comparison operator. Possible values include:\n+ 'EqualTo', 'GreaterThan', 'GreaterThanOrEqualTo'\n+ :type operator: str or ~azure.mgmt.consumption.models.OperatorType\n+ :param threshold: Threshold value associated with a notification.\n+ Notification is sent when the cost exceeded the threshold. It is always\n+ percent and has to be between 0 and 1000.\n+ :type threshold: decimal.Decimal\n+ :param contact_emails: Email addresses to send the budget notification to\n+ when the threshold is exceeded.\n+ :type contact_emails: list[str]\n+ :param contact_roles: Contact roles to send the budget notification to\n+ when the threshold is exceeded.\n+ :type contact_roles: list[str]\n+ :param contact_groups: Action groups to send the budget notification to\n+ when the threshold is exceeded.\n+ :type contact_groups: list[str]\n+ \"\"\"\n+\n+ _validation = {\n+ 'enabled': {'required': True},\n+ 'operator': {'required': True},\n+ 'threshold': {'required': True},\n+ 'contact_emails': {'required': True, 'max_items': 50, 'min_items': 1},\n+ 'contact_groups': {'max_items': 50, 'min_items': 0},\n+ }\n+\n+ _attribute_map = {\n+ 'enabled': {'key': 'enabled', 'type': 'bool'},\n+ 'operator': {'key': 'operator', 'type': 'str'},\n+ 'threshold': {'key': 'threshold', 'type': 'decimal'},\n+ 'contact_emails': {'key': 'contactEmails', 'type': '[str]'},\n+ 'contact_roles': {'key': 'contactRoles', 'type': '[str]'},\n+ 'contact_groups': {'key': 'contactGroups', 'type': '[str]'},\n+ }\n+\n+ def __init__(self, enabled, operator, threshold, contact_emails, contact_roles=None, contact_groups=None):\n+ super(Notification, self).__init__()\n+ self.enabled = enabled\n+ self.operator = operator\n+ self.threshold = threshold\n+ self.contact_emails = contact_emails\n+ self.contact_roles = contact_roles\n+ self.contact_groups = contact_groups"},{"sha":"6b201161f1dd7f05fef48e2355c696e882bb029c","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_list_result.py","status":"added","additions":41,"deletions":0,"changes":41,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_list_result.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_list_result.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_list_result.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,41 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class PriceSheetListResult(Model):\n+ \"\"\"price sheet result. It contains the pricesheet associated with billing\n+ period.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar value: Price sheet\n+ :vartype value: object\n+ :ivar next_link: The link (url) to the next page of results.\n+ :vartype next_link: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'value': {'readonly': True},\n+ 'next_link': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'value': {'key': 'value', 'type': 'object'},\n+ 'next_link': {'key': 'nextLink', 'type': 'str'},\n+ }\n+\n+ def __init__(self):\n+ super(PriceSheetListResult, self).__init__()\n+ self.value = None\n+ self.next_link = None"},{"sha":"0f51585aa714c16764b94d5170b6f65e3f4b5ac0","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_model.py","status":"added","additions":88,"deletions":0,"changes":88,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_model.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_model.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_model.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,88 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from .resource import Resource\n+\n+\n+class PriceSheetModel(Resource):\n+ \"\"\"An pricesheet resource.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar id: Resource Id.\n+ :vartype id: str\n+ :ivar name: Resource name.\n+ :vartype name: str\n+ :ivar type: Resource type.\n+ :vartype type: str\n+ :ivar tags: Resource tags.\n+ :vartype tags: dict[str, str]\n+ :ivar billing_period_id: The id of the billing period resource that the\n+ usage belongs to.\n+ :vartype billing_period_id: str\n+ :ivar meter_id: The meter id\n+ :vartype meter_id: str\n+ :ivar meter_details: The details about the meter. By default this is not\n+ populated, unless it's specified in $expand.\n+ :vartype meter_details: ~azure.mgmt.consumption.models.MeterDetails\n+ :ivar unit_of_measure: Unit of measure\n+ :vartype unit_of_measure: str\n+ :ivar included_quantity: Included quality for an offer\n+ :vartype included_quantity: decimal.Decimal\n+ :ivar part_number: Part Number\n+ :vartype part_number: str\n+ :ivar unit_price: Unit Price\n+ :vartype unit_price: decimal.Decimal\n+ :ivar currency_code: Currency Code\n+ :vartype currency_code: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'id': {'readonly': True},\n+ 'name': {'readonly': True},\n+ 'type': {'readonly': True},\n+ 'tags': {'readonly': True},\n+ 'billing_period_id': {'readonly': True},\n+ 'meter_id': {'readonly': True},\n+ 'meter_details': {'readonly': True},\n+ 'unit_of_measure': {'readonly': True},\n+ 'included_quantity': {'readonly': True},\n+ 'part_number': {'readonly': True},\n+ 'unit_price': {'readonly': True},\n+ 'currency_code': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'id': {'key': 'id', 'type': 'str'},\n+ 'name': {'key': 'name', 'type': 'str'},\n+ 'type': {'key': 'type', 'type': 'str'},\n+ 'tags': {'key': 'tags', 'type': '{str}'},\n+ 'billing_period_id': {'key': 'properties.billingPeriodId', 'type': 'str'},\n+ 'meter_id': {'key': 'properties.meterId', 'type': 'str'},\n+ 'meter_details': {'key': 'properties.meterDetails', 'type': 'MeterDetails'},\n+ 'unit_of_measure': {'key': 'properties.unitOfMeasure', 'type': 'str'},\n+ 'included_quantity': {'key': 'properties.includedQuantity', 'type': 'decimal'},\n+ 'part_number': {'key': 'properties.partNumber', 'type': 'str'},\n+ 'unit_price': {'key': 'properties.unitPrice', 'type': 'decimal'},\n+ 'currency_code': {'key': 'properties.currencyCode', 'type': 'str'},\n+ }\n+\n+ def __init__(self):\n+ super(PriceSheetModel, self).__init__()\n+ self.billing_period_id = None\n+ self.meter_id = None\n+ self.meter_details = None\n+ self.unit_of_measure = None\n+ self.included_quantity = None\n+ self.part_number = None\n+ self.unit_price = None\n+ self.currency_code = None"},{"sha":"f6a9a40d22d569970958af165de44c9f84162e47","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py","status":"added","additions":51,"deletions":0,"changes":51,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,51 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class ProxyResource(Model):\n+ \"\"\"The Resource model definition.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar id: Resource Id.\n+ :vartype id: str\n+ :ivar name: Resource name.\n+ :vartype name: str\n+ :ivar type: Resource type.\n+ :vartype type: str\n+ :param e_tag: eTag of the resource. To handle concurrent update scenarion,\n+ this field will be used to determine whether the user is updating the\n+ latest version or not.\n+ :type e_tag: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'id': {'readonly': True},\n+ 'name': {'readonly': True},\n+ 'type': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'id': {'key': 'id', 'type': 'str'},\n+ 'name': {'key': 'name', 'type': 'str'},\n+ 'type': {'key': 'type', 'type': 'str'},\n+ 'e_tag': {'key': 'eTag', 'type': 'str'},\n+ }\n+\n+ def __init__(self, e_tag=None):\n+ super(ProxyResource, self).__init__()\n+ self.id = None\n+ self.name = None\n+ self.type = None\n+ self.e_tag = e_tag"},{"sha":"cb1dff45a8f9ca787f34422829a20b142a1b9339","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py","status":"modified","additions":6,"deletions":0,"changes":6,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -10,13 +10,19 @@\n # --------------------------------------------------------------------------\n \n from .usage_details_operations import UsageDetailsOperations\n+from .marketplaces_operations import MarketplacesOperations\n from .reservations_summaries_operations import ReservationsSummariesOperations\n from .reservations_details_operations import ReservationsDetailsOperations\n+from .budgets_operations import BudgetsOperations\n from .operations import Operations\n+from .price_sheet_operations import PriceSheetOperations\n \n __all__ = [\n 'UsageDetailsOperations',\n+ 'MarketplacesOperations',\n 'ReservationsSummariesOperations',\n 'ReservationsDetailsOperations',\n+ 'BudgetsOperations',\n 'Operations',\n+ 'PriceSheetOperations',\n ]"},{"sha":"38562f5af055bad608bd52aee7804a97040fab44","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py","status":"added","additions":514,"deletions":0,"changes":514,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,514 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+import uuid\n+from msrest.pipeline import ClientRawResponse\n+\n+from .. import models\n+\n+\n+class BudgetsOperations(object):\n+ \"\"\"BudgetsOperations operations.\n+\n+ :param client: Client for service requests.\n+ :param config: Configuration of service client.\n+ :param serializer: An object model serializer.\n+ :param deserializer: An objec model deserializer.\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n+ \"\"\"\n+\n+ models = models\n+\n+ def __init__(self, client, config, serializer, deserializer):\n+\n+ self._client = client\n+ self._serialize = serializer\n+ self._deserialize = deserializer\n+ self.api_version = \"2018-01-31\"\n+\n+ self.config = config\n+\n+ def list(\n+ self, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists all budgets for a subscription.\n+\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of Budget\n+ :rtype:\n+ ~azure.mgmt.consumption.models.BudgetPaged[~azure.mgmt.consumption.models.Budget]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Consumption/budgets'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.BudgetPaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.BudgetPaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def list_by_resource_group_name(\n+ self, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists all budgets for a resource group under a subscription.\n+\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of Budget\n+ :rtype:\n+ ~azure.mgmt.consumption.models.BudgetPaged[~azure.mgmt.consumption.models.Budget]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Consumption/budgets'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'resourceGroupName': self._serialize.url(\"self.config.resource_group_name\", self.config.resource_group_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.BudgetPaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.BudgetPaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def get(\n+ self, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Gets the budget for a subscription by budget name.\n+\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: Budget or ClientRawResponse if raw=true\n+ :rtype: ~azure.mgmt.consumption.models.Budget or\n+ ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Consumption/budgets/{budgetName}'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'budgetName': self._serialize.url(\"self.config.budget_name\", self.config.budget_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ deserialized = None\n+\n+ if response.status_code == 200:\n+ deserialized = self._deserialize('Budget', response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(deserialized, response)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def create_or_update(\n+ self, parameters, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"The operation to create or update a budget. Update operation requires\n+ latest eTag to be set in the request mandatorily. You may obtain the\n+ latest eTag by performing a get operation. Create operation does not\n+ require eTag.\n+\n+ :param parameters: Parameters supplied to the Create Budget operation.\n+ :type parameters: ~azure.mgmt.consumption.models.Budget\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of None\n+ :rtype: ~azure.mgmt.consumption.models.Budget[None]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Consumption/budgets/{budgetName}'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'budgetName': self._serialize.url(\"self.config.budget_name\", self.config.budget_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct body\n+ body_content = self._serialize.body(parameters, 'Budget')\n+\n+ # Construct and send request\n+ request = self._client.put(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, body_content, stream=False, **operation_config)\n+\n+ if response.status_code not in [200, 201]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.Budget(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.Budget(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def delete(\n+ self, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"The operation to delete a budget.\n+\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: None or ClientRawResponse if raw=true\n+ :rtype: None or ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Consumption/budgets/{budgetName}'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'budgetName': self._serialize.url(\"self.config.budget_name\", self.config.budget_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.delete(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(None, response)\n+ return client_raw_response\n+\n+ def get_by_resource_group_name(\n+ self, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Gets the budget for a resource group under a subscription by budget\n+ name.\n+\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: Budget or ClientRawResponse if raw=true\n+ :rtype: ~azure.mgmt.consumption.models.Budget or\n+ ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Consumption/budgets/{budgetName}'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'resourceGroupName': self._serialize.url(\"self.config.resource_group_name\", self.config.resource_group_name, 'str'),\n+ 'budgetName': self._serialize.url(\"self.config.budget_name\", self.config.budget_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ deserialized = None\n+\n+ if response.status_code == 200:\n+ deserialized = self._deserialize('Budget', response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(deserialized, response)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def create_or_update_by_resource_group_name(\n+ self, parameters, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"The operation to create or update a budget. Update operation requires\n+ latest eTag to be set in the request mandatorily. You may obtain the\n+ latest eTag by performing a get operation. Create operation does not\n+ require eTag.\n+\n+ :param parameters: Parameters supplied to the Create Budget operation.\n+ :type parameters: ~azure.mgmt.consumption.models.Budget\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of None\n+ :rtype: ~azure.mgmt.consumption.models.Budget[None]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Consumption/budgets/{budgetName}'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'resourceGroupName': self._serialize.url(\"self.config.resource_group_name\", self.config.resource_group_name, 'str'),\n+ 'budgetName': self._serialize.url(\"self.config.budget_name\", self.config.budget_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct body\n+ body_content = self._serialize.body(parameters, 'Budget')\n+\n+ # Construct and send request\n+ request = self._client.put(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, body_content, stream=False, **operation_config)\n+\n+ if response.status_code not in [200, 201]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.Budget(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.Budget(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def delete_by_resource_group_name(\n+ self, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"The operation to delete a budget.\n+\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: None or ClientRawResponse if raw=true\n+ :rtype: None or ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Consumption/budgets/{budgetName}'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'resourceGroupName': self._serialize.url(\"self.config.resource_group_name\", self.config.resource_group_name, 'str'),\n+ 'budgetName': self._serialize.url(\"self.config.budget_name\", self.config.budget_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.delete(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(None, response)\n+ return client_raw_response"},{"sha":"e74aa82ad6ec36fee8e4c10903efe7a5d5e9a584","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/marketplaces_operations.py","status":"added","additions":209,"deletions":0,"changes":209,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/marketplaces_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/marketplaces_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/marketplaces_operations.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,209 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+import uuid\n+from msrest.pipeline import ClientRawResponse\n+\n+from .. import models\n+\n+\n+class MarketplacesOperations(object):\n+ \"\"\"MarketplacesOperations operations.\n+\n+ :param client: Client for service requests.\n+ :param config: Configuration of service client.\n+ :param serializer: An object model serializer.\n+ :param deserializer: An objec model deserializer.\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n+ \"\"\"\n+\n+ models = models\n+\n+ def __init__(self, client, config, serializer, deserializer):\n+\n+ self._client = client\n+ self._serialize = serializer\n+ self._deserialize = deserializer\n+ self.api_version = \"2018-01-31\"\n+\n+ self.config = config\n+\n+ def list(\n+ self, filter=None, top=None, skiptoken=None, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists the marketplaces for a scope by subscriptionId. Marketplaces are\n+ available via this API only for May 1, 2014 or later.\n+\n+ :param filter: May be used to filter marketplaces by\n+ properties/usageEnd (Utc time), properties/usageStart (Utc time),\n+ properties/resourceGroup, properties/instanceName or\n+ properties/instanceId. The filter supports 'eq', 'lt', 'gt', 'le',\n+ 'ge', and 'and'. It does not currently support 'ne', 'or', or 'not'.\n+ :type filter: str\n+ :param top: May be used to limit the number of results to the most\n+ recent N marketplaces.\n+ :type top: int\n+ :param skiptoken: Skiptoken is only used if a previous operation\n+ returned a partial result. If a previous response contains a nextLink\n+ element, the value of the nextLink element will include a skiptoken\n+ parameter that specifies a starting point to use for subsequent calls.\n+ :type skiptoken: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of Marketplace\n+ :rtype:\n+ ~azure.mgmt.consumption.models.MarketplacePaged[~azure.mgmt.consumption.models.Marketplace]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Consumption/marketplaces'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ if filter is not None:\n+ query_parameters['$filter'] = self._serialize.query(\"filter\", filter, 'str')\n+ if top is not None:\n+ query_parameters['$top'] = self._serialize.query(\"top\", top, 'int', maximum=1000, minimum=1)\n+ if skiptoken is not None:\n+ query_parameters['$skiptoken'] = self._serialize.query(\"skiptoken\", skiptoken, 'str')\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.MarketplacePaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.MarketplacePaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def list_by_billing_period(\n+ self, billing_period_name, filter=None, top=None, skiptoken=None, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists the marketplaces for a scope by billing period and\n+ subscripotionId. Marketplaces are available via this API only for May\n+ 1, 2014 or later.\n+\n+ :param billing_period_name: Billing Period Name.\n+ :type billing_period_name: str\n+ :param filter: May be used to filter marketplaces by\n+ properties/usageEnd (Utc time), properties/usageStart (Utc time),\n+ properties/resourceGroup, properties/instanceName or\n+ properties/instanceId. The filter supports 'eq', 'lt', 'gt', 'le',\n+ 'ge', and 'and'. It does not currently support 'ne', 'or', or 'not'.\n+ :type filter: str\n+ :param top: May be used to limit the number of results to the most\n+ recent N marketplaces.\n+ :type top: int\n+ :param skiptoken: Skiptoken is only used if a previous operation\n+ returned a partial result. If a previous response contains a nextLink\n+ element, the value of the nextLink element will include a skiptoken\n+ parameter that specifies a starting point to use for subsequent calls.\n+ :type skiptoken: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of Marketplace\n+ :rtype:\n+ ~azure.mgmt.consumption.models.MarketplacePaged[~azure.mgmt.consumption.models.Marketplace]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}/providers/Microsoft.Consumption/marketplaces'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'billingPeriodName': self._serialize.url(\"billing_period_name\", billing_period_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ if filter is not None:\n+ query_parameters['$filter'] = self._serialize.query(\"filter\", filter, 'str')\n+ if top is not None:\n+ query_parameters['$top'] = self._serialize.query(\"top\", top, 'int', maximum=1000, minimum=1)\n+ if skiptoken is not None:\n+ query_parameters['$skiptoken'] = self._serialize.query(\"skiptoken\", skiptoken, 'str')\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.MarketplacePaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.MarketplacePaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized"},{"sha":"f3efdae1c20868aef1cbad552979edb11f41663f","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py","status":"modified","additions":3,"deletions":3,"changes":6,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -22,7 +22,7 @@ class Operations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,7 +32,7 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n@@ -78,7 +78,7 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"701320c573d314526b127b4b3e5f8233852ad8b1","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py","status":"added","additions":176,"deletions":0,"changes":176,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -0,0 +1,176 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+import uuid\n+from msrest.pipeline import ClientRawResponse\n+\n+from .. import models\n+\n+\n+class PriceSheetOperations(object):\n+ \"\"\"PriceSheetOperations operations.\n+\n+ :param client: Client for service requests.\n+ :param config: Configuration of service client.\n+ :param serializer: An object model serializer.\n+ :param deserializer: An objec model deserializer.\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n+ \"\"\"\n+\n+ models = models\n+\n+ def __init__(self, client, config, serializer, deserializer):\n+\n+ self._client = client\n+ self._serialize = serializer\n+ self._deserialize = deserializer\n+ self.api_version = \"2018-01-31\"\n+\n+ self.config = config\n+\n+ def list(\n+ self, expand=None, skiptoken=None, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists the price sheet for a scope by subscriptionId. Price sheets are\n+ available via this API only for May 1, 2014 or later.\n+\n+ :param expand: May be used to expand the properties/meterDetails\n+ within a price sheet. By default, these fields are not included when\n+ returning price sheet.\n+ :type expand: str\n+ :param skiptoken: Skiptoken is only used if a previous operation\n+ returned a partial result. If a previous response contains a nextLink\n+ element, the value of the nextLink element will include a skiptoken\n+ parameter that specifies a starting point to use for subsequent calls.\n+ :type skiptoken: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: PriceSheetListResult or ClientRawResponse if raw=true\n+ :rtype: ~azure.mgmt.consumption.models.PriceSheetListResult or\n+ ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Consumption/pricesheets/default'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ if expand is not None:\n+ query_parameters['$expand'] = self._serialize.query(\"expand\", expand, 'str')\n+ if skiptoken is not None:\n+ query_parameters['$skiptoken'] = self._serialize.query(\"skiptoken\", skiptoken, 'str')\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ deserialized = None\n+\n+ if response.status_code == 200:\n+ deserialized = self._deserialize('PriceSheetListResult', response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(deserialized, response)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def list_by_billing_period(\n+ self, billing_period_name, expand=None, skiptoken=None, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists the price sheet for a scope by subscriptionId and billing period.\n+ Price sheets are available via this API only for May 1, 2014 or later.\n+\n+ :param billing_period_name: Billing Period Name.\n+ :type billing_period_name: str\n+ :param expand: May be used to expand the properties/meterDetails\n+ within a price sheet. By default, these fields are not included when\n+ returning price sheet.\n+ :type expand: str\n+ :param skiptoken: Skiptoken is only used if a previous operation\n+ returned a partial result. If a previous response contains a nextLink\n+ element, the value of the nextLink element will include a skiptoken\n+ parameter that specifies a starting point to use for subsequent calls.\n+ :type skiptoken: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: PriceSheetListResult or ClientRawResponse if raw=true\n+ :rtype: ~azure.mgmt.consumption.models.PriceSheetListResult or\n+ ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}/providers/Microsoft.Consumption/pricesheets/default'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'billingPeriodName': self._serialize.url(\"billing_period_name\", billing_period_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ if expand is not None:\n+ query_parameters['$expand'] = self._serialize.query(\"expand\", expand, 'str')\n+ if skiptoken is not None:\n+ query_parameters['$skiptoken'] = self._serialize.query(\"skiptoken\", skiptoken, 'str')\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ deserialized = None\n+\n+ if response.status_code == 200:\n+ deserialized = self._deserialize('PriceSheetListResult', response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(deserialized, response)\n+ return client_raw_response\n+\n+ return deserialized"},{"sha":"485bb51bf4eb5333baf96a44f51ae286faabb00c","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py","status":"modified","additions":82,"deletions":12,"changes":94,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -22,7 +22,7 @@ class ReservationsDetailsOperations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,19 +32,16 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n- def list(\n- self, scope, filter, custom_headers=None, raw=False, **operation_config):\n+ def list_by_reservation_order(\n+ self, reservation_order_id, filter, custom_headers=None, raw=False, **operation_config):\n \"\"\"Lists the reservations details for provided date range.\n \n- :param scope: The scope of the reservation details. The scope can be\n- 'providers/Microsoft.Capacity/reservationorders/{ReservationOrderId}'\n- or\n- 'providers/Microsoft.Capacity/reservationorders/{ReservationOrderId}/reservations/{ReservationId}'\n- :type scope: str\n+ :param reservation_order_id: Order Id of the reservation\n+ :type reservation_order_id: str\n :param filter: Filter reservation details by date range. The\n properties/UsageDate for start date and end date. The filter supports\n 'le' and 'ge'\n@@ -64,9 +61,9 @@ def internal_paging(next_link=None, raw=False):\n \n if not next_link:\n # Construct URL\n- url = '/{scope}/providers/Microsoft.Consumption/reservationDetails'\n+ url = '/providers/Microsoft.Capacity/reservationorders/{reservationOrderId}/providers/Microsoft.Consumption/reservationDetails'\n path_format_arguments = {\n- 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True)\n+ 'reservationOrderId': self._serialize.url(\"reservation_order_id\", reservation_order_id, 'str')\n }\n url = self._client.format_url(url, **path_format_arguments)\n \n@@ -92,7 +89,80 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.ReservationDetailsPaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.ReservationDetailsPaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def list_by_reservation_order_and_reservation(\n+ self, reservation_order_id, reservation_id, filter, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists the reservations details for provided date range.\n+\n+ :param reservation_order_id: Order Id of the reservation\n+ :type reservation_order_id: str\n+ :param reservation_id: Id of the reservation\n+ :type reservation_id: str\n+ :param filter: Filter reservation details by date range. The\n+ properties/UsageDate for start date and end date. The filter supports\n+ 'le' and 'ge'\n+ :type filter: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of ReservationDetails\n+ :rtype:\n+ ~azure.mgmt.consumption.models.ReservationDetailsPaged[~azure.mgmt.consumption.models.ReservationDetails]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/providers/Microsoft.Capacity/reservationorders/{reservationOrderId}/reservations/{reservationId}/providers/Microsoft.Consumption/reservationDetails'\n+ path_format_arguments = {\n+ 'reservationOrderId': self._serialize.url(\"reservation_order_id\", reservation_order_id, 'str'),\n+ 'reservationId': self._serialize.url(\"reservation_id\", reservation_id, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['$filter'] = self._serialize.query(\"filter\", filter, 'str')\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"2c1c2b451318b518d75a578a83e49e5597c6be6d","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py","status":"modified","additions":86,"deletions":12,"changes":98,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -22,7 +22,7 @@ class ReservationsSummariesOperations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,19 +32,16 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n- def list(\n- self, scope, grain, filter=None, custom_headers=None, raw=False, **operation_config):\n+ def list_by_reservation_order(\n+ self, reservation_order_id, grain, filter=None, custom_headers=None, raw=False, **operation_config):\n \"\"\"Lists the reservations summaries for daily or monthly grain.\n \n- :param scope: The scope of the reservation summaries. The scope can be\n- 'providers/Microsoft.Capacity/reservationorders/{ReservationOrderId}'\n- or\n- 'providers/Microsoft.Capacity/reservationorders/{ReservationOrderId}/reservations/{ReservationId}'\n- :type scope: str\n+ :param reservation_order_id: Order Id of the reservation\n+ :type reservation_order_id: str\n :param grain: Can be daily or monthly. Possible values include:\n 'DailyGrain', 'MonthlyGrain'\n :type grain: str or ~azure.mgmt.consumption.models.Datagrain\n@@ -66,9 +63,9 @@ def internal_paging(next_link=None, raw=False):\n \n if not next_link:\n # Construct URL\n- url = '/{scope}/providers/Microsoft.Consumption/reservationSummaries'\n+ url = '/providers/Microsoft.Capacity/reservationorders/{reservationOrderId}/providers/Microsoft.Consumption/reservationSummaries'\n path_format_arguments = {\n- 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True)\n+ 'reservationOrderId': self._serialize.url(\"reservation_order_id\", reservation_order_id, 'str')\n }\n url = self._client.format_url(url, **path_format_arguments)\n \n@@ -96,7 +93,84 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.ReservationSummariesPaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.ReservationSummariesPaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def list_by_reservation_order_and_reservation(\n+ self, reservation_order_id, reservation_id, grain, filter=None, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists the reservations summaries for daily or monthly grain.\n+\n+ :param reservation_order_id: Order Id of the reservation\n+ :type reservation_order_id: str\n+ :param reservation_id: Id of the reservation\n+ :type reservation_id: str\n+ :param grain: Can be daily or monthly. Possible values include:\n+ 'DailyGrain', 'MonthlyGrain'\n+ :type grain: str or ~azure.mgmt.consumption.models.Datagrain\n+ :param filter: Required only for daily grain. The properties/UsageDate\n+ for start date and end date. The filter supports 'le' and 'ge'\n+ :type filter: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of ReservationSummaries\n+ :rtype:\n+ ~azure.mgmt.consumption.models.ReservationSummariesPaged[~azure.mgmt.consumption.models.ReservationSummaries]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/providers/Microsoft.Capacity/reservationorders/{reservationOrderId}/reservations/{reservationId}/providers/Microsoft.Consumption/reservationSummaries'\n+ path_format_arguments = {\n+ 'reservationOrderId': self._serialize.url(\"reservation_order_id\", reservation_order_id, 'str'),\n+ 'reservationId': self._serialize.url(\"reservation_id\", reservation_id, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['grain'] = self._serialize.query(\"grain\", grain, 'str')\n+ if filter is not None:\n+ query_parameters['$filter'] = self._serialize.query(\"filter\", filter, 'str')\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"a0f6cd91bd084879c4ac7e89959d2231a4b5795e","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py","status":"modified","additions":100,"deletions":11,"changes":111,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -22,7 +22,7 @@ class UsageDetailsOperations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,20 +32,15 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n def list(\n- self, scope, expand=None, filter=None, skiptoken=None, top=None, custom_headers=None, raw=False, **operation_config):\n+ self, expand=None, filter=None, skiptoken=None, top=None, custom_headers=None, raw=False, **operation_config):\n \"\"\"Lists the usage details for a scope by billing period. Usage details\n are available via this API only for May 1, 2014 or later.\n \n- :param scope: The scope of the usage details. The scope can be\n- '/subscriptions/{subscriptionId}' for a subscription, or\n- '/subscriptions/{subscriptionId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}'\n- for a billing perdiod.\n- :type scope: str\n :param expand: May be used to expand the\n properties/additionalProperties or properties/meterDetails within a\n list of usage details. By default, these fields are not included when\n@@ -80,9 +75,9 @@ def internal_paging(next_link=None, raw=False):\n \n if not next_link:\n # Construct URL\n- url = '/{scope}/providers/Microsoft.Consumption/usageDetails'\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Consumption/usageDetails'\n path_format_arguments = {\n- 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True)\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str')\n }\n url = self._client.format_url(url, **path_format_arguments)\n \n@@ -115,7 +110,101 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.UsageDetailPaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.UsageDetailPaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def list_by_billing_period(\n+ self, billing_period_name, expand=None, filter=None, skiptoken=None, top=None, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists the usage details for a scope by billing period. Usage details\n+ are available via this API only for May 1, 2014 or later.\n+\n+ :param billing_period_name: Billing Period Name.\n+ :type billing_period_name: str\n+ :param expand: May be used to expand the\n+ properties/additionalProperties or properties/meterDetails within a\n+ list of usage details. By default, these fields are not included when\n+ listing usage details.\n+ :type expand: str\n+ :param filter: May be used to filter usageDetails by\n+ properties/usageEnd (Utc time), properties/usageStart (Utc time),\n+ properties/resourceGroup, properties/instanceName or\n+ properties/instanceId. The filter supports 'eq', 'lt', 'gt', 'le',\n+ 'ge', and 'and'. It does not currently support 'ne', 'or', or 'not'.\n+ :type filter: str\n+ :param skiptoken: Skiptoken is only used if a previous operation\n+ returned a partial result. If a previous response contains a nextLink\n+ element, the value of the nextLink element will include a skiptoken\n+ parameter that specifies a starting point to use for subsequent calls.\n+ :type skiptoken: str\n+ :param top: May be used to limit the number of results to the most\n+ recent N usageDetails.\n+ :type top: int\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of UsageDetail\n+ :rtype:\n+ ~azure.mgmt.consumption.models.UsageDetailPaged[~azure.mgmt.consumption.models.UsageDetail]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/subscriptions/{subscriptionId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}/providers/Microsoft.Consumption/usageDetails'\n+ path_format_arguments = {\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'billingPeriodName': self._serialize.url(\"billing_period_name\", billing_period_name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ if expand is not None:\n+ query_parameters['$expand'] = self._serialize.query(\"expand\", expand, 'str')\n+ if filter is not None:\n+ query_parameters['$filter'] = self._serialize.query(\"filter\", filter, 'str')\n+ if skiptoken is not None:\n+ query_parameters['$skiptoken'] = self._serialize.query(\"skiptoken\", skiptoken, 'str')\n+ if top is not None:\n+ query_parameters['$top'] = self._serialize.query(\"top\", top, 'int', maximum=1000, minimum=1)\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"9c644827672b274106be6000914f998e7e703574","filename":"azure-mgmt-consumption/azure/mgmt/consumption/version.py","status":"modified","additions":1,"deletions":1,"changes":2,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/version.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/3d6c419cd2ade53c240c40db96dbe34957351244/azure-mgmt-consumption/azure/mgmt/consumption/version.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/version.py?ref=3d6c419cd2ade53c240c40db96dbe34957351244","patch":"@@ -9,5 +9,5 @@\n # regenerated.\n # --------------------------------------------------------------------------\n \n-VERSION = \"1.1.0\"\n+VERSION = \"1.2.0\"\n "}] + +https +GET +api.github.com +None +/repos/Azure/azure-sdk-for-python/commits/042b7a5840ff471776bb64e46b50950ee9f84430 +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:38 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4773'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"dc862e28bdff24590d33c5d927a64947"'), ('Last-Modified', 'Thu, 25 Jan 2018 19:40:02 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.277675'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1714:97BA:C92467:104F1B5:5AFDF3CA')] +{"sha":"042b7a5840ff471776bb64e46b50950ee9f84430","commit":{"author":{"name":"Azure SDK for Python bot","email":"aspysdk2@microsoft.com","date":"2018-01-25T19:40:02Z"},"committer":{"name":"Azure SDK for Python bot","email":"aspysdk2@microsoft.com","date":"2018-01-25T19:40:02Z"},"message":"Generated from a59b564eca116f99d057c9758d0dd40393ce75b7\n\nIntroduce Pricesheet Arm API","tree":{"sha":"a6d63b3754e7f65c6a4fbed3d3e9c5a2d72ce778","url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/trees/a6d63b3754e7f65c6a4fbed3d3e9c5a2d72ce778"},"url":"https://api.github.com/repos/Azure/azure-sdk-for-python/git/commits/042b7a5840ff471776bb64e46b50950ee9f84430","comment_count":0,"verification":{"verified":false,"reason":"unsigned","signature":null,"payload":null}},"url":"https://api.github.com/repos/Azure/azure-sdk-for-python/commits/042b7a5840ff471776bb64e46b50950ee9f84430","html_url":"https://github.com/Azure/azure-sdk-for-python/commit/042b7a5840ff471776bb64e46b50950ee9f84430","comments_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/commits/042b7a5840ff471776bb64e46b50950ee9f84430/comments","author":{"login":"AutorestCI","id":18218145,"avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"committer":{"login":"AutorestCI","id":18218145,"avatar_url":"https://avatars3.githubusercontent.com/u/18218145?v=4","gravatar_id":"","url":"https://api.github.com/users/AutorestCI","html_url":"https://github.com/AutorestCI","followers_url":"https://api.github.com/users/AutorestCI/followers","following_url":"https://api.github.com/users/AutorestCI/following{/other_user}","gists_url":"https://api.github.com/users/AutorestCI/gists{/gist_id}","starred_url":"https://api.github.com/users/AutorestCI/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AutorestCI/subscriptions","organizations_url":"https://api.github.com/users/AutorestCI/orgs","repos_url":"https://api.github.com/users/AutorestCI/repos","events_url":"https://api.github.com/users/AutorestCI/events{/privacy}","received_events_url":"https://api.github.com/users/AutorestCI/received_events","type":"User","site_admin":false},"parents":[{"sha":"f4715da4f929733b2b95c03142512f85ae8728a5","url":"https://api.github.com/repos/Azure/azure-sdk-for-python/commits/f4715da4f929733b2b95c03142512f85ae8728a5","html_url":"https://github.com/Azure/azure-sdk-for-python/commit/f4715da4f929733b2b95c03142512f85ae8728a5"}],"stats":{"total":985,"additions":967,"deletions":18},"files":[{"sha":"55432c5a7edf83b2ce128aa764edf18e8bfb3149","filename":"azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py","status":"modified","additions":21,"deletions":4,"changes":25,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -16,7 +16,9 @@\n from .operations.usage_details_operations import UsageDetailsOperations\n from .operations.reservations_summaries_operations import ReservationsSummariesOperations\n from .operations.reservations_details_operations import ReservationsDetailsOperations\n+from .operations.budgets_operations import BudgetsOperations\n from .operations.operations import Operations\n+from .operations.price_sheet_operations import PriceSheetOperations\n from . import models\n \n \n@@ -30,16 +32,20 @@ class ConsumptionManagementClientConfiguration(AzureConfiguration):\n object`\n :param subscription_id: Azure Subscription ID.\n :type subscription_id: str\n+ :param name: Budget name.\n+ :type name: str\n :param str base_url: Service URL\n \"\"\"\n \n def __init__(\n- self, credentials, subscription_id, base_url=None):\n+ self, credentials, subscription_id, name, base_url=None):\n \n if credentials is None:\n raise ValueError(\"Parameter 'credentials' must not be None.\")\n if subscription_id is None:\n raise ValueError(\"Parameter 'subscription_id' must not be None.\")\n+ if name is None:\n+ raise ValueError(\"Parameter 'name' must not be None.\")\n if not base_url:\n base_url = 'https://management.azure.com'\n \n@@ -50,6 +56,7 @@ def __init__(\n \n self.credentials = credentials\n self.subscription_id = subscription_id\n+ self.name = name\n \n \n class ConsumptionManagementClient(object):\n@@ -64,25 +71,31 @@ class ConsumptionManagementClient(object):\n :vartype reservations_summaries: azure.mgmt.consumption.operations.ReservationsSummariesOperations\n :ivar reservations_details: ReservationsDetails operations\n :vartype reservations_details: azure.mgmt.consumption.operations.ReservationsDetailsOperations\n+ :ivar budgets: Budgets operations\n+ :vartype budgets: azure.mgmt.consumption.operations.BudgetsOperations\n :ivar operations: Operations operations\n :vartype operations: azure.mgmt.consumption.operations.Operations\n+ :ivar price_sheet: PriceSheet operations\n+ :vartype price_sheet: azure.mgmt.consumption.operations.PriceSheetOperations\n \n :param credentials: Credentials needed for the client to connect to Azure.\n :type credentials: :mod:`A msrestazure Credentials\n object`\n :param subscription_id: Azure Subscription ID.\n :type subscription_id: str\n+ :param name: Budget name.\n+ :type name: str\n :param str base_url: Service URL\n \"\"\"\n \n def __init__(\n- self, credentials, subscription_id, base_url=None):\n+ self, credentials, subscription_id, name, base_url=None):\n \n- self.config = ConsumptionManagementClientConfiguration(credentials, subscription_id, base_url)\n+ self.config = ConsumptionManagementClientConfiguration(credentials, subscription_id, name, base_url)\n self._client = ServiceClient(self.config.credentials, self.config)\n \n client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)}\n- self.api_version = '2017-11-30'\n+ self.api_version = '2018-01-31'\n self._serialize = Serializer(client_models)\n self._deserialize = Deserializer(client_models)\n \n@@ -92,5 +105,9 @@ def __init__(\n self._client, self.config, self._serialize, self._deserialize)\n self.reservations_details = ReservationsDetailsOperations(\n self._client, self.config, self._serialize, self._deserialize)\n+ self.budgets = BudgetsOperations(\n+ self._client, self.config, self._serialize, self._deserialize)\n self.operations = Operations(\n self._client, self.config, self._serialize, self._deserialize)\n+ self.price_sheet = PriceSheetOperations(\n+ self._client, self.config, self._serialize, self._deserialize)"},{"sha":"2565b46a9d2b4dc2df7fa591699f866b2f496d1b","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py","status":"modified","additions":24,"deletions":0,"changes":24,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/__init__.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -13,16 +13,28 @@\n from .usage_detail import UsageDetail\n from .reservation_summaries import ReservationSummaries\n from .reservation_details import ReservationDetails\n+from .budget_time_period import BudgetTimePeriod\n+from .filters import Filters\n+from .current_spend import CurrentSpend\n+from .notification import Notification\n+from .budget import Budget\n from .error_details import ErrorDetails\n from .error_response import ErrorResponse, ErrorResponseException\n from .operation_display import OperationDisplay\n from .operation import Operation\n from .resource import Resource\n+from .proxy_resource import ProxyResource\n+from .price_sheet import PriceSheet\n from .usage_detail_paged import UsageDetailPaged\n from .reservation_summaries_paged import ReservationSummariesPaged\n from .reservation_details_paged import ReservationDetailsPaged\n+from .budget_paged import BudgetPaged\n from .operation_paged import OperationPaged\n+from .price_sheet_paged import PriceSheetPaged\n from .consumption_management_client_enums import (\n+ CategoryType,\n+ TimeGrainType,\n+ OperatorType,\n Datagrain,\n )\n \n@@ -31,14 +43,26 @@\n 'UsageDetail',\n 'ReservationSummaries',\n 'ReservationDetails',\n+ 'BudgetTimePeriod',\n+ 'Filters',\n+ 'CurrentSpend',\n+ 'Notification',\n+ 'Budget',\n 'ErrorDetails',\n 'ErrorResponse', 'ErrorResponseException',\n 'OperationDisplay',\n 'Operation',\n 'Resource',\n+ 'ProxyResource',\n+ 'PriceSheet',\n 'UsageDetailPaged',\n 'ReservationSummariesPaged',\n 'ReservationDetailsPaged',\n+ 'BudgetPaged',\n 'OperationPaged',\n+ 'PriceSheetPaged',\n+ 'CategoryType',\n+ 'TimeGrainType',\n+ 'OperatorType',\n 'Datagrain',\n ]"},{"sha":"f6485d49266ddf2734c02ab55dceb9aba94bfe0a","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py","status":"added","additions":91,"deletions":0,"changes":91,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/budget.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,91 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from .proxy_resource import ProxyResource\n+\n+\n+class Budget(ProxyResource):\n+ \"\"\"A budget resource.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar id: Resource Id.\n+ :vartype id: str\n+ :ivar name: Resource name.\n+ :vartype name: str\n+ :ivar type: Resource type.\n+ :vartype type: str\n+ :param e_tag: eTag of the resource. To handle concurrent update scenarion,\n+ this field will be used to determine whether the user is updating the\n+ latest version or not.\n+ :type e_tag: str\n+ :param category: The category of the budget, whether the budget tracks\n+ cost or usage. Possible values include: 'Cost', 'Usage'\n+ :type category: str or ~azure.mgmt.consumption.models.CategoryType\n+ :param amount: The total amount of cost to track with the budget\n+ :type amount: decimal.Decimal\n+ :param time_grain: The time covered by a budget. Tracking of the amount\n+ will be reset based on the time grain. Possible values include: 'Monthly',\n+ 'Quarterly', 'Annually'\n+ :type time_grain: str or ~azure.mgmt.consumption.models.TimeGrainType\n+ :param time_period: Has start and end date of the budget. The start date\n+ must be first of the month and should be less than the end date. Budget\n+ start date must be on or after June 1, 2017. Future start date should not\n+ be more than three months. Past start date should be selected within the\n+ timegrain preiod. There are no restrictions on the end date.\n+ :type time_period: ~azure.mgmt.consumption.models.BudgetTimePeriod\n+ :param filters: May be used to filter budgets by resource group, resource,\n+ or meter.\n+ :type filters: ~azure.mgmt.consumption.models.Filters\n+ :ivar current_spend: The current amount of cost which is being tracked for\n+ a budget.\n+ :vartype current_spend: ~azure.mgmt.consumption.models.CurrentSpend\n+ :param notifications: Dictionary of notifications associated with the\n+ budget. Budget can have up to five notifications.\n+ :type notifications: dict[str,\n+ ~azure.mgmt.consumption.models.Notification]\n+ \"\"\"\n+\n+ _validation = {\n+ 'id': {'readonly': True},\n+ 'name': {'readonly': True},\n+ 'type': {'readonly': True},\n+ 'category': {'required': True},\n+ 'amount': {'required': True},\n+ 'time_grain': {'required': True},\n+ 'time_period': {'required': True},\n+ 'current_spend': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'id': {'key': 'id', 'type': 'str'},\n+ 'name': {'key': 'name', 'type': 'str'},\n+ 'type': {'key': 'type', 'type': 'str'},\n+ 'e_tag': {'key': 'eTag', 'type': 'str'},\n+ 'category': {'key': 'properties.category', 'type': 'str'},\n+ 'amount': {'key': 'properties.amount', 'type': 'decimal'},\n+ 'time_grain': {'key': 'properties.timeGrain', 'type': 'str'},\n+ 'time_period': {'key': 'properties.timePeriod', 'type': 'BudgetTimePeriod'},\n+ 'filters': {'key': 'properties.filters', 'type': 'Filters'},\n+ 'current_spend': {'key': 'properties.currentSpend', 'type': 'CurrentSpend'},\n+ 'notifications': {'key': 'properties.notifications', 'type': '{Notification}'},\n+ }\n+\n+ def __init__(self, category, amount, time_grain, time_period, e_tag=None, filters=None, notifications=None):\n+ super(Budget, self).__init__(e_tag=e_tag)\n+ self.category = category\n+ self.amount = amount\n+ self.time_grain = time_grain\n+ self.time_period = time_period\n+ self.filters = filters\n+ self.current_spend = None\n+ self.notifications = notifications"},{"sha":"2668382253e2d7aaefb8665a466d2482193e0246","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py","status":"added","additions":27,"deletions":0,"changes":27,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_paged.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,27 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.paging import Paged\n+\n+\n+class BudgetPaged(Paged):\n+ \"\"\"\n+ A paging container for iterating over a list of :class:`Budget ` object\n+ \"\"\"\n+\n+ _attribute_map = {\n+ 'next_link': {'key': 'nextLink', 'type': 'str'},\n+ 'current_page': {'key': 'value', 'type': '[Budget]'}\n+ }\n+\n+ def __init__(self, *args, **kwargs):\n+\n+ super(BudgetPaged, self).__init__(*args, **kwargs)"},{"sha":"2b1c0e78418a1deb6b6147fc90ea53f1a03256d0","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py","status":"added","additions":37,"deletions":0,"changes":37,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/budget_time_period.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,37 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class BudgetTimePeriod(Model):\n+ \"\"\"The start and end date for a budget.\n+\n+ :param start_date: The start date for the budget.\n+ :type start_date: datetime\n+ :param end_date: The end date for the budget. If not provided, we default\n+ this to 10 years from the start date.\n+ :type end_date: datetime\n+ \"\"\"\n+\n+ _validation = {\n+ 'start_date': {'required': True},\n+ }\n+\n+ _attribute_map = {\n+ 'start_date': {'key': 'startDate', 'type': 'iso-8601'},\n+ 'end_date': {'key': 'endDate', 'type': 'iso-8601'},\n+ }\n+\n+ def __init__(self, start_date, end_date=None):\n+ super(BudgetTimePeriod, self).__init__()\n+ self.start_date = start_date\n+ self.end_date = end_date"},{"sha":"bb0db82f76b32c1d02cca1de69b0ecc49b3b548b","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py","status":"modified","additions":20,"deletions":0,"changes":20,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/consumption_management_client_enums.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -12,6 +12,26 @@\n from enum import Enum\n \n \n+class CategoryType(Enum):\n+\n+ cost = \"Cost\"\n+ usage = \"Usage\"\n+\n+\n+class TimeGrainType(Enum):\n+\n+ monthly = \"Monthly\"\n+ quarterly = \"Quarterly\"\n+ annually = \"Annually\"\n+\n+\n+class OperatorType(Enum):\n+\n+ equal_to = \"EqualTo\"\n+ greater_than = \"GreaterThan\"\n+ greater_than_or_equal_to = \"GreaterThanOrEqualTo\"\n+\n+\n class Datagrain(Enum):\n \n daily_grain = \"daily\""},{"sha":"839c286b104079f531a4b130f3e01082d63d08ac","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py","status":"added","additions":41,"deletions":0,"changes":41,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/current_spend.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,41 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class CurrentSpend(Model):\n+ \"\"\"The current amount of cost which is being tracked for a budget.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar amount: The total amount of cost which is being tracked by the\n+ budget.\n+ :vartype amount: decimal.Decimal\n+ :ivar unit: The unit of measure for the budget amount.\n+ :vartype unit: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'amount': {'readonly': True},\n+ 'unit': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'amount': {'key': 'amount', 'type': 'decimal'},\n+ 'unit': {'key': 'unit', 'type': 'str'},\n+ }\n+\n+ def __init__(self):\n+ super(CurrentSpend, self).__init__()\n+ self.amount = None\n+ self.unit = None"},{"sha":"dc010a065900621f02b77dfe1b389071e597fd73","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py","status":"added","additions":44,"deletions":0,"changes":44,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/filters.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,44 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class Filters(Model):\n+ \"\"\"May be used to filter budgets by resource group, resource, or meter.\n+\n+ :param resource_groups: The list of filters on resource groups, allowed at\n+ subscription level only.\n+ :type resource_groups: list[str]\n+ :param resources: The list of filters on resources.\n+ :type resources: list[str]\n+ :param meters: The list of filters on meters, mandatory for budgets of\n+ usage category.\n+ :type meters: list[str]\n+ \"\"\"\n+\n+ _validation = {\n+ 'resource_groups': {'max_items': 10, 'min_items': 0},\n+ 'resources': {'max_items': 10, 'min_items': 0},\n+ 'meters': {'max_items': 10, 'min_items': 0},\n+ }\n+\n+ _attribute_map = {\n+ 'resource_groups': {'key': 'resourceGroups', 'type': '[str]'},\n+ 'resources': {'key': 'resources', 'type': '[str]'},\n+ 'meters': {'key': 'meters', 'type': '[str]'},\n+ }\n+\n+ def __init__(self, resource_groups=None, resources=None, meters=None):\n+ super(Filters, self).__init__()\n+ self.resource_groups = resource_groups\n+ self.resources = resources\n+ self.meters = meters"},{"sha":"61e1ca0ed34df63b0df71d2970b19f7fa8a866bd","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py","status":"added","additions":62,"deletions":0,"changes":62,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/notification.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,62 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class Notification(Model):\n+ \"\"\"The notification associated with a budget.\n+\n+ :param enabled: The notification is enabled or not.\n+ :type enabled: bool\n+ :param operator: The comparison operator. Possible values include:\n+ 'EqualTo', 'GreaterThan', 'GreaterThanOrEqualTo'\n+ :type operator: str or ~azure.mgmt.consumption.models.OperatorType\n+ :param threshold: Threshold value associated with a notification.\n+ Notification is sent when the cost exceeded the threshold. It is always\n+ percent and has to be between 0 and 1000.\n+ :type threshold: decimal.Decimal\n+ :param contact_emails: Email addresses to send the budget notification to\n+ when the threshold is exceeded.\n+ :type contact_emails: list[str]\n+ :param contact_roles: Contact roles to send the budget notification to\n+ when the threshold is exceeded.\n+ :type contact_roles: list[str]\n+ :param contact_groups: Action groups to send the budget notification to\n+ when the threshold is exceeded.\n+ :type contact_groups: list[str]\n+ \"\"\"\n+\n+ _validation = {\n+ 'enabled': {'required': True},\n+ 'operator': {'required': True},\n+ 'threshold': {'required': True},\n+ 'contact_emails': {'required': True, 'max_items': 50, 'min_items': 1},\n+ 'contact_groups': {'max_items': 50, 'min_items': 0},\n+ }\n+\n+ _attribute_map = {\n+ 'enabled': {'key': 'enabled', 'type': 'bool'},\n+ 'operator': {'key': 'operator', 'type': 'str'},\n+ 'threshold': {'key': 'threshold', 'type': 'decimal'},\n+ 'contact_emails': {'key': 'contactEmails', 'type': '[str]'},\n+ 'contact_roles': {'key': 'contactRoles', 'type': '[str]'},\n+ 'contact_groups': {'key': 'contactGroups', 'type': '[str]'},\n+ }\n+\n+ def __init__(self, enabled, operator, threshold, contact_emails, contact_roles=None, contact_groups=None):\n+ super(Notification, self).__init__()\n+ self.enabled = enabled\n+ self.operator = operator\n+ self.threshold = threshold\n+ self.contact_emails = contact_emails\n+ self.contact_roles = contact_roles\n+ self.contact_groups = contact_groups"},{"sha":"bc5f89b78fbeb0a81a93d089f3a640f8e63ff3a2","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet.py","status":"added","additions":88,"deletions":0,"changes":88,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,88 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from .resource import Resource\n+\n+\n+class PriceSheet(Resource):\n+ \"\"\"An pricesheet resource.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar id: Resource Id.\n+ :vartype id: str\n+ :ivar name: Resource name.\n+ :vartype name: str\n+ :ivar type: Resource type.\n+ :vartype type: str\n+ :ivar tags: Resource tags.\n+ :vartype tags: dict[str, str]\n+ :ivar billing_period_id: The id of the billing period resource that the\n+ usage belongs to.\n+ :vartype billing_period_id: str\n+ :ivar meter_id: The meter id\n+ :vartype meter_id: str\n+ :ivar meter_details: The details about the meter. By default this is not\n+ populated, unless it's specified in $expand.\n+ :vartype meter_details: ~azure.mgmt.consumption.models.MeterDetails\n+ :ivar unit_of_measure: Unit of measure\n+ :vartype unit_of_measure: str\n+ :ivar included_quantity: Included quality for an offer\n+ :vartype included_quantity: decimal.Decimal\n+ :ivar part_number: Part Number\n+ :vartype part_number: str\n+ :ivar unit_price: Unit Price\n+ :vartype unit_price: decimal.Decimal\n+ :ivar currency_code: Currency Code\n+ :vartype currency_code: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'id': {'readonly': True},\n+ 'name': {'readonly': True},\n+ 'type': {'readonly': True},\n+ 'tags': {'readonly': True},\n+ 'billing_period_id': {'readonly': True},\n+ 'meter_id': {'readonly': True},\n+ 'meter_details': {'readonly': True},\n+ 'unit_of_measure': {'readonly': True},\n+ 'included_quantity': {'readonly': True},\n+ 'part_number': {'readonly': True},\n+ 'unit_price': {'readonly': True},\n+ 'currency_code': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'id': {'key': 'id', 'type': 'str'},\n+ 'name': {'key': 'name', 'type': 'str'},\n+ 'type': {'key': 'type', 'type': 'str'},\n+ 'tags': {'key': 'tags', 'type': '{str}'},\n+ 'billing_period_id': {'key': 'properties.billingPeriodId', 'type': 'str'},\n+ 'meter_id': {'key': 'properties.meterId', 'type': 'str'},\n+ 'meter_details': {'key': 'properties.meterDetails', 'type': 'MeterDetails'},\n+ 'unit_of_measure': {'key': 'properties.unitOfMeasure', 'type': 'str'},\n+ 'included_quantity': {'key': 'properties.includedQuantity', 'type': 'decimal'},\n+ 'part_number': {'key': 'properties.partNumber', 'type': 'str'},\n+ 'unit_price': {'key': 'properties.unitPrice', 'type': 'decimal'},\n+ 'currency_code': {'key': 'properties.currencyCode', 'type': 'str'},\n+ }\n+\n+ def __init__(self):\n+ super(PriceSheet, self).__init__()\n+ self.billing_period_id = None\n+ self.meter_id = None\n+ self.meter_details = None\n+ self.unit_of_measure = None\n+ self.included_quantity = None\n+ self.part_number = None\n+ self.unit_price = None\n+ self.currency_code = None"},{"sha":"5dfe48207a52fc6efd11d8a2108a89bbed439301","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_paged.py","status":"added","additions":27,"deletions":0,"changes":27,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_paged.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_paged.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/price_sheet_paged.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,27 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.paging import Paged\n+\n+\n+class PriceSheetPaged(Paged):\n+ \"\"\"\n+ A paging container for iterating over a list of :class:`PriceSheet ` object\n+ \"\"\"\n+\n+ _attribute_map = {\n+ 'next_link': {'key': 'nextLink', 'type': 'str'},\n+ 'current_page': {'key': 'value', 'type': '[PriceSheet]'}\n+ }\n+\n+ def __init__(self, *args, **kwargs):\n+\n+ super(PriceSheetPaged, self).__init__(*args, **kwargs)"},{"sha":"f6a9a40d22d569970958af165de44c9f84162e47","filename":"azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py","status":"added","additions":51,"deletions":0,"changes":51,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/models/proxy_resource.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,51 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+from msrest.serialization import Model\n+\n+\n+class ProxyResource(Model):\n+ \"\"\"The Resource model definition.\n+\n+ Variables are only populated by the server, and will be ignored when\n+ sending a request.\n+\n+ :ivar id: Resource Id.\n+ :vartype id: str\n+ :ivar name: Resource name.\n+ :vartype name: str\n+ :ivar type: Resource type.\n+ :vartype type: str\n+ :param e_tag: eTag of the resource. To handle concurrent update scenarion,\n+ this field will be used to determine whether the user is updating the\n+ latest version or not.\n+ :type e_tag: str\n+ \"\"\"\n+\n+ _validation = {\n+ 'id': {'readonly': True},\n+ 'name': {'readonly': True},\n+ 'type': {'readonly': True},\n+ }\n+\n+ _attribute_map = {\n+ 'id': {'key': 'id', 'type': 'str'},\n+ 'name': {'key': 'name', 'type': 'str'},\n+ 'type': {'key': 'type', 'type': 'str'},\n+ 'e_tag': {'key': 'eTag', 'type': 'str'},\n+ }\n+\n+ def __init__(self, e_tag=None):\n+ super(ProxyResource, self).__init__()\n+ self.id = None\n+ self.name = None\n+ self.type = None\n+ self.e_tag = e_tag"},{"sha":"f791e0bc747d0bcd880175ab41f6f1a94f599bb1","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py","status":"modified","additions":4,"deletions":0,"changes":4,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/__init__.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -12,11 +12,15 @@\n from .usage_details_operations import UsageDetailsOperations\n from .reservations_summaries_operations import ReservationsSummariesOperations\n from .reservations_details_operations import ReservationsDetailsOperations\n+from .budgets_operations import BudgetsOperations\n from .operations import Operations\n+from .price_sheet_operations import PriceSheetOperations\n \n __all__ = [\n 'UsageDetailsOperations',\n 'ReservationsSummariesOperations',\n 'ReservationsDetailsOperations',\n+ 'BudgetsOperations',\n 'Operations',\n+ 'PriceSheetOperations',\n ]"},{"sha":"1694905cc3b44bf71f17a69479734d1a90f0128a","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py","status":"added","additions":297,"deletions":0,"changes":297,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/budgets_operations.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,297 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+import uuid\n+from msrest.pipeline import ClientRawResponse\n+\n+from .. import models\n+\n+\n+class BudgetsOperations(object):\n+ \"\"\"BudgetsOperations operations.\n+\n+ :param client: Client for service requests.\n+ :param config: Configuration of service client.\n+ :param serializer: An object model serializer.\n+ :param deserializer: An objec model deserializer.\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n+ \"\"\"\n+\n+ models = models\n+\n+ def __init__(self, client, config, serializer, deserializer):\n+\n+ self._client = client\n+ self._serialize = serializer\n+ self._deserialize = deserializer\n+ self.api_version = \"2018-01-31\"\n+\n+ self.config = config\n+\n+ def list(\n+ self, scope, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Lists all budgets for a scope.\n+\n+ :param scope: The scope of the budgets. The scope can be\n+ 'subscriptions/{subscriptionId}' for a subscription, or\n+ 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}' for a\n+ resource group under a subscription.\n+ :type scope: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of Budget\n+ :rtype:\n+ ~azure.mgmt.consumption.models.BudgetPaged[~azure.mgmt.consumption.models.Budget]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/{scope}/providers/Microsoft.Consumption/budgets'\n+ path_format_arguments = {\n+ 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True),\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.BudgetPaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.BudgetPaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def get(\n+ self, scope, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Gets the budget for a scope by budget name.\n+\n+ :param scope: The scope of the budgets. The scope can be\n+ 'subscriptions/{subscriptionId}' for a subscription, or\n+ 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}' for a\n+ resource group under a subscription.\n+ :type scope: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: Budget or ClientRawResponse if raw=true\n+ :rtype: ~azure.mgmt.consumption.models.Budget or\n+ ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/{scope}/providers/Microsoft.Consumption/budgets/{name}'\n+ path_format_arguments = {\n+ 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True),\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'name': self._serialize.url(\"self.config.name\", self.config.name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ deserialized = None\n+\n+ if response.status_code == 200:\n+ deserialized = self._deserialize('Budget', response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(deserialized, response)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def create_or_update(\n+ self, scope, parameters, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"The operation to create or update a budget. Update operation requires\n+ latest eTag to be set in the request mandatorily. You may obtain the\n+ latest eTag by performing a get operation. Create operation does not\n+ require eTag.\n+\n+ :param scope: The scope of the budgets. The scope can be\n+ 'subscriptions/{subscriptionId}' for a subscription, or\n+ 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}' for a\n+ resource group under a subscription.\n+ :type scope: str\n+ :param parameters: Parameters supplied to the Create Budget operation.\n+ :type parameters: ~azure.mgmt.consumption.models.Budget\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of None\n+ :rtype: ~azure.mgmt.consumption.models.Budget[None]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/{scope}/providers/Microsoft.Consumption/budgets/{name}'\n+ path_format_arguments = {\n+ 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True),\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'name': self._serialize.url(\"self.config.name\", self.config.name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct body\n+ body_content = self._serialize.body(parameters, 'Budget')\n+\n+ # Construct and send request\n+ request = self._client.put(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, body_content, stream=False, **operation_config)\n+\n+ if response.status_code not in [200, 201]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.Budget(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.Budget(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized\n+\n+ def delete(\n+ self, scope, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"The operation to delete a budget.\n+\n+ :param scope: The scope of the budgets. The scope can be\n+ 'subscriptions/{subscriptionId}' for a subscription, or\n+ 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}' for a\n+ resource group under a subscription.\n+ :type scope: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: None or ClientRawResponse if raw=true\n+ :rtype: None or ~msrest.pipeline.ClientRawResponse\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ # Construct URL\n+ url = '/{scope}/providers/Microsoft.Consumption/budgets/{name}'\n+ path_format_arguments = {\n+ 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True),\n+ 'subscriptionId': self._serialize.url(\"self.config.subscription_id\", self.config.subscription_id, 'str'),\n+ 'name': self._serialize.url(\"self.config.name\", self.config.name, 'str')\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.delete(url, query_parameters)\n+ response = self._client.send(request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ if raw:\n+ client_raw_response = ClientRawResponse(None, response)\n+ return client_raw_response"},{"sha":"f3efdae1c20868aef1cbad552979edb11f41663f","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py","status":"modified","additions":3,"deletions":3,"changes":6,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/operations.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -22,7 +22,7 @@ class Operations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,7 +32,7 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n@@ -78,7 +78,7 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"d5663fb7895a1f04d509f50a5821dbe9b94704dc","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py","status":"added","additions":119,"deletions":0,"changes":119,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/price_sheet_operations.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -0,0 +1,119 @@\n+# coding=utf-8\n+# --------------------------------------------------------------------------\n+# Copyright (c) Microsoft Corporation. All rights reserved.\n+# Licensed under the MIT License. See License.txt in the project root for\n+# license information.\n+#\n+# Code generated by Microsoft (R) AutoRest Code Generator.\n+# Changes may cause incorrect behavior and will be lost if the code is\n+# regenerated.\n+# --------------------------------------------------------------------------\n+\n+import uuid\n+from msrest.pipeline import ClientRawResponse\n+\n+from .. import models\n+\n+\n+class PriceSheetOperations(object):\n+ \"\"\"PriceSheetOperations operations.\n+\n+ :param client: Client for service requests.\n+ :param config: Configuration of service client.\n+ :param serializer: An object model serializer.\n+ :param deserializer: An objec model deserializer.\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n+ \"\"\"\n+\n+ models = models\n+\n+ def __init__(self, client, config, serializer, deserializer):\n+\n+ self._client = client\n+ self._serialize = serializer\n+ self._deserialize = deserializer\n+ self.api_version = \"2018-01-31\"\n+\n+ self.config = config\n+\n+ def list(\n+ self, scope, expand=None, skiptoken=None, custom_headers=None, raw=False, **operation_config):\n+ \"\"\"Returns the price sheet associated with subscription guid, for a scope\n+ by billing period.\n+\n+ :param scope: The scope of the price sheet. The scope can be\n+ '/subscriptions/{subscriptionId}' for a subscription, or\n+ '/subscriptions/{subscriptionId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodId}'\n+ for a billing period.\n+ :type scope: str\n+ :param expand: May be used to expand the properties/meterDetails\n+ within a price sheet. By default, these fields are not included when\n+ returning price sheet.\n+ :type expand: str\n+ :param skiptoken: Skiptoken is only used if a previous operation\n+ returned a partial result. If a previous response contains a nextLink\n+ element, the value of the nextLink element will include a skiptoken\n+ parameter that specifies a starting point to use for subsequent calls.\n+ :type skiptoken: str\n+ :param dict custom_headers: headers that will be added to the request\n+ :param bool raw: returns the direct response alongside the\n+ deserialized response\n+ :param operation_config: :ref:`Operation configuration\n+ overrides`.\n+ :return: An iterator like instance of PriceSheet\n+ :rtype:\n+ ~azure.mgmt.consumption.models.PriceSheetPaged[~azure.mgmt.consumption.models.PriceSheet]\n+ :raises:\n+ :class:`ErrorResponseException`\n+ \"\"\"\n+ def internal_paging(next_link=None, raw=False):\n+\n+ if not next_link:\n+ # Construct URL\n+ url = '/{scope}/providers/Microsoft.Consumption/pricesheets/default'\n+ path_format_arguments = {\n+ 'scope': self._serialize.url(\"scope\", scope, 'str', skip_quote=True)\n+ }\n+ url = self._client.format_url(url, **path_format_arguments)\n+\n+ # Construct parameters\n+ query_parameters = {}\n+ if expand is not None:\n+ query_parameters['$expand'] = self._serialize.query(\"expand\", expand, 'str')\n+ if skiptoken is not None:\n+ query_parameters['$skiptoken'] = self._serialize.query(\"skiptoken\", skiptoken, 'str')\n+ query_parameters['api-version'] = self._serialize.query(\"self.api_version\", self.api_version, 'str')\n+\n+ else:\n+ url = next_link\n+ query_parameters = {}\n+\n+ # Construct headers\n+ header_parameters = {}\n+ header_parameters['Content-Type'] = 'application/json; charset=utf-8'\n+ if self.config.generate_client_request_id:\n+ header_parameters['x-ms-client-request-id'] = str(uuid.uuid1())\n+ if custom_headers:\n+ header_parameters.update(custom_headers)\n+ if self.config.accept_language is not None:\n+ header_parameters['accept-language'] = self._serialize.header(\"self.config.accept_language\", self.config.accept_language, 'str')\n+\n+ # Construct and send request\n+ request = self._client.get(url, query_parameters)\n+ response = self._client.send(\n+ request, header_parameters, stream=False, **operation_config)\n+\n+ if response.status_code not in [200]:\n+ raise models.ErrorResponseException(self._deserialize, response)\n+\n+ return response\n+\n+ # Deserialize response\n+ deserialized = models.PriceSheetPaged(internal_paging, self._deserialize.dependencies)\n+\n+ if raw:\n+ header_dict = {}\n+ client_raw_response = models.PriceSheetPaged(internal_paging, self._deserialize.dependencies, header_dict)\n+ return client_raw_response\n+\n+ return deserialized"},{"sha":"300e09f55c73071474db4e279693c0d4eef7d4db","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py","status":"modified","additions":3,"deletions":3,"changes":6,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_details_operations.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -22,7 +22,7 @@ class ReservationsDetailsOperations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,7 +32,7 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n@@ -92,7 +92,7 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"2c5124d9e9e4263cb4b1279bd8347fb627d199c5","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py","status":"modified","additions":3,"deletions":3,"changes":6,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/reservations_summaries_operations.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -22,7 +22,7 @@ class ReservationsSummariesOperations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,7 +32,7 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n@@ -96,7 +96,7 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"69abfd9386466b0d517e293a16264e8082e42147","filename":"azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py","status":"modified","additions":4,"deletions":4,"changes":8,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/operations/usage_details_operations.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -22,7 +22,7 @@ class UsageDetailsOperations(object):\n :param config: Configuration of service client.\n :param serializer: An object model serializer.\n :param deserializer: An objec model deserializer.\n- :ivar api_version: Version of the API to be used with the client request. The current version is 2017-11-30. Constant value: \"2017-11-30\".\n+ :ivar api_version: Version of the API to be used with the client request. The current version is 2018-01-31. Constant value: \"2018-01-31\".\n \"\"\"\n \n models = models\n@@ -32,7 +32,7 @@ def __init__(self, client, config, serializer, deserializer):\n self._client = client\n self._serialize = serializer\n self._deserialize = deserializer\n- self.api_version = \"2017-11-30\"\n+ self.api_version = \"2018-01-31\"\n \n self.config = config\n \n@@ -44,7 +44,7 @@ def list(\n :param scope: The scope of the usage details. The scope can be\n '/subscriptions/{subscriptionId}' for a subscription, or\n '/subscriptions/{subscriptionId}/providers/Microsoft.Billing/billingPeriods/{billingPeriodName}'\n- for a billing perdiod.\n+ for a billing period.\n :type scope: str\n :param expand: May be used to expand the\n properties/additionalProperties or properties/meterDetails within a\n@@ -115,7 +115,7 @@ def internal_paging(next_link=None, raw=False):\n # Construct and send request\n request = self._client.get(url, query_parameters)\n response = self._client.send(\n- request, header_parameters, **operation_config)\n+ request, header_parameters, stream=False, **operation_config)\n \n if response.status_code not in [200]:\n raise models.ErrorResponseException(self._deserialize, response)"},{"sha":"7bae806554140ef811329cd7f7e3a8e337d580fe","filename":"azure-mgmt-consumption/azure/mgmt/consumption/version.py","status":"modified","additions":1,"deletions":1,"changes":2,"blob_url":"https://github.com/Azure/azure-sdk-for-python/blob/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/version.py","raw_url":"https://github.com/Azure/azure-sdk-for-python/raw/042b7a5840ff471776bb64e46b50950ee9f84430/azure-mgmt-consumption/azure/mgmt/consumption/version.py","contents_url":"https://api.github.com/repos/Azure/azure-sdk-for-python/contents/azure-mgmt-consumption/azure/mgmt/consumption/version.py?ref=042b7a5840ff471776bb64e46b50950ee9f84430","patch":"@@ -9,5 +9,5 @@\n # regenerated.\n # --------------------------------------------------------------------------\n \n-VERSION = \"1.1.0\"\n+VERSION = \"2018-01-31\"\n "}]} + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_or_create_pull.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_or_create_pull.txt new file mode 100644 index 000000000000..70d25dd0519d --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_or_create_pull.txt @@ -0,0 +1,22 @@ +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/pulls +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"title": "Title", "body": "Body", "base": "b2", "head": "b1"} +422 +[('Date', 'Thu, 17 May 2018 21:27:38 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '209'), ('Server', 'GitHub.com'), ('Status', '422 Unprocessable Entity'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4772'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.087848'), ('X-GitHub-Request-Id', '1715:97B6:61F22E:7EE5EA:5AFDF3CA')] +{"message":"Validation Failed","errors":[{"resource":"PullRequest","code":"custom","message":"No commits between b2 and b1"}],"documentation_url":"https://developer.github.com/v3/pulls/#create-a-pull-request"} + +https +POST +api.github.com +None +/repos/lmazuel/TestingRepo/pulls +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"title": "Title", "body": "Body", "base": "b2", "head": "b1"} +422 +[('Date', 'Thu, 17 May 2018 21:27:39 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '209'), ('Server', 'GitHub.com'), ('Status', '422 Unprocessable Entity'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4771'), ('X-RateLimit-Reset', '1526593184'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.118070'), ('X-GitHub-Request-Id', '1716:97B8:C24888:FB581B:5AFDF3CA')] +{"message":"Validation Failed","errors":[{"resource":"PullRequest","code":"custom","message":"No commits between b2 and b1"}],"documentation_url":"https://developer.github.com/v3/pulls/#create-a-pull-request"} + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_user.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_user.txt new file mode 100644 index 000000000000..059d39112e47 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_get_user.txt @@ -0,0 +1,11 @@ +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:39 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4770'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"77a0c498bc6360506f9e7a4dd33857df"'), ('Last-Modified', 'Tue, 08 May 2018 04:10:43 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.048690'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1717:97B6:61F247:7EE60C:5AFDF3CB')] +{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":46,"public_gists":14,"followers":30,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-05-08T04:10:43Z","private_gists":1,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41216,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_manage_git_folder.txt b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_manage_git_folder.txt new file mode 100644 index 000000000000..e994d3de5241 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/ReplayData/GithubTools.test_manage_git_folder.txt @@ -0,0 +1,33 @@ +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:39 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4769'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"77a0c498bc6360506f9e7a4dd33857df"'), ('Last-Modified', 'Tue, 08 May 2018 04:10:43 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.070117'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '1719:97B6:61F253:7EE61B:5AFDF3CB')] +{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":46,"public_gists":14,"followers":30,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-05-08T04:10:43Z","private_gists":1,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41216,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:42 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4768'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"77a0c498bc6360506f9e7a4dd33857df"'), ('Last-Modified', 'Tue, 08 May 2018 04:10:43 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.054549'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '171C:97B6:61F309:7EE6FD:5AFDF3CE')] +{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":46,"public_gists":14,"followers":30,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-05-08T04:10:43Z","private_gists":1,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41216,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + +https +GET +api.github.com +None +/user +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Date', 'Thu, 17 May 2018 21:27:46 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Server', 'GitHub.com'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4767'), ('X-RateLimit-Reset', '1526593184'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('ETag', 'W/"77a0c498bc6360506f9e7a4dd33857df"'), ('Last-Modified', 'Tue, 08 May 2018 04:10:43 GMT'), ('X-OAuth-Scopes', 'repo, user'), ('X-Accepted-OAuth-Scopes', ''), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('Access-Control-Expose-Headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '1; mode=block'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-Runtime-rack', '0.063164'), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', '171F:97B8:C24AB5:FB5AD5:5AFDF3D2')] +{"login":"lmazuel","id":1050156,"avatar_url":"https://avatars3.githubusercontent.com/u/1050156?v=4","gravatar_id":"","url":"https://api.github.com/users/lmazuel","html_url":"https://github.com/lmazuel","followers_url":"https://api.github.com/users/lmazuel/followers","following_url":"https://api.github.com/users/lmazuel/following{/other_user}","gists_url":"https://api.github.com/users/lmazuel/gists{/gist_id}","starred_url":"https://api.github.com/users/lmazuel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lmazuel/subscriptions","organizations_url":"https://api.github.com/users/lmazuel/orgs","repos_url":"https://api.github.com/users/lmazuel/repos","events_url":"https://api.github.com/users/lmazuel/events{/privacy}","received_events_url":"https://api.github.com/users/lmazuel/received_events","type":"User","site_admin":false,"name":"Laurent Mazuel","company":"Microsoft.","blog":"","location":"Redmond, WA, USA","email":"lmazuel@microsoft.com","hireable":null,"bio":"Azure SDK for Python","public_repos":46,"public_gists":14,"followers":30,"following":11,"created_at":"2011-09-14T12:44:37Z","updated_at":"2018-05-08T04:10:43Z","private_gists":1,"total_private_repos":4,"owned_private_repos":0,"disk_usage":41216,"collaborators":0,"two_factor_authentication":true,"plan":{"name":"free","space":976562499,"collaborators":0,"private_repos":0}} + diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/__init__.py b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/conftest.py b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/conftest.py new file mode 100644 index 000000000000..869626a022c2 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/conftest.py @@ -0,0 +1,44 @@ +"""Configuration of fixtures for pytest""" +import logging +import os +import sys +import types + +from github import Github + +import pytest + +_LOGGER = logging.getLogger(__name__) + +collect_ignore = [] +if sys.version_info < (3, 6): + # Might do something more generic later + collect_ignore.append("test_bot_framework.py") + collect_ignore.append("test_git_tools.py") + collect_ignore.append("test_github_tools.py") + +_context = { + 'login': "login", + 'password': "password", + 'oauth_token': os.environ.get('GH_TOKEN', 'oauth_token') +} +_test_context_module = types.ModuleType( + 'GithubCredentials', + 'Module created to provide a context for tests' +) +_test_context_module.__dict__.update(_context) +sys.modules['GithubCredentials'] = _test_context_module + + +@pytest.fixture +def github_token(): + """Return the Github token to use for real tests.""" + if not 'GH_TOKEN' in os.environ: + _LOGGER.warning('GH_TOKEN must be defined for this test') + return "faketoken" + return os.environ['GH_TOKEN'] + +@pytest.fixture +def github_client(github_token): + """Return a Github client with configured token.""" + return Github(github_token) diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_bot_framework.py b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_bot_framework.py new file mode 100644 index 000000000000..d7d407bc970e --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_bot_framework.py @@ -0,0 +1,215 @@ +import os.path +from unittest import mock + +import pytest +from github.tests import Framework + +from azure_devtools.ci_tools.bot_framework import BotHandler, order, build_from_issue_comment, build_from_issues + +class BotFrameworkTest(Framework.TestCase): + + def setUp(self): + self.maxDiff = None # Big diff to come + self.recordMode = False # turn to True to record + self.tokenAuthMode = True + self.replayDataFolder = os.path.join(os.path.dirname(__file__), "ReplayData") + super(BotFrameworkTest, self).setUp() + + def test_webhook_data(self): + github_token = self.oauth_token + repo = self.g.get_repo("lmazuel/TestingRepo") + + fake_webhook = { + 'action': 'opened', # What is the comment state? + 'repository': { + 'full_name': repo.full_name # On what repo is this command? + }, + 'issue': { + 'number': 16, # On what issue is this comment? + 'body': "@AutorestCI help" # Message? + }, + 'sender': { + 'login': "lmazuel" # Who wrote the command? + }, + } + webhook_data = build_from_issues(github_token, fake_webhook) + assert webhook_data.text == "@AutorestCI help" + assert webhook_data.issue.number == 16 + assert webhook_data.repo.full_name == repo.full_name + + fake_webhook = { + 'action': 'created', # What is the comment state? + 'repository': { + 'full_name': repo.full_name # On what repo is this command? + }, + 'issue': { + 'number': 16 # On what issue is this comment? + }, + 'sender': { + 'login': "lmazuel" # Who wrote the command? + }, + 'comment': { + 'id': 365120206, + 'body': "@AutorestCI help" # Message? + } + } + webhook_data = build_from_issue_comment(github_token, fake_webhook) + assert webhook_data.text == "@AutorestCI help" + assert webhook_data.issue.number == 16 + assert webhook_data.repo.full_name == repo.full_name + + def test_bot_help(self): + github_token = self.oauth_token + repo = self.g.get_repo("lmazuel/TestingRepo") + issue = repo.get_issue(16) + + class BotHelp: + @order + def command1(self, issue): + pass + @order + def command2(self, issue): + pass + def notacommand(self): + pass + + bot = BotHandler(BotHelp(), "AutorestCI", github_token) + + fake_webhook = { + 'action': 'opened', # What is the comment state? + 'repository': { + 'full_name': issue.repository.full_name # On what repo is this command? + }, + 'issue': { + 'number': issue.number, # On what issue is this comment? + 'body': "@AutorestCI help" # Message? + }, + 'sender': { + 'login': "lmazuel" # Who wrote the command? + }, + } + + response = bot.issues(fake_webhook) + assert "this help message" in response["message"] + assert "command1" in response["message"] + assert "notacommand" not in response["message"] + + help_comment = list(issue.get_comments())[-1] + assert "this help message" in help_comment.body + assert "command1" in help_comment.body + assert "notacommand" not in help_comment.body + + # Clean + help_comment.delete() + + def test_bot_basic_command(self): + github_token = self.oauth_token + repo = self.g.get_repo("lmazuel/TestingRepo") + issue = repo.get_issue(17) + + class BotCommand: + @order + def command1(self, issue, param1): + assert issue.number == 17 + return "I did something with "+param1 + + bot = BotHandler(BotCommand(), "AutorestCI", github_token) + + fake_webhook = { + 'action': 'opened', # What is the comment state? + 'repository': { + 'full_name': issue.repository.full_name # On what repo is this command? + }, + 'issue': { + 'number': issue.number, # On what issue is this comment? + 'body': "@AutorestCI command1 myparameter" # Message? + }, + 'sender': { + 'login': "lmazuel" # Who wrote the command? + }, + } + + response = bot.issues(fake_webhook) + assert response["message"] == "I did something with myparameter" + + help_comment = list(issue.get_comments())[-1] + assert "I did something with myparameter" in help_comment.body + + # Clean + help_comment.delete() + + @mock.patch('traceback.format_exc') + def test_bot_basic_failure(self, format_exc): + format_exc.return_value = 'something to do with an exception' + + github_token = self.oauth_token + repo = self.g.get_repo("lmazuel/TestingRepo") + issue = repo.get_issue(18) + + class BotCommand: + @order + def command1(self, issue, param1): + assert issue.number == 18 + raise ValueError("Not happy") + + bot = BotHandler(BotCommand(), "AutorestCI", github_token) + + fake_webhook = { + 'action': 'opened', # What is the comment state? + 'repository': { + 'full_name': issue.repository.full_name # On what repo is this command? + }, + 'issue': { + 'number': issue.number, # On what issue is this comment? + 'body': "@AutorestCI command1 myparameter" # Message? + }, + 'sender': { + 'login': "lmazuel" # Who wrote the command? + }, + } + + response = bot.issues(fake_webhook) + assert response['message'] == 'Nothing for me or exception' + + help_comment = list(issue.get_comments())[-1] + assert "something to do with an exception" in help_comment.body + assert "```python" in help_comment.body + + # Clean + help_comment.delete() + + + def test_bot_unknown_command(self): + github_token = self.oauth_token + repo = self.g.get_repo("lmazuel/TestingRepo") + issue = repo.get_issue(19) + + class BotCommand: + pass + + bot = BotHandler(BotCommand(), "AutorestCI", github_token) + + fake_webhook = { + 'action': 'opened', # What is the comment state? + 'repository': { + 'full_name': issue.repository.full_name # On what repo is this command? + }, + 'issue': { + 'number': issue.number, # On what issue is this comment? + 'body': "@AutorestCI command1 myparameter" # Message? + }, + 'sender': { + 'login': "lmazuel" # Who wrote the command? + }, + } + + response = bot.issues(fake_webhook) + assert "I didn't understand your command" in response['message'] + assert "command1 myparameter" in response['message'] + + help_comment = list(issue.get_comments())[-1] + assert "I didn't understand your command" in help_comment.body + assert "command1 myparameter" in help_comment.body + + # Clean + help_comment.delete() diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_git_tools.py b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_git_tools.py new file mode 100644 index 000000000000..432824f611b1 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_git_tools.py @@ -0,0 +1,72 @@ +from pathlib import Path +import tempfile + +from git import Repo + +from azure_devtools.ci_tools.git_tools import ( + do_commit, + get_files_in_commit +) + +def test_do_commit(): + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir: + Repo.clone_from('https://github.com/lmazuel/TestingRepo.git', temp_dir) + repo = Repo(temp_dir) + + result = do_commit(repo, 'Test {hexsha}', 'testing', 'fakehexsha') + assert not result + assert 'fakehexsha' not in repo.head.commit.message + assert repo.active_branch.name == 'master' + + file_path = Path(temp_dir, 'file.txt') + file_path.write_text('Something') + + result = do_commit(repo, 'Test {hexsha}', 'testing', 'fakehexsha') + assert result + assert repo.head.commit.message == 'Test fakehexsha' + assert repo.active_branch.name == 'testing' + assert 'file.txt' in repo.head.commit.stats.files + + file_path.write_text('New content') + + result = do_commit(repo, 'Now it is {hexsha}', 'newbranch', 'new-fakehexsha') + assert result + assert repo.head.commit.message == 'Now it is new-fakehexsha' + assert repo.active_branch.name == 'newbranch' + assert 'file.txt' in repo.head.commit.stats.files + + file_path.unlink() + file_path.write_text('New content') + + result = do_commit(repo, 'Now it is {hexsha}', 'fakebranch', 'hexsha_not_used') + assert not result + assert repo.head.commit.message == 'Now it is new-fakehexsha' + assert repo.active_branch.name == 'newbranch' + + finished = True + except PermissionError: + if finished: + return + raise + +def test_get_files_in_commit(): + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir: + Repo.clone_from('https://github.com/lmazuel/swagger-to-sdk.git', temp_dir) + + files = get_files_in_commit(temp_dir, "b40451e55b26e3db61ea17bd751181cbf91f60c5") + + assert files == [ + 'swaggertosdk/generate_package.py', + 'swaggertosdk/python_sdk_tools.py', + 'swaggertosdk/restapi/sdkbot.py' + ] + + finished = True + except PermissionError: + if finished: + return + raise diff --git a/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_github_tools.py b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_github_tools.py new file mode 100644 index 000000000000..a6829810be80 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/ci_tools/tests/test_github_tools.py @@ -0,0 +1,382 @@ +import os.path +from pathlib import Path +from subprocess import CalledProcessError +import tempfile +from unittest import mock + +import pytest + +from git import Repo, GitCommandError +from github import GithubException +from github.tests import Framework + +from azure_devtools.ci_tools.github_tools import ( + exception_to_github, + user_from_token, + configure_user, + clone_to_path, + manage_git_folder, + do_pr, + get_files, + create_comment, + GithubLink, + DashboardCommentableObject, + DashboardComment, + get_or_create_pull +) + +class GithubTools(Framework.TestCase): + + def setUp(self): + self.maxDiff = None # Big diff to come + self.recordMode = False # turn to True to record + self.tokenAuthMode = True + self.replayDataFolder = os.path.join(os.path.dirname(__file__), "ReplayData") + super(GithubTools, self).setUp() + + @mock.patch('traceback.format_exc') + def test_exception_to_github(self, format_exc): + format_exc.return_value = 'something to do with an exception' + + # Prepare + repo = self.g.get_repo("lmazuel/TestingRepo") + issue = repo.get_issue(13) + + # Act + with exception_to_github(issue) as error: + pass + + assert error.comment is None + + # Act + with exception_to_github(issue) as error: + "Test".fakemethod(12) # pylint: disable=no-member + + # Test + assert error.comment is not None + assert "Encountered an unknown error" in error.comment.body + + # Clean my mess + error.comment.delete() + + # Act + with exception_to_github(issue, "Python bot") as error: + "Test".fakemethod(12) # pylint: disable=no-member + + # Test + assert error.comment is not None + assert "Encountered an unknown error: (Python bot)" in error.comment.body + + # Clean my mess + error.comment.delete() + + # Act + with exception_to_github(issue, "Python bot") as error: + raise CalledProcessError( + 2, + ["autorest", "readme.md"], + "Error line 1\nError line 2" + ) + + # Test + assert error.comment is not None + assert "Encountered a Subprocess error: (Python bot)" in error.comment.body + assert "Error line 1" in error.comment.body + + # Clean my mess + error.comment.delete() + + # Act + with exception_to_github(issue, "Python bot") as error: + raise CalledProcessError( + 2, + ["autorest", "readme.md"], + ) + + # Test + assert error.comment is not None + assert "Encountered a Subprocess error: (Python bot)" in error.comment.body + assert "no output" in error.comment.body + + # Clean my mess + error.comment.delete() + + def test_get_or_create_pull(self): + repo = self.g.get_repo("lmazuel/TestingRepo") + + # b1 and b2 should exist and be the same + with pytest.raises(GithubException): + get_or_create_pull(repo, "Title", "Body", "b1", "b2") + + prresult = get_or_create_pull(repo, "Title", "Body", "b1", "b2", none_if_no_commit=True) + assert prresult is None + + @mock.patch('traceback.format_exc') + def test_dashboard(self, format_exc): + format_exc.return_value = 'something to do with an exception' + + # Prepare + repo = self.g.get_repo("lmazuel/TestingRepo") + issue = repo.get_issue(15) + initial_size = len(list(issue.get_comments())) + header = "# MYHEADER" + + dashboard = DashboardCommentableObject(issue, header) + + with exception_to_github(dashboard, "Python bot") as error: + "Test".fakemethod(12) # pylint: disable=no-member + + after_size = len(list(issue.get_comments())) + assert after_size == initial_size + 1 + + assert error.comment is not None + assert "Encountered an unknown error" in error.comment.body + + dashboard.create_comment("New text comment") + after_size_2 = len(list(issue.get_comments())) + assert after_size == after_size_2 + + # Clean my mess + error.comment.delete() + + def test_get_user(self): + github_token = self.oauth_token + user = user_from_token(github_token) + assert user.login == 'lmazuel' + + def test_get_files(self): + repo = self.g.get_repo("Azure/azure-sdk-for-python") + pr = repo.get_pull(1833) + files = get_files(pr) + assert "azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py" in [f.filename for f in files] + + commit = repo.get_commit("042b7a5840ff471776bb64e46b50950ee9f84430") + files = get_files(commit) + assert "azure-mgmt-consumption/azure/mgmt/consumption/consumption_management_client.py" in [f.filename for f in files] + + def test_create_comment(self): + repo = self.g.get_repo("lmazuel/TestingRepo") + issue = repo.get_issue(14) + comment = create_comment(issue, "This is a test") + comment.delete() + + pull = repo.get_pull(2) + comment = create_comment(pull, "This is a test") + comment.delete() + + def test_configure(self): + github_token = self.oauth_token + finished = False + try: + with tempfile.TemporaryDirectory() as temp_dir: + try: + Repo.clone_from('https://github.com/lmazuel/TestingRepo.git', temp_dir) + repo = Repo(temp_dir) + + # If it's not throwing, I'm happy enough + configure_user(github_token, repo) + + assert repo.git.config('--get', 'user.name') == 'Laurent Mazuel' + except Exception as err: + print(err) + pytest.fail(err) + else: + finished = True + except PermissionError: + if finished: + return + raise + + def test_clone_path(self): + github_token = self.oauth_token + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir: + clone_to_path(github_token, temp_dir, "lmazuel/TestingRepo") + assert (Path(temp_dir) / Path("README.md")).exists() + + finished = True + except PermissionError: + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir: + clone_to_path(github_token, temp_dir, "https://github.com/lmazuel/TestingRepo") + assert (Path(temp_dir) / Path("README.md")).exists() + + finished = True + except PermissionError: + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir: + clone_to_path(github_token, temp_dir, "lmazuel/TestingRepo", "lmazuel-patch-1") + assert (Path(temp_dir) / Path("README.md")).exists() + + finished = True + except PermissionError: + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir: + with pytest.raises(GitCommandError): + clone_to_path(github_token, temp_dir, "lmazuel/TestingRepo", "fakebranch") + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + # PR 2 must be open, or the test means nothing + try: + with tempfile.TemporaryDirectory() as temp_dir: + clone_to_path(github_token, temp_dir, "lmazuel/TestingRepo", pr_number=2) + assert (Path(temp_dir) / Path("README.md")).exists() + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + # PR 1 must be MERGED, or the test means nothing + try: + with tempfile.TemporaryDirectory() as temp_dir: + clone_to_path(github_token, temp_dir, "lmazuel/TestingRepo", pr_number=1) + assert (Path(temp_dir) / Path("README.md")).exists() + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + # PR 2 must be opened, or the test means nothing + repo = self.g.get_repo("lmazuel/TestingRepo") + pr = repo.get_pull(2) + try: + with tempfile.TemporaryDirectory() as temp_dir: + clone_to_path(github_token, temp_dir, "lmazuel/TestingRepo", branch_or_commit=pr.merge_commit_sha, pr_number=2) + assert (Path(temp_dir) / Path("README.md")).stat().st_size >= 107 # File in the PR + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir: + with pytest.raises(GitCommandError): + clone_to_path(github_token, temp_dir, "lmazuel/TestingRepo", pr_number=123456789) + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + def test_manage_git_folder(self): + github_token = self.oauth_token + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir, \ + manage_git_folder(github_token, temp_dir, "lmazuel/TestingRepo") as rest_repo: + + assert (Path(rest_repo) / Path("README.md")).exists() + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir, \ + manage_git_folder(github_token, temp_dir, "lmazuel/TestingRepo@lmazuel-patch-1") as rest_repo: + + assert (Path(rest_repo) / Path("README.md")).exists() + assert "lmazuel-patch-1" in str(Repo(rest_repo).active_branch) + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + finished = False # Authorize PermissionError on cleanup + try: + with tempfile.TemporaryDirectory() as temp_dir, \ + manage_git_folder(github_token, temp_dir, "lmazuel/TestingRepo", pr_number=1) as rest_repo: + + assert (Path(rest_repo) / Path("README.md")).exists() + with pytest.raises(TypeError) as err: + Repo(rest_repo).active_branch + assert "HEAD is a detached symbolic reference" in str(err) + + finished = True + except (PermissionError, FileNotFoundError): + if not finished: + raise + + def test_do_pr(self): + github_token = self.oauth_token + # Should do nothing + do_pr(None, 'bad', 'bad', 'bad', 'bad') + + # Should do nothing + do_pr(github_token, 'bad', None, 'bad', 'bad') + + # FIXME - more tests + + +def test_github_link(): + inputstr = "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/billing/resource-manager/readme.md" + link = GithubLink.from_string(inputstr) + assert link.gitid == "Azure/azure-rest-api-specs" + assert link.branch_or_commit == "master" + assert link.link_type == "raw" + assert link.path == "specification/billing/resource-manager/readme.md" + assert str(link) == inputstr + raw_link = link.as_raw_link() + assert isinstance(raw_link, GithubLink) + assert str(raw_link) == str(link) + + inputstr = "https://github.com/Azure/azure-rest-api-specs/blob/master/specification/billing/resource-manager/readme.md" + link = GithubLink.from_string(inputstr) + assert link.gitid == "Azure/azure-rest-api-specs" + assert link.branch_or_commit == "master" + assert link.link_type == "blob" + assert link.path == "specification/billing/resource-manager/readme.md" + assert str(link) == inputstr + raw_link = link.as_raw_link() + assert isinstance(raw_link, GithubLink) + assert str(raw_link) == "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/billing/resource-manager/readme.md" + + inputstr = "https://github.com/Azure/azure-rest-api-specs/tree/master/specification/billing/resource-manager" + link = GithubLink.from_string(inputstr) + assert link.gitid == "Azure/azure-rest-api-specs" + assert link.branch_or_commit == "master" + assert link.link_type == "tree" + assert link.path == "specification/billing/resource-manager" + assert str(link) == inputstr + with pytest.raises(ValueError): + link.as_raw_link() + + inputstr = "https://token@github.com/Azure/azure-rest-api-specs/blob/master/specification/billing/resource-manager/readme.md" + link = GithubLink.from_string(inputstr) + assert link.token == "token" + assert link.gitid == "Azure/azure-rest-api-specs" + assert link.branch_or_commit == "master" + assert link.link_type == "blob" + assert link.path == "specification/billing/resource-manager/readme.md" + assert str(link) == inputstr + raw_link = link.as_raw_link() + assert isinstance(raw_link, GithubLink) + # Raw link with token does not use token in URL, since it has to be provided as Authorization: token + assert str(raw_link) == "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/billing/resource-manager/readme.md" diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/__init__.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/__init__.py new file mode 100644 index 000000000000..b90b5aaa96b8 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/__init__.py @@ -0,0 +1,28 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from .base import IntegrationTestBase, ReplayableTest, LiveTest +from .exceptions import AzureTestError +from .decorators import live_only, record_only, AllowLargeResponse +from .patches import mock_in_unit_test, patch_time_sleep_api, patch_long_run_operation_delay +from .preparers import AbstractPreparer, SingleValueReplacer +from .recording_processors import ( + RecordingProcessor, SubscriptionRecordingProcessor, + LargeRequestBodyProcessor, LargeResponseBodyProcessor, LargeResponseBodyReplacer, + OAuthRequestResponsesFilter, DeploymentNameReplacer, GeneralNameReplacer, AccessTokenReplacer, RequestUrlNormalizer, +) +from .utilities import create_random_name, get_sha1_hash + +__all__ = ['IntegrationTestBase', 'ReplayableTest', 'LiveTest', + 'AzureTestError', + 'mock_in_unit_test', 'patch_time_sleep_api', 'patch_long_run_operation_delay', + 'AbstractPreparer', 'SingleValueReplacer', 'AllowLargeResponse', + 'RecordingProcessor', 'SubscriptionRecordingProcessor', + 'LargeRequestBodyProcessor', 'LargeResponseBodyProcessor', 'LargeResponseBodyReplacer', + 'OAuthRequestResponsesFilter', 'DeploymentNameReplacer', 'GeneralNameReplacer', + 'AccessTokenReplacer', 'RequestUrlNormalizer', + 'live_only', 'record_only', + 'create_random_name', 'get_sha1_hash'] +__version__ = '0.5.2' diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/base.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/base.py new file mode 100644 index 000000000000..81d90f96a46c --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/base.py @@ -0,0 +1,214 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from __future__ import print_function +import unittest +import os +import inspect +import tempfile +import shutil +import logging +import threading +import six +import vcr + +from .config import TestConfig +from .const import ENV_TEST_DIAGNOSE +from .utilities import create_random_name +from .decorators import live_only + + +class IntegrationTestBase(unittest.TestCase): + def __init__(self, method_name): + super(IntegrationTestBase, self).__init__(method_name) + self.diagnose = os.environ.get(ENV_TEST_DIAGNOSE, None) == 'True' + self.logger = logging.getLogger('azure_devtools.scenario_tests') + + def create_random_name(self, prefix, length): # pylint: disable=no-self-use + return create_random_name(prefix=prefix, length=length) + + def create_temp_file(self, size_kb, full_random=False): + """ Create a temporary file for testing. The test harness will delete the file during tearing down. """ + fd, path = tempfile.mkstemp() + os.close(fd) + self.addCleanup(lambda: os.remove(path)) + + with open(path, mode='r+b') as f: + if full_random: + chunk = os.urandom(1024) + else: + chunk = bytearray([0] * 1024) + for _ in range(size_kb): + f.write(chunk) + + return path + + def create_temp_dir(self): + """ + Create a temporary directory for testing. The test harness will delete the directory during tearing down. + """ + temp_dir = tempfile.mkdtemp() + self.addCleanup(lambda: shutil.rmtree(temp_dir, ignore_errors=True)) + + return temp_dir + + @classmethod + def set_env(cls, key, val): + os.environ[key] = val + + @classmethod + def pop_env(cls, key): + return os.environ.pop(key, None) + + +@live_only() +class LiveTest(IntegrationTestBase): + pass + + +class ReplayableTest(IntegrationTestBase): # pylint: disable=too-many-instance-attributes + FILTER_HEADERS = [ + 'authorization', + 'client-request-id', + 'retry-after', + 'x-ms-client-request-id', + 'x-ms-correlation-request-id', + 'x-ms-ratelimit-remaining-subscription-reads', + 'x-ms-request-id', + 'x-ms-routing-request-id', + 'x-ms-gateway-service-instanceid', + 'x-ms-ratelimit-remaining-tenant-reads', + 'x-ms-served-by', + 'x-ms-authorization-auxiliary' + ] + + def __init__(self, # pylint: disable=too-many-arguments + method_name, config_file=None, recording_dir=None, recording_name=None, recording_processors=None, + replay_processors=None, recording_patches=None, replay_patches=None): + super(ReplayableTest, self).__init__(method_name) + + self.recording_processors = recording_processors or [] + self.replay_processors = replay_processors or [] + + self.recording_patches = recording_patches or [] + self.replay_patches = replay_patches or [] + + self.config = TestConfig(config_file=config_file) + + self.disable_recording = False + + test_file_path = inspect.getfile(self.__class__) + recording_dir = recording_dir or os.path.join(os.path.dirname(test_file_path), 'recordings') + self.is_live = self.config.record_mode + + self.vcr = vcr.VCR( + cassette_library_dir=recording_dir, + before_record_request=self._process_request_recording, + before_record_response=self._process_response_recording, + decode_compressed_response=True, + record_mode='once' if not self.is_live else 'all', + filter_headers=self.FILTER_HEADERS + ) + self.vcr.register_matcher('query', self._custom_request_query_matcher) + + self.recording_file = os.path.join( + recording_dir, + '{}.yaml'.format(recording_name or method_name) + ) + if self.is_live and os.path.exists(self.recording_file): + os.remove(self.recording_file) + + self.in_recording = self.is_live or not os.path.exists(self.recording_file) + self.test_resources_count = 0 + self.original_env = os.environ.copy() + + def setUp(self): + super(ReplayableTest, self).setUp() + + # set up cassette + cm = self.vcr.use_cassette(self.recording_file) + self.cassette = cm.__enter__() + self.addCleanup(cm.__exit__) + + # set up mock patches + if self.in_recording: + for patch in self.recording_patches: + patch(self) + else: + for patch in self.replay_patches: + patch(self) + + def tearDown(self): + os.environ = self.original_env + # Autorest.Python 2.x + assert not [t for t in threading.enumerate() if t.name.startswith("AzureOperationPoller")], \ + "You need to call 'result' or 'wait' on all AzureOperationPoller you have created" + # Autorest.Python 3.x + assert not [t for t in threading.enumerate() if t.name.startswith("LROPoller")], \ + "You need to call 'result' or 'wait' on all LROPoller you have created" + + def _process_request_recording(self, request): + if self.disable_recording: + return None + + if self.in_recording: + for processor in self.recording_processors: + request = processor.process_request(request) + if not request: + break + else: + for processor in self.replay_processors: + request = processor.process_request(request) + if not request: + break + + return request + + def _process_response_recording(self, response): + from .utilities import is_text_payload + if self.in_recording: + # make header name lower case and filter unwanted headers + headers = {} + for key in response['headers']: + if key.lower() not in self.FILTER_HEADERS: + headers[key.lower()] = response['headers'][key] + response['headers'] = headers + + body = response['body']['string'] + if is_text_payload(response) and body and not isinstance(body, six.string_types): + response['body']['string'] = body.decode('utf-8') + + for processor in self.recording_processors: + response = processor.process_response(response) + if not response: + break + else: + for processor in self.replay_processors: + response = processor.process_response(response) + if not response: + break + + return response + + @classmethod + def _custom_request_query_matcher(cls, r1, r2): + """ Ensure method, path, and query parameters match. """ + from six.moves.urllib_parse import urlparse, parse_qs # pylint: disable=import-error,relative-import + + url1 = urlparse(r1.uri) + url2 = urlparse(r2.uri) + + q1 = parse_qs(url1.query) + q2 = parse_qs(url2.query) + shared_keys = set(q1.keys()).intersection(set(q2.keys())) + + if len(shared_keys) != len(q1) or len(shared_keys) != len(q2): + return False + + for key in shared_keys: + if q1[key][0].lower() != q2[key][0].lower(): + return False + + return True diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/config.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/config.py new file mode 100644 index 000000000000..ac6ac6f91c0a --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/config.py @@ -0,0 +1,28 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import configargparse + +from .const import ENV_LIVE_TEST + + +class TestConfig(object): # pylint: disable=too-few-public-methods + def __init__(self, parent_parsers=None, config_file=None): + parent_parsers = parent_parsers or [] + self.parser = configargparse.ArgumentParser(parents=parent_parsers) + self.parser.add_argument( + '-c', '--config', is_config_file=True, default=config_file, + help='Path to a configuration file in YAML format.' + ) + self.parser.add_argument( + '-l', '--live-mode', action='store_true', dest='live_mode', + env_var=ENV_LIVE_TEST, + help='Activate "live" recording mode for tests.' + ) + self.args = self.parser.parse_args([]) + + @property + def record_mode(self): + return self.args.live_mode diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/const.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/const.py new file mode 100644 index 000000000000..e27e7289a021 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/const.py @@ -0,0 +1,14 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# Replaced mock values +MOCKED_SUBSCRIPTION_ID = '00000000-0000-0000-0000-000000000000' +MOCKED_TENANT_ID = '00000000-0000-0000-0000-000000000000' + +# Configuration environment variable +ENV_COMMAND_COVERAGE = 'AZURE_TEST_COMMAND_COVERAGE' +ENV_LIVE_TEST = 'AZURE_TEST_RUN_LIVE' +ENV_SKIP_ASSERT = 'AZURE_TEST_SKIP_ASSERT' +ENV_TEST_DIAGNOSE = 'AZURE_TEST_DIAGNOSE' diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/decorators.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/decorators.py new file mode 100644 index 000000000000..b31d8ee29dae --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/decorators.py @@ -0,0 +1,44 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import os +import functools +import unittest +from .const import ENV_LIVE_TEST +from .utilities import trim_kwargs_from_test_function + + +def live_only(): + return unittest.skipUnless( + os.environ.get(ENV_LIVE_TEST, False), + 'This is a live only test. A live test will bypass all vcrpy components.') + + +def record_only(): + return unittest.skipUnless( + not os.environ.get(ENV_LIVE_TEST, False), + 'This test is excluded from being run live. To force a recording, please remove the recording file.') + + +class AllowLargeResponse(object): # pylint: disable=too-few-public-methods + + def __init__(self, size_kb=1024): + self.size_kb = size_kb + + def __call__(self, fn): + def _preparer_wrapper(test_class_instance, **kwargs): + from azure_devtools.scenario_tests import LargeResponseBodyProcessor + large_resp_body = next((r for r in test_class_instance.recording_processors + if isinstance(r, LargeResponseBodyProcessor)), None) + if large_resp_body: + large_resp_body._max_response_body = self.size_kb # pylint: disable=protected-access + + trim_kwargs_from_test_function(fn, kwargs) + + fn(test_class_instance, **kwargs) + + setattr(_preparer_wrapper, '__is_preparer', True) + functools.update_wrapper(_preparer_wrapper, fn) + return _preparer_wrapper diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/exceptions.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/exceptions.py new file mode 100644 index 000000000000..bdebae0b44e8 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/exceptions.py @@ -0,0 +1,10 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + + +class AzureTestError(Exception): + def __init__(self, error_message): + message = 'An error caused by the Azure test harness failed the test: {}' + super(AzureTestError, self).__init__(message.format(error_message)) diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/patches.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/patches.py new file mode 100644 index 000000000000..74c27927c29c --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/patches.py @@ -0,0 +1,37 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from .exceptions import AzureTestError + + +def patch_time_sleep_api(unit_test): + def _time_sleep_skip(*_): + return + + mock_in_unit_test(unit_test, 'time.sleep', _time_sleep_skip) + + +def patch_long_run_operation_delay(unit_test): + def _shortcut_long_run_operation(*args, **kwargs): # pylint: disable=unused-argument + return + + mock_in_unit_test(unit_test, + 'msrestazure.azure_operation.AzureOperationPoller._delay', + _shortcut_long_run_operation) + + +def mock_in_unit_test(unit_test, target, replacement): + try: + import unittest.mock as mock + except ImportError: + import mock + import unittest + + if not isinstance(unit_test, unittest.TestCase): + raise AzureTestError('Patches can be only called from a unit test') + + mp = mock.patch(target, replacement) + mp.__enter__() + unit_test.addCleanup(mp.__exit__) diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/preparers.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/preparers.py new file mode 100644 index 000000000000..b10d8c949b68 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/preparers.py @@ -0,0 +1,122 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import contextlib +import functools + +from .base import ReplayableTest +from .utilities import create_random_name, is_text_payload, trim_kwargs_from_test_function +from .recording_processors import RecordingProcessor + + +# Core Utility + +class AbstractPreparer(object): + def __init__(self, name_prefix, name_len, disable_recording=False): + self.name_prefix = name_prefix + self.name_len = name_len + self.resource_moniker = None + self.resource_random_name = None + self.test_class_instance = None + self.live_test = False + self.disable_recording = disable_recording + + def __call__(self, fn): + def _preparer_wrapper(test_class_instance, **kwargs): + self.live_test = not isinstance(test_class_instance, ReplayableTest) + self.test_class_instance = test_class_instance + + if self.live_test or test_class_instance.in_recording: + resource_name = self.random_name + if not self.live_test and isinstance(self, RecordingProcessor): + test_class_instance.recording_processors.append(self) + else: + resource_name = self.moniker + + with self.override_disable_recording(): + parameter_update = self.create_resource( + resource_name, + **kwargs + ) + + if parameter_update: + kwargs.update(parameter_update) + + trim_kwargs_from_test_function(fn, kwargs) + + try: + fn(test_class_instance, **kwargs) + finally: + # Russian Doll - the last declared resource to be deleted first. + self.remove_resource_with_record_override(resource_name, **kwargs) + + setattr(_preparer_wrapper, '__is_preparer', True) + functools.update_wrapper(_preparer_wrapper, fn) + return _preparer_wrapper + + @contextlib.contextmanager + def override_disable_recording(self): + if hasattr(self.test_class_instance, 'disable_recording'): + orig_enabled = self.test_class_instance.disable_recording + self.test_class_instance.disable_recording = self.disable_recording + yield + self.test_class_instance.disable_recording = orig_enabled + else: + yield + + @property + def moniker(self): + if not self.resource_moniker: + self.test_class_instance.test_resources_count += 1 + self.resource_moniker = '{}{:06}'.format(self.name_prefix, + self.test_class_instance.test_resources_count) + return self.resource_moniker + + def create_random_name(self): + return create_random_name(self.name_prefix, self.name_len) + + @property + def random_name(self): + if not self.resource_random_name: + self.resource_random_name = self.create_random_name() + return self.resource_random_name + + def create_resource(self, name, **kwargs): # pylint: disable=unused-argument,no-self-use + return {} + + def remove_resource(self, name, **kwargs): # pylint: disable=unused-argument + pass + + def remove_resource_with_record_override(self, name, **kwargs): + with self.override_disable_recording(): + self.remove_resource(name, **kwargs) + + +class SingleValueReplacer(RecordingProcessor): + # pylint: disable=no-member + def process_request(self, request): + from six.moves.urllib_parse import quote_plus # pylint: disable=import-error,relative-import + if self.random_name in request.uri: + request.uri = request.uri.replace(self.random_name, self.moniker) + elif quote_plus(self.random_name) in request.uri: + request.uri = request.uri.replace(quote_plus(self.random_name), + quote_plus(self.moniker)) + + if is_text_payload(request) and request.body: + body = str(request.body, 'utf-8') if isinstance(request.body, bytes) else str(request.body) + if self.random_name in body: + request.body = body.replace(self.random_name, self.moniker) + + return request + + def process_response(self, response): + if is_text_payload(response) and response['body']['string']: + response['body']['string'] = response['body']['string'].replace(self.random_name, + self.moniker) + + self.replace_header(response, 'location', self.random_name, self.moniker) + self.replace_header(response, 'azure-asyncoperation', self.random_name, self.moniker) + + return response diff --git a/tools/azure-devtools/src/azure_devtools/scenario_tests/recording_processors.py b/tools/azure-devtools/src/azure_devtools/scenario_tests/recording_processors.py new file mode 100644 index 000000000000..cfbc6b3cfd96 --- /dev/null +++ b/tools/azure-devtools/src/azure_devtools/scenario_tests/recording_processors.py @@ -0,0 +1,200 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from .utilities import is_text_payload, is_json_payload + + +class RecordingProcessor(object): + def process_request(self, request): # pylint: disable=no-self-use + return request + + def process_response(self, response): # pylint: disable=no-self-use + return response + + @classmethod + def replace_header(cls, entity, header, old, new): + cls.replace_header_fn(entity, header, lambda v: v.replace(old, new)) + + @classmethod + def replace_header_fn(cls, entity, header, replace_fn): + # Loop over the headers to find the one we want case insensitively, + # but we don't want to modify the case of original header key. + for key, values in entity['headers'].items(): + if key.lower() == header.lower(): + entity['headers'][key] = [replace_fn(v) for v in values] + + +class SubscriptionRecordingProcessor(RecordingProcessor): + def __init__(self, replacement): + self._replacement = replacement + + def process_request(self, request): + request.uri = self._replace_subscription_id(request.uri) + + if is_text_payload(request) and request.body: + request.body = self._replace_subscription_id(request.body.decode()).encode() + + return request + + def process_response(self, response): + if is_text_payload(response) and response['body']['string']: + response['body']['string'] = self._replace_subscription_id(response['body']['string']) + + self.replace_header_fn(response, 'location', self._replace_subscription_id) + self.replace_header_fn(response, 'azure-asyncoperation', self._replace_subscription_id) + + return response + + def _replace_subscription_id(self, val): + import re + # subscription presents in all api call + retval = re.sub('/(subscriptions)/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', + r'/\1/{}'.format(self._replacement), + val, + flags=re.IGNORECASE) + + # subscription is also used in graph call + retval = re.sub('https://(graph.windows.net)/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', + r'https://\1/{}'.format(self._replacement), + retval, + flags=re.IGNORECASE) + return retval + + +class LargeRequestBodyProcessor(RecordingProcessor): + def __init__(self, max_request_body=128): + self._max_request_body = max_request_body + + def process_request(self, request): + if is_text_payload(request) and request.body and len(request.body) > self._max_request_body * 1024: + request.body = '!!! The request body has been omitted from the recording because its ' \ + 'size {} is larger than {}KB. !!!'.format(len(request.body), + self._max_request_body) + + return request + + +class LargeResponseBodyProcessor(RecordingProcessor): + control_flag = '' + + def __init__(self, max_response_body=128): + self._max_response_body = max_response_body + + def process_response(self, response): + if is_text_payload(response): + length = len(response['body']['string'] or '') + if length > self._max_response_body * 1024: + + if is_json_payload(response): + from .decorators import AllowLargeResponse # pylint: disable=cyclic-import + raise ValueError("The json response body exceeds the default limit of {}kb. Use '@{}' " + "on your test method to increase the limit or update test logics to avoid " + "big payloads".format(self._max_response_body, AllowLargeResponse.__name__)) + + response['body']['string'] = \ + "!!! The response body has been omitted from the recording because it is larger " \ + "than {} KB. It will be replaced with blank content of {} bytes while replay. " \ + "{}{}".format(self._max_response_body, length, self.control_flag, length) + return response + + +class LargeResponseBodyReplacer(RecordingProcessor): + def process_response(self, response): + if is_text_payload(response) and not is_json_payload(response): + import six + body = response['body']['string'] + + # backward compatibility. under 2.7 response body is unicode, under 3.5 response body is + # bytes. when set the value back, the same type must be used. + body_is_string = isinstance(body, six.string_types) + + content_in_string = (response['body']['string'] or b'').decode('utf-8') + index = content_in_string.find(LargeResponseBodyProcessor.control_flag) + + if index > -1: + length = int(content_in_string[index + len(LargeResponseBodyProcessor.control_flag):]) + if body_is_string: + response['body']['string'] = '0' * length + else: + response['body']['string'] = bytes([0] * length) + + return response + + +class OAuthRequestResponsesFilter(RecordingProcessor): + """Remove oauth authentication requests and responses from recording.""" + + def process_request(self, request): + # filter request like: + # GET https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/oauth2/token + # POST https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/oauth2/v2.0/token + import re + if not re.match('https://login.microsoftonline.com/([^/]+)/oauth2(?:/v2.0)?/token', request.uri): + return request + return None + + +class DeploymentNameReplacer(RecordingProcessor): + """Replace the random deployment name with a fixed mock name.""" + + def process_request(self, request): + import re + request.uri = re.sub('/deployments/([^/?]+)', '/deployments/mock-deployment', request.uri) + return request + + +class AccessTokenReplacer(RecordingProcessor): + """Replace the access token for service principal authentication in a response body.""" + + def __init__(self, replacement='fake_token'): + self._replacement = replacement + + def process_response(self, response): + import json + try: + body = json.loads(response['body']['string']) + body['access_token'] = self._replacement + except (KeyError, ValueError): + return response + response['body']['string'] = json.dumps(body) + return response + + +class GeneralNameReplacer(RecordingProcessor): + def __init__(self): + self.names_name = [] + + def register_name_pair(self, old, new): + self.names_name.append((old, new)) + + def process_request(self, request): + for old, new in self.names_name: + request.uri = request.uri.replace(old, new) + + if is_text_payload(request) and request.body: + body = str(request.body) + if old in body: + request.body = body.replace(old, new) + + return request + + def process_response(self, response): + for old, new in self.names_name: + if is_text_payload(response) and response['body']['string']: + response['body']['string'] = response['body']['string'].replace(old, new) + + self.replace_header(response, 'location', old, new) + self.replace_header(response, 'azure-asyncoperation', old, new) + + return response + + +class RequestUrlNormalizer(RecordingProcessor): + """URL parsing fix to account for '//' vs '/' in different versions of python""" + + def process_request(self, request): + import re + request.uri = re.sub('(? length: + raise ValueError('The length of the prefix must not be longer than random name length') + + padding_size = length - len(prefix) + if padding_size < 4: + raise ValueError('The randomized part of the name is shorter than 4, which may not be able to offer enough ' + 'randomness') + + random_bytes = os.urandom(int(math.ceil(float(padding_size) / 8) * 5)) + random_padding = base64.b32encode(random_bytes)[:padding_size] + + return str(prefix + random_padding.decode().lower()) + + +def get_sha1_hash(file_path): + sha1 = hashlib.sha256() + with open(file_path, 'rb') as f: + while True: + data = f.read(65536) + if not data: + break + sha1.update(data) + + return sha1.hexdigest() + + +def _get_content_type(entity): + # 'headers' is a field of 'request', but it is a dict-key in 'response' + headers = getattr(entity, 'headers', None) + if headers is None: + headers = entity.get('headers') + + content_type = None + if headers: + content_type = headers.get('content-type', None) + if content_type: + # content-type could an array from response, let us extract it out + content_type = content_type[0] if isinstance(content_type, list) else content_type + content_type = content_type.split(";")[0].lower() + return content_type + + +def is_text_payload(entity): + text_content_list = ['application/json', 'application/xml', 'text/', 'application/test-content'] + + content_type = _get_content_type(entity) + if content_type: + return any(content_type.startswith(x) for x in text_content_list) + return True + + +def is_json_payload(entity): + return _get_content_type(entity) == 'application/json' + + +def trim_kwargs_from_test_function(fn, kwargs): + # the next function is the actual test function. the kwargs need to be trimmed so + # that parameters which are not required will not be passed to it. + if not is_preparer_func(fn): + args, _, kw, _ = inspect.getargspec(fn) # pylint: disable=deprecated-method + if kw is None: + args = set(args) + for key in [k for k in kwargs if k not in args]: + del kwargs[key] + + +def is_preparer_func(fn): + return getattr(fn, '__is_preparer', False) diff --git a/tools/azure-sdk-tools/dev_requirements.txt b/tools/azure-sdk-tools/dev_requirements.txt new file mode 100644 index 000000000000..252afe5ae37a --- /dev/null +++ b/tools/azure-sdk-tools/dev_requirements.txt @@ -0,0 +1 @@ +-e ../azure-devtools \ No newline at end of file