pax_global_header 0000666 0000000 0000000 00000000064 13456152267 0014525 g ustar 00root root 0000000 0000000 52 comment=f3c1f5ccd9dacb56693bd8737b0e16d886ab65e0
pamqp-2.3.0/ 0000775 0000000 0000000 00000000000 13456152267 0012645 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/.checkignore 0000664 0000000 0000000 00000000042 13456152267 0015123 0 ustar 00root root 0000000 0000000 tests
docs
codegen
tools
setup.py
pamqp-2.3.0/.codeclimate.yml 0000664 0000000 0000000 00000000202 13456152267 0015711 0 ustar 00root root 0000000 0000000 languages:
Python: true
exclude_paths:
- codegen/*
- docs/*
- pamqp/specification.py
- tests/*
- tools/*
pamqp-2.3.0/.gitignore 0000664 0000000 0000000 00000000315 13456152267 0014634 0 ustar 00root root 0000000 0000000 .idea
.vscode
codegen/amqp-rabbitmq-0.9.1.json
codegen/amqp0-9-1.xml
*.pyc
build
dist
docs/_build
atlassian-ide-plugin.xml
.DS_Store
pamqp.egg-info
env
env2.7
env3
.coverage
coverage.xml
xunit.xml
coverage pamqp-2.3.0/.travis.yml 0000664 0000000 0000000 00000002656 13456152267 0014767 0 ustar 00root root 0000000 0000000 language: python
dist: xenial
python:
- 2.7
- 3.4
- 3.5
- 3.6
- 3.7
env:
global:
- PATH=$HOME/.local/bin:$PATH
- AWS_DEFAULT_REGION=us-east-1
- secure: "H1xbz9QUvgoNtDvY9K72YvUkGGVWiq5qL2IZDfG1y7scIKdUMZqvj2s/aB/UCw95POc1/SSo1vf5rtpvz7D4TTo+YW9y9ZLuHxetbGPnkql+lu/+HTpPJcr91pg4fEz4txhnAlJ+cdp3bITOvbuKYoUZ+toxiTf3wouETBikfGo="
- secure: "JZRJyA7fGSHjEx8nIyCzhD9KLWbu4h1R5A+VLDuFN0FjCjALKjJxaIUwT8/xHT97FXbqTbN+xvFyWnKerVpGX1peNGifralm3tMl63QXdATaprsmENmM3fYRWYGqWhy+6a21hrxFZ+MdblFKWsFWq/TNbsLWYM3vahvZDe1eyck="
stages:
- test
- name: upload coverage
if: repo = gmr/pamqp
- name: deploy
if: tag IS present
install:
- pip install -r requirements.txt
- pip install awscli
script:
- nosetests
- flake8
after_success: bin/upload-coverage.sh
jobs:
include:
- stage: upload coverage
if: repo = gmr/pamqp
python: 3.6
install:
- pip install awscli coverage codecov
script: bin/combine-coverage.sh
after_success: codecov
- stage: deploy
python: 3.6
install: true
script: true
after_success: true
deploy:
distributions: sdist bdist_wheel
provider: pypi
user: crad
on:
tags: true
password:
secure: "HW5Ak3scfeQ1/qdXQYrmIVnpGex59qNSGN2WRoHSFMXLfsjzdBQccy2nxWAo7p6P1wgoZ/51lTamJXGKgVqqQGC3gfBiD+AVMu3CROQht+Q4x5xKKLXQtTBoEOpurnx7q0oXRxhK7qmMOek9qqn/GGrK5PJV+pGoPwCvSTF6aic="
pamqp-2.3.0/CONTRIBUTING.md 0000664 0000000 0000000 00000000676 13456152267 0015107 0 ustar 00root root 0000000 0000000 # Contributing
To get setup in the environment and run the tests, take the following steps:
```bash
virtualenv -p python3 env
source env/bin/activate
pip install -r requirements.txt
nosetests
flake8
```
Please format your code contributions with the ``yapf`` formatter:
```bash
yapf -i --style=pep8 pamqp
```
## Test Coverage
Pull requests that make changes or additions that are not covered by tests
will likely be closed without review.
pamqp-2.3.0/LICENSE 0000664 0000000 0000000 00000002721 13456152267 0013654 0 ustar 00root root 0000000 0000000 Copyright (c) 2011-2015 Gavin M. Roy
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the paqmp nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pamqp-2.3.0/MANIFEST.in 0000664 0000000 0000000 00000000043 13456152267 0014400 0 ustar 00root root 0000000 0000000 include README.rst
include LICENSE
pamqp-2.3.0/README.rst 0000664 0000000 0000000 00000001740 13456152267 0014336 0 ustar 00root root 0000000 0000000 pamqp
=====
pamqp is a pure-python AMQP 0-9-1 frame encoder and decoder. The aim is to create a
client agnostic python encoder and decoder for general purpose use.
|Version| |Status| |Coverage| |License|
Documentation
-------------
http://pamqp.readthedocs.org
License
-------
BSD
Python Versions Supported
-------------------------
2.7, 3.4+
Roadmap
-------
pamqp 3.0 will drop support for Python 2.7 and will be released after January 1st, 2020.
Requirements
------------
codegen (not required for use) requires lxml.
.. |Version| image:: https://img.shields.io/pypi/v/pamqp.svg?
:target: https://pypi.python.org/pypi/pamqp
.. |Status| image:: https://img.shields.io/travis/gmr/pamqp.svg?
:target: https://travis-ci.org/gmr/pamqp
.. |Coverage| image:: https://img.shields.io/codecov/c/github/gmr/pamqp.svg?
:target: https://codecov.io/github/gmr/pamqp?branch=master
.. |License| image:: https://img.shields.io/pypi/l/pamqp.svg?
:target: https://pamqp.readthedocs.org
pamqp-2.3.0/bin/ 0000775 0000000 0000000 00000000000 13456152267 0013415 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/bin/combine-coverage.sh 0000775 0000000 0000000 00000000301 13456152267 0017153 0 ustar 00root root 0000000 0000000 #!/usr/bin/env sh
mkdir coverage
aws s3 cp --recursive s3://com-gavinroy-travis/pamqp/${TRAVIS_BUILD_NUMBER}/ coverage
cd coverage
coverage combine
cd ..
mv coverage/.coverage .
coverage report pamqp-2.3.0/bin/upload-coverage.sh 0000775 0000000 0000000 00000000367 13456152267 0017037 0 ustar 00root root 0000000 0000000 #!/usr/bin/env sh
if [ "${TRAVIS_REPO_SLUG}" = "gmr/pamqp" ];
then
echo "Uploading coverage for ${TRAVIS_PYTHON_VERSION} to S3"
aws s3 cp .coverage "s3://com-gavinroy-travis/pamqp/$TRAVIS_BUILD_NUMBER/.coverage.${TRAVIS_PYTHON_VERSION}"
fi pamqp-2.3.0/codegen/ 0000775 0000000 0000000 00000000000 13456152267 0014251 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/codegen/extensions.xml 0000664 0000000 0000000 00000006170 13456152267 0017176 0 ustar 00root root 0000000 0000000
This method signals to the client that the connection is blocked by RabbitMQ.
This method signals to the client that the connection is no longer blocked by RabbitMQ.
do not send a reply method
If set, the server will not respond to the method. The client
should not wait for a reply method. If the server could not
complete the method it will raise a channel or connection exception.
Deprecated value that must be zero.
Deprecated value that must be empty.
Deprecated value that must be False.
Used when negotiating a connection on an out-of-band channel. Do
not use, must be zero.
Deprecated value that must be False.
Deprecated value that must be zero.
If set, the queue is deleted when all consumers have finished using
it. The last consumer can be cancelled either explicitly or because
its channel is closed. If there was no consumer ever on the queue,
it won't be deleted. Applications can explicitly delete auto-delete
queues using the Delete method as normal.
Deprecated value that must be zero.
Deprecated value that must be zero.
pamqp-2.3.0/codegen/include.py 0000664 0000000 0000000 00000016213 13456152267 0016251 0 ustar 00root root 0000000 0000000
class Frame(object):
"""Base Class for AMQP Methods which specifies the encoding and decoding
behavior.
"""
__slots__ = []
frame_id = 0
index = 0
name = 'Frame'
synchronous = False
valid_responses = []
def __iter__(self):
"""Iterate the attributes and values as key, value pairs.
:rtype: tuple
"""
for attribute in self.__slots__:
yield (attribute, getattr(self, attribute))
def __contains__(self, item):
"""Return if the item is in the attribute list.
:rtype: bool
"""
return item in self.__slots__
def __getitem__(self, item):
"""Return an attribute as if it were a dict.
:param str item: The item to look for
:raises: KeyError
:rtype: any
"""
return getattr(self, item)
def __len__(self):
"""Return the length of the attribute list.
:rtype: int
"""
return len(self.__slots__)
def __repr__(self):
"""Return the representation of the frame object
:return: str
"""
return '<%s.%s object at %s>' % (__name__, self.name, hex(id(self)))
@classmethod
def type(cls, attr):
"""Return the data type for an attribute.
:rtype: str
"""
return getattr(cls, '_' + attr)
def marshal(self):
"""
Dynamically encode the frame by taking the list of attributes and
encode them item by item getting the value form the object attribute
and the data type from the class attribute.
:rtype: str
"""
output = []
processing_bitset = False
byte = None
offset = 0
for argument in self.__slots__:
data_type = self.type(argument)
# Check if we need to turn on bit processing
if not processing_bitset and data_type == 'bit':
byte = 0
offset = 0
processing_bitset = True
# Get the data value
data_value = getattr(self, argument)
# If we're processing a bitset, apply special rules
if processing_bitset:
# Is this value not a bit? turn off bitset processing and
# append the byte value as an octet
if data_type != 'bit':
processing_bitset = False
output.append(encode.octet(byte))
else:
# Apply the bit value to the byte
byte = encode.bit(data_value, byte, offset)
offset += 1
if offset == 8:
# We've filled a byte for all bits, add the byte
output.append(encode.octet(byte))
# Turn off processing, we'll turn on in next iteration
# if needed
processing_bitset = False
# Go to the next iteration
continue
# Not a bit, so just process by type
output.append(encode.by_type(data_value, data_type))
# Append the last byte if we're processing a bitset
if processing_bitset:
output.append(encode.octet(byte))
return b''.join(output)
def unmarshal(self, data):
"""
Dynamically decode the frame data applying the values to the method
object by iterating through the attributes in order and decoding them.
:param str data: The binary encoded method data
"""
offset = 0
processing_bitset = False
for argument in self.__slots__:
data_type = self.type(argument)
if offset == 7 and processing_bitset:
data = data[1:]
offset = 0
if processing_bitset and data_type != 'bit':
offset = 0
processing_bitset = False
data = data[1:]
consumed, value = decode.by_type(data, data_type, offset)
if data_type == 'bit':
offset += 1
processing_bitset = True
consumed = 0
setattr(self, argument, value)
if consumed:
data = data[consumed:]
class PropertiesBase(object):
"""Provide a base object that marshals and unmarshals the Basic.Properties
object values.
"""
__slots__ = []
flags = {}
name = 'PropertiesBase'
def __contains__(self, item):
return item in self.__slots__
def __delattr__(self, item):
setattr(self, item, None)
def __iter__(self):
"""Iterate the attributes and values as key, value pairs.
:rtype: tuple
"""
for attribute in self.__slots__:
yield (attribute, getattr(self, attribute))
@classmethod
def attributes(cls):
"""Return the list of attributes
:rtype: list
"""
return [attr for attr in cls.__slots__]
@classmethod
def type(cls, attr):
"""Return the data type for an attribute.
:rtype: str
"""
return getattr(cls, '_' + attr)
def encode_property(self, property_name, property_value):
"""Encode a single property value
:param str property_name: The property name to encode
:param any property_value: The value to encode
"""
return encode.by_type(property_value, self.type(property_name))
def marshal(self):
"""Take the Basic.Properties data structure and marshal it into the
data structure needed for the ContentHeader.
:rtype: bytes
"""
flags = 0
parts = []
for property_name in self.__slots__:
property_value = getattr(self, property_name)
if property_value is not None and property_value != '':
flags = flags | self.flags[property_name]
parts.append(self.encode_property(property_name,
property_value))
flag_pieces = []
while True:
remainder = flags >> 16
partial_flags = flags & 0xFFFE
if remainder != 0:
partial_flags |= 1
flag_pieces.append(struct.pack('>H', partial_flags))
flags = remainder
if not flags:
break
return b''.join(flag_pieces + parts)
def to_dict(self):
"""Return the properties as a dict
:rtype: dict
"""
return dict(self)
def unmarshal(self, flags, data):
"""
Dynamically decode the frame data applying the values to the method
object by iterating through the attributes in order and decoding them.
:param int flags: Flags that indicate if the data has the property
:param bytes data: The binary encoded method data
"""
for property_name in self.__slots__:
if flags & self.flags[property_name]:
data_type = getattr(self.__class__, '_' + property_name)
consumed, value = decode.by_type(data, data_type)
setattr(self, property_name, value)
data = data[consumed:]
pamqp-2.3.0/docs/ 0000775 0000000 0000000 00000000000 13456152267 0013575 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/docs/Makefile 0000664 0000000 0000000 00000012670 13456152267 0015243 0 ustar 00root root 0000000 0000000 # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pamqp.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pamqp.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/pamqp"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pamqp"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
pamqp-2.3.0/docs/body.rst 0000664 0000000 0000000 00000000077 13456152267 0015270 0 ustar 00root root 0000000 0000000 pamqp.body
==========
.. automodule:: pamqp.body
:members:
pamqp-2.3.0/docs/conf.py 0000664 0000000 0000000 00000017225 13456152267 0015103 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# pamqp documentation build configuration file, created by
# sphinx-quickstart on Wed Mar 27 13:26:28 2013.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
sys.path.insert(0, '../')
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode',
'sphinx.ext.autosummary']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'pamqp'
copyright = u'2011 - 2014, Gavin M. Roy'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
import pamqp
release = pamqp.__version__
version = '.'.join(release.split('.')[0:1])
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'pamqpdoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'pamqp.tex', u'pamqp Documentation',
u'Gavin M. Roy', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'pamqp', u'pamqp Documentation',
[u'Gavin M. Roy'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'pamqp', u'pamqp Documentation',
u'Gavin M. Roy', 'pamqp', 'AMQP Frame Encoding and Decoding Library.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
pamqp-2.3.0/docs/decode.rst 0000664 0000000 0000000 00000000105 13456152267 0015546 0 ustar 00root root 0000000 0000000 pamqp.decode
============
.. automodule:: pamqp.decode
:members:
pamqp-2.3.0/docs/encode.rst 0000664 0000000 0000000 00000000105 13456152267 0015560 0 ustar 00root root 0000000 0000000 pamqp.encode
============
.. automodule:: pamqp.encode
:members:
pamqp-2.3.0/docs/frame.rst 0000664 0000000 0000000 00000000102 13456152267 0015412 0 ustar 00root root 0000000 0000000 pamqp.frame
===========
.. automodule:: pamqp.frame
:members:
pamqp-2.3.0/docs/header.rst 0000664 0000000 0000000 00000000105 13456152267 0015553 0 ustar 00root root 0000000 0000000 pamqp.header
============
.. automodule:: pamqp.header
:members:
pamqp-2.3.0/docs/heartbeat.rst 0000664 0000000 0000000 00000000116 13456152267 0016264 0 ustar 00root root 0000000 0000000 pamqp.heartbeat
===============
.. automodule:: pamqp.heartbeat
:members:
pamqp-2.3.0/docs/history.rst 0000664 0000000 0000000 00000013111 13456152267 0016025 0 ustar 00root root 0000000 0000000 Version History
===============
2.3.0 (2019-04-18)
------------------
- Add :py:func:`pamqp.encode.support_deprecated_rabbitmq` function to limit data types available when encoding field-tables for older RabbitMQ versions.
2.2.0 (2019-04-18)
------------------
- Change :py:meth:`pamqp.encode.timestamp` to allow for numeric/epoch timestamps (#14 - `mosquito `_)
- Change :py:meth:`pamqp.frame.frame_parts` to a public method (#15 - `mosquito `_)
- Cleanup of code to pass configured flake8 tests
- Add support for 8-bit unsigned integer values in :py:meth:`pamqp.encode.table_integer`
2.1.0 (2018-12-28)
------------------
- Change raising a DeprecationWarning exception to using warnings.warn for deprecated AMQP methods (#13 - `dzen `_)
2.0.0 (2018-09-11)
------------------
- **Change Python versions supported to 2.7 and 3.4+**
- **Always decode field table keys as strings (#6)**
- This may be a breaking change means in Python3 keys will always be type str for short strings. This includes frame
values and field table values.
- In Python 2.7 if a short-string (key, frame field value, etc) has UTF-8 characters in it, it will be a `unicode` object.
- Combine test coverage across all Python versions
- Fix range for signed short integer (#7)
- Fix guards for usage of unsigned short usage in `pamqp.encode` (#7)
- Fix encoding and decoding of unsigned short (#7)
- Add support for unsigned short integer and long integer in field tables (#10)
- Address edge case of small value in long type (#8)
- Address long string encoding inconsistency (#9)
- Cleanup unicode object & conditionals in py3 (#9)
- Add `pamqp.exceptions.PAMQPException` as a base class for pamqp specific exceptions (#4)
- Fix decoding of void values in a field table or array
1.6.1 (2015-02-05)
------------------
- Fix the encoding guard for unsigned short integers to be 65535 [rabbitpy #62]
1.6.0 (2014-12-12)
------------------
- Remove UTF-8 encoding from byte_array (#2)
- Fix AMQP Field Tables / `Basic.Properties` headers behavior:
- Field names per spec should not exceed 128 bytes
- long-strings should not be utf-8 encoded (only short-strings *boggle*)
- Ensure that field table long strings are not coerced to UTF-8 as specified in AMQP 0-9-1
If a string is passed in as a long string in a field table and it contains UTF-8 characters it will be UTF-8 encoded
- Move AMQP Methods in specification.py to slotted classes
- Change `Basic.Properties` to a slotted class
- Instead of class level attributes with the same name as obj attributes, prefix class attributes for data types with an underscore
- Add new class method type() for `Basic.Properties` for accessing data type
- Add new class method type() for AMQP methods for accessing data type
- Change `Basic.Properties.attributes` to `Basic.Properties.attributes()`, returning the list of slotted attributes
- Fix a typo for booleans in the method mapping for table decoding
- `Frame.__getitem__` will now raise a KeyError instead of None for an invalid attribute
- `PropertiesBase` no longer checks to see if an attribute is set for contains
- Adds new specification tests
- More efficiently handle the frame end character in Python 3
1.5.0 (2014-11-05)
------------------
- Cleanup how UTF-8 is handled in decoding strings
- Ensure that field tables (headers property, etc) can use keys with utf-8 data
- Address missing and mis-aligned AMQP-0-9-1 field table decoding with the field type indicators from the RabbitMQ protocol errata page
- Fix a encoding by type bug introduced with 1.4 having to do with bytearrays
- Be explicit about needing a class id in the ContentHeader
- Update the tests to reflect the unicode changes
- Clean up the tests
1.4.0 (2014-11-04)
------------------
- Fix a long standing bug for non-specified responses for RabbitMQ AMQP extensions
- Refactor adding bytearrays and recoding complexity
- Add bytearray support (#1 and gmr/rabbitpy#48)
- Change encode/decode type errors from ValueError to TypeError exceptions
- Remove separate codecs for Python 2 & 3
- Move codecs from `pamqp.codec.encode` and `pamqp.codec.decode` to `pamqp.encode` and `pamqp.decode`
- Deprecate pamqp.codec
- Remove weird imports from top level __init__.py, not sure what I was thinking there
- Clean up codegen a bit to make it more PYTHON3 compatible
- Update codegen/include for new codec and PYTHON2/PYTHON3 behavior
- Update documentation
- Distribution updates:
- Let travis upload to pypi
- Add wheel distribution
- Update supported python versions
- Update classifiers
1.3.1 (2014-02-14)
------------------
- Fix encoding of long-long-integers
1.3.0 (2014-01-17)
------------------
- Remove support for short strings in field tables
1.2.4 (2013-12-22)
------------------
- Add short-short-int support
1.2.3 (2013-12-22)
------------------
- Fix distribution requirements
1.2.2 (2013-12-22)
------------------
- Add decimal data type support
1.2.1 (2013-07-29)
------------------
- Fix Confirm.Select definition
1.2.0 (2013-07-08)
------------------
- Add support for Connection.Blocked, Connection.Unblocked
- Add documentation to specification.py in the codegen process
1.1.3 (2013-03-27)
------------------
- Fix exception creation
1.1.2 (2013-03-27)
------------------
- Add Confirm.Select, Confirm.SelectOk
1.1.1 (2013-03-22)
------------------
- Remove debugging print statements (eek)
1.1.0 (2013-03-21)
------------------
- Add Python 3.3 support
1.0.1 (2012-10-02)
------------------
- Address Unicode issues
- Add void support in table arrays
1.0.0 (2012-09-24)
------------------
- Initial version
pamqp-2.3.0/docs/index.rst 0000664 0000000 0000000 00000002414 13456152267 0015437 0 ustar 00root root 0000000 0000000 pamqp
=====
pamqp is a low level AMQP 0-9-1 frame encoding and decoding library for Python 2 & 3
released under the BSD license.
pamqp is not a end-user client library for talking to RabbitMQ but rather is used
by client libraries for marshaling and unmarshaling AMQP frames. All methods should
have test coverage and pass in Python 2.7, and 3.4 - 3.7.
AMQP class/method command class mappings can be found in the :py:mod:`pamqp.specification`
module while actual frame encoding and encoding should be run through the :py:mod:`pamqp.frame`
module.
Issues
------
Please report any issues to the Github repo at `https://github.com/gmr/pamqp/issues `_
Source
------
pamqp source is available on Github at `https://github.com/gmr/pamqp `_
Installation
------------
pamqp is available from the `Python Package Index `_ but should generally be installed as a dependency from a client library.
pamqp module documentation
--------------------------
.. toctree::
:maxdepth: 2
body
decode
encode
frame
header
heartbeat
specification
Version History
---------------
See :doc:`history`
Indices and tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
pamqp-2.3.0/docs/specification.rst 0000664 0000000 0000000 00000001714 13456152267 0017152 0 ustar 00root root 0000000 0000000 pamqp.specification
===================
The :py:mod:`pamqp.specification` module is auto-generated, created by the ``tools/codegen.py`` application. It contains all of the information about the protocol that is required for a client library to communicate with RabbitMQ or another AMQP 0-9-1 broker.
The classes inside :py:mod:`pamqp.specification` allow for the automatic marshaling and unmarshaling of AMQP method frames and Basic.Properties. In addition the command classes contain information that designates if they are synchronous commands and if so, what the expected responses are. Each commands arguments are detailed in the class and are listed in the attributes property.
:py:mod:`pamqp.specification` also implements AMQP exceptions as Python exceptions so that client libraries can raise these exceptions as is appropriate without having to implement their own extensions for AMQP protocol related issues.
.. automodule:: pamqp.specification
:members:
pamqp-2.3.0/pamqp/ 0000775 0000000 0000000 00000000000 13456152267 0013763 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/pamqp/__init__.py 0000664 0000000 0000000 00000000664 13456152267 0016102 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""AMQP Specifications and Classes"""
from pamqp.constants import PYTHON3
from pamqp.header import ContentHeader, ProtocolHeader
__author__ = 'Gavin M. Roy'
__email__ = 'gavinmroy@gmail.com'
__since__ = '2011-09-23'
__version__ = '2.3.0'
__all__ = [
'body', 'constants', 'decode', 'encode', 'exceptions', 'frame', 'header',
'heartbeat', 'specification', 'PYTHON3', 'ContentHeader', 'ProtocolHeader'
]
pamqp-2.3.0/pamqp/body.py 0000664 0000000 0000000 00000002425 13456152267 0015275 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""
The pamqp.body module contains the Body class which is used when
unmarshaling body frames. When dealing with content frames, the message body
will be returned from the library as an instance of the body class.
"""
class ContentBody(object):
"""ContentBody carries the value for an AMQP message body frame"""
name = 'ContentBody'
def __init__(self, value=None):
"""Create a new instance of a ContentBody object, passing in the value
of the message body
:param str|unicode|bytes value: The content body
"""
self.value = value
def __len__(self):
"""Return the length of the content body value
:rtype: int
"""
return len(self.value)
def marshal(self):
"""Return the marshaled content body. This method is here for API
compatibility, there is no special marhsaling for the payload in a
content frame.
:rtype: str|unicode|bytes
"""
return self.value
def unmarshal(self, data):
"""Apply the data to the object. This method is here for API
compatibility, there is no special unmarhsaling for the payload in a
content frame.
:rtype: str|unicode|bytes
"""
self.value = data
pamqp-2.3.0/pamqp/codec/ 0000775 0000000 0000000 00000000000 13456152267 0015040 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/pamqp/codec/__init__.py 0000664 0000000 0000000 00000000343 13456152267 0017151 0 ustar 00root root 0000000 0000000 """
Deprecating the codec subpackage
"""
import warnings
from pamqp import decode, encode
warnings.warn('Imports for decode/encode are no longer under codec',
DeprecationWarning)
__all__ = ['decode', 'encode']
pamqp-2.3.0/pamqp/constants.py 0000664 0000000 0000000 00000000237 13456152267 0016353 0 ustar 00root root 0000000 0000000 """
Common Constants
"""
import sys
# Keep a constant that indicates if Python 3 support is needed
PYTHON3 = True if sys.version_info > (3, 0, 0) else False
pamqp-2.3.0/pamqp/decode.py 0000664 0000000 0000000 00000026060 13456152267 0015564 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""
AMQP Data Decoder
=================
Functions for decoding data of various types including field tables and arrays
"""
import decimal as _decimal
import struct
import time
from pamqp import PYTHON3
class Struct(object):
"""Simple object for getting to the struct objects"""
byte = struct.Struct('B')
double = struct.Struct('>d')
float = struct.Struct('>f')
integer = struct.Struct('>I')
ulong = struct.Struct('>L')
long = struct.Struct('>l')
ushort = struct.Struct('>H')
short = struct.Struct('>h')
short_short = struct.Struct('>B')
timestamp = struct.Struct('>Q')
def bit(value, position):
"""Decode a bit value
:param bytes value: Value to decode
:param int position: The bit position to retrieve
:return tuple: bytes used, bool value
:raises: ValueError
"""
bit_buffer = Struct.byte.unpack_from(value)[0]
try:
return 0, (bit_buffer & (1 << position)) != 0
except TypeError:
raise ValueError('Could not unpack data')
def boolean(value):
"""Decode a boolean value
:param bytes value: Value to decode
:return tuple: bytes used, bool
:raises: ValueError
"""
try:
return 1, bool(Struct.byte.unpack_from(value[0:1])[0])
except TypeError:
raise ValueError('Could not unpack data')
def byte_array(value):
"""Decode a byte_array value
:param bytes value: Value to decode
:return tuple: bytes used, bool
:raises: ValueError
"""
try:
length = Struct.integer.unpack(value[0:4])[0]
return length + 4, bytearray(value[4:length + 4])
except TypeError:
raise ValueError('Could not unpack data')
def decimal(value):
"""Decode a decimal value
:param bytes value: Value to decode
:return tuple: bytes used, decimal.Decimal value
:raises: ValueError
"""
try:
decimals = Struct.byte.unpack(value[0:1])[0]
raw = Struct.integer.unpack(value[1:5])[0]
return 5, _decimal.Decimal(raw) * (_decimal.Decimal(10)**-decimals)
except TypeError:
raise ValueError('Could not unpack data')
def double(value):
"""Decode a double value
:param bytes value: Value to decode
:return tuple: bytes used, float
:raises: ValueError
"""
try:
return 8, Struct.double.unpack_from(value)[0]
except TypeError:
raise ValueError('Could not unpack data')
def floating_point(value):
"""Decode a floating point value
:param bytes value: Value to decode
:return tuple: bytes used, float
:raises: ValueError
"""
try:
return 4, Struct.float.unpack_from(value)[0]
except TypeError:
raise ValueError('Could not unpack data')
def long_int(value):
"""Decode a long integer value
:param bytes value: Value to decode
:return tuple: bytes used, int
:raises: ValueError
"""
try:
return 4, Struct.long.unpack(value[0:4])[0]
except TypeError:
raise ValueError('Could not unpack data')
def long_uint(value):
"""Decode an unsigned long integer value
:param bytes value: Value to decode
:return tuple: bytes used, int
:raises: ValueError
"""
try:
return 4, Struct.ulong.unpack(value[0:4])[0]
except TypeError:
raise ValueError('Could not unpack data')
def long_long_int(value):
"""Decode a long-long integer value
:param bytes value: Value to decode
:return tuple: bytes used, int
:raises: ValueError
"""
try:
return 8, struct.unpack('>q', value[0:8])[0]
except TypeError:
raise ValueError('Could not unpack data')
def long_str(value):
"""Decode a string value
:param bytes value: Value to decode
:return tuple: bytes used, bytes|str
:raises: ValueError
"""
try:
length = Struct.integer.unpack(value[0:4])[0]
return length + 4, value[4:length + 4]
except TypeError:
raise ValueError('Could not unpack data')
def octet(value):
"""Decode an octet value
:param bytes value: Value to decode
:return tuple: bytes used, int
:raises: ValueError
"""
try:
return 1, Struct.byte.unpack(value[0:1])[0]
except TypeError:
raise ValueError('Could not unpack data')
def short_int(value):
"""Decode a short integer value
:param bytes value: Value to decode
:return tuple: bytes used, int
:raises: ValueError
"""
try:
return 2, Struct.short.unpack_from(value[0:2])[0]
except TypeError:
raise ValueError('Could not unpack data')
def short_uint(value):
"""Decode an unsigned short integer value
:param bytes value: Value to decode
:return tuple: bytes used, int
:raises: ValueError
"""
try:
return 2, Struct.ushort.unpack_from(value[0:2])[0]
except TypeError:
raise ValueError('Could not unpack data')
def short_short_int(value):
"""Decode a short, short integer value
:param bytes value: Value to decode
:return tuple: bytes used, int
:raises: ValueError
"""
try:
return 1, Struct.short_short.unpack_from(value[0:1])[0]
except TypeError:
raise ValueError('Could not unpack data')
def short_str(value):
"""Decode a string value
:param bytes value: Value to decode
:return tuple: bytes used, unicode|str
:raises: ValueError
"""
try:
length = Struct.byte.unpack(value[0:1])[0]
return length + 1, _to_str(value[1:length + 1])
except TypeError:
raise ValueError('Could not unpack data')
def timestamp(value):
"""Decode a timestamp value
:param bytes value: Value to decode
:return tuple: bytes used, struct_time
:raises: ValueError
"""
try:
value = Struct.timestamp.unpack(value[0:8])
return 8, time.gmtime(value[0])
except TypeError:
raise ValueError('Could not unpack data')
def field_array(value):
"""Decode a field array value
:param bytes value: Value to decode
:return tuple: bytes used, list
:raises: ValueError
"""
try:
length = Struct.integer.unpack(value[0:4])[0]
offset = 4
data = []
field_array_end = offset + length
while offset < field_array_end:
consumed, result = _embedded_value(value[offset:])
offset += consumed
data.append(result)
return offset, data
except TypeError:
raise ValueError('Could not unpack data')
def field_table(value):
"""Decode a field array value
:param bytes value: Value to decode
:return tuple: bytes used, dict
:raises: ValueError
"""
try:
length = Struct.integer.unpack(value[0:4])[0]
offset = 4
data = {}
field_table_end = offset + length
while offset < field_table_end:
key_length = Struct.byte.unpack_from(value, offset)[0]
offset += 1
key = _to_str(value[offset:offset + key_length])
offset += key_length
consumed, result = _embedded_value(value[offset:])
offset += consumed
data[key] = result
return field_table_end, data
except TypeError:
raise ValueError('Could not unpack data')
def _embedded_value(value):
"""Takes in a value looking at the first byte to determine which decoder to
use
:param bytes value: Value to decode
:return tuple: bytes consumed, mixed
"""
if not value:
return 0, None
# Determine the field type and encode it
if value[0:1] == b't':
bytes_consumed, value = boolean(value[1:])
elif value[0:1] == b'b':
bytes_consumed, value = short_short_int(value[1:])
elif value[0:1] == b's':
bytes_consumed, value = short_int(value[1:])
elif value[0:1] == b'u':
bytes_consumed, value = short_uint(value[1:])
elif value[0:1] == b'I':
bytes_consumed, value = long_int(value[1:])
elif value[0:1] == b'i':
bytes_consumed, value = long_uint(value[1:])
elif value[0:1] == b'l':
bytes_consumed, value = long_long_int(value[1:])
elif value[0:1] == b'f':
bytes_consumed, value = floating_point(value[1:])
elif value[0:1] == b'd':
bytes_consumed, value = double(value[1:])
elif value[0:1] == b'D':
bytes_consumed, value = decimal(value[1:])
elif value[0:1] == b'S':
bytes_consumed, value = long_str(value[1:])
elif value[0:1] == b'A':
bytes_consumed, value = field_array(value[1:])
elif value[0:1] == b'T':
bytes_consumed, value = timestamp(value[1:])
elif value[0:1] == b'F':
bytes_consumed, value = field_table(value[1:])
elif value[0:1] == b'V':
bytes_consumed, value = 0, None
elif value[0:1] == b'x':
bytes_consumed, value = byte_array(value[1:])
elif value[0:1] == b'\x00':
return 0, None
else:
raise ValueError('Unknown type: {!r}'.format(value[:1]))
return bytes_consumed + 1, value
def by_type(value, data_type, offset=0):
"""Decodes values using the specified type
:param bytes value: Value to decode
:param str data_type: type of data to decode
:return tuple: bytes consumed, mixed based on field type
"""
# Determine the field type and encode it
data_type = str(data_type)
if data_type == 'array':
return field_array(value)
elif data_type == 'bit':
return bit(value, offset)
elif data_type == 'boolean':
return boolean(value)
elif data_type == 'byte_array':
return byte_array(value)
elif data_type == 'decimal':
return decimal(value)
elif data_type == 'double':
return double(value)
elif data_type == 'float':
return floating_point(value)
elif data_type == 'long':
return long_uint(value)
elif data_type == 'longlong':
return long_long_int(value)
elif data_type == 'longstr':
return long_str(value)
elif data_type == 'octet':
return octet(value)
elif data_type == 'short':
return short_uint(value)
elif data_type == 'shortstr':
return short_str(value)
elif data_type == 'table':
return field_table(value)
elif data_type == 'timestamp':
return timestamp(value)
elif data_type == 'void':
return None
raise ValueError('Unknown type: {}'.format(data_type))
def _to_str(value):
"""Ensure the field table keys are strings (unicode or otherwise)
:param bytes value: The value to try and decode to unicode
:rtype: unicode or str
"""
if PYTHON3:
return value.decode('utf-8')
try:
return str(value.decode('utf-8'))
except UnicodeEncodeError:
return value.decode('utf-8')
# Define a data type mapping to methods
METHODS = {
'array': field_array,
'bit': bit,
'boolean': boolean,
'byte_array': byte_array,
'decimal': decimal,
'double': double,
'float': floating_point,
'long': long_uint,
'longlong': long_long_int,
'longstr': long_str,
'octet': octet,
'short': short_uint,
'shortstr': short_str,
'table': field_table,
'timestamp': timestamp
}
pamqp-2.3.0/pamqp/encode.py 0000664 0000000 0000000 00000031473 13456152267 0015602 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""
AMQP Data Encoder
=================
Functions for encoding data of various types including field tables and arrays
"""
import calendar
import datetime
import decimal as _decimal
import logging
import struct
import time
from pamqp import PYTHON3
LOGGER = logging.getLogger(__name__)
if PYTHON3:
long = int
unicode = None # Dont throw exceptions as it is not defined
DEPRECATED_RABBITMQ_SUPPORT = False
"""Toggle to support older versions of RabbitMQ."""
def support_deprecated_rabbitmq():
"""Invoke to restrict the data types available in field-tables that are
sent to RabbitMQ.
"""
global DEPRECATED_RABBITMQ_SUPPORT
DEPRECATED_RABBITMQ_SUPPORT = True
def bit(value, byte, position):
"""Encode a bit value
:param int value: Value to decode
:param int byte: The byte to apply the value to
:param int position: The position in the byte to set the bit on
:rtype: tuple of bytes used and a bool value
"""
return byte | (value << position)
def boolean(value):
"""Encode a boolean value.
:param bool value: Value to encode
:rtype: bytes
"""
if not isinstance(value, bool):
raise TypeError('bool type required')
return struct.pack('>B', int(value))
def byte_array(value):
"""Encode a bytearray
:param bytearray value: Value to encode
:rtype: bytes
"""
if not isinstance(value, bytearray):
raise TypeError('bytearray type required')
elif PYTHON3:
return struct.pack('>I', len(value)) + value
return bytes(struct.pack('>I', len(value)) + value)
def decimal(value):
"""Encode a decimal.Decimal value.
:param decimal.Decimal value: Value to encode
:rtype: bytes
"""
if not isinstance(value, _decimal.Decimal):
raise TypeError('decimal.Decimal type required')
tmp = '%s' % value
if '.' in tmp:
decimals = len(tmp.split('.')[-1])
value = value.normalize()
raw = int(value * (_decimal.Decimal(10)**decimals))
return struct.pack('>Bi', decimals, raw)
return struct.pack('>Bi', 0, int(value))
def double(value):
"""Encode a floating point value as a double
:param float value: Value to encode
:rtype: str
"""
if not isinstance(value, float):
raise TypeError('float type required')
return struct.pack('>d', value)
def floating_point(value):
"""Encode a floating point value.
:param float value: Value to encode
:rtype: bytes
"""
if not isinstance(value, float):
raise TypeError('float type required')
return struct.pack('>f', value)
def long_int(value):
"""Encode a long integer.
:param int value: Value to encode
:rtype: bytes
"""
if PYTHON3 and not isinstance(value, int):
raise TypeError('int type required')
elif not isinstance(value, int) and not isinstance(value, long):
raise TypeError('long type required')
elif not (-2147483648 <= value <= 2147483647):
raise TypeError('Long integer range: -2147483648 to 2147483647')
return struct.pack('>l', value)
def long_uint(value):
"""Encode a long integer.
:param int value: Value to encode
:rtype: bytes
"""
if PYTHON3 and not isinstance(value, int):
raise TypeError('int type required')
elif not isinstance(value, int) and not isinstance(value, long):
raise TypeError('long type required')
elif not (0 <= value <= 4294967295):
raise TypeError('Long unsigned-integer range: 0 to 4294967295')
return struct.pack('>L', value)
def long_long_int(value):
"""Encode a long-long int.
:param long or int value: Value to encode
:rtype: bytes
"""
if PYTHON3 and not isinstance(value, int):
raise TypeError('int type required')
elif not isinstance(value, long) and not isinstance(value, int):
raise TypeError('int or long type required')
elif not (-9223372036854775808 <= value <= 9223372036854775807):
raise TypeError('long-long integer range: '
'-9223372036854775808 to 9223372036854775807')
return struct.pack('>q', value)
def long_string(value):
"""Encode a "long string" which the specific defines as any non-null
data. We will auto-convert str and unicode to bytes but ignore
bytes objects and place them opaquely.
:param value: Value to encode
:type value: bytes or str or unicode
:rtype: bytes
:raises: TypeError
"""
if PYTHON3 and not isinstance(value, (bytes, str)):
raise TypeError('bytes or str required')
elif not PYTHON3 and not isinstance(value, (bytes, str, unicode)):
raise TypeError('bytes, str or unicode required')
if not isinstance(value, bytes):
value = _utf8_encode(value)
return struct.pack('>I', len(value)) + value
def octet(value):
"""Encode an octet value.
:param value: Value to encode
:rtype: bytes
:raises: TypeError
"""
if not isinstance(value, int):
raise TypeError('int type required')
return struct.pack('B', value)
def short_int(value):
"""Encode a short integer.
:param int value: Value to encode
:rtype: bytes
:raises: TypeError
"""
if not isinstance(value, (int, long)):
raise TypeError('int or long type required')
elif not (-32768 <= value <= 32767):
raise TypeError('Short integer range: -32678 to 32767')
return struct.pack('>h', value)
def short_uint(value):
"""Encode an unsigned short integer.
:param int value: Value to encode
:rtype: bytes
:raises: TypeError
"""
if not isinstance(value, int):
raise TypeError('int type required')
elif not (0 <= value <= 65535):
raise TypeError('Short unsigned integer range: 0 to 65535')
return struct.pack('>H', value)
def short_string(value):
""" Encode a string.
:param value: Value to encode
:type value: bytes or str or unicode
:rtype: bytes
:raises: TypeError
"""
if PYTHON3 and not isinstance(value, (bytes, str)):
raise TypeError('bytes or str required')
elif not PYTHON3 and not isinstance(value, (bytes, str, unicode)):
raise TypeError('bytes, str or unicode required')
# Ensure that the value is utf-8 encoded if it's unicode
value = _utf8_encode(value)
return struct.pack('B', len(value)) + value
def timestamp(value):
"""Encode a datetime.datetime object or time.struct_time.
:param value: Value to encode
:type value: datetime.datetime, time.struct_time, integer
:rtype: bytes
:raises: TypeError
"""
if isinstance(value, datetime.datetime):
value = value.timetuple()
elif isinstance(value, int):
value = time.gmtime(value)
if isinstance(value, time.struct_time):
return struct.pack('>Q', calendar.timegm(value))
raise TypeError('datetime.datetime or time.struct_time type required')
def field_array(value):
"""Encode a field array from a dictionary.
:param list value: Value to encode
:rtype: bytes
:raises: TypeError
"""
if not isinstance(value, list):
raise TypeError('list type required')
data = []
for item in value:
data.append(encode_table_value(item))
output = b''.join(data)
return struct.pack('>I', len(output)) + output
def field_table(value):
"""Encode a field table from a dictionary.
:param dict or None value: Value to encode
:rtype: bytes
:raises: TypeError
"""
# If there is no value, return a standard 4 null bytes
if not value:
return struct.pack('>I', 0)
elif not isinstance(value, dict):
raise TypeError('dict type required, got {}'.format(type(value)))
# Iterate through all of the keys and encode the data into a table
data = []
for key, value in sorted(value.items()):
# UTF-8 encode the key since it behaves like a short-string
key = _utf8_encode(key)
# According to the spec, field names should be 128 char max
if len(key) > 128:
LOGGER.warning('Truncating key %s to 128 bytes', key)
key = key[0:128]
# Append the field header / delimiter
data.append(struct.pack('B', len(key)))
data.append(key)
try:
data.append(encode_table_value(value))
except TypeError as err:
raise TypeError('{} error: {}/'.format(key, err))
# Join all of the data together as a string
output = b''.join(data)
return struct.pack('>I', len(output)) + output
def table_integer(value):
"""Determines the best type of numeric type to encode value as, preferring
the smallest data size first.
:param int value: Value to encode
:rtype: bytes
:raises: TypeError
"""
if DEPRECATED_RABBITMQ_SUPPORT:
return _deprecated_table_integer(value)
# Send the appropriately sized data value
if 0 <= value <= 255:
return b'b' + octet(value)
elif -32768 <= value <= 32767:
return b's' + short_int(value)
elif 0 <= value <= 65535:
return b'u' + short_uint(value)
elif -2147483648 <= value <= 2147483647:
return b'I' + long_int(value)
elif 0 <= value <= 4294967295:
return b'i' + long_uint(value)
elif -9223372036854775808 <= value <= 9223372036854775807:
return b'l' + long_long_int(value)
raise TypeError('Unsupported numeric value: {}'.format(value))
def _deprecated_table_integer(value):
"""Determines the best type of numeric type to encode value as, preferring
the smallest data size first, supporting versions of RabbitMQ < 3.6
:param int value: Value to encode
:rtype: bytes
:raises: TypeError
"""
# Send the appropriately sized data value
if 0 <= value <= 255:
return b'b' + octet(value)
elif -32768 <= value <= 32767:
return b's' + short_int(value)
elif -2147483648 <= value <= 2147483647:
return b'I' + long_int(value)
elif -9223372036854775808 <= value <= 9223372036854775807:
return b'l' + long_long_int(value)
raise TypeError('Unsupported numeric value: {}'.format(value))
def encode_table_value(value):
"""Takes a value of any type and tries to encode it with the proper encoder
:param any value: Value to encode
:rtype: bytes
:raises: TypeError
"""
# Determine the field type and encode it
if isinstance(value, bool):
result = b't' + boolean(value)
elif isinstance(value, int) or isinstance(value, long):
result = table_integer(value)
elif isinstance(value, _decimal.Decimal):
result = b'D' + decimal(value)
elif isinstance(value, float):
result = b'f' + floating_point(value)
elif PYTHON3 and isinstance(value, (str, bytes)):
result = b'S' + long_string(value)
elif not PYTHON3 and isinstance(value, (str, bytes, unicode)):
result = b'S' + long_string(value)
elif (isinstance(value, datetime.datetime) or
isinstance(value, time.struct_time)):
result = b'T' + timestamp(value)
elif isinstance(value, dict):
result = b'F' + field_table(value)
elif isinstance(value, list):
result = b'A' + field_array(value)
elif isinstance(value, bytearray):
result = b'x' + byte_array(value)
elif value is None:
result = b'V'
else:
raise TypeError('Unknown type: {} ({!r})'.format(type(value), value))
# Return the encoded value
return result
def by_type(value, data_type):
"""Takes a value of any type and tries to encode it with the specified
encoder.
:param any value: Value to encode
:param str data_type: type of data to encode
:rtype: bytes
:raises: TypeError
"""
# Determine the field type and encode it
if data_type == 'field_array':
return field_array(value)
elif data_type == 'bytearray':
return byte_array(value)
elif data_type == 'double':
return double(value)
elif data_type == 'long':
return long_uint(value)
elif data_type == 'longlong':
return long_long_int(value)
elif data_type == 'longstr':
return long_string(value)
elif data_type == 'octet':
return octet(value)
elif data_type == 'short':
return short_uint(value)
elif data_type == 'shortstr':
return short_string(value)
elif data_type == 'table':
return field_table(value)
elif data_type == 'timestamp':
return timestamp(value)
elif data_type == 'void':
return None
raise TypeError('Unknown type: {}'.format(value))
def _utf8_encode(value):
"""Ensure that a string or unicode object is UTF-8 encoded.
:param value: The value to evaluate
:type value: str, bytes, or unicode
:rtype: bytes
"""
if PYTHON3 and isinstance(value, str):
return value.encode('utf-8')
elif not PYTHON3 and isinstance(value, unicode):
return value.encode('utf-8')
return value
pamqp-2.3.0/pamqp/exceptions.py 0000664 0000000 0000000 00000000715 13456152267 0016521 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""
pamqp specific exceptions that do not fit within the AMQP exceptions
contained in pamqp.specification
"""
class PAMQPException(Exception):
"""Base exception for all pamqp specific exceptions"""
class UnmarshalingException(PAMQPException):
"""Raised when a frame is not able to be unmarshaled."""
def __str__(self):
return 'Could not unmarshal {} frame: {}'.format(
self.args[0], self.args[1])
pamqp-2.3.0/pamqp/frame.py 0000664 0000000 0000000 00000017455 13456152267 0015443 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""Manage the marshaling and unmarshaling of AMQP frames
unmarshal will turn a raw AMQP byte stream into the appropriate AMQP objects
from the specification file.
marshal will take an object created from the specification file and turn it
into a raw byte stream.
"""
import logging
import struct
from pamqp import (body, decode, exceptions, header, heartbeat, PYTHON3,
specification)
AMQP = b'AMQP'
FRAME_HEADER_SIZE = 7
FRAME_END_CHAR = chr(specification.FRAME_END)
DECODE_FRAME_END_CHAR = FRAME_END_CHAR
if PYTHON3:
FRAME_END_CHAR = bytes((specification.FRAME_END, ))
DECODE_FRAME_END_CHAR = specification.FRAME_END
LOGGER = logging.getLogger(__name__)
UNMARSHAL_FAILURE = 0, 0, None
def unmarshal(data_in):
"""Takes in binary data and maps builds the appropriate frame type,
returning a frame object.
:param bytes data_in: Raw byte stream data
:rtype: tuple of bytes consumed, channel, and a frame object
:raises: specification.FrameError
"""
# Look to see if it's a protocol header frame
try:
frame_value = _unmarshal_protocol_header_frame(data_in)
if frame_value:
return 8, 0, frame_value
except ValueError as error:
raise exceptions.UnmarshalingException(header.ProtocolHeader, error)
# Decode the low level frame and break it into parts
frame_type, channel_id, frame_size = frame_parts(data_in)
# Heartbeats do not have frame length indicators
if frame_type == specification.FRAME_HEARTBEAT and frame_size == 0:
return 8, channel_id, heartbeat.Heartbeat()
if not frame_size:
raise exceptions.UnmarshalingException('Unknown', 'No frame size')
byte_count = FRAME_HEADER_SIZE + frame_size + 1
if byte_count > len(data_in):
raise exceptions.UnmarshalingException('Unknown',
'Not all data received')
if data_in[byte_count - 1] != DECODE_FRAME_END_CHAR:
raise exceptions.UnmarshalingException('Unknown', 'Last byte error')
frame_data = data_in[FRAME_HEADER_SIZE:byte_count - 1]
# Decode a method frame
if frame_type == specification.FRAME_METHOD:
return byte_count, channel_id, _unmarshal_method_frame(frame_data)
# Decode a header frame
elif frame_type == specification.FRAME_HEADER:
return byte_count, channel_id, _unmarshal_header_frame(frame_data)
# Decode a body frame
elif frame_type == specification.FRAME_BODY:
return byte_count, channel_id, _unmarshal_body_frame(frame_data)
raise exceptions.UnmarshalingException(
'Unknown', 'Unknown frame type: {}'.format(frame_type))
def marshal(frame_value, channel_id):
"""Marshal a frame to be sent over the wire.
:param frame_value: The frame object to marshal
:type frame_value: pamqp.specification.Frame or pamqp.heartbeat.Heartbeat
:param int channel_id: The channel number to send the frame on
:rtype: str
:raises: ValueError
"""
if isinstance(frame_value, header.ProtocolHeader):
return frame_value.marshal()
elif isinstance(frame_value, specification.Frame):
return _marshal_method_frame(frame_value, channel_id)
elif isinstance(frame_value, header.ContentHeader):
return _marshal_content_header_frame(frame_value, channel_id)
elif isinstance(frame_value, body.ContentBody):
return _marshal_content_body_frame(frame_value, channel_id)
elif isinstance(frame_value, heartbeat.Heartbeat):
return frame_value.marshal()
raise ValueError('Could not determine frame type: {}'.format(frame_value))
def _unmarshal_protocol_header_frame(data_in):
"""Attempt to unmarshal a protocol header frame
The ProtocolHeader is abbreviated in size and functionality compared to
the rest of the frame types, so return UNMARSHAL_ERROR doesn't apply
as cleanly since we don't have all of the attributes to return even
regardless of success or failure.
:param bytes data_in: Raw byte stream data
:rtype: header.ProtocolHeader
:raises: ValueError
"""
# Do the first four bytes match?
if data_in[0:4] == AMQP:
frame = header.ProtocolHeader()
frame.unmarshal(data_in)
return frame
def _unmarshal_method_frame(frame_data):
"""Attempt to unmarshal a method frame
:param bytes frame_data: Raw frame data to assign to our method frame
:return tuple: Amount of data consumed and the frame object
"""
# Get the Method Index from the class data
bytes_used, method_index = decode.long_int(frame_data[0:4])
# Create an instance of the method object we're going to unmarshal
try:
method = specification.INDEX_MAPPING[method_index]()
except KeyError:
raise exceptions.UnmarshalingException(
'Unknown', 'Unknown method index: {}'.format(str(method_index)))
# Unmarshal the data
try:
method.unmarshal(frame_data[bytes_used:])
except struct.error as error:
raise exceptions.UnmarshalingException(method, error)
# Unmarshal the data in the object and return it
return method
def _unmarshal_header_frame(frame_data):
"""Attempt to unmarshal a header frame
:param bytes frame_data: Raw frame data to assign to our header frame
:return tuple: Amount of data consumed and the frame object
"""
content_header = header.ContentHeader()
try:
content_header.unmarshal(frame_data)
except struct.error as error:
raise exceptions.UnmarshalingException('ContentHeader', error)
return content_header
def _unmarshal_body_frame(frame_data):
"""Attempt to unmarshal a body frame
:param bytes frame_data: Raw frame data to assign to our body frame
:return tuple: Amount of data consumed and the frame object
"""
content_body = body.ContentBody()
content_body.unmarshal(frame_data)
return content_body
def frame_parts(data_in):
"""Try and decode a low-level AMQP frame and return the parts of the frame.
:param bytes data_in: Raw byte stream data
:return tuple: frame type, channel number, and frame data to decode
"""
# Get the Frame Type, Channel Number and Frame Size
try:
return struct.unpack('>BHI', data_in[0:FRAME_HEADER_SIZE])
except struct.error:
# We didn't get a full frame
return UNMARSHAL_FAILURE
def _marshal(frame_type, channel_id, payload):
"""Marshal the low-level AMQ frame.
:param int frame_type: The frame type to marshal
:param int channel_id: The channel it will be sent on
:param bytes|bytes payload: The frame payload
:rtype: str or bytes
"""
return b''.join([
struct.pack('>BHI', frame_type, channel_id, len(payload)), payload,
FRAME_END_CHAR
])
def _marshal_content_body_frame(frame_value, channel_id):
"""Marshal as many content body frames as needed to transmit the content
:param body.ContentBody frame_value: Frame object to marshal
:param int channel_id: The channel number for the frame(s)
:rtype: str
"""
return _marshal(specification.FRAME_BODY, channel_id,
frame_value.marshal())
def _marshal_content_header_frame(frame_value, channel_id):
"""Marshal a content header frame
:param header.ContentHeader frame_value: Frame object to marshal
:param int channel_id: The channel number for the frame
:rtype: str
"""
return _marshal(specification.FRAME_HEADER, channel_id,
frame_value.marshal())
def _marshal_method_frame(frame_value, channel_id):
"""Marshal a method frame
:param specification.Frame frame_value: Frame object to marshal
:param int channel_id: The channel number for the frame
:rtype: str
"""
return _marshal(
specification.FRAME_METHOD, channel_id,
struct.pack('>I', frame_value.index) + frame_value.marshal())
pamqp-2.3.0/pamqp/header.py 0000664 0000000 0000000 00000010466 13456152267 0015574 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""
AMQP Header Class Definitions
For encoding AMQP Header frames into binary AMQP stream data and decoding AMQP
binary data into AMQP Header frames.
"""
import struct
from pamqp import decode, specification
AMQP = b'AMQP'
class ProtocolHeader(object):
"""Class that represents the AMQP Protocol Header"""
name = 'ProtocolHeader'
def __init__(self, major_version=None, minor_version=None, revision=None):
"""Construct a Protocol Header frame object for the specified AMQP
version.
:param int major_version: Major version number
:param int minor_version: Minor version number
:param int revision: Revision number
"""
self.major_version = major_version or specification.VERSION[0]
self.minor_version = minor_version or specification.VERSION[1]
self.revision = revision or specification.VERSION[2]
def marshal(self):
"""Return the full AMQP wire protocol frame data representation of the
ProtocolHeader frame.
:rtype: str or bytes
"""
return AMQP + struct.pack('BBBB', 0, self.major_version,
self.minor_version, self.revision)
def unmarshal(self, data):
"""Dynamically decode the frame data applying the values to the method
object by iterating through the attributes in order and decoding them.
:param bytes data: The binary encoded method data
:rtype: int byte count of data used to unmarshal the frame
:raises: ValueError
"""
try:
(self.major_version, self.minor_version,
self.revision) = struct.unpack('BBB', data[5:8])
except struct.error:
raise ValueError('Data did not match the ProtocolHeader '
'format: {}'.format(data))
# All in we consume 8 bytes
return 8
class ContentHeader(object):
"""Represent a content header frame
A Content Header frame is received after a Basic.Deliver or Basic.GetOk
frame and has the data and properties for the Content Body frames that
follow.
"""
name = 'ContentHeader'
def __init__(self, weight=0, body_size=0, properties=None):
"""Initialize the Exchange.DeleteOk class
:param int weight: Unused, must be 0
:param long body_size: The size of the body for the message across all
received AMQP frames
:param specification.Basic.Properties properties: Message properties
"""
self.class_id = None
self.weight = weight
self.body_size = body_size
self.properties = properties or specification.Basic.Properties()
def marshal(self):
"""Return the AMQP binary encoded value of the frame
"""
return struct.pack('>HxxQ', specification.Basic.frame_id,
self.body_size) + self.properties.marshal()
def unmarshal(self, data):
"""Dynamically decode the frame data applying the values to the method
object by iterating through the attributes in order and decoding them.
:param bytes data: The binary encoded method data
:rtype: int byte count of data used to unmarshal the frame
:raises: ValueError
"""
# Get the class, weight and body size
(self.class_id, self.weight,
self.body_size) = struct.unpack('>HHQ', data[0:12])
# Get the flags for what properties we have available
offset, flags = self._get_flags(data[12:])
# Demarshal the properties
self.properties.unmarshal(flags, data[12 + offset:])
def _get_flags(self, data):
"""Decode the flags from the data returning the bytes consumed and
flags
:param bytes data: The data to pull flags out of
:rtype: int, int
"""
# Defaults
bytes_consumed, flags, flagword_index = 0, 0, 0
# Read until we don't have a value pulled out of the flags
while True:
consumed, partial_flags = decode.short_int(data)
bytes_consumed += consumed
flags |= (partial_flags << (flagword_index * 16))
if not partial_flags & 1:
break
flagword_index += 1
# Return the bytes consumed and the flags
return bytes_consumed, flags
pamqp-2.3.0/pamqp/heartbeat.py 0000664 0000000 0000000 00000001325 13456152267 0016275 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
"""
AMQP Heartbeat Frame, used to create new Heartbeat frames for sending to a peer
"""
import struct
from pamqp import PYTHON3, specification
class Heartbeat(object):
"""Heartbeat frame object mapping class. AMQP Heartbeat frames are mapped
on to this class for a common access structure to the attributes/data
values.
"""
name = 'Heartbeat'
@staticmethod
def marshal():
"""Return the binary frame content
:rtype: str or bytes
"""
value = struct.pack('>BHI', specification.FRAME_HEARTBEAT, 0, 0)
if PYTHON3:
return value + bytes((specification.FRAME_END, ))
return value + chr(specification.FRAME_END)
pamqp-2.3.0/pamqp/specification.py 0000664 0000000 0000000 00000252751 13456152267 0017171 0 ustar 00root root 0000000 0000000 """specification.py
Auto-generated AMQP Support Module
WARNING: DO NOT EDIT. To Generate run tools/codegen.py
"""
__since__ = '2019-04-18'
import struct
import warnings
from pamqp import decode, encode
# AMQP Protocol Version
VERSION = (0, 9, 1)
# RabbitMQ Defaults
DEFAULT_HOST = 'localhost'
DEFAULT_PORT = 5672
DEFAULT_USER = 'guest'
DEFAULT_PASS = 'guest'
DEFAULT_VHOST = '/'
# AMQP Constants
FRAME_METHOD = 1
FRAME_HEADER = 2
FRAME_BODY = 3
FRAME_HEARTBEAT = 8
FRAME_MIN_SIZE = 4096
FRAME_END = 206
# Indicates that the method completed successfully. This reply code is reserved
# for future use - the current protocol design does not use positive
# confirmation and reply codes are sent only in case of an error.
REPLY_SUCCESS = 200
# Not included in the spec XML or JSON files.
FRAME_MAX_SIZE = 131072
# AMQP data types
DATA_TYPES = [
'bit', 'long', 'longlong', 'longstr', 'octet', 'short', 'shortstr',
'table', 'timestamp'
]
# AMQP domains
DOMAINS = {
'channel-id': 'longstr',
'class-id': 'short',
'consumer-tag': 'shortstr',
'delivery-tag': 'longlong',
'destination': 'shortstr',
'duration': 'longlong',
'exchange-name': 'shortstr',
'method-id': 'short',
'no-ack': 'bit',
'no-local': 'bit',
'offset': 'longlong',
'path': 'shortstr',
'peer-properties': 'table',
'queue-name': 'shortstr',
'redelivered': 'bit',
'reference': 'longstr',
'reject-code': 'short',
'reject-text': 'shortstr',
'reply-code': 'short',
'reply-text': 'shortstr',
'security-token': 'longstr'
}
# Other constants
DEPRECATION_WARNING = 'This command is deprecated in AMQP 0-9-1'
class Frame(object):
"""Base Class for AMQP Methods which specifies the encoding and decoding
behavior.
"""
__slots__ = []
frame_id = 0
index = 0
name = 'Frame'
synchronous = False
valid_responses = []
def __iter__(self):
"""Iterate the attributes and values as key, value pairs.
:rtype: tuple
"""
for attribute in self.__slots__:
yield (attribute, getattr(self, attribute))
def __contains__(self, item):
"""Return if the item is in the attribute list.
:rtype: bool
"""
return item in self.__slots__
def __getitem__(self, item):
"""Return an attribute as if it were a dict.
:param str item: The item to look for
:raises: KeyError
:rtype: any
"""
return getattr(self, item)
def __len__(self):
"""Return the length of the attribute list.
:rtype: int
"""
return len(self.__slots__)
def __repr__(self):
"""Return the representation of the frame object
:return: str
"""
return '<%s.%s object at %s>' % (__name__, self.name, hex(id(self)))
@classmethod
def type(cls, attr):
"""Return the data type for an attribute.
:rtype: str
"""
return getattr(cls, '_' + attr)
def marshal(self):
"""
Dynamically encode the frame by taking the list of attributes and
encode them item by item getting the value form the object attribute
and the data type from the class attribute.
:rtype: str
"""
output = []
processing_bitset = False
byte = None
offset = 0
for argument in self.__slots__:
data_type = self.type(argument)
# Check if we need to turn on bit processing
if not processing_bitset and data_type == 'bit':
byte = 0
offset = 0
processing_bitset = True
# Get the data value
data_value = getattr(self, argument)
# If we're processing a bitset, apply special rules
if processing_bitset:
# Is this value not a bit? turn off bitset processing and
# append the byte value as an octet
if data_type != 'bit':
processing_bitset = False
output.append(encode.octet(byte))
else:
# Apply the bit value to the byte
byte = encode.bit(data_value, byte, offset)
offset += 1
if offset == 8:
# We've filled a byte for all bits, add the byte
output.append(encode.octet(byte))
# Turn off processing, we'll turn on in next iteration
# if needed
processing_bitset = False
# Go to the next iteration
continue
# Not a bit, so just process by type
output.append(encode.by_type(data_value, data_type))
# Append the last byte if we're processing a bitset
if processing_bitset:
output.append(encode.octet(byte))
return b''.join(output)
def unmarshal(self, data):
"""
Dynamically decode the frame data applying the values to the method
object by iterating through the attributes in order and decoding them.
:param str data: The binary encoded method data
"""
offset = 0
processing_bitset = False
for argument in self.__slots__:
data_type = self.type(argument)
if offset == 7 and processing_bitset:
data = data[1:]
offset = 0
if processing_bitset and data_type != 'bit':
offset = 0
processing_bitset = False
data = data[1:]
consumed, value = decode.by_type(data, data_type, offset)
if data_type == 'bit':
offset += 1
processing_bitset = True
consumed = 0
setattr(self, argument, value)
if consumed:
data = data[consumed:]
class PropertiesBase(object):
"""Provide a base object that marshals and unmarshals the Basic.Properties
object values.
"""
__slots__ = []
flags = {}
name = 'PropertiesBase'
def __contains__(self, item):
return item in self.__slots__
def __delattr__(self, item):
setattr(self, item, None)
def __iter__(self):
"""Iterate the attributes and values as key, value pairs.
:rtype: tuple
"""
for attribute in self.__slots__:
yield (attribute, getattr(self, attribute))
@classmethod
def attributes(cls):
"""Return the list of attributes
:rtype: list
"""
return [attr for attr in cls.__slots__]
@classmethod
def type(cls, attr):
"""Return the data type for an attribute.
:rtype: str
"""
return getattr(cls, '_' + attr)
def encode_property(self, property_name, property_value):
"""Encode a single property value
:param str property_name: The property name to encode
:param any property_value: The value to encode
"""
return encode.by_type(property_value, self.type(property_name))
def marshal(self):
"""Take the Basic.Properties data structure and marshal it into the
data structure needed for the ContentHeader.
:rtype: bytes
"""
flags = 0
parts = []
for property_name in self.__slots__:
property_value = getattr(self, property_name)
if property_value is not None and property_value != '':
flags = flags | self.flags[property_name]
parts.append(
self.encode_property(property_name, property_value))
flag_pieces = []
while True:
remainder = flags >> 16
partial_flags = flags & 0xFFFE
if remainder != 0:
partial_flags |= 1
flag_pieces.append(struct.pack('>H', partial_flags))
flags = remainder
if not flags:
break
return b''.join(flag_pieces + parts)
def to_dict(self):
"""Return the properties as a dict
:rtype: dict
"""
return dict(self)
def unmarshal(self, flags, data):
"""
Dynamically decode the frame data applying the values to the method
object by iterating through the attributes in order and decoding them.
:param int flags: Flags that indicate if the data has the property
:param bytes data: The binary encoded method data
"""
for property_name in self.__slots__:
if flags & self.flags[property_name]:
data_type = getattr(self.__class__, '_' + property_name)
consumed, value = decode.by_type(data, data_type)
setattr(self, property_name, value)
data = data[consumed:]
# AMQP Errors
class AMQPContentTooLarge(Warning):
"""
The client attempted to transfer content larger than the server could
accept at the present time. The client may retry at a later time.
"""
name = 'CONTENT-TOO-LARGE'
value = 311
class AMQPNoRoute(Warning):
"""
Undocumented AMQP Soft Error
"""
name = 'NO-ROUTE'
value = 312
class AMQPNoConsumers(Warning):
"""
When the exchange cannot deliver to a consumer when the immediate flag is
set. As a result of pending data on the queue or the absence of any
consumers of the queue.
"""
name = 'NO-CONSUMERS'
value = 313
class AMQPAccessRefused(Warning):
"""
The client attempted to work with a server entity to which it has no access
due to security settings.
"""
name = 'ACCESS-REFUSED'
value = 403
class AMQPNotFound(Warning):
"""
The client attempted to work with a server entity that does not exist.
"""
name = 'NOT-FOUND'
value = 404
class AMQPResourceLocked(Warning):
"""
The client attempted to work with a server entity to which it has no access
because another client is working with it.
"""
name = 'RESOURCE-LOCKED'
value = 405
class AMQPPreconditionFailed(Warning):
"""
The client requested a method that was not allowed because some
precondition failed.
"""
name = 'PRECONDITION-FAILED'
value = 406
class AMQPConnectionForced(Exception):
"""
An operator intervened to close the connection for some reason. The client
may retry at some later date.
"""
name = 'CONNECTION-FORCED'
value = 320
class AMQPInvalidPath(Exception):
"""
The client tried to work with an unknown virtual host.
"""
name = 'INVALID-PATH'
value = 402
class AMQPFrameError(Exception):
"""
The sender sent a malformed frame that the recipient could not decode. This
strongly implies a programming error in the sending peer.
"""
name = 'FRAME-ERROR'
value = 501
class AMQPSyntaxError(Exception):
"""
The sender sent a frame that contained illegal values for one or more
fields. This strongly implies a programming error in the sending peer.
"""
name = 'SYNTAX-ERROR'
value = 502
class AMQPCommandInvalid(Exception):
"""
The client sent an invalid sequence of frames, attempting to perform an
operation that was considered invalid by the server. This usually implies a
programming error in the client.
"""
name = 'COMMAND-INVALID'
value = 503
class AMQPChannelError(Exception):
"""
The client attempted to work with a channel that had not been correctly
opened. This most likely indicates a fault in the client layer.
"""
name = 'CHANNEL-ERROR'
value = 504
class AMQPUnexpectedFrame(Exception):
"""
The peer sent a frame that was not expected, usually in the context of a
content header and body. This strongly indicates a fault in the peer's
content processing.
"""
name = 'UNEXPECTED-FRAME'
value = 505
class AMQPResourceError(Exception):
"""
The server could not complete the method because it lacked sufficient
resources. This may be due to the client creating too many of some type of
entity.
"""
name = 'RESOURCE-ERROR'
value = 506
class AMQPNotAllowed(Exception):
"""
The client tried to work with some entity in a manner that is prohibited by
the server, due to security settings or by some other criteria.
"""
name = 'NOT-ALLOWED'
value = 530
class AMQPNotImplemented(Exception):
"""
The client tried to use functionality that is not implemented in the
server.
"""
name = 'NOT-IMPLEMENTED'
value = 540
class AMQPInternalError(Exception):
"""
The server could not complete the method because of an internal error. The
server may require intervention by an operator in order to resume normal
operations.
"""
name = 'INTERNAL-ERROR'
value = 541
# AMQP Error code to class mapping
ERRORS = {
320: AMQPConnectionForced,
505: AMQPUnexpectedFrame,
502: AMQPSyntaxError,
503: AMQPCommandInvalid,
530: AMQPNotAllowed,
504: AMQPChannelError,
402: AMQPInvalidPath,
403: AMQPAccessRefused,
404: AMQPNotFound,
405: AMQPResourceLocked,
406: AMQPPreconditionFailed,
311: AMQPContentTooLarge,
312: AMQPNoRoute,
313: AMQPNoConsumers,
506: AMQPResourceError,
540: AMQPNotImplemented,
541: AMQPInternalError,
501: AMQPFrameError
}
# AMQP Classes and Methods
class Connection(object):
"""Work with socket connections
The connection class provides methods for a client to establish a network
connection to a server, and for both peers to operate the connection
thereafter.
"""
__slots__ = []
# AMQP Class Number and Mapping Index
frame_id = 10
index = 0x000A0000
class Start(Frame):
"""Start connection negotiation
This method starts the connection negotiation process by telling the
client the protocol version that the server proposes, along with a list
of security mechanisms which the client can use for authentication.
"""
# AMQP Method Number and Mapping Index
frame_id = 10
index = 0x000A000A
name = 'Connection.Start'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Connection.StartOk']
# AMQP Method Attributes
__slots__ = [
'version_major', 'version_minor', 'server_properties',
'mechanisms', 'locales'
]
# Class Attribute Types
_version_major = 'octet'
_version_minor = 'octet'
_server_properties = 'table'
_mechanisms = 'longstr'
_locales = 'longstr'
def __init__(self,
version_major=0,
version_minor=9,
server_properties=None,
mechanisms='PLAIN',
locales='en_US'):
"""Initialize the Connection.Start class
:param int version_major: Protocol major version
:param int version_minor: Protocol minor version
:param dict server_properties: Server properties
:param str mechanisms: Available security mechanisms
:param str locales: Available message locales
"""
# Protocol major version
self.version_major = version_major
# Protocol minor version
self.version_minor = version_minor
# Server properties
self.server_properties = server_properties
# Available security mechanisms
self.mechanisms = mechanisms
# Available message locales
self.locales = locales
class StartOk(Frame):
"""Select security mechanism and locale
This method selects a SASL security mechanism.
"""
# AMQP Method Number and Mapping Index
frame_id = 11
index = 0x000A000B
name = 'Connection.StartOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['client_properties', 'mechanism', 'response', 'locale']
# Class Attribute Types
_client_properties = 'table'
_mechanism = 'shortstr'
_response = 'longstr'
_locale = 'shortstr'
def __init__(self,
client_properties=None,
mechanism='PLAIN',
response='',
locale='en_US'):
"""Initialize the Connection.StartOk class
:param dict client_properties: Client properties
:param str mechanism: Selected security mechanism
:param str response: Security response data
:param str locale: Selected message locale
"""
# Client properties
self.client_properties = client_properties
# Selected security mechanism
self.mechanism = mechanism
# Security response data
self.response = response
# Selected message locale
self.locale = locale
class Secure(Frame):
"""Security mechanism challenge
The SASL protocol works by exchanging challenges and responses until
both peers have received sufficient information to authenticate each
other. This method challenges the client to provide more information.
"""
# AMQP Method Number and Mapping Index
frame_id = 20
index = 0x000A0014
name = 'Connection.Secure'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Connection.SecureOk']
# AMQP Method Attributes
__slots__ = ['challenge']
# Class Attribute Types
_challenge = 'longstr'
def __init__(self, challenge=''):
"""Initialize the Connection.Secure class
:param str challenge: Security challenge data
"""
# Security challenge data
self.challenge = challenge
class SecureOk(Frame):
"""Security mechanism response
This method attempts to authenticate, passing a block of SASL data for
the security mechanism at the server side.
"""
# AMQP Method Number and Mapping Index
frame_id = 21
index = 0x000A0015
name = 'Connection.SecureOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['response']
# Class Attribute Types
_response = 'longstr'
def __init__(self, response=''):
"""Initialize the Connection.SecureOk class
:param str response: Security response data
"""
# Security response data
self.response = response
class Tune(Frame):
"""Propose connection tuning parameters
This method proposes a set of connection configuration values to the
client. The client can accept and/or adjust these.
"""
# AMQP Method Number and Mapping Index
frame_id = 30
index = 0x000A001E
name = 'Connection.Tune'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Connection.TuneOk']
# AMQP Method Attributes
__slots__ = ['channel_max', 'frame_max', 'heartbeat']
# Class Attribute Types
_channel_max = 'short'
_frame_max = 'long'
_heartbeat = 'short'
def __init__(self, channel_max=0, frame_max=0, heartbeat=0):
"""Initialize the Connection.Tune class
:param int channel_max: Proposed maximum channels
:param int/long frame_max: Proposed maximum frame size
:param int heartbeat: Desired heartbeat delay
"""
# Proposed maximum channels
self.channel_max = channel_max
# Proposed maximum frame size
self.frame_max = frame_max
# Desired heartbeat delay
self.heartbeat = heartbeat
class TuneOk(Frame):
"""Negotiate connection tuning parameters
This method sends the client's connection tuning parameters to the
server. Certain fields are negotiated, others provide capability
information.
"""
# AMQP Method Number and Mapping Index
frame_id = 31
index = 0x000A001F
name = 'Connection.TuneOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['channel_max', 'frame_max', 'heartbeat']
# Class Attribute Types
_channel_max = 'short'
_frame_max = 'long'
_heartbeat = 'short'
def __init__(self, channel_max=0, frame_max=0, heartbeat=0):
"""Initialize the Connection.TuneOk class
:param int channel_max: Negotiated maximum channels
:param int/long frame_max: Negotiated maximum frame size
:param int heartbeat: Desired heartbeat delay
"""
# Negotiated maximum channels
self.channel_max = channel_max
# Negotiated maximum frame size
self.frame_max = frame_max
# Desired heartbeat delay
self.heartbeat = heartbeat
class Open(Frame):
"""Open connection to virtual host
This method opens a connection to a virtual host, which is a collection
of resources, and acts to separate multiple application domains within
a server. The server may apply arbitrary limits per virtual host, such
as the number of each type of entity that may be used, per connection
and/or in total.
"""
# AMQP Method Number and Mapping Index
frame_id = 40
index = 0x000A0028
name = 'Connection.Open'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Connection.OpenOk']
# AMQP Method Attributes
__slots__ = ['virtual_host', 'capabilities', 'insist']
# Class Attribute Types
_virtual_host = 'shortstr'
_capabilities = 'shortstr'
_insist = 'bit'
def __init__(self, virtual_host='/', capabilities='', insist=False):
"""Initialize the Connection.Open class
:param str virtual_host: Virtual host name
:param str capabilities: Deprecated
:param bool insist: Deprecated
"""
# Virtual host name
self.virtual_host = virtual_host
# Deprecated
self.capabilities = capabilities
# Deprecated
self.insist = insist
class OpenOk(Frame):
"""Signal that connection is ready
This method signals to the client that the connection is ready for use.
"""
# AMQP Method Number and Mapping Index
frame_id = 41
index = 0x000A0029
name = 'Connection.OpenOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['known_hosts']
# Class Attribute Types
_known_hosts = 'shortstr'
def __init__(self, known_hosts=''):
"""Initialize the Connection.OpenOk class
:param str known_hosts: Deprecated
"""
# Deprecated
self.known_hosts = known_hosts
class Close(Frame):
"""Request a connection close
This method indicates that the sender wants to close the connection.
This may be due to internal conditions (e.g. a forced shut-down) or due
to an error handling a specific method, i.e. an exception. When a close
is due to an exception, the sender provides the class and method id of
the method which caused the exception.
"""
# AMQP Method Number and Mapping Index
frame_id = 50
index = 0x000A0032
name = 'Connection.Close'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Connection.CloseOk']
# AMQP Method Attributes
__slots__ = ['reply_code', 'reply_text', 'class_id', 'method_id']
# Class Attribute Types
_reply_code = 'short'
_reply_text = 'shortstr'
_class_id = 'short'
_method_id = 'short'
def __init__(self,
reply_code=0,
reply_text='',
class_id=0,
method_id=0):
"""Initialize the Connection.Close class
:param int reply_code: Reply code from server
:param str reply_text: Localised reply text
:param int class_id: Failing method class
:param int method_id: Failing method ID
"""
# Reply code from server
self.reply_code = reply_code
# Localised reply text
self.reply_text = reply_text
# Failing method class
self.class_id = class_id
# Failing method ID
self.method_id = method_id
class CloseOk(Frame):
"""Confirm a connection close
This method confirms a Connection.Close method and tells the recipient
that it is safe to release resources for the connection and close the
socket.
"""
# AMQP Method Number and Mapping Index
frame_id = 51
index = 0x000A0033
name = 'Connection.CloseOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Blocked(Frame):
"""Signal that connection is blocked
This method signals to the client that the connection is blocked by
RabbitMQ.
"""
# AMQP Method Number and Mapping Index
frame_id = 60
index = 0x000A003C
name = 'Connection.Blocked'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['reason']
# Class Attribute Types
_reason = 'shortstr'
def __init__(self, reason=''):
"""Initialize the Connection.Blocked class
:param str reason:
"""
self.reason = reason
class Unblocked(Frame):
"""Signal that connection is no longer blocked
This method signals to the client that the connection is no longer
blocked by RabbitMQ.
"""
# AMQP Method Number and Mapping Index
frame_id = 61
index = 0x000A003D
name = 'Connection.Unblocked'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Channel(object):
"""Work with channels
The channel class provides methods for a client to establish a channel to a
server and for both peers to operate the channel thereafter.
"""
__slots__ = []
# AMQP Class Number and Mapping Index
frame_id = 20
index = 0x00140000
class Open(Frame):
"""Open a channel for use
This method opens a channel to the server.
"""
# AMQP Method Number and Mapping Index
frame_id = 10
index = 0x0014000A
name = 'Channel.Open'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Channel.OpenOk']
# AMQP Method Attributes
__slots__ = ['out_of_band']
# Class Attribute Types
_out_of_band = 'shortstr'
def __init__(self, out_of_band=''):
"""Initialize the Channel.Open class
:param str out_of_band: Protocol level field, do not use, must be
zero.
"""
# Protocol level field, do not use, must be zero.
self.out_of_band = out_of_band
class OpenOk(Frame):
"""Signal that the channel is ready
This method signals to the client that the channel is ready for use.
"""
# AMQP Method Number and Mapping Index
frame_id = 11
index = 0x0014000B
name = 'Channel.OpenOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['channel_id']
# Class Attribute Types
_channel_id = 'longstr'
def __init__(self, channel_id=''):
"""Initialize the Channel.OpenOk class
:param str channel_id: Deprecated
"""
# Deprecated
self.channel_id = channel_id
class Flow(Frame):
"""Enable/disable flow from peer
This method asks the peer to pause or restart the flow of content data
sent by a consumer. This is a simple flow-control mechanism that a peer
can use to avoid overflowing its queues or otherwise finding itself
receiving more messages than it can process. Note that this method is
not intended for window control. It does not affect contents returned
by Basic.Get-Ok methods.
"""
# AMQP Method Number and Mapping Index
frame_id = 20
index = 0x00140014
name = 'Channel.Flow'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Channel.FlowOk']
# AMQP Method Attributes
__slots__ = ['active']
# Class Attribute Types
_active = 'bit'
def __init__(self, active=None):
"""Initialize the Channel.Flow class
:param bool active: Start/stop content frames
"""
# Start/stop content frames
self.active = active
class FlowOk(Frame):
"""Confirm a flow method
Confirms to the peer that a flow command was received and processed.
"""
# AMQP Method Number and Mapping Index
frame_id = 21
index = 0x00140015
name = 'Channel.FlowOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['active']
# Class Attribute Types
_active = 'bit'
def __init__(self, active=None):
"""Initialize the Channel.FlowOk class
:param bool active: Current flow setting
"""
# Current flow setting
self.active = active
class Close(Frame):
"""Request a channel close
This method indicates that the sender wants to close the channel. This
may be due to internal conditions (e.g. a forced shut-down) or due to
an error handling a specific method, i.e. an exception. When a close is
due to an exception, the sender provides the class and method id of the
method which caused the exception.
"""
# AMQP Method Number and Mapping Index
frame_id = 40
index = 0x00140028
name = 'Channel.Close'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Channel.CloseOk']
# AMQP Method Attributes
__slots__ = ['reply_code', 'reply_text', 'class_id', 'method_id']
# Class Attribute Types
_reply_code = 'short'
_reply_text = 'shortstr'
_class_id = 'short'
_method_id = 'short'
def __init__(self,
reply_code=0,
reply_text='',
class_id=0,
method_id=0):
"""Initialize the Channel.Close class
:param int reply_code: Reply code from server
:param str reply_text: Localised reply text
:param int class_id: Failing method class
:param int method_id: Failing method ID
"""
# Reply code from server
self.reply_code = reply_code
# Localised reply text
self.reply_text = reply_text
# Failing method class
self.class_id = class_id
# Failing method ID
self.method_id = method_id
class CloseOk(Frame):
"""Confirm a channel close
This method confirms a Channel.Close method and tells the recipient
that it is safe to release resources for the channel.
"""
# AMQP Method Number and Mapping Index
frame_id = 41
index = 0x00140029
name = 'Channel.CloseOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Exchange(object):
"""Work with exchanges
Exchanges match and distribute messages across queues. Exchanges can be
configured in the server or declared at runtime.
"""
__slots__ = []
# AMQP Class Number and Mapping Index
frame_id = 40
index = 0x00280000
class Declare(Frame):
"""Verify exchange exists, create if needed
This method creates an exchange if it does not already exist, and if
the exchange exists, verifies that it is of the correct and expected
class.
"""
# AMQP Method Number and Mapping Index
frame_id = 10
index = 0x0028000A
name = 'Exchange.Declare'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Exchange.DeclareOk']
# AMQP Method Attributes
__slots__ = [
'ticket', 'exchange', 'exchange_type', 'passive', 'durable',
'auto_delete', 'internal', 'nowait', 'arguments'
]
# Class Attribute Types
_ticket = 'short'
_exchange = 'shortstr'
_exchange_type = 'shortstr'
_passive = 'bit'
_durable = 'bit'
_auto_delete = 'bit'
_internal = 'bit'
_nowait = 'bit'
_arguments = 'table'
def __init__(self,
ticket=0,
exchange='',
exchange_type='direct',
passive=False,
durable=False,
auto_delete=False,
internal=False,
nowait=False,
arguments=None):
"""Initialize the Exchange.Declare class
Note that the AMQP type argument is referred to as "exchange_type"
to not conflict with the Python type keyword.
:param int ticket: Deprecated
:param str exchange:
:param str exchange_type: Exchange type
:param bool passive: Do not create exchange
:param bool durable: Request a durable exchange
:param bool auto_delete: Automatically delete when not in use
:param bool internal: Deprecated
:param bool nowait: Do not send a reply method
:param dict arguments: Arguments for declaration
"""
# Deprecated
self.ticket = ticket
self.exchange = exchange
# Exchange type
self.exchange_type = exchange_type
# Do not create exchange
self.passive = passive
# Request a durable exchange
self.durable = durable
# Automatically delete when not in use
self.auto_delete = auto_delete
# Deprecated
self.internal = internal
# Do not send a reply method
self.nowait = nowait
# Arguments for declaration
self.arguments = arguments or {}
class DeclareOk(Frame):
"""Confirm exchange declaration
This method confirms a Declare method and confirms the name of the
exchange, essential for automatically-named exchanges.
"""
# AMQP Method Number and Mapping Index
frame_id = 11
index = 0x0028000B
name = 'Exchange.DeclareOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Delete(Frame):
"""Delete an exchange
This method deletes an exchange. When an exchange is deleted all queue
bindings on the exchange are cancelled.
"""
# AMQP Method Number and Mapping Index
frame_id = 20
index = 0x00280014
name = 'Exchange.Delete'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Exchange.DeleteOk']
# AMQP Method Attributes
__slots__ = ['ticket', 'exchange', 'if_unused', 'nowait']
# Class Attribute Types
_ticket = 'short'
_exchange = 'shortstr'
_if_unused = 'bit'
_nowait = 'bit'
def __init__(self,
ticket=0,
exchange='',
if_unused=False,
nowait=False):
"""Initialize the Exchange.Delete class
:param int ticket: Deprecated
:param str exchange:
:param bool if_unused: Delete only if unused
:param bool nowait: Do not send a reply method
"""
# Deprecated
self.ticket = ticket
self.exchange = exchange
# Delete only if unused
self.if_unused = if_unused
# Do not send a reply method
self.nowait = nowait
class DeleteOk(Frame):
"""Confirm deletion of an exchange
This method confirms the deletion of an exchange.
"""
# AMQP Method Number and Mapping Index
frame_id = 21
index = 0x00280015
name = 'Exchange.DeleteOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Bind(Frame):
# AMQP Method Number and Mapping Index
frame_id = 30
index = 0x0028001E
name = 'Exchange.Bind'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Exchange.BindOk']
# AMQP Method Attributes
__slots__ = [
'ticket', 'destination', 'source', 'routing_key', 'nowait',
'arguments'
]
# Class Attribute Types
_ticket = 'short'
_destination = 'shortstr'
_source = 'shortstr'
_routing_key = 'shortstr'
_nowait = 'bit'
_arguments = 'table'
def __init__(self,
ticket=0,
destination='',
source='',
routing_key='',
nowait=False,
arguments=None):
"""Initialize the Exchange.Bind class
:param int ticket: Deprecated
:param str destination:
:param str source:
:param str routing-key:
:param bool nowait: Do not send a reply method
:param dict arguments:
"""
# Deprecated
self.ticket = ticket
self.destination = destination
self.source = source
self.routing_key = routing_key
# Do not send a reply method
self.nowait = nowait
self.arguments = arguments or {}
class BindOk(Frame):
# AMQP Method Number and Mapping Index
frame_id = 31
index = 0x0028001F
name = 'Exchange.BindOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Unbind(Frame):
# AMQP Method Number and Mapping Index
frame_id = 40
index = 0x00280028
name = 'Exchange.Unbind'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Exchange.UnbindOk']
# AMQP Method Attributes
__slots__ = [
'ticket', 'destination', 'source', 'routing_key', 'nowait',
'arguments'
]
# Class Attribute Types
_ticket = 'short'
_destination = 'shortstr'
_source = 'shortstr'
_routing_key = 'shortstr'
_nowait = 'bit'
_arguments = 'table'
def __init__(self,
ticket=0,
destination='',
source='',
routing_key='',
nowait=False,
arguments=None):
"""Initialize the Exchange.Unbind class
:param int ticket: Deprecated
:param str destination:
:param str source:
:param str routing-key:
:param bool nowait: Do not send a reply method
:param dict arguments:
"""
# Deprecated
self.ticket = ticket
self.destination = destination
self.source = source
self.routing_key = routing_key
# Do not send a reply method
self.nowait = nowait
self.arguments = arguments or {}
class UnbindOk(Frame):
# AMQP Method Number and Mapping Index
frame_id = 51
index = 0x00280033
name = 'Exchange.UnbindOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Queue(object):
"""Work with queues
Queues store and forward messages. Queues can be configured in the server
or created at runtime. Queues must be attached to at least one exchange in
order to receive messages from publishers.
"""
__slots__ = []
# AMQP Class Number and Mapping Index
frame_id = 50
index = 0x00320000
class Declare(Frame):
"""Declare queue, create if needed
This method creates or checks a queue. When creating a new queue the
client can specify various properties that control the durability of
the queue and its contents, and the level of sharing for the queue.
"""
# AMQP Method Number and Mapping Index
frame_id = 10
index = 0x0032000A
name = 'Queue.Declare'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Queue.DeclareOk']
# AMQP Method Attributes
__slots__ = [
'ticket', 'queue', 'passive', 'durable', 'exclusive',
'auto_delete', 'nowait', 'arguments'
]
# Class Attribute Types
_ticket = 'short'
_queue = 'shortstr'
_passive = 'bit'
_durable = 'bit'
_exclusive = 'bit'
_auto_delete = 'bit'
_nowait = 'bit'
_arguments = 'table'
def __init__(self,
ticket=0,
queue='',
passive=False,
durable=False,
exclusive=False,
auto_delete=False,
nowait=False,
arguments=None):
"""Initialize the Queue.Declare class
:param int ticket: Deprecated
:param str queue:
:param bool passive: Do not create queue
:param bool durable: Request a durable queue
:param bool exclusive: Request an exclusive queue
:param bool auto_delete: Auto-delete queue when unused
:param bool nowait: Do not send a reply method
:param dict arguments: Arguments for declaration
"""
# Deprecated
self.ticket = ticket
self.queue = queue
# Do not create queue
self.passive = passive
# Request a durable queue
self.durable = durable
# Request an exclusive queue
self.exclusive = exclusive
# Auto-delete queue when unused
self.auto_delete = auto_delete
# Do not send a reply method
self.nowait = nowait
# Arguments for declaration
self.arguments = arguments or {}
class DeclareOk(Frame):
"""Confirms a queue definition
This method confirms a Declare method and confirms the name of the
queue, essential for automatically-named queues.
"""
# AMQP Method Number and Mapping Index
frame_id = 11
index = 0x0032000B
name = 'Queue.DeclareOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['queue', 'message_count', 'consumer_count']
# Class Attribute Types
_queue = 'shortstr'
_message_count = 'long'
_consumer_count = 'long'
def __init__(self, queue='', message_count=0, consumer_count=0):
"""Initialize the Queue.DeclareOk class
:param str queue:
:param int/long message_count: Number of messages in queue
:param int/long consumer_count: Number of consumers
"""
self.queue = queue
# Number of messages in queue
self.message_count = message_count
# Number of consumers
self.consumer_count = consumer_count
class Bind(Frame):
"""Bind queue to an exchange
This method binds a queue to an exchange. Until a queue is bound it
will not receive any messages. In a classic messaging model, store-and-
forward queues are bound to a direct exchange and subscription queues
are bound to a topic exchange.
"""
# AMQP Method Number and Mapping Index
frame_id = 20
index = 0x00320014
name = 'Queue.Bind'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Queue.BindOk']
# AMQP Method Attributes
__slots__ = [
'ticket', 'queue', 'exchange', 'routing_key', 'nowait', 'arguments'
]
# Class Attribute Types
_ticket = 'short'
_queue = 'shortstr'
_exchange = 'shortstr'
_routing_key = 'shortstr'
_nowait = 'bit'
_arguments = 'table'
def __init__(self,
ticket=0,
queue='',
exchange='',
routing_key='',
nowait=False,
arguments=None):
"""Initialize the Queue.Bind class
:param int ticket: Deprecated
:param str queue:
:param str exchange: Name of the exchange to bind to
:param str routing_key: Message routing key
:param bool nowait: Do not send a reply method
:param dict arguments: Arguments for binding
"""
# Deprecated
self.ticket = ticket
self.queue = queue
# Name of the exchange to bind to
self.exchange = exchange
# Message routing key
self.routing_key = routing_key
# Do not send a reply method
self.nowait = nowait
# Arguments for binding
self.arguments = arguments or {}
class BindOk(Frame):
"""Confirm bind successful
This method confirms that the bind was successful.
"""
# AMQP Method Number and Mapping Index
frame_id = 21
index = 0x00320015
name = 'Queue.BindOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Purge(Frame):
"""Purge a queue
This method removes all messages from a queue which are not awaiting
acknowledgment.
"""
# AMQP Method Number and Mapping Index
frame_id = 30
index = 0x0032001E
name = 'Queue.Purge'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Queue.PurgeOk']
# AMQP Method Attributes
__slots__ = ['ticket', 'queue', 'nowait']
# Class Attribute Types
_ticket = 'short'
_queue = 'shortstr'
_nowait = 'bit'
def __init__(self, ticket=0, queue='', nowait=False):
"""Initialize the Queue.Purge class
:param int ticket: Deprecated
:param str queue:
:param bool nowait: Do not send a reply method
"""
# Deprecated
self.ticket = ticket
self.queue = queue
# Do not send a reply method
self.nowait = nowait
class PurgeOk(Frame):
"""Confirms a queue purge
This method confirms the purge of a queue.
"""
# AMQP Method Number and Mapping Index
frame_id = 31
index = 0x0032001F
name = 'Queue.PurgeOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['message_count']
# Class Attribute Types
_message_count = 'long'
def __init__(self, message_count=0):
"""Initialize the Queue.PurgeOk class
:param int/long message-count:
"""
self.message_count = message_count
class Delete(Frame):
"""Delete a queue
This method deletes a queue. When a queue is deleted any pending
messages are sent to a dead-letter queue if this is defined in the
server configuration, and all consumers on the queue are cancelled.
"""
# AMQP Method Number and Mapping Index
frame_id = 40
index = 0x00320028
name = 'Queue.Delete'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Queue.DeleteOk']
# AMQP Method Attributes
__slots__ = ['ticket', 'queue', 'if_unused', 'if_empty', 'nowait']
# Class Attribute Types
_ticket = 'short'
_queue = 'shortstr'
_if_unused = 'bit'
_if_empty = 'bit'
_nowait = 'bit'
def __init__(self,
ticket=0,
queue='',
if_unused=False,
if_empty=False,
nowait=False):
"""Initialize the Queue.Delete class
:param int ticket: Deprecated
:param str queue:
:param bool if_unused: Delete only if unused
:param bool if_empty: Delete only if empty
:param bool nowait: Do not send a reply method
"""
# Deprecated
self.ticket = ticket
self.queue = queue
# Delete only if unused
self.if_unused = if_unused
# Delete only if empty
self.if_empty = if_empty
# Do not send a reply method
self.nowait = nowait
class DeleteOk(Frame):
"""Confirm deletion of a queue
This method confirms the deletion of a queue.
"""
# AMQP Method Number and Mapping Index
frame_id = 41
index = 0x00320029
name = 'Queue.DeleteOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['message_count']
# Class Attribute Types
_message_count = 'long'
def __init__(self, message_count=0):
"""Initialize the Queue.DeleteOk class
:param int/long message-count:
"""
self.message_count = message_count
class Unbind(Frame):
"""Unbind a queue from an exchange
This method unbinds a queue from an exchange.
"""
# AMQP Method Number and Mapping Index
frame_id = 50
index = 0x00320032
name = 'Queue.Unbind'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Queue.UnbindOk']
# AMQP Method Attributes
__slots__ = ['ticket', 'queue', 'exchange', 'routing_key', 'arguments']
# Class Attribute Types
_ticket = 'short'
_queue = 'shortstr'
_exchange = 'shortstr'
_routing_key = 'shortstr'
_arguments = 'table'
def __init__(self,
ticket=0,
queue='',
exchange='',
routing_key='',
arguments=None):
"""Initialize the Queue.Unbind class
:param int ticket: Deprecated
:param str queue:
:param str exchange:
:param str routing_key: Routing key of binding
:param dict arguments: Arguments of binding
"""
# Deprecated
self.ticket = ticket
self.queue = queue
self.exchange = exchange
# Routing key of binding
self.routing_key = routing_key
# Arguments of binding
self.arguments = arguments or {}
class UnbindOk(Frame):
"""Confirm unbind successful
This method confirms that the unbind was successful.
"""
# AMQP Method Number and Mapping Index
frame_id = 51
index = 0x00320033
name = 'Queue.UnbindOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Basic(object):
"""Work with basic content
The Basic class provides methods that support an industry-standard
messaging model.
"""
__slots__ = []
# AMQP Class Number and Mapping Index
frame_id = 60
index = 0x003C0000
class Qos(Frame):
"""Specify quality of service
This method requests a specific quality of service. The QoS can be
specified for the current channel or for all channels on the
connection. The particular properties and semantics of a qos method
always depend on the content class semantics. Though the qos method
could in principle apply to both peers, it is currently meaningful only
for the server.
"""
# AMQP Method Number and Mapping Index
frame_id = 10
index = 0x003C000A
name = 'Basic.Qos'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Basic.QosOk']
# AMQP Method Attributes
__slots__ = ['prefetch_size', 'prefetch_count', 'global_']
# Class Attribute Types
_prefetch_size = 'long'
_prefetch_count = 'short'
_global_ = 'bit'
def __init__(self, prefetch_size=0, prefetch_count=0, global_=False):
"""Initialize the Basic.Qos class
:param int/long prefetch_size: Prefetch window in octets
:param int prefetch_count: Prefetch window in messages
:param bool global_: Apply to entire connection
"""
# Prefetch window in octets
self.prefetch_size = prefetch_size
# Prefetch window in messages
self.prefetch_count = prefetch_count
# Apply to entire connection
self.global_ = global_
class QosOk(Frame):
"""Confirm the requested qos
This method tells the client that the requested QoS levels could be
handled by the server. The requested QoS applies to all active
consumers until a new QoS is defined.
"""
# AMQP Method Number and Mapping Index
frame_id = 11
index = 0x003C000B
name = 'Basic.QosOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Consume(Frame):
"""Start a queue consumer
This method asks the server to start a "consumer", which is a transient
request for messages from a specific queue. Consumers last as long as
the channel they were declared on, or until the client cancels them.
"""
# AMQP Method Number and Mapping Index
frame_id = 20
index = 0x003C0014
name = 'Basic.Consume'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Basic.ConsumeOk']
# AMQP Method Attributes
__slots__ = [
'ticket', 'queue', 'consumer_tag', 'no_local', 'no_ack',
'exclusive', 'nowait', 'arguments'
]
# Class Attribute Types
_ticket = 'short'
_queue = 'shortstr'
_consumer_tag = 'shortstr'
_no_local = 'bit'
_no_ack = 'bit'
_exclusive = 'bit'
_nowait = 'bit'
_arguments = 'table'
def __init__(self,
ticket=0,
queue='',
consumer_tag='',
no_local=False,
no_ack=False,
exclusive=False,
nowait=False,
arguments=None):
"""Initialize the Basic.Consume class
:param int ticket: Deprecated
:param str queue:
:param str consumer-tag:
:param bool no_local: Do not deliver own messages
:param bool no_ack: No acknowledgement needed
:param bool exclusive: Request exclusive access
:param bool nowait: Do not send a reply method
:param dict arguments: Arguments for declaration
"""
# Deprecated
self.ticket = ticket
self.queue = queue
self.consumer_tag = consumer_tag
# Do not deliver own messages
self.no_local = no_local
# No acknowledgement needed
self.no_ack = no_ack
# Request exclusive access
self.exclusive = exclusive
# Do not send a reply method
self.nowait = nowait
# Arguments for declaration
self.arguments = arguments or {}
class ConsumeOk(Frame):
"""Confirm a new consumer
The server provides the client with a consumer tag, which is used by
the client for methods called on the consumer at a later stage.
"""
# AMQP Method Number and Mapping Index
frame_id = 21
index = 0x003C0015
name = 'Basic.ConsumeOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['consumer_tag']
# Class Attribute Types
_consumer_tag = 'shortstr'
def __init__(self, consumer_tag=''):
"""Initialize the Basic.ConsumeOk class
:param str consumer-tag:
"""
self.consumer_tag = consumer_tag
class Cancel(Frame):
"""End a queue consumer
This method cancels a consumer. This does not affect already delivered
messages, but it does mean the server will not send any more messages
for that consumer. The client may receive an arbitrary number of
messages in between sending the cancel method and receiving the cancel-
ok reply.
"""
# AMQP Method Number and Mapping Index
frame_id = 30
index = 0x003C001E
name = 'Basic.Cancel'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Basic.CancelOk']
# AMQP Method Attributes
__slots__ = ['consumer_tag', 'nowait']
# Class Attribute Types
_consumer_tag = 'shortstr'
_nowait = 'bit'
def __init__(self, consumer_tag='', nowait=False):
"""Initialize the Basic.Cancel class
:param str consumer_tag: Consumer tag
:param bool nowait: Do not send a reply method
"""
# Consumer tag
self.consumer_tag = consumer_tag
# Do not send a reply method
self.nowait = nowait
class CancelOk(Frame):
"""Confirm a cancelled consumer
This method confirms that the cancellation was completed.
"""
# AMQP Method Number and Mapping Index
frame_id = 31
index = 0x003C001F
name = 'Basic.CancelOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['consumer_tag']
# Class Attribute Types
_consumer_tag = 'shortstr'
def __init__(self, consumer_tag=''):
"""Initialize the Basic.CancelOk class
:param str consumer_tag: Consumer tag
"""
# Consumer tag
self.consumer_tag = consumer_tag
class Publish(Frame):
"""Publish a message
This method publishes a message to a specific exchange. The message
will be routed to queues as defined by the exchange configuration and
distributed to any active consumers when the transaction, if any, is
committed.
"""
# AMQP Method Number and Mapping Index
frame_id = 40
index = 0x003C0028
name = 'Basic.Publish'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = [
'ticket', 'exchange', 'routing_key', 'mandatory', 'immediate'
]
# Class Attribute Types
_ticket = 'short'
_exchange = 'shortstr'
_routing_key = 'shortstr'
_mandatory = 'bit'
_immediate = 'bit'
def __init__(self,
ticket=0,
exchange='',
routing_key='',
mandatory=False,
immediate=False):
"""Initialize the Basic.Publish class
:param int ticket: Deprecated
:param str exchange:
:param str routing_key: Message routing key
:param bool mandatory: Indicate mandatory routing
:param bool immediate: Request immediate delivery
"""
# Deprecated
self.ticket = ticket
self.exchange = exchange
# Message routing key
self.routing_key = routing_key
# Indicate mandatory routing
self.mandatory = mandatory
# Request immediate delivery
self.immediate = immediate
class Return(Frame):
"""Return a failed message
This method returns an undeliverable message that was published with
the "immediate" flag set, or an unroutable message published with the
"mandatory" flag set. The reply code and text provide information about
the reason that the message was undeliverable.
"""
# AMQP Method Number and Mapping Index
frame_id = 50
index = 0x003C0032
name = 'Basic.Return'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['reply_code', 'reply_text', 'exchange', 'routing_key']
# Class Attribute Types
_reply_code = 'short'
_reply_text = 'shortstr'
_exchange = 'shortstr'
_routing_key = 'shortstr'
def __init__(self,
reply_code=0,
reply_text='',
exchange='',
routing_key=''):
"""Initialize the Basic.Return class
:param int reply_code: Reply code from server
:param str reply_text: Localised reply text
:param str exchange:
:param str routing_key: Message routing key
"""
# Reply code from server
self.reply_code = reply_code
# Localised reply text
self.reply_text = reply_text
self.exchange = exchange
# Message routing key
self.routing_key = routing_key
class Deliver(Frame):
"""Notify the client of a consumer message
This method delivers a message to the client, via a consumer. In the
asynchronous message delivery model, the client starts a consumer using
the Consume method, then the server responds with Deliver methods as
and when messages arrive for that consumer.
"""
# AMQP Method Number and Mapping Index
frame_id = 60
index = 0x003C003C
name = 'Basic.Deliver'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = [
'consumer_tag', 'delivery_tag', 'redelivered', 'exchange',
'routing_key'
]
# Class Attribute Types
_consumer_tag = 'shortstr'
_delivery_tag = 'longlong'
_redelivered = 'bit'
_exchange = 'shortstr'
_routing_key = 'shortstr'
def __init__(self,
consumer_tag='',
delivery_tag=None,
redelivered=False,
exchange='',
routing_key=''):
"""Initialize the Basic.Deliver class
:param str consumer_tag: Consumer tag
:param int/long delivery_tag: Server-assigned delivery tag
:param bool redelivered: Message is being redelivered
:param str exchange:
:param str routing_key: Message routing key
"""
# Consumer tag
self.consumer_tag = consumer_tag
# Server-assigned delivery tag
self.delivery_tag = delivery_tag
# Message is being redelivered
self.redelivered = redelivered
self.exchange = exchange
# Message routing key
self.routing_key = routing_key
class Get(Frame):
"""Direct access to a queue
This method provides a direct access to the messages in a queue using a
synchronous dialogue that is designed for specific types of application
where synchronous functionality is more important than performance.
"""
# AMQP Method Number and Mapping Index
frame_id = 70
index = 0x003C0046
name = 'Basic.Get'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Basic.GetOk', 'Basic.GetEmpty']
# AMQP Method Attributes
__slots__ = ['ticket', 'queue', 'no_ack']
# Class Attribute Types
_ticket = 'short'
_queue = 'shortstr'
_no_ack = 'bit'
def __init__(self, ticket=0, queue='', no_ack=False):
"""Initialize the Basic.Get class
:param int ticket: Deprecated
:param str queue:
:param bool no_ack: No acknowledgement needed
"""
# Deprecated
self.ticket = ticket
self.queue = queue
# No acknowledgement needed
self.no_ack = no_ack
class GetOk(Frame):
"""Provide client with a message
This method delivers a message to the client following a get method. A
message delivered by 'get-ok' must be acknowledged unless the no-ack
option was set in the get method.
"""
# AMQP Method Number and Mapping Index
frame_id = 71
index = 0x003C0047
name = 'Basic.GetOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = [
'delivery_tag', 'redelivered', 'exchange', 'routing_key',
'message_count'
]
# Class Attribute Types
_delivery_tag = 'longlong'
_redelivered = 'bit'
_exchange = 'shortstr'
_routing_key = 'shortstr'
_message_count = 'long'
def __init__(self,
delivery_tag=None,
redelivered=False,
exchange='',
routing_key='',
message_count=0):
"""Initialize the Basic.GetOk class
:param int/long delivery_tag: Server-assigned delivery tag
:param bool redelivered: Message is being redelivered
:param str exchange:
:param str routing_key: Message routing key
:param int/long message_count: Number of messages in queue
"""
# Server-assigned delivery tag
self.delivery_tag = delivery_tag
# Message is being redelivered
self.redelivered = redelivered
self.exchange = exchange
# Message routing key
self.routing_key = routing_key
# Number of messages in queue
self.message_count = message_count
class GetEmpty(Frame):
"""Indicate no messages available
This method tells the client that the queue has no messages available
for the client.
"""
# AMQP Method Number and Mapping Index
frame_id = 72
index = 0x003C0048
name = 'Basic.GetEmpty'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['cluster_id']
# Class Attribute Types
_cluster_id = 'shortstr'
def __init__(self, cluster_id=''):
"""Initialize the Basic.GetEmpty class
:param str cluster_id: Deprecated
"""
# Deprecated
self.cluster_id = cluster_id
class Ack(Frame):
"""Acknowledge one or more messages
This method acknowledges one or more messages delivered via the Deliver
or Get-Ok methods. The client can ask to confirm a single message or a
set of messages up to and including a specific message.
"""
# AMQP Method Number and Mapping Index
frame_id = 80
index = 0x003C0050
name = 'Basic.Ack'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['delivery_tag', 'multiple']
# Class Attribute Types
_delivery_tag = 'longlong'
_multiple = 'bit'
def __init__(self, delivery_tag=0, multiple=False):
"""Initialize the Basic.Ack class
:param int/long delivery_tag: Server-assigned delivery tag
:param bool multiple: Acknowledge multiple messages
"""
# Server-assigned delivery tag
self.delivery_tag = delivery_tag
# Acknowledge multiple messages
self.multiple = multiple
class Reject(Frame):
"""Reject an incoming message
This method allows a client to reject a message. It can be used to
interrupt and cancel large incoming messages, or return untreatable
messages to their original queue.
"""
# AMQP Method Number and Mapping Index
frame_id = 90
index = 0x003C005A
name = 'Basic.Reject'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['delivery_tag', 'requeue']
# Class Attribute Types
_delivery_tag = 'longlong'
_requeue = 'bit'
def __init__(self, delivery_tag=None, requeue=True):
"""Initialize the Basic.Reject class
:param int/long delivery_tag: Server-assigned delivery tag
:param bool requeue: Requeue the message
"""
# Server-assigned delivery tag
self.delivery_tag = delivery_tag
# Requeue the message
self.requeue = requeue
class RecoverAsync(Frame):
"""Redeliver unacknowledged messages
This method asks the server to redeliver all unacknowledged messages on
a specified channel. Zero or more messages may be redelivered. This
method is deprecated in favour of the synchronous Recover/Recover-Ok.
"""
# AMQP Method Number and Mapping Index
frame_id = 100
index = 0x003C0064
name = 'Basic.RecoverAsync'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['requeue']
# Class Attribute Types
_requeue = 'bit'
def __init__(self, requeue=False):
"""Initialize the Basic.RecoverAsync class
:param bool requeue: Requeue the message
.. deprecated:: 0-9-1
This command is deprecated in AMQP 0-9-1
"""
# Requeue the message
self.requeue = requeue
# This command is deprecated in AMQP 0-9-1
warnings.warn(DEPRECATION_WARNING, category=DeprecationWarning)
class Recover(Frame):
"""Redeliver unacknowledged messages
This method asks the server to redeliver all unacknowledged messages on
a specified channel. Zero or more messages may be redelivered. This
method replaces the asynchronous Recover.
"""
# AMQP Method Number and Mapping Index
frame_id = 110
index = 0x003C006E
name = 'Basic.Recover'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Basic.RecoverOk']
# AMQP Method Attributes
__slots__ = ['requeue']
# Class Attribute Types
_requeue = 'bit'
def __init__(self, requeue=False):
"""Initialize the Basic.Recover class
:param bool requeue: Requeue the message
"""
# Requeue the message
self.requeue = requeue
class RecoverOk(Frame):
"""Confirm recovery
This method acknowledges a Basic.Recover method.
"""
# AMQP Method Number and Mapping Index
frame_id = 111
index = 0x003C006F
name = 'Basic.RecoverOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Nack(Frame):
# AMQP Method Number and Mapping Index
frame_id = 120
index = 0x003C0078
name = 'Basic.Nack'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Method Attributes
__slots__ = ['delivery_tag', 'multiple', 'requeue']
# Class Attribute Types
_delivery_tag = 'longlong'
_multiple = 'bit'
_requeue = 'bit'
def __init__(self, delivery_tag=0, multiple=False, requeue=True):
"""Initialize the Basic.Nack class
:param int/long delivery_tag: Server-assigned delivery tag
:param bool multiple:
:param bool requeue:
"""
# Server-assigned delivery tag
self.delivery_tag = delivery_tag
self.multiple = multiple
self.requeue = requeue
class Properties(PropertiesBase):
"""Content Properties"""
name = 'Basic.Properties'
__slots__ = [
'content_type', 'content_encoding', 'headers', 'delivery_mode',
'priority', 'correlation_id', 'reply_to', 'expiration',
'message_id', 'timestamp', 'message_type', 'user_id', 'app_id',
'cluster_id'
]
# Flag Values
flags = {
'content_type': 32768,
'content_encoding': 16384,
'headers': 8192,
'delivery_mode': 4096,
'priority': 2048,
'correlation_id': 1024,
'reply_to': 512,
'expiration': 256,
'message_id': 128,
'timestamp': 64,
'message_type': 32,
'user_id': 16,
'app_id': 8,
'cluster_id': 4
}
# Class Attribute Types
_content_type = 'shortstr'
_content_encoding = 'shortstr'
_headers = 'table'
_delivery_mode = 'octet'
_priority = 'octet'
_correlation_id = 'shortstr'
_reply_to = 'shortstr'
_expiration = 'shortstr'
_message_id = 'shortstr'
_timestamp = 'timestamp'
_message_type = 'shortstr'
_user_id = 'shortstr'
_app_id = 'shortstr'
_cluster_id = 'shortstr'
frame_id = 60
index = 0x003C
def __init__(self,
content_type='',
content_encoding='',
headers=None,
delivery_mode=None,
priority=None,
correlation_id='',
reply_to='',
expiration='',
message_id='',
timestamp=None,
message_type='',
user_id='',
app_id='',
cluster_id=''):
"""Initialize the Basic.Properties class
Note that the AMQP property type is named message_type as to
not conflict with the Python type keyword
:param str content_type: MIME content type
:param str content_encoding: MIME content encoding
:param dict headers: Message header field table
:param int delivery_mode: Non-persistent (1) or persistent (2)
:param int priority: Message priority, 0 to 9
:param str correlation_id: Application correlation identifier
:param str reply_to: Address to reply to
:param str expiration: Message expiration specification
:param str message_id: Application message identifier
:param struct_time timestamp: Message timestamp
:param str message_type: Message type name
:param str user_id: Creating user id
:param str app_id: Creating application id
:param str cluster_id: Deprecated
"""
# MIME content type
self.content_type = content_type
# MIME content encoding
self.content_encoding = content_encoding
# Message header field table
self.headers = headers
# Non-persistent (1) or persistent (2)
self.delivery_mode = delivery_mode
# Message priority, 0 to 9
self.priority = priority
# Application correlation identifier
self.correlation_id = correlation_id
# Address to reply to
self.reply_to = reply_to
# Message expiration specification
self.expiration = expiration
# Application message identifier
self.message_id = message_id
# Message timestamp
self.timestamp = timestamp
# Message type name
self.message_type = message_type
# Creating user id
self.user_id = user_id
# Creating application id
self.app_id = app_id
# Deprecated
self.cluster_id = cluster_id
class Tx(object):
"""Work with transactions
The Tx class allows publish and ack operations to be batched into atomic
units of work. The intention is that all publish and ack requests issued
within a transaction will complete successfully or none of them will.
Servers SHOULD implement atomic transactions at least where all publish or
ack requests affect a single queue. Transactions that cover multiple
queues may be non-atomic, given that queues can be created and destroyed
asynchronously, and such events do not form part of any transaction.
Further, the behaviour of transactions with respect to the immediate and
mandatory flags on Basic.Publish methods is not defined.
"""
__slots__ = []
# AMQP Class Number and Mapping Index
frame_id = 90
index = 0x005A0000
class Select(Frame):
"""Select standard transaction mode
This method sets the channel to use standard transactions. The client
must use this method at least once on a channel before using the Commit
or Rollback methods.
"""
# AMQP Method Number and Mapping Index
frame_id = 10
index = 0x005A000A
name = 'Tx.Select'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Tx.SelectOk']
class SelectOk(Frame):
"""Confirm transaction mode
This method confirms to the client that the channel was successfully
set to use standard transactions.
"""
# AMQP Method Number and Mapping Index
frame_id = 11
index = 0x005A000B
name = 'Tx.SelectOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Commit(Frame):
"""Commit the current transaction
This method commits all message publications and acknowledgments
performed in the current transaction. A new transaction starts
immediately after a commit.
"""
# AMQP Method Number and Mapping Index
frame_id = 20
index = 0x005A0014
name = 'Tx.Commit'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Tx.CommitOk']
class CommitOk(Frame):
"""Confirm a successful commit
This method confirms to the client that the commit succeeded. Note that
if a commit fails, the server raises a channel exception.
"""
# AMQP Method Number and Mapping Index
frame_id = 21
index = 0x005A0015
name = 'Tx.CommitOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Rollback(Frame):
"""Abandon the current transaction
This method abandons all message publications and acknowledgments
performed in the current transaction. A new transaction starts
immediately after a rollback. Note that unacked messages will not be
automatically redelivered by rollback; if that is required an explicit
recover call should be issued.
"""
# AMQP Method Number and Mapping Index
frame_id = 30
index = 0x005A001E
name = 'Tx.Rollback'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Tx.RollbackOk']
class RollbackOk(Frame):
"""Confirm successful rollback
This method confirms to the client that the rollback succeeded. Note
that if an rollback fails, the server raises a channel exception.
"""
# AMQP Method Number and Mapping Index
frame_id = 31
index = 0x005A001F
name = 'Tx.RollbackOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
class Confirm(object):
__slots__ = []
# AMQP Class Number and Mapping Index
frame_id = 85
index = 0x00550000
class Select(Frame):
# AMQP Method Number and Mapping Index
frame_id = 10
index = 0x0055000A
name = 'Confirm.Select'
# Specifies if this is a synchronous AMQP method
synchronous = True
# Valid responses to this method
valid_responses = ['Confirm.SelectOk']
# AMQP Method Attributes
__slots__ = ['nowait']
# Class Attribute Types
_nowait = 'bit'
def __init__(self, nowait=False):
"""Initialize the Confirm.Select class
:param bool nowait: Do not send a reply method
"""
# Do not send a reply method
self.nowait = nowait
class SelectOk(Frame):
# AMQP Method Number and Mapping Index
frame_id = 11
index = 0x0055000B
name = 'Confirm.SelectOk'
# Specifies if this is a synchronous AMQP method
synchronous = False
# AMQP Class.Method Index Mapping
INDEX_MAPPING = {
0x000A000A: Connection.Start,
0x000A000B: Connection.StartOk,
0x000A0014: Connection.Secure,
0x000A0015: Connection.SecureOk,
0x000A001E: Connection.Tune,
0x000A001F: Connection.TuneOk,
0x000A0028: Connection.Open,
0x000A0029: Connection.OpenOk,
0x000A0032: Connection.Close,
0x000A0033: Connection.CloseOk,
0x000A003C: Connection.Blocked,
0x000A003D: Connection.Unblocked,
0x0014000A: Channel.Open,
0x0014000B: Channel.OpenOk,
0x00140014: Channel.Flow,
0x00140015: Channel.FlowOk,
0x00140028: Channel.Close,
0x00140029: Channel.CloseOk,
0x0028000A: Exchange.Declare,
0x0028000B: Exchange.DeclareOk,
0x00280014: Exchange.Delete,
0x00280015: Exchange.DeleteOk,
0x0028001E: Exchange.Bind,
0x0028001F: Exchange.BindOk,
0x00280028: Exchange.Unbind,
0x00280033: Exchange.UnbindOk,
0x0032000A: Queue.Declare,
0x0032000B: Queue.DeclareOk,
0x00320014: Queue.Bind,
0x00320015: Queue.BindOk,
0x0032001E: Queue.Purge,
0x0032001F: Queue.PurgeOk,
0x00320028: Queue.Delete,
0x00320029: Queue.DeleteOk,
0x00320032: Queue.Unbind,
0x00320033: Queue.UnbindOk,
0x003C000A: Basic.Qos,
0x003C000B: Basic.QosOk,
0x003C0014: Basic.Consume,
0x003C0015: Basic.ConsumeOk,
0x003C001E: Basic.Cancel,
0x003C001F: Basic.CancelOk,
0x003C0028: Basic.Publish,
0x003C0032: Basic.Return,
0x003C003C: Basic.Deliver,
0x003C0046: Basic.Get,
0x003C0047: Basic.GetOk,
0x003C0048: Basic.GetEmpty,
0x003C0050: Basic.Ack,
0x003C005A: Basic.Reject,
0x003C0064: Basic.RecoverAsync,
0x003C006E: Basic.Recover,
0x003C006F: Basic.RecoverOk,
0x003C0078: Basic.Nack,
0x005A000A: Tx.Select,
0x005A000B: Tx.SelectOk,
0x005A0014: Tx.Commit,
0x005A0015: Tx.CommitOk,
0x005A001E: Tx.Rollback,
0x005A001F: Tx.RollbackOk,
0x0055000A: Confirm.Select,
0x0055000B: Confirm.SelectOk
}
pamqp-2.3.0/requirements.txt 0000664 0000000 0000000 00000000257 13456152267 0016135 0 ustar 00root root 0000000 0000000 codecov
coverage
flake8
flake8-comprehensions
flake8-deprecated
flake8-html
flake8-import-order
flake8-quotes
flake8-rst-docstrings
flake8-tuple
lxml
mock
nose
unittest2
yapf
pamqp-2.3.0/setup.cfg 0000664 0000000 0000000 00000000571 13456152267 0014471 0 ustar 00root root 0000000 0000000 [wheel]
universal=1
[nosetests]
cover-branches=1
cover-html=true
cover-html-dir=coverage
cover-package=pamqp
cover-xml=true
cover-xml-file=coverage.xml
logging-level=DEBUG
verbosity=2
with-coverage=1
with-xunit=true
xunit-file=xunit.xml
[flake8]
application-import-names=pamqp
ignore=RST303,RST399,W504,F821
exclude=bin,build,codegen,docs,env,env2.7
import-order-style=google pamqp-2.3.0/setup.py 0000664 0000000 0000000 00000002273 13456152267 0014363 0 ustar 00root root 0000000 0000000 import setuptools
from pamqp import __version__
setuptools.setup(
name='pamqp',
version=__version__,
description='RabbitMQ Focused AMQP low-level library',
long_description=open('README.rst').read(),
author='Gavin M. Roy',
author_email='gavinmroy@gmail.com',
url='http://pamqp.readthedocs.org',
package_data={'': ['LICENSE', 'README.rst']},
packages=['pamqp', 'pamqp.codec'],
extras_require={'codegen': ['lxml']},
license='BSD',
classifiers=[
'Development Status :: 5 - Production/Stable',
'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',
'Programming Language :: Python :: 3.7',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Topic :: Communications',
'Topic :: Internet',
'Topic :: Software Development :: Libraries'
],
zip_safe=True)
pamqp-2.3.0/tests/ 0000775 0000000 0000000 00000000000 13456152267 0014007 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/tests/test_decoding.py 0000664 0000000 0000000 00000072017 13456152267 0017203 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
import decimal
import struct
import time
import unittest
from pamqp import decode, PYTHON3
if PYTHON3:
long = int
unicode = None
basestring = (bytes, str)
PLATFORM_32BIT = (struct.calcsize('P') * 8) == 32
PLATFORM_64BIT = (struct.calcsize('P') * 8) == 64
def _utf8_key(value):
return value.decode('utf-8') if not PYTHON3 else value
class CodecDecodeTests(unittest.TestCase):
FIELD_ARR = (b'\x00\x00\x00@s\x00\x01I\x00\x00\xaf\xc8S\x00\x00'
b'\x00\x08Test \xe2\x9c\x88T\x00\x00\x00\x00Ec)\x92'
b'I\xbb\x9a\xca\x00D\x02\x00\x00\x01:f@H\xf5\xc3l'
b'\x00\x00\x00\x00\xc4e5\xffl\x80\x00\x00\x00\x00'
b'\x00\x00\x08')
FIELD_ARR_VALUE = [
1, 45000, b'Test \xe2\x9c\x88',
time.struct_time((2006, 11, 21, 16, 30, 10, 1, 325, 0)), -1147483648,
decimal.Decimal('3.14'), 3.14, 3294967295, -9223372036854775800
]
FIELD_TBL = (
b'\x00\x00\x00\x9d\x08arrayvalA\x00\x00\x00\ts\x00\x01s\x00\x02s\x00'
b'\x03\x07boolvalt\x01\x06decvalD\x02\x00\x00\x01:\x07dictvalF\x00'
b'\x00\x00\r\x04f\xe2\x9c\x89S\x00\x00\x00\x03\xe2\x9c\x90\x08'
b'floatvalf@H\xf5\xc3\x06intvals\x00\x01\x07longvalI6e&U\x06strvalS'
b'\x00\x00\x00\x08Test \xe2\x9c\x88\x0ctimestampvalT\x00\x00\x00'
b'\x00Ec)\x92\x04\xf0\x9f\x90\xb0V'
)
FIELD_TBL_VALUE = {
'intval': 1,
'strval': b'Test \xe2\x9c\x88',
'boolval': True,
'timestampval': time.struct_time(
(2006, 11, 21, 16, 30, 10, 1, 325, 0)),
'decval': decimal.Decimal('3.14'),
_utf8_key('🐰'): None,
'floatval': 3.14,
'longval': long(912598613),
'dictval': {
_utf8_key('f✉'): b'\xe2\x9c\x90'
},
'arrayval': [1, 2, 3]
}
def test_decode_by_type_invalid_data_type(self):
self.assertRaises(ValueError, decode.by_type, b'Z\x00', b'foobar')
def test_decode_bit_bytes_consumed(self):
self.assertEqual(decode.bit(b'\xff', 4)[0], 0)
def test_decode_invalid_value(self):
self.assertRaises(ValueError, decode.bit, b'\xff', None)
def test_decode_bit_on(self):
self.assertTrue(decode.bit(b'\xff', 4)[1])
def test_decode_bit_off(self):
self.assertFalse(decode.bit(b'\x0f', 4)[1])
def test_decode_boolean_bytes_consumed(self):
self.assertEqual(decode.boolean(b'\x01')[0], 1)
def test_decode_boolean_false(self):
self.assertFalse(decode.boolean(b'\x00')[1])
def test_decode_boolean_false_data_type(self):
self.assertIsInstance(decode.boolean(b'\x00')[1], bool)
def test_decode_boolean_invalid_value(self):
self.assertRaises(ValueError, decode.boolean, None)
def test_decode_boolean_true(self):
self.assertTrue(decode.boolean(b'\x01')[1])
def test_decode_boolean_true_data_type(self):
self.assertIsInstance(decode.boolean(b'\x01')[1], bool)
def test_decode_byte_array(self):
self.assertEqual(decode.byte_array(b'\x00\x00\x00\x03ABC'),
(7, bytearray([65, 66, 67])))
def test_decode_byte_array_invalid_value(self):
self.assertRaises(ValueError, decode.byte_array, None)
def test_decode_decimal_value_bytes_consumed(self):
value = b'\x05\x00\x04\xcb/'
self.assertEqual(decode.decimal(value)[0], len(value))
def test_decode_decimal_value_data_type(self):
value = b'\x05\x00\x04\xcb/'
self.assertIsInstance(decode.decimal(value)[1], decimal.Decimal)
def test_decode_decimal_value(self):
value = b'\x05\x00\x04\xcb/'
self.assertEqual(round(float(decode.decimal(value)[1]), 5),
round(float(decimal.Decimal('3.14159')), 5))
def test_decode_decimal_invalid_value(self):
self.assertRaises(ValueError, decode.decimal, False)
def test_decode_double_value(self):
value = b'@\t!\xf9\xf0\x1b\x86n'
self.assertEqual(round(decode.double(value)[1], 5),
round(float(3.14159), 5))
def test_decode_double_invalid_value(self):
self.assertRaises(ValueError, decode.double, 123)
def test_decode_embedded_value_null(self):
self.assertEqual(decode._embedded_value(b'\00')[1], None)
def test_decode_embedded_value_invalid_data(self):
self.assertRaises(ValueError, decode._embedded_value, b'Z\x00')
def test_decode_floating_point_bytes_consumed(self):
value = b'@I\x0f\xd0'
self.assertEqual(decode.floating_point(value)[0], 4)
def test_decode_floating_point_data_type(self):
value = b'@I\x0f\xd0'
self.assertIsInstance(decode.floating_point(value)[1], float)
def test_decode_floating_point_invalid_value(self):
self.assertRaises(ValueError, decode.floating_point, False)
def test_decode_floating_point_value(self):
value = b'@I\x0f\xd0'
self.assertEqual(round(decode.floating_point(value)[1], 5),
round(float(3.14159), 5))
def test_decode_long_int_bytes_consumed(self):
value = b'\x7f\xff\xff\xff'
self.assertEqual(decode.long_int(value)[0], 4)
def test_decode_long_int_data_type(self):
value = b'\x7f\xff\xff\xff'
self.assertIsInstance(decode.long_int(value)[1], int)
def test_decode_long_int_invalid_value(self):
self.assertRaises(ValueError, decode.long_int, None)
def test_decode_long_int_value(self):
value = b'\x7f\xff\xff\xff'
self.assertEqual(decode.long_int(value)[1], 2147483647)
def test_decode_long_long_int_bytes_consumed(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertEqual(decode.long_long_int(value)[0], 8)
@unittest.skipIf(PLATFORM_32BIT, 'Skipped on 32-bit platforms')
def test_decode_long_long_int_data_type_64bit(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertIsInstance(decode.long_long_int(value)[1], int)
@unittest.skipIf(PLATFORM_64BIT, 'Skipped on 64-bit platforms')
def test_decode_long_long_int_data_type_32bit(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertIsInstance(decode.long_long_int(value)[1], long)
def test_decode_long_long_int_invalid_value(self):
self.assertRaises(ValueError, decode.long_long_int, None)
def test_decode_long_long_int_value(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertEqual(decode.long_long_int(value)[1], 9223372036854775800)
def test_decode_long_str_bytes_consumed(self):
value = b'\x00\x00\x00\n0123456789'
self.assertEqual(decode.long_str(value)[0], 14)
def test_decode_long_str_data_type(self):
value = b'\x00\x00\x00\n0123456789'
self.assertIsInstance(decode.long_str(value)[1], basestring)
def test_decode_long_str_data_type_unicode(self):
self.assertIsInstance(
decode.long_str(b'\x00\x00\x00\x0c\xd8\xa7'
b'\xd8\xae\xd8\xaa\xd8\xa8'
b'\xd8\xa7\xd8\xb1')[1], bytes)
def test_decode_long_str_invalid_value(self):
self.assertRaises(ValueError, decode.long_str, None)
def test_decode_long_str_value(self):
value = b'\x00\x00\x00\n0123456789'
self.assertEqual(decode.long_str(value)[1], b'0123456789')
def test_decode_octet_bytes_consumed(self):
value = b'\xff'
self.assertEqual(decode.octet(value)[0], 1)
def test_decode_octet_data_type(self):
value = b'\xff'
self.assertIsInstance(decode.octet(value)[1], int)
def test_decode_octet_invalid_value(self):
self.assertRaises(ValueError, decode.octet, None)
def test_decode_octet_value(self):
value = b'\xff'
self.assertEqual(decode.octet(value)[1], 255)
def test_decode_short_int_bytes_consumed(self):
value = b'\x7f\xff'
self.assertEqual(decode.short_int(value)[0], 2)
def test_decode_short_int_data_type(self):
value = b'\x7f\xff'
self.assertIsInstance(decode.short_int(value)[0], int)
def test_decode_short_int_invalid_value(self):
self.assertRaises(ValueError, decode.short_int, None)
def test_decode_short_int_value(self):
value = b'\x7f\xff'
self.assertEqual(decode.short_int(value)[1], 32767)
def test_decode_short_short_int_data_type(self):
self.assertIsInstance(decode.short_short_int(b'\xff')[0], int)
def test_decode_short_short_int_invalid_value(self):
self.assertRaises(ValueError, decode.short_short_int, None)
def test_decode_short_short_int_value(self):
self.assertEqual(decode.short_short_int(b'\xff')[1], 255)
def test_decode_short_str_bytes_consumed(self):
self.assertEqual(decode.short_str(b'\n0123456789')[0], 11)
def test_decode_short_str_data_type(self):
self.assertIsInstance(decode.short_str(b'\n0123456789')[1], basestring)
def test_decode_short_str_invalid_value(self):
self.assertRaises(ValueError, decode.short_str, None)
def test_decode_short_str_value(self):
self.assertEqual(decode.short_str(b'\n0123456789')[1], '0123456789')
def test_decode_timestamp_bytes_consumed(self):
self.assertEqual(decode.timestamp(b'\x00\x00\x00\x00Ec)\x92')[0], 8)
def test_decode_timestamp_data_type(self):
self.assertIsInstance(
decode.timestamp(b'\x00\x00\x00\x00Ec)\x92')[1], time.struct_time)
def test_decode_timestamp_invalid_value(self):
self.assertRaises(ValueError, decode.timestamp, None)
def test_decode_timestamp_value(self):
self.assertEqual(
decode.timestamp(b'\x00\x00\x00\x00Ec)\x92')[1],
time.struct_time((2006, 11, 21, 16, 30, 10, 1, 325, 0)))
def test_decode_field_array_bytes_consumed(self):
self.assertEqual(
decode.field_array(self.FIELD_ARR)[0], len(self.FIELD_ARR))
def test_decode_field_array_data_type(self):
self.assertIsInstance(decode.field_array(self.FIELD_ARR)[1], list)
def test_decode_field_array_invalid_value(self):
self.assertRaises(ValueError, decode.field_array, None)
def test_decode_field_array_value(self):
value = decode.field_array(self.FIELD_ARR)[1]
for position in range(0, len(value)):
if isinstance(value[position], float):
self.assertAlmostEqual(
round(value[position], 3),
round(self.FIELD_ARR_VALUE[position], 3))
else:
self.assertEqual(value[position],
self.FIELD_ARR_VALUE[position])
def test_decode_field_table_bytes_consumed(self):
self.assertEqual(
decode.field_table(self.FIELD_TBL)[0], len(self.FIELD_TBL))
def test_decode_field_table_data_type(self):
self.assertIsInstance(decode.field_table(self.FIELD_TBL)[1], dict)
def test_decode_field_table_invalid_value(self):
self.assertRaises(ValueError, decode.field_table, None)
def test_decode_field_table_value(self):
value = decode.field_table(self.FIELD_TBL)[1]
for key in self.FIELD_TBL_VALUE.keys():
if isinstance(value[key], float):
self.assertAlmostEqual(round(value[key], 3),
round(self.FIELD_TBL_VALUE[key], 3))
else:
self.assertEqual(value[key], self.FIELD_TBL_VALUE[key])
def test_decode_by_type_bit_bytes_consumed(self):
self.assertEqual(decode.by_type(b'\xff', 'bit', 4)[0], 0)
def test_decode_by_type_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, b'\xff', 'bit', None)
def test_decode_by_type_bit_on(self):
self.assertTrue(decode.by_type(b'\xff', 'bit', 4)[1])
def test_decode_by_type_bit_off(self):
self.assertFalse(decode.by_type(b'\x0f', 'bit', 4)[1])
def test_decode_by_type_boolean_bytes_consumed(self):
self.assertEqual(decode.by_type(b'\x01', 'boolean')[0], 1)
def test_decode_by_type_boolean_false(self):
self.assertFalse(decode.by_type(b'\x00', 'boolean')[1])
def test_decode_by_type_boolean_false_data_type(self):
self.assertIsInstance(decode.by_type(b'\x00', 'boolean')[1], bool)
def test_decode_by_type_boolean_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'boolean')
def test_decode_by_type_boolean_true(self):
self.assertTrue(decode.by_type(b'\x01', 'boolean')[1])
def test_decode_by_type_boolean_true_data_type(self):
self.assertIsInstance(decode.by_type(b'\x01', 'boolean')[1], bool)
def test_decode_by_type_byte_array_bytes_consumed(self):
value = b'\x00\x00\x00\t123456789'
self.assertEqual(decode.by_type(value, 'byte_array')[0], 13)
def test_decode_by_type_byte_array_data_type(self):
value = b'\x00\x00\x00\t123456789'
self.assertIsInstance(
decode.by_type(value, 'byte_array')[1], bytearray)
def test_decode_by_type_byte_array_value(self):
value = b'\x00\x00\x00\t123456789'
self.assertEqual(
decode.by_type(value, 'byte_array')[1], bytearray(b'123456789'))
def test_decode_by_type_decimal_bytes_consumed(self):
value = b'\x05\x00\x04\xcb/'
self.assertEqual(decode.by_type(value, 'decimal')[0], len(value))
def test_decode_by_type_decimal_data_type(self):
self.assertIsInstance(
decode.by_type(b'\x05\x00\x04\xcb/', 'decimal')[1],
decimal.Decimal)
def test_decode_by_type_decimal_value(self):
self.assertEqual(
round(float(decode.by_type(b'\x05\x00\x04\xcb/', 'decimal')[1]),
5), round(float(decimal.Decimal('3.14159')), 5))
def test_decode_by_type_decimal_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, False, 'decimal')
def test_decode_by_type_double_data_type(self):
value = b'C\x0f\xd8\x91\x14\xb9\xc3\x98'
self.assertIsInstance(decode.by_type(value, 'double')[1], float)
def test_decode_by_type_double_bytes_consumed(self):
value = b'C\x0f\xd8\x91\x14\xb9\xc3\x98'
self.assertEqual(decode.by_type(value, 'double')[0], 8)
def test_decode_by_type_double_value(self):
value = b'C\x0f\xd8\x91\x14\xb9\xc3\x98'
self.assertEqual(
decode.by_type(value, 'double')[1], 1120480238450803.0)
def test_decode_by_type_floating_point_data_type(self):
self.assertIsInstance(decode.by_type(b'@I\x0f\xd0', 'float')[1], float)
def test_decode_by_type_float_bytes_consumed(self):
self.assertEqual(decode.by_type(b'@I\x0f\xd0', 'float')[0], 4)
def test_decode_by_type_floating_point_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, False, 'float')
def test_decode_by_type_floating_point_value(self):
value = b'@I\x0f\xd0'
self.assertEqual(round(decode.by_type(value, 'float')[1], 5),
round(float(3.14159), 5))
def test_decode_by_type_long_bytes_consumed(self):
value = b'\x7f\xff\xff\xff'
self.assertEqual(decode.by_type(value, 'long')[0], 4)
def test_decode_by_type_long_data_type(self):
value = b'\x7f\xff\xff\xff'
self.assertIsInstance(decode.by_type(value, 'long')[1], int)
def test_decode_by_type_long_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'long')
def test_decode_by_type_long_value(self):
value = b'\x7f\xff\xff\xff'
self.assertEqual(decode.by_type(value, 'long')[1], 2147483647)
def test_decode_by_type_long_long_bytes_consumed(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertEqual(decode.by_type(value, 'longlong')[0], 8)
@unittest.skipIf(PLATFORM_64BIT, 'Skipped on 64-bit platforms')
def test_decode_by_type_long_long_data_type_32bit(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertIsInstance(decode.by_type(value, 'longlong')[1], long)
@unittest.skipIf(PLATFORM_32BIT, 'Skipped on 32-bit platforms')
def test_decode_by_type_long_long_data_type_64bit(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertIsInstance(decode.by_type(value, 'longlong')[1], int)
def test_decode_by_type_long_long_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'longlong')
def test_decode_by_type_long_long_value(self):
value = b'\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertEqual(
decode.by_type(value, 'longlong')[1], 9223372036854775800)
def test_decode_by_type_longstr_bytes_consumed(self):
value = b'\x00\x00\x00\n0123456789'
self.assertEqual(decode.by_type(value, 'longstr')[0], 14)
def test_decode_by_type_longstr_data_type_with_unicode(self):
value = b'\x00\x00\x00\x08Test \xe2\x9c\x88'
self.assertIsInstance(decode.by_type(value, 'longstr')[1], bytes)
def test_decode_by_type_longstr_data_type(self):
value = b'\x00\x00\x00\n0123456789'
self.assertIsInstance(decode.by_type(value, 'longstr')[1], basestring)
def test_decode_by_type_longstr_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'longstr')
def test_decode_by_type_longstr_value(self):
value = b'\x00\x00\x00\n0123456789'
self.assertEqual(decode.by_type(value, 'longstr')[1], b'0123456789')
def test_decode_by_type_octet_bytes_consumed(self):
self.assertEqual(decode.by_type(b'\xff', 'octet')[0], 1)
def test_decode_by_type_octet_data_type(self):
self.assertIsInstance(decode.by_type(b'\xff', 'octet')[1], int)
def test_decode_by_type_octet_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'octet')
def test_decode_by_type_octet_value(self):
self.assertEqual(decode.by_type(b'\xff', 'octet')[1], 255)
def test_decode_by_type_short_bytes_consumed(self):
value = b'\x7f\xff'
self.assertEqual(decode.by_type(value, 'short')[0], 2)
def test_decode_by_type_short_data_type(self):
value = b'\x7f\xff'
self.assertIsInstance(decode.by_type(value, 'short')[1], int)
def test_decode_by_type_short_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'short')
def test_decode_by_type_short_value(self):
value = b'\x7f\xff'
self.assertEqual(decode.by_type(value, 'short')[1], 32767)
def test_decode_by_type_timestamp_bytes_consumed(self):
value = b'\x00\x00\x00\x00Ec)\x92'
self.assertEqual(decode.by_type(value, 'timestamp')[0], 8)
def test_decode_by_type_timestamp_data_type(self):
value = b'\x00\x00\x00\x00Ec)\x92'
self.assertIsInstance(
decode.by_type(value, 'timestamp')[1], time.struct_time)
def test_decode_by_type_timestamp_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'timestamp')
def test_decode_by_type_timestamp_value(self):
value = b'\x00\x00\x00\x00Ec)\x92'
self.assertEqual(
decode.by_type(value, 'timestamp')[1],
time.struct_time((2006, 11, 21, 16, 30, 10, 1, 325, 0)))
def test_decode_by_type_void(self):
self.assertIsNone(decode.by_type(b'', 'void'))
def test_decode_by_type_field_array_bytes_consumed(self):
self.assertEqual(
decode.by_type(self.FIELD_ARR, 'array')[0], len(self.FIELD_ARR))
def test_decode_by_type_field_array_data_type(self):
self.assertIsInstance(decode.by_type(self.FIELD_ARR, 'array')[1], list)
def test_decode_by_type_field_array_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'array')
def test_decode_by_type_field_array_value(self):
value = decode.by_type(self.FIELD_ARR, 'array')[1]
for position in range(0, len(value)):
if isinstance(value[position], float):
self.assertAlmostEqual(
round(value[position], 3),
round(self.FIELD_ARR_VALUE[position], 3))
else:
self.assertEqual(value[position],
self.FIELD_ARR_VALUE[position])
def test_decode_by_type_field_table_bytes_consumed(self):
self.assertEqual(
decode.by_type(self.FIELD_TBL, 'table')[0], len(self.FIELD_TBL))
def test_decode_by_type_field_table_data_type(self):
self.assertIsInstance(decode.by_type(self.FIELD_TBL, 'table')[1], dict)
def test_decode_by_type_field_table_invalid_value(self):
self.assertRaises(ValueError, decode.by_type, None, 'table')
def test_decode_by_type_field_table_value(self):
value = decode.by_type(self.FIELD_TBL, 'table')[1]
for key in self.FIELD_TBL_VALUE.keys():
if isinstance(value[key], float):
self.assertAlmostEqual(round(value[key], 3),
round(self.FIELD_TBL_VALUE[key], 3))
else:
self.assertEqual(value[key], self.FIELD_TBL_VALUE[key])
def test_decode_embedded_value_empty_bytes_consumed(self):
self.assertEqual(decode._embedded_value(b'')[0], 0)
def test_decode_embedded_value_empty_value(self):
self.assertEqual(decode._embedded_value(b'')[1], None)
def test_decode_embedded_value_decimal_bytes_consumed(self):
value = b'D\x05\x00\x04\xcb/'
self.assertEqual(decode._embedded_value(value)[0], len(value))
def test_decode_embedded_value_decimal_data_type(self):
value = b'D\x05\x00\x04\xcb/'
self.assertIsInstance(
decode._embedded_value(value)[1], decimal.Decimal)
def test_decode_embedded_value_decimal_value(self):
value = b'D\x05\x00\x04\xcb/'
self.assertEqual(round(float(decode._embedded_value(value)[1]), 5),
round(float(decimal.Decimal('3.14159')), 5))
def test_decode_embedded_value_double_bytes_consumed(self):
value = b'dC\x0f\xd8\x91\x14\xb9\xc3\x98'
self.assertEqual(decode._embedded_value(value)[0], len(value))
def test_decode_embedded_value_double_data_type(self):
value = b'dC\x0f\xd8\x91\x14\xb9\xc3\x98'
self.assertIsInstance(decode._embedded_value(value)[1], float)
def test_decode_embedded_value_double_value(self):
value = b'dC\x0f\xd8\x91\x14\xb9\xc3\x98'
self.assertEqual(decode._embedded_value(value)[1], 1120480238450803.0)
def test_decode_embedded_value_long_bytes_consumed(self):
value = b'I\x7f\xff\xff\xff'
self.assertEqual(decode._embedded_value(value)[0], 5)
def test_decode_embedded_value_long_data_type(self):
value = b'I\x7f\xff\xff\xff'
self.assertIsInstance(decode._embedded_value(value)[1], int)
def test_decode_embedded_value_long_value(self):
value = b'I\x7f\xff\xff\xff'
self.assertEqual(decode._embedded_value(value)[1], 2147483647)
def test_decode_embedded_value_long_uint_bytes_consumed(self):
value = b'i\xff\xff\xff\xff'
self.assertEqual(decode._embedded_value(value)[0], 5)
def test_decode_embedded_value_long_uint_data_type(self):
value = b'i\xff\xff\xff\xff'
self.assertIsInstance(decode._embedded_value(value)[1], int)
def test_decode_embedded_value_long_uint_value(self):
value = b'i\xff\xff\xff\xff'
self.assertEqual(decode._embedded_value(value)[1], 4294967295)
def test_decode_embedded_value_long_long_bytes_consumed(self):
value = b'l\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertEqual(decode._embedded_value(value)[0], 9)
@unittest.skipIf(PLATFORM_32BIT, 'Skipped on 32-bit platforms')
def test_decode_embedded_value_long_long_data_type_64bit(self):
value = b'l\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertIsInstance(decode._embedded_value(value)[1], int)
@unittest.skipIf(PLATFORM_64BIT, 'Skipped on 64-bit platforms')
def test_decode_embedded_value_long_long_data_type_32bit(self):
value = b'l\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertIsInstance(decode._embedded_value(value)[1], long)
def test_decode_embedded_value_long_long_value(self):
value = b'l\x7f\xff\xff\xff\xff\xff\xff\xf8'
self.assertEqual(decode._embedded_value(value)[1], 9223372036854775800)
def test_decode_embedded_value_longstr_bytes_consumed(self):
value = b'S\x00\x00\x00\n0123456789'
self.assertEqual(decode._embedded_value(value)[0], 15)
def test_decode_embedded_value_longstr_data_type(self):
value = b'S\x00\x00\x00\n0123456789'
expectation = bytes if PYTHON3 else str
self.assertIsInstance(decode._embedded_value(value)[1], expectation)
def test_decode_embedded_value_byte_array_data(self):
value = b'x\x00\x00\x00\x03ABC'
self.assertEqual(
decode._embedded_value(value)[1], bytearray([65, 66, 67]))
def test_decode_embedded_value_byte_array_data_type(self):
value = b'x\x00\x00\x00\x03ABC'
self.assertIsInstance(decode._embedded_value(value)[1], bytearray)
def test_decode_embedded_value_longstr_data_type_unicode(self):
value = (b'S\x00\x00\x00\x0c\xd8\xa7\xd8\xae\xd8\xaa\xd8\xa8\xd8'
b'\xa7\xd8\xb1')
self.assertIsInstance(decode._embedded_value(value)[1], bytes)
def test_decode_embedded_value_longstr_value(self):
value = b'S\x00\x00\x00\n0123456789'
self.assertEqual(decode._embedded_value(value)[1], b'0123456789')
def test_decode_embedded_value_short_bytes_consumed(self):
value = b's\x7f\xff'
self.assertEqual(decode._embedded_value(value)[0], 3)
def test_decode_embedded_value_short_short_bytes_consumed(self):
self.assertEqual(decode._embedded_value(b'b\xff')[0], 2)
def test_decode_embedded_value_short_short_data_type(self):
self.assertIsInstance(decode._embedded_value(b'b\xff')[1], int)
def test_decode_embedded_value_short_short_value(self):
self.assertEqual(decode._embedded_value(b'b\xff')[1], 255)
def test_decode_embedded_value_short_data_type(self):
value = b's\x7f\xff'
self.assertIsInstance(decode._embedded_value(value)[1], int)
def test_decode_embedded_value_short_value(self):
self.assertEqual(decode._embedded_value(b's\x7f\xff')[1], 32767)
def test_decode_embedded_value_short_uint_data_type(self):
self.assertIsInstance(decode._embedded_value(b'u\xff\xff')[1], int)
def test_decode_embedded_value_short_uint_value(self):
self.assertEqual(decode._embedded_value(b'u\xff\xff')[1], 65535)
def test_decode_embedded_value_timestamp_bytes_consumed(self):
value = b'T\x00\x00\x00\x00Ec)\x92'
self.assertEqual(decode._embedded_value(value)[0], 9)
def test_decode_embedded_value_timestamp_data_type(self):
value = b'T\x00\x00\x00\x00Ec)\x92'
self.assertIsInstance(
decode._embedded_value(value)[1], time.struct_time)
def test_decode_embedded_value_timestamp_value(self):
value = b'T\x00\x00\x00\x00Ec)\x92'
self.assertEqual(
decode._embedded_value(value)[1],
time.struct_time((2006, 11, 21, 16, 30, 10, 1, 325, 0)))
def test_decode_embedded_value_field_array_bytes_consumed(self):
self.assertEqual(
decode._embedded_value(b'A' + self.FIELD_ARR)[0],
len(b'A' + self.FIELD_ARR))
def test_decode_embedded_value_field_array_data_type(self):
self.assertIsInstance(
decode._embedded_value(b'A' + self.FIELD_ARR)[1], list)
def test_decode_embedded_value_field_array_value(self):
value = decode._embedded_value(b'A' + self.FIELD_ARR)[1]
for position in range(0, len(value)):
if isinstance(value[position], float):
self.assertAlmostEqual(
round(value[position], 3),
round(self.FIELD_ARR_VALUE[position], 3))
else:
self.assertEqual(value[position],
self.FIELD_ARR_VALUE[position])
def test_decode_embedded_value_field_table_bytes_consumed(self):
self.assertEqual(
decode._embedded_value(b'F' + self.FIELD_TBL)[0],
len(b'F' + self.FIELD_TBL))
def test_decode_embedded_value_field_table_data_type(self):
self.assertIsInstance(
decode._embedded_value(b'F' + self.FIELD_TBL)[1], dict)
def test_decode_embedded_value_field_table_value(self):
value = decode._embedded_value(b'F' + self.FIELD_TBL)[1]
for key in self.FIELD_TBL_VALUE.keys():
if isinstance(value[key], float):
self.assertAlmostEqual(round(value[key], 3),
round(self.FIELD_TBL_VALUE[key], 3))
else:
self.assertEqual(value[key], self.FIELD_TBL_VALUE[key])
def test_decode_embedded_value_void_consumed(self):
self.assertEqual(decode._embedded_value(b'V')[0], 1)
def test_decode_embedded_value_void_value(self):
self.assertIsNone(decode._embedded_value(b'V')[1])
def test_field_embedded_value_field_table_keys(self):
value = decode._embedded_value(b'F' + self.FIELD_TBL)[1]
self.assertListEqual(sorted(value.keys()),
sorted(self.FIELD_TBL_VALUE.keys()))
pamqp-2.3.0/tests/test_encode_decode.py 0000664 0000000 0000000 00000001030 13456152267 0020152 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
import unittest
from pamqp import decode, encode
class EncodeDecodeTests(unittest.TestCase):
def test_encode_decode_field_table_long_keys(self):
"""Encoding and decoding a field_table with too long keys."""
# second key is 126 A's + \N{PILE OF POO}
data = {'A' * 256: 1,
((b'A' * 128) + b'\xf0\x9f\x92\xa9').decode('utf-8'): 2}
encoded = encode.field_table(data)
decoded = decode.field_table(encoded)[1]
self.assertIn('A' * 128, decoded)
pamqp-2.3.0/tests/test_encoding.py 0000664 0000000 0000000 00000044534 13456152267 0017220 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
from datetime import datetime
from decimal import Decimal
import unittest
from pamqp import encode, PYTHON3
if PYTHON3:
long = int
class MarshalingTests(unittest.TestCase):
def test_encode_bool_wrong_type(self):
self.assertRaises(TypeError, encode.boolean, 'hi')
def test_encode_bool_false(self):
self.assertEqual(encode.boolean(False), b'\x00')
def test_encode_bool_true(self):
self.assertEqual(encode.boolean(True), b'\x01')
def test_encode_byte_array(self):
self.assertEqual(encode.byte_array(bytearray([65, 66, 67])),
b'\x00\x00\x00\x03ABC')
def test_encode_byte_array_wrong_type(self):
self.assertRaises(TypeError, encode.byte_array, b'ABC')
def test_encode_decimal_wrong_type(self):
self.assertRaises(TypeError, encode.decimal, 3.141597)
def test_encode_decimal(self):
self.assertEqual(encode.decimal(Decimal('3.14159')),
b'\x05\x00\x04\xcb/')
def test_encode_decimal_whole(self):
self.assertEqual(encode.decimal(Decimal('314159')),
b'\x00\x00\x04\xcb/')
def test_encode_double_invalid_value(self):
self.assertRaises(TypeError, encode.double, '1234')
def test_encode_double(self):
self.assertEqual(encode.double(float(3.14159)),
b'@\t!\xf9\xf0\x1b\x86n')
def test_encode_floating_point_type(self):
self.assertRaises(TypeError, encode.floating_point, '1234')
def test_encode_float(self):
self.assertEqual(encode.floating_point(float(3.14159)), b'@I\x0f\xd0')
def test_encode_long_int_wrong_type(self):
self.assertRaises(TypeError, encode.long_int, 3.141597)
def test_encode_table_integer_bad_value_error(self):
self.assertRaises(TypeError, encode.long_int, 9223372036854775808)
def test_encode_long_int(self):
self.assertEqual(encode.long_int(long(2147483647)),
b'\x7f\xff\xff\xff')
def test_encode_long_int_error(self):
self.assertRaises(TypeError, encode.long_int, long(21474836449))
def test_encode_long_uint(self):
self.assertEqual(encode.long_uint(long(4294967295)),
b'\xff\xff\xff\xff')
def test_encode_long_uint_error(self):
self.assertRaises(TypeError, encode.long_uint, long(4294967296))
def test_encode_long_uint_wrong_type(self):
self.assertRaises(TypeError, encode.long_uint, 3.141597)
def test_encode_long_long_int_wrong_type(self):
self.assertRaises(TypeError, encode.long_long_int, 3.141597)
def test_encode_long_long_int_error(self):
self.assertRaises(TypeError, encode.long_long_int,
long(9223372036854775808))
def test_encode_octet(self):
self.assertEqual(encode.octet(1), b'\x01')
def test_encode_octet_error(self):
self.assertRaises(TypeError, encode.octet, 'hi')
def test_encode_short_wrong_type(self):
self.assertRaises(TypeError, encode.short_int, 3.141597)
def test_encode_short(self):
self.assertEqual(encode.short_int(32767), b'\x7f\xff')
def test_encode_short_error(self):
self.assertRaises(TypeError, encode.short_int, 32768)
def test_encode_short_uint(self):
self.assertEqual(encode.short_uint(65535), b'\xff\xff')
def test_encode_short_uint_error(self):
self.assertRaises(TypeError, encode.short_uint, 65536)
def test_encode_short_uint_type_error(self):
self.assertRaises(TypeError, encode.short_uint, 'hello')
def test_encode_table_integer_error(self):
self.assertRaises(TypeError, encode.table_integer, 9223372036854775808)
def test_encode_short_string(self):
self.assertEqual(encode.short_string('Hello'), b'\x05Hello')
def test_encode_short_string_error(self):
self.assertRaises(TypeError, encode.short_string, 32768)
@unittest.skipIf(PYTHON3, 'Python2 UTF-8 test')
def test_encode_short_string_utf8_python2(self):
self.assertEqual(
encode.short_string('\xf0\x9f\x90\xb0'.decode('utf-8')),
b'\x04\xf0\x9f\x90\xb0')
@unittest.skipIf(not PYTHON3, 'Python3 UTF-8 test')
def test_encode_short_string_utf8_python3(self):
self.assertEqual(encode.short_string('🐰'), b'\x04\xf0\x9f\x90\xb0')
def test_encode_long_string(self):
self.assertEqual(encode.long_string(b'0123456789'),
b'\x00\x00\x00\n0123456789')
def test_encode_long_string_bytes(self):
self.assertEqual(encode.long_string('rabbitmq'),
b'\x00\x00\x00\x08rabbitmq')
@unittest.skipIf(PYTHON3, 'Python2 UTF-8 test')
def test_encode_long_string_utf8_python2(self):
self.assertEqual(
encode.long_string('\xf0\x9f\x90\xb0'.decode('utf-8')),
b'\x00\x00\x00\x04\xf0\x9f\x90\xb0')
@unittest.skipIf(not PYTHON3, 'Python3 UTF-8 test')
def test_encode_long_string_utf8_python3(self):
self.assertEqual(encode.long_string('🐰'),
b'\x00\x00\x00\x04\xf0\x9f\x90\xb0')
def test_encode_long_string_error(self):
self.assertRaises(TypeError, encode.long_string, 100)
def test_encode_timestamp_from_datetime(self):
self.assertEqual(encode.timestamp(datetime(2006, 11, 21, 16, 30, 10)),
b'\x00\x00\x00\x00Ec)\x92')
def test_encode_timestamp_from_struct_time(self):
value = \
encode.timestamp(datetime(2006, 11, 21, 16, 30, 10).timetuple())
self.assertEqual(value, b'\x00\x00\x00\x00Ec)\x92')
def test_encode_timestamp_from_numeric(self):
value = encode.timestamp(1555574815)
self.assertEqual(value, b'\x00\x00\x00\x00\\\xb80\x1f')
def test_encode_timestamp_error(self):
self.assertRaises(TypeError, encode.timestamp, 'hi')
def test_encode_field_array(self):
expectation = (b'\x00\x00\x00:b\x01u\xaf\xc8I\x02bZ\x00S\x00\x00\x00'
b'\x04TestT\x00\x00\x00\x00Ec)\x92I\xbb\x9a\xca\x00D'
b'\x02\x00\x00\x01:f@H\xf5\xc3i\xc4e5\xffl\x80\x00\x00'
b'\x00\x00\x00\x00\x08')
data = [
1, 45000, 40000000, b'Test',
datetime(2006, 11, 21, 16, 30, 10), -1147483648,
Decimal('3.14'), 3.14,
long(3294967295), -9223372036854775800
]
self.assertEqual(encode.field_array(data), expectation)
def test_encode_field_array_error(self):
self.assertRaises(TypeError, encode.field_array, 'hi')
def test_encode_field_table_empty(self):
self.assertEqual(encode.field_table(None), b'\x00\x00\x00\x00')
def test_encode_field_table_type_error(self):
self.assertRaises(TypeError, encode.field_table, [1, 2, 3])
def test_encode_field_table_object(self):
self.assertRaises(TypeError, encode.field_table,
{'key': encode.field_table})
def test_encode_field_table(self):
expectation = (b"\x00\x00\x04'\x08arrayvalA\x00\x00\x00\x06b\x01b"
b'\x02b\x03\x07boolvalt\x01\tbytearrayx\x00\x00\x00'
b'\x03AAA\x06decvalD\x02\x00\x00\x01:\x07dictvalF\x00'
b'\x00\x00\x0c\x03fooS\x00\x00\x00\x03bar\x08floatval'
b'f@H\xf5\xc3\x06intvalb\x01\x07longstrS\x00\x00\x03t'
b'000000000000000000000000000000000000000000000000000'
b'011111111111111111111111111111111111111111111111111'
b'112222222222222222222222222222222222222222222222222'
b'222111111111111111111111111111111111111111111111111'
b'111122222222222222222222222222222222222222222222222'
b'222221111111111111111111111111111111111111111111111'
b'111111222222222222222222222222222222222222222222222'
b'222222211111111111111111111111111111111111111111111'
b'111111112222222222222222222222222222222222222222222'
b'222222222111111111111111111111111111111111111111111'
b'111111111122222222222222222222222222222222222222222'
b'222222222221111111111111111111111111111111111111111'
b'111111111111222222222222222222222222222222222222222'
b'222222222222211111111111111111111111111111111111111'
b'111111111111112222222222222222222222222222222222222'
b'222222222222222111111111111111111111111111111111111'
b'111111111111111100000000000000000000000000000000000'
b'00000000000000000\x07longvalI6e&U\x04noneV\x06strva'
b'lS\x00\x00\x00\x04Test\x0ctimestampvalT\x00\x00\x00'
b'\x00Ec)\x92')
data = {
'intval': 1,
'strval': b'Test',
'boolval': True,
'timestampval': datetime(2006, 11, 21, 16, 30, 10),
'decval': Decimal('3.14'),
'floatval': 3.14,
'longval': long(912598613),
'dictval': {
b'foo': b'bar'
},
'arrayval': [1, 2, 3],
'none': None,
'bytearray': bytearray((65, 65, 65)),
'longstr': ('0000000000000000000000000000000000000000000000000'
'0001111111111111111111111111111111111111111111111'
'1111112222222222222222222222222222222222222222222'
'2222222221111111111111111111111111111111111111111'
'1111111111112222222222222222222222222222222222222'
'2222222222222221111111111111111111111111111111111'
'1111111111111111112222222222222222222222222222222'
'2222222222222222222221111111111111111111111111111'
'1111111111111111111111112222222222222222222222222'
'2222222222222222222222222221111111111111111111111'
'1111111111111111111111111111112222222222222222222'
'2222222222222222222222222222222221111111111111111'
'1111111111111111111111111111111111112222222222222'
'2222222222222222222222222222222222222221111111111'
'1111111111111111111111111111111111111111112222222'
'2222222222222222222222222222222222222222222221111'
'1111111111111111111111111111111111111111111111110'
'0000000000000000000000000000000000000000000000000'
'00')
}
self.assertEqual(encode.field_table(data), expectation)
def test_encode_by_type_field_array(self):
expectation = (b'\x00\x00\x008b\x01sBhu\xaf\xc8S\x00\x00\x00\x04TestT'
b'\x00\x00\x00\x00Ec)\x92I\xbb\x9a\xca\x00D\x02\x00'
b'\x00\x01:f@H\xf5\xc3i\xc4e5\xffl\x80\x00\x00\x00\x00'
b'\x00\x00\x08')
data = [
1, 17000, 45000, b'Test',
datetime(2006, 11, 21, 16, 30, 10), -1147483648,
Decimal('3.14'), 3.14,
long(3294967295), -9223372036854775800
]
self.assertEqual(encode.by_type(data, 'field_array'), expectation)
def test_encode_by_type_byte_array(self):
self.assertEqual(encode.by_type(bytearray((65, 66, 67)), 'bytearray'),
b'\x00\x00\x00\x03ABC')
def test_encode_by_type_double(self):
self.assertEqual(encode.by_type(float(4294967295), 'double'),
b'A\xef\xff\xff\xff\xe0\x00\x00')
def test_encode_by_type_long_uint(self):
self.assertEqual(encode.by_type(long(4294967295), 'long'),
b'\xff\xff\xff\xff')
def test_encode_by_type_long_long_int(self):
self.assertEqual(encode.by_type(long(9223372036854775800), 'longlong'),
b'\x7f\xff\xff\xff\xff\xff\xff\xf8')
def test_encode_by_type_long_str(self):
self.assertEqual(encode.by_type(b'0123456789', 'longstr'),
b'\x00\x00\x00\n0123456789')
def test_encode_by_type_none(self):
self.assertEqual(encode.by_type(None, 'void'), None)
def test_encode_by_type_octet(self):
self.assertEqual(encode.by_type(1, 'octet'), b'\x01')
def test_encode_by_type_short(self):
self.assertEqual(encode.by_type(32767, 'short'), b'\x7f\xff')
def test_encode_by_type_timestamp(self):
self.assertEqual(
encode.by_type(datetime(2006, 11, 21, 16, 30, 10), 'timestamp'),
b'\x00\x00\x00\x00Ec)\x92')
def test_encode_by_type_field_table(self):
expectation = (b'\x00\x00\x04B\x08arrayvalA\x00\x00\x00\x08b\x01s\x10'
b'`u\xa4\x10\x07boolvalt\x01\x06decvalD\x02\x00\x00\x01'
b':\x07dictvalF\x00\x00\x00\x0c\x03fooS\x00\x00\x00\x03'
b'bar\x08floatvalf@H\xf5\xc3\x07longstrS\x00\x00\x03t00'
b'00000000000000000000000000000000000000000000000000111'
b'11111111111111111111111111111111111111111111111112222'
b'22222222222222222222222222222222222222222222222211111'
b'11111111111111111111111111111111111111111111111222222'
b'22222222222222222222222222222222222222222222221111111'
b'11111111111111111111111111111111111111111111122222222'
b'22222222222222222222222222222222222222222222111111111'
b'11111111111111111111111111111111111111111112222222222'
b'22222222222222222222222222222222222222222211111111111'
b'11111111111111111111111111111111111111111222222222222'
b'22222222222222222222222222222222222222221111111111111'
b'11111111111111111111111111111111111111122222222222222'
b'22222222222222222222222222222222222222111111111111111'
b'11111111111111111111111111111111111112222222222222222'
b'22222222222222222222222222222222222211111111111111111'
b'11111111111111111111111111111111111000000000000000000'
b'0000000000000000000000000000000000\x07longvalI6e&U'
b'\x06s32intI\xc4e6\x00\x06s64intl7\x82\xda\xce\x9d\x90'
b'\x00\x00\x06strvalS\x00\x00\x00\x04Test\x0ctimestamp'
b'valT\x00\x00\x00\x00Ec)\x92\x06u16ints \x00\x06u32int'
b'i\xeek(\x00\x05u8bitb ')
data = {
'u8bit': 32,
'u16int': 8192,
's32int': -1000000000,
'u32int': 4000000000,
's64int': 4000000000000000000,
'strval': b'Test',
'boolval': True,
'timestampval': datetime(2006, 11, 21, 16, 30, 10),
'decval': Decimal('3.14'),
'floatval': 3.14,
'longval': long(912598613),
'dictval': {
b'foo': b'bar'
},
'arrayval': [1, 4192, 42000],
'longstr': ('0000000000000000000000000000000000000000000000000'
'0001111111111111111111111111111111111111111111111'
'1111112222222222222222222222222222222222222222222'
'2222222221111111111111111111111111111111111111111'
'1111111111112222222222222222222222222222222222222'
'2222222222222221111111111111111111111111111111111'
'1111111111111111112222222222222222222222222222222'
'2222222222222222222221111111111111111111111111111'
'1111111111111111111111112222222222222222222222222'
'2222222222222222222222222221111111111111111111111'
'1111111111111111111111111111112222222222222222222'
'2222222222222222222222222222222221111111111111111'
'1111111111111111111111111111111111112222222222222'
'2222222222222222222222222222222222222221111111111'
'1111111111111111111111111111111111111111112222222'
'2222222222222222222222222222222222222222222221111'
'1111111111111111111111111111111111111111111111110'
'0000000000000000000000000000000000000000000000000'
'00')
}
self.assertEqual(encode.by_type(data, 'table'), expectation)
def test_encode_by_type_error(self):
self.assertRaises(TypeError, encode.by_type, 12345.12434, 'foo')
class EncodeTableIntegerTestCase(unittest.TestCase):
def setUp(self):
encode.DEPRECATED_RABBITMQ_SUPPORT = False
def tearDown(self):
encode.DEPRECATED_RABBITMQ_SUPPORT = False
def test_table_integer(self):
tests = {
'short-short': (32, b'b '),
'short': (1024, b's\x04\x00'),
'short-negative': (-1024, b's\xfc\x00'),
'short-unsigned': (32768, b'u\x80\x00'),
'long': (65536, b'I\x00\x01\x00\x00'),
'long-negative': (65536, b'I\x00\x01\x00\x00'),
'long-unsigned': (4294967295, b'i\xff\xff\xff\xff'),
'long-long': (9223372036854775805,
b'l\x7f\xff\xff\xff\xff\xff\xff\xfd'),
}
for key, value in tests.items():
result = encode.table_integer(value[0])
self.assertEqual(result, value[1],
'encode {} mismatch ({!r} != {!r})'.format(
key, result, value[1]))
def test_deprecated_table_integer(self):
tests = {
'short-short': (32, b'b '),
'short': (1024, b's\x04\x00'),
'short-negative': (-1024, b's\xfc\x00'),
'long': (65536, b'I\x00\x01\x00\x00'),
'long-negative': (65536, b'I\x00\x01\x00\x00'),
'long-long': (2147483648, b'l\x00\x00\x00\x00\x80\x00\x00\x00'),
}
encode.support_deprecated_rabbitmq()
for key, value in tests.items():
result = encode.table_integer(value[0])
self.assertEqual(result, value[1],
'encode {} mismatch ({!r} != {!r})'.format(
key, result, value[1]))
pamqp-2.3.0/tests/test_frame_marshaling.py 0000664 0000000 0000000 00000005634 13456152267 0020727 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
import unittest
import uuid
from pamqp import body, frame, header, heartbeat, specification
class MarshalingTests(unittest.TestCase):
def test_protocol_header(self):
expectation = b'AMQP\x00\x00\t\x01'
response = frame.marshal(header.ProtocolHeader(), 0)
self.assertEqual(response, expectation,
'ProtocolHeader did not match expectation')
def test_basic_ack(self):
expectation = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00P\x00\x00\x00'
b'\x00\x00\x00\x00\x01\x00\xce')
frame_obj = specification.Basic.Ack(1, False)
response = frame.marshal(frame_obj, 1)
self.assertEqual(response, expectation,
'Basic.Ack did not match expectation')
def test_basic_cancel(self):
expectation = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00\x1e\x07'
b'ctag1.0\x00\xce')
frame_obj = specification.Basic.Cancel(consumer_tag='ctag1.0')
response = frame.marshal(frame_obj, 1)
self.assertEqual(response, expectation,
'Basic.Cancel did not match expectation')
def test_basic_cancelok(self):
expectation = (b'\x01\x00\x01\x00\x00\x00\x0c\x00<\x00\x1f\x07'
b'ctag1.0\xce')
frame_obj = specification.Basic.CancelOk(consumer_tag='ctag1.0')
response = frame.marshal(frame_obj, 1)
self.assertEqual(response, expectation,
'Basic.Cancel did not match expectation')
def test_basic_consume(self):
expectation = (b'\x01\x00\x01\x00\x00\x00\x15\x00<\x00\x14\x00'
b'\x00\x03bar\x05ctag0\x00\x00\x00\x00\x00\xce')
frame_obj = specification.Basic.Consume(0, 'bar', 'ctag0', False,
False, False, False)
response = frame.marshal(frame_obj, 1)
self.assertEqual(response, expectation,
'Basic.Consume did not match expectation')
def test_heartbeat(self):
expectation = b'\x08\x00\x00\x00\x00\x00\x00\xce'
response = frame.marshal(heartbeat.Heartbeat(), 0)
self.assertEqual(response, expectation,
'Heartbeat did not match expectation')
def test_content_body(self):
value = str(uuid.uuid4()).encode('utf-8')
expectation = b'\x03\x00\x01\x00\x00\x00$' + value + b'\xce'
self.assertEqual(frame.marshal(body.ContentBody(value), 1),
expectation)
def test_content_header(self):
expectation = (b'\x02\x00\x01\x00\x00\x00\x0e\x00<\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\n\x00\x00\xce')
self.assertEqual(frame.marshal(header.ContentHeader(body_size=10), 1),
expectation)
def test_unknown_frame_type(self):
with self.assertRaises(ValueError):
frame.marshal(self, 1)
pamqp-2.3.0/tests/test_frame_unmarshaling.py 0000664 0000000 0000000 00000177160 13456152267 0021276 0 ustar 00root root 0000000 0000000 # -*- encoding: utf-8 -*-
import time
import unittest
from pamqp import body, frame, header, PYTHON3, specification
if PYTHON3:
long = int
basestring = str
unicode = None
class DemarshalingTests(unittest.TestCase):
def test_protocol_header(self):
# Decode the frame and validate lengths
frame_data = b'AMQP\x00\x00\t\x01'
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 8,
'Bytes consumed did not match expectation: %i, %i' % (consumed, 8))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'ProtocolHeader',
('Frame was of wrong type, expected ProtocolHeader, '
'received %s' % frame_obj.name))
self.assertEqual((frame_obj.major_version, frame_obj.minor_version,
frame_obj.revision), (0, 9, 1),
'Protocol version is incorrect')
def test_heartbeat(self):
frame_data = b'\x08\x00\x00\x00\x00\x00\x00\xce'
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 8,
'Bytes consumed did not match expectation: %i, %i' % (consumed, 8))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Heartbeat',
('Frame was of wrong type, expected Heartbeat, '
'received %s' % frame_obj.name))
def test_basic_ack(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00P\x00\x00\x00\x00'
b'\x00\x00\x00\x01\x00\xce')
expectation = {'multiple': False, 'delivery_tag': 1}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 21, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 21))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Ack',
('Frame was of wrong type, expected Basic.Ack, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_cancel(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00\x1e\x07ctag1.0\x00'
b'\xce')
expectation = {'consumer_tag': 'ctag1.0', 'nowait': False}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 21, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 21))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Cancel',
('Frame was of wrong type, expected Basic.Cancel, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_cancelok(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x0c\x00<\x00\x1f\x07ctag1.0'
b'\xce')
expectation = {'consumer_tag': 'ctag1.0'}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 20, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 20))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.CancelOk',
('Frame was of wrong type, expected Basic.CancelOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_consume(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x18\x00<\x00\x14\x00\x00\x04'
b'test\x07ctag1.0\x00\x00\x00\x00\x00\xce')
expectation = {
'exclusive': False,
'nowait': False,
'no_local': False,
'consumer_tag': 'ctag1.0',
'queue': 'test',
'arguments': {},
'ticket': 0,
'no_ack': False
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 32, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 32))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Consume',
('Frame was of wrong type, expected Basic.Consume, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_consumeok(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x0c\x00<\x00\x15\x07ctag1.0'
b'\xce')
expectation = {'consumer_tag': 'ctag1.0'}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 20, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 20))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.ConsumeOk',
('Frame was of wrong type, expected Basic.ConsumeOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_deliver(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x1b\x00<\x00<\x07ctag1.0'
b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x04test\xce')
expectation = {
'consumer_tag': 'ctag1.0',
'delivery_tag': 1,
'redelivered': False,
'exchange': '',
'routing_key': 'test'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 35, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 35))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Deliver',
('Frame was of wrong type, expected Basic.Deliver, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_get(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x0c\x00<\x00F\x00\x00\x04'
b'test\x00\xce')
expectation = {'queue': 'test', 'ticket': 0, 'no_ack': False}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 20, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 20))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Get',
('Frame was of wrong type, expected Basic.Get, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_getempty(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x05\x00<\x00H\x00\xce'
expectation = {'cluster_id': ''}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.GetEmpty',
('Frame was of wrong type, expected Basic.GetEmpty, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_getok(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x17\x00<\x00G\x00\x00\x00\x00'
b'\x00\x00\x00\x10\x00\x00\x04test\x00\x00\x12\x06\xce')
expectation = {
'message_count': 4614,
'redelivered': False,
'routing_key': 'test',
'delivery_tag': 16,
'exchange': ''
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 31, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 31))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.GetOk',
('Frame was of wrong type, expected Basic.GetOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_nack(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00x\x00\x00\x00\x00'
b'\x00\x00\x00\x01\x00\xce')
expectation = {'requeue': False, 'multiple': False, 'delivery_tag': 1}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 21, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 21))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Nack',
('Frame was of wrong type, expected Basic.Nack, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_content_header(self):
result = frame.unmarshal(frame.marshal(header.ContentHeader(0, 100),
1))
self.assertEqual(result[2].body_size, 100)
def test_content_body(self):
result = frame.unmarshal(frame.marshal(body.ContentBody(b'TEST'), 1))
self.assertEqual(len(result[2]), 4)
def test_basic_properties(self):
encoded_properties = (b'\xff\xfc\x10application/json\x04gzip\x00\x00'
b'\x00\x1d\x03bazS\x00\x00\x00\x08Test \xe2\x9c'
b'\x88\x03fooS\x00\x00\x00\x03bar\x01\x00$a5304'
b'5ef-f174-4621-9ff2-ac0b8fbe6e4a\x12unmarshali'
b'ng_tests\n1345274026$746a1902-39dc-47cf-9471-'
b'9feecda35660\x00\x00\x00\x00Pj\xb9\x07\x08uni'
b'ttest\x04pika\x18frame_unmarshaling_tests\x00')
properties = {
'content_type': 'application/json',
'content_encoding': 'gzip',
'headers': {
'foo': b'bar',
'baz': b'Test \xe2\x9c\x88'
},
'delivery_mode': 1,
'priority': 0,
'correlation_id': 'a53045ef-f174-4621-9ff2-ac0b8fbe6e4a',
'reply_to': 'unmarshaling_tests',
'expiration': '1345274026',
'message_id': '746a1902-39dc-47cf-9471-9feecda35660',
'timestamp': time.struct_time((2012, 10, 2, 9, 51, 3, 1, 276, 0)),
'message_type': 'unittest',
'user_id': 'pika',
'app_id': 'frame_unmarshaling_tests',
'cluster_id': ''
}
obj = header.ContentHeader()
offset, flags = obj._get_flags(encoded_properties)
# Decode the frame and validate lengths
obj = specification.Basic.Properties()
obj.unmarshal(flags, encoded_properties[offset:])
for key in properties:
self.assertEqual(
getattr(obj, key), properties[key],
'%r value of %r did not match expectation of %r' %
(key, getattr(obj, key), properties[key]))
def test_basic_publish(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00(\x00\x00\x00'
b'\x04test\x00\xce')
expectation = {
'ticket': 0,
'mandatory': False,
'routing_key': 'test',
'immediate': False,
'exchange': ''
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 21, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 21))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Publish',
('Frame was of wrong type, expected Basic.Publish, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_qos(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x0b\x00<\x00\n\x00\x00\x00'
b'\x00\x00\x01\x00\xce')
expectation = {
'prefetch_count': 1,
'prefetch_size': 0,
'global_': False
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 19, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 19))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Qos',
('Frame was of wrong type, expected Basic.Qos, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_qosok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00<\x00\x0b\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.QosOk',
('Frame was of wrong type, expected Basic.QosOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_recover(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x05\x00<\x00n\x00\xce'
expectation = {'requeue': False}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Recover',
('Frame was of wrong type, expected Basic.Recover, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_recoverasync(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x05\x00<\x00d\x00\xce'
expectation = {'requeue': False}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(
frame_obj.name, 'Basic.RecoverAsync',
('Frame was of wrong type, expected Basic.RecoverAsync, '
'received %s' % frame_obj.name))
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_recoverok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00<\x00o\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.RecoverOk',
('Frame was of wrong type, expected Basic.RecoverOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_reject(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00Z\x00\x00\x00\x00'
b'\x00\x00\x00\x10\x01\xce')
expectation = {'requeue': True, 'delivery_tag': 16}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 21, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 21))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Reject',
('Frame was of wrong type, expected Basic.Reject, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_basic_return(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00"\x00<\x002\x00\xc8\x0f'
b'Normal shutdown\x03foo\x07foo.bar\xce')
expectation = {
'reply_code': 200,
'reply_text': 'Normal shutdown',
'routing_key': 'foo.bar',
'exchange': 'foo'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 42, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 42))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Basic.Return',
('Frame was of wrong type, expected Basic.Return, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_channel_close(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x1a\x00\x14\x00(\x00\xc8\x0f'
b'Normal shutdown\x00\x00\x00\x00\xce')
expectation = {
'class_id': 0,
'method_id': 0,
'reply_code': 200,
'reply_text': 'Normal shutdown'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 34, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 34))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Channel.Close',
('Frame was of wrong type, expected Channel.Close, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_channel_closeok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00\x14\x00)\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Channel.CloseOk',
('Frame was of wrong type, expected Channel.CloseOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_channel_flow(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x05\x00\x14\x00\x14\x01\xce'
expectation = {'active': True}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Channel.Flow',
('Frame was of wrong type, expected Channel.Flow, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_channel_flowok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x05\x00\x14\x00\x15\x01\xce'
expectation = {'active': True}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Channel.FlowOk',
('Frame was of wrong type, expected Channel.FlowOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_channel_open(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x05\x00\x14\x00\n\x00\xce'
expectation = {'out_of_band': ''}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Channel.Open',
('Frame was of wrong type, expected Channel.Open, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_channel_openok(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x08\x00\x14\x00\x0b\x00\x00'
b'\x00\x00\xce')
expectation = {'channel_id': b''}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 16, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 16))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Channel.OpenOk',
('Frame was of wrong type, expected Channel.OpenOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_confirm_select(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x05\x00U\x00\n\x00\xce'
expectation = {'nowait': False}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Confirm.Select',
('Frame was of wrong type, expected Confirm.Select, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_confirm_selectok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00U\x00\x0b\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Confirm.SelectOk',
('Frame was of wrong type, expected '
'Confirm.SelectOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_close(self):
frame_data = (b'\x01\x00\x00\x00\x00\x00\x1a\x00\n\x002\x00\xc8\x0f'
b'Normal shutdown\x00\x00\x00\x00\xce')
expectation = {
'class_id': 0,
'method_id': 0,
'reply_code': 200,
'reply_text': 'Normal shutdown'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 34, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 34))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.Close',
('Frame was of wrong type, expected '
'Connection.Close, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_closeok(self):
frame_data = b'\x01\x00\x00\x00\x00\x00\x04\x00\n\x003\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.CloseOk',
('Frame was of wrong type, expected '
'Connection.CloseOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_open(self):
frame_data = (b'\x01\x00\x00\x00\x00\x00\x08\x00\n\x00(\x01/\x00'
b'\x01\xce')
expectation = {'insist': True, 'capabilities': '', 'virtual_host': '/'}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 16, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 16))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.Open',
('Frame was of wrong type, expected Connection.Open, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_openok(self):
frame_data = b'\x01\x00\x00\x00\x00\x00\x05\x00\n\x00)\x00\xce'
expectation = {'known_hosts': ''}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 13, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 13))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.OpenOk',
('Frame was of wrong type, expected '
'Connection.OpenOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_secure(self):
frame_data = (b'\x01\x00\x00\x00\x00\x00\x08\x00\n\x00\x14\x00\x00'
b'\x00\x00\xce')
expectation = {'challenge': b''}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 16, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 16))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.Secure',
('Frame was of wrong type, expected '
'Connection.Secure, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_secureok(self):
frame_data = (b'\x01\x00\x00\x00\x00\x00\x08\x00\n\x00\x15\x00\x00'
b'\x00\x00\xce')
expectation = {'response': b''}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 16, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 16))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.SecureOk',
('Frame was of wrong type, expected '
'Connection.SecureOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_start(self):
frame_data = (b'\x01\x00\x00\x00\x00\x01G\x00\n\x00\n\x00\t'
b'\x00\x00\x01"\x0ccapabilitiesF\x00\x00\x00X'
b'\x12publisher_confirmst\x01\x1aexchange_exc'
b'hange_bindingst\x01\nbasic.nackt\x01\x16con'
b'sumer_cancel_notifyt\x01\tcopyrightS\x00'
b'\x00\x00$Copyright (C) 2007-2011 VMware, I'
b'nc.\x0binformationS\x00\x00\x005Licensed u'
b'nder the MPL. See http://www.rabbitmq.com'
b'/\x08platformS\x00\x00\x00\nErlang/OTP\x07'
b'productS\x00\x00\x00\x08RabbitMQ\x07versio'
b'nS\x00\x00\x00\x052.6.1\x00\x00\x00\x0ePLA'
b'IN AMQPLAIN\x00\x00\x00\x05en_US\xce')
expectation = {
'server_properties': {
'information': (b'Licensed under the MPL. '
b'See http://www.rabbitmq.com/'),
'product':
b'RabbitMQ',
'copyright':
b'Copyright (C) 2007-2011 VMware, Inc.',
'capabilities': {
'exchange_exchange_bindings': True,
'consumer_cancel_notify': True,
'publisher_confirms': True,
'basic.nack': True
},
'platform':
b'Erlang/OTP',
'version':
b'2.6.1'
},
'version_minor': 9,
'mechanisms': b'PLAIN AMQPLAIN',
'locales': b'en_US',
'version_major': 0
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 335, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 335))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.Start',
('Frame was of wrong type, expected '
'Connection.Start, received %s' % frame_obj.name))
self.maxDiff = 32768
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_startok(self):
frame_data = (b'\x01\x00\x00\x00\x00\x00\xf4\x00\n\x00\x0b'
b'\x00\x00\x00\xd0\x08platformS\x00\x00\x00'
b'\x0cPython 2.7.1\x07productS\x00\x00\x00'
b'\x1aPika Python Client Library\x07versionS'
b'\x00\x00\x00\n0.9.6-pre0\x0ccapabilitiesF'
b'\x00\x00\x00;\x16consumer_cancel_notifyt'
b'\x01\x12publisher_confirmst\x01\nbasic.nack'
b't\x01\x0binformationS\x00\x00\x00\x1aSee '
b'http://pika.github.com\x05PLAIN\x00\x00'
b'\x00\x0c\x00guest\x00guest\x05en_US\xce')
expectation = {
'locale': 'en_US',
'mechanism': 'PLAIN',
'client_properties': {
'platform': b'Python 2.7.1',
'product': b'Pika Python Client Library',
'version': b'0.9.6-pre0',
'capabilities': {
'consumer_cancel_notify': True,
'publisher_confirms': True,
'basic.nack': True
},
'information': b'See http://pika.github.com'
},
'response': b'\x00guest\x00guest'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 252, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 252))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.StartOk',
('Frame was of wrong type, expected '
'Connection.StartOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_tune(self):
frame_data = (b'\x01\x00\x00\x00\x00\x00\x0c\x00\n\x00\x1e\x00\x00'
b'\x00\x02\x00\x00\x00\x00\xce')
expectation = {'frame_max': 131072, 'channel_max': 0, 'heartbeat': 0}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 20, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 20))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.Tune',
('Frame was of wrong type, expected Connection.Tune, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_connection_tuneok(self):
frame_data = (b'\x01\x00\x00\x00\x00\x00\x0c\x00\n\x00\x1f\x00\x00'
b'\x00\x02\x00\x00\x00\x00\xce')
expectation = {'frame_max': 131072, 'channel_max': 0, 'heartbeat': 0}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 20, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 20))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Connection.TuneOk',
('Frame was of wrong type, expected '
'Connection.TuneOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_content_body_frame(self):
frame_data = (b'\x03\x00\x00\x00\x00\x00"Hello World #0:1316899165.'
b'75516605\xce')
expectation = b'Hello World #0:1316899165.75516605'
# Decode the frame and validate lengths
consumed, channel, data = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 42, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 42))
self.assertEqual(
channel, 0,
'Channel number did not match expectation: %i, %i' % (channel, 0))
# Validate the unmarshaled data matches the expectation
self.assertEqual(data.value, expectation)
def test_exchange_bind(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x15\x00(\x00\x1e\x00\x00'
b'\x00\x00\x07foo.bar\x00\x00\x00\x00\x00\xce')
expectation = {
'arguments': {},
'source': '',
'ticket': 0,
'destination': '',
'nowait': False,
'routing_key': 'foo.bar'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 29, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 29))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.Bind',
('Frame was of wrong type, expected Exchange.Bind, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_exchange_bindok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00(\x00\x1f\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.BindOk',
('Frame was of wrong type, expected Exchange.BindOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_exchange_declare(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00%\x00(\x00\n\x00\x00\x12pika_'
b'test_exchange\x06direct\x00\x00\x00\x00\x00\xce')
expectation = {
'nowait': False,
'exchange': 'pika_test_exchange',
'durable': False,
'passive': False,
'internal': False,
'arguments': {},
'ticket': 0,
'exchange_type': 'direct',
'auto_delete': False
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 45, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 45))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.Declare',
('Frame was of wrong type, expected '
'Exchange.Declare, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_exchange_declareok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00(\x00\x0b\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.DeclareOk',
('Frame was of wrong type, expected Exchange.'
'DeclareOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_exchange_delete(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x1a\x00(\x00\x14\x00\x00\x12'
b'pika_test_exchange\x00\xce')
expectation = {
'ticket': 0,
'if_unused': False,
'nowait': False,
'exchange': 'pika_test_exchange'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 34, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 34))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.Delete',
('Frame was of wrong type, expected Exchange.Delete, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_exchange_deleteok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00(\x00\x15\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.DeleteOk',
('Frame was of wrong type, expected '
'Exchange.DeleteOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_exchange_unbind(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x15\x00(\x00(\x00\x00\x00'
b'\x00\x07foo.bar\x00\x00\x00\x00\x00\xce')
expectation = {
'arguments': {},
'source': '',
'ticket': 0,
'destination': '',
'nowait': False,
'routing_key': 'foo.bar'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 29, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 29))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.Unbind',
('Frame was of wrong type, expected Exchange.Unbind, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_exchange_unbindok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00(\x003\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Exchange.UnbindOk',
('Frame was of wrong type, expected '
'Exchange.UnbindOk, received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_bind(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00?\x002\x00\x14\x00'
b'\x00\x0fpika_test_queue\x12pika_test_excha'
b'nge\x10test_routing_key\x00\x00\x00\x00\x00'
b'\xce')
expectation = {
'nowait': False,
'exchange': 'pika_test_exchange',
'routing_key': 'test_routing_key',
'queue': 'pika_test_queue',
'arguments': {},
'ticket': 0
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 71, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 71))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.Bind',
('Frame was of wrong type, expected Queue.Bind, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_bindok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x002\x00\x15\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.BindOk',
('Frame was of wrong type, expected Queue.BindOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_declare(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x10\x002\x00\n\x00\x00\x04'
b'test\x02\x00\x00\x00\x00\xce')
expectation = {
'passive': False,
'nowait': False,
'exclusive': False,
'durable': True,
'queue': 'test',
'arguments': {},
'ticket': 0,
'auto_delete': False
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 24, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 24))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.Declare',
('Frame was of wrong type, expected Queue.Declare, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_declareok(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x11\x002\x00\x0b\x04test'
b'\x00\x00\x12\x07\x00\x00\x00\x00\xce')
expectation = {
'queue': 'test',
'message_count': 4615,
'consumer_count': 0
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 25, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 25))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.DeclareOk',
('Frame was of wrong type, expected Queue.DeclareOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_delete(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x17\x002\x00(\x00\x00\x0f'
b'pika_test_queue\x00\xce')
expectation = {
'queue': 'pika_test_queue',
'ticket': 0,
'if_empty': False,
'nowait': False,
'if_unused': False
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 31, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 31))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.Delete',
('Frame was of wrong type, expected Queue.Delete, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_deleteok(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x08\x002\x00)\x00\x00\x00'
b'\x00\xce')
expectation = {'message_count': 0}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 16, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 16))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.DeleteOk',
('Frame was of wrong type, expected Queue.DeleteOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_purge(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x0c\x002\x00\x1e\x00\x00'
b'\x04test\x00\xce')
expectation = {'queue': 'test', 'ticket': 0, 'nowait': False}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 20, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 20))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.Purge',
('Frame was of wrong type, expected Queue.Purge, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_purgeok(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x08\x002\x00\x1f\x00\x00\x00'
b'\x01\xce')
expectation = {'message_count': 1}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 16, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 16))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.PurgeOk',
('Frame was of wrong type, expected Queue.PurgeOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_unbind(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00>\x002\x002\x00\x00\x0f'
b'pika_test_queue\x12pika_test_exchange\x10test_routing'
b'_key\x00\x00\x00\x00\xce')
expectation = {
'queue': 'pika_test_queue',
'arguments': {},
'ticket': 0,
'routing_key': 'test_routing_key',
'exchange': 'pika_test_exchange'
}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 70, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 70))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.Unbind',
('Frame was of wrong type, expected Queue.Unbind, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_queue_unbindok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x002\x003\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Queue.UnbindOk',
('Frame was of wrong type, expected Queue.UnbindOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_tx_commit(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00Z\x00\x14\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Tx.Commit',
('Frame was of wrong type, expected Tx.Commit, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_tx_commitok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00Z\x00\x15\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Tx.CommitOk',
('Frame was of wrong type, expected Tx.CommitOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_tx_rollback(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00Z\x00\x1e\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Tx.Rollback',
('Frame was of wrong type, expected Tx.Rollback, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_tx_rollbackok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00Z\x00\x1f\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Tx.RollbackOk',
('Frame was of wrong type, expected Tx.RollbackOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_tx_select(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00Z\x00\n\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Tx.Select',
('Frame was of wrong type, expected Tx.Select, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
def test_tx_selectok(self):
frame_data = b'\x01\x00\x01\x00\x00\x00\x04\x00Z\x00\x0b\xce'
expectation = {}
# Decode the frame and validate lengths
consumed, channel, frame_obj = frame.unmarshal(frame_data)
self.assertEqual(
consumed, 12, 'Bytes consumed did not match expectation: %i, %i' %
(consumed, 12))
self.assertEqual(
channel, 1,
'Channel number did not match expectation: %i, %i' % (channel, 1))
# Validate the frame name
self.assertEqual(frame_obj.name, 'Tx.SelectOk',
('Frame was of wrong type, expected Tx.SelectOk, '
'received %s' % frame_obj.name))
# Validate the unmarshaled data matches the expectation
self.assertDictEqual(dict(frame_obj), expectation)
pamqp-2.3.0/tests/test_frame_unmarshaling_errors.py 0000664 0000000 0000000 00000010633 13456152267 0022661 0 ustar 00root root 0000000 0000000 # coding=utf-8
import struct
import unittest
from pamqp import exceptions, frame
class TestCase(unittest.TestCase):
def test_invalid_protocol_header(self):
try:
frame.unmarshal(b'AMQP\x00\x00\t')
except exceptions.UnmarshalingException as err:
self.assertTrue(str(err).startswith(
"Could not unmarshal "
'frame: Data did not match the ProtocolHeader format'))
else:
assert False, 'Failed to raise exception'
def test_invalid_frame_header(self):
frame_data = struct.pack('>BI', 255, 0)
try:
frame.unmarshal(frame_data)
except exceptions.UnmarshalingException as err:
self.assertEqual(
str(err), 'Could not unmarshal Unknown frame: No frame size')
else:
assert False, 'Failed to raise exception'
def test_frame_with_no_length(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x00\x00<\x00P\x00\x00\x00\x00'
b'\x00\x00\x00\x01\x00\xce')
try:
frame.unmarshal(frame_data)
except exceptions.UnmarshalingException as err:
self.assertEqual(
str(err), 'Could not unmarshal Unknown frame: No frame size')
else:
assert False, 'Failed to raise exception'
def test_frame_malformed_length(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\x0c\x00<\x00P\x00\x00\x00\x00'
b'\x00\x00\x00\xce')
try:
frame.unmarshal(frame_data)
except exceptions.UnmarshalingException as err:
self.assertEqual(
str(err),
'Could not unmarshal Unknown frame: Not all data received')
else:
assert False, 'Failed to raise exception'
def test_frame_malformed_end_byte(self):
frame_data = (b'\x01\x00\x01\x00\x00\x00\r\x00<\x00P\x00\x00\x00\x00'
b'\x00\x00\x00\x01\x00\x00')
try:
frame.unmarshal(frame_data)
except exceptions.UnmarshalingException as err:
self.assertEqual(
str(err),
'Could not unmarshal Unknown frame: Last byte error')
else:
assert False, 'Failed to raise exception'
def test_malformed_frame_content(self):
payload = struct.pack('>HxxQ', 8192, 32768)
frame_value = b''.join([struct.pack('>BHI', 5, 0, len(payload)),
payload, frame.FRAME_END_CHAR])
try:
frame.unmarshal(frame_value)
except exceptions.UnmarshalingException as err:
self.assertEqual(
str(err),
'Could not unmarshal Unknown frame: Unknown frame type: 5')
else:
assert False, 'Failed to raise exception'
def test_invalid_method_frame_index(self):
payload = struct.pack('>L', 42949)
frame_value = b''.join([struct.pack('>BHI', 1, 0, len(payload)),
payload, frame.FRAME_END_CHAR])
try:
frame.unmarshal(frame_value)
except exceptions.UnmarshalingException as err:
self.assertEqual(
str(err),
('Could not unmarshal Unknown frame: '
'Unknown method index: 42949'))
else:
assert False, 'Failed to raise exception'
def test_invalid_method_frame_content(self):
payload = struct.pack('>L', 0x000A0029)
frame_value = b''.join([struct.pack('>BHI', 1, 0, len(payload)),
payload, frame.FRAME_END_CHAR])
try:
frame.unmarshal(frame_value)
except exceptions.UnmarshalingException as err:
self.assertTrue(str(err).startswith(
'Could not unmarshal L', 0x000A0029)
frame_value = b''.join([struct.pack('>BHI', 2, 0, len(payload)),
payload, frame.FRAME_END_CHAR])
try:
frame.unmarshal(frame_value)
except exceptions.UnmarshalingException as err:
self.assertTrue(str(err).startswith(
'Could not unmarshal ContentHeader frame:'))
else:
assert False, 'Failed to raise exception'
pamqp-2.3.0/tests/test_specification.py 0000664 0000000 0000000 00000201427 13456152267 0020246 0 ustar 00root root 0000000 0000000 try:
import unittest2 as unittest
except ImportError:
import unittest
from pamqp import specification
class ArgumentTypeTests(unittest.TestCase):
def test_basic_ack_has_delivery_tag(self):
self.assertEqual(specification.Basic.Ack.type('delivery_tag'),
'longlong')
def test_basic_ack_has_multiple(self):
self.assertEqual(specification.Basic.Ack.type('multiple'), 'bit')
def test_basic_cancel_has_consumer_tag(self):
self.assertEqual(specification.Basic.Cancel.type('consumer_tag'),
'shortstr')
def test_basic_cancel_has_nowait(self):
self.assertEqual(specification.Basic.Cancel.type('nowait'), 'bit')
def test_basic_cancelok_has_consumer_tag(self):
self.assertEqual(specification.Basic.CancelOk.type('consumer_tag'),
'shortstr')
def test_basic_consume_has_ticket(self):
self.assertEqual(specification.Basic.Consume.type('ticket'), 'short')
def test_basic_consume_has_queue(self):
self.assertEqual(specification.Basic.Consume.type('queue'), 'shortstr')
def test_basic_consume_has_consumer_tag(self):
self.assertEqual(specification.Basic.Consume.type('consumer_tag'),
'shortstr')
def test_basic_consume_has_no_local(self):
self.assertEqual(specification.Basic.Consume.type('no_local'), 'bit')
def test_basic_consume_has_no_ack(self):
self.assertEqual(specification.Basic.Consume.type('no_ack'), 'bit')
def test_basic_consume_has_exclusive(self):
self.assertEqual(specification.Basic.Consume.type('exclusive'), 'bit')
def test_basic_consume_has_nowait(self):
self.assertEqual(specification.Basic.Consume.type('nowait'), 'bit')
def test_basic_consume_has_arguments(self):
self.assertEqual(specification.Basic.Consume.type('arguments'),
'table')
def test_basic_consumeok_has_consumer_tag(self):
self.assertEqual(specification.Basic.ConsumeOk.type('consumer_tag'),
'shortstr')
def test_basic_deliver_has_consumer_tag(self):
self.assertEqual(specification.Basic.Deliver.type('consumer_tag'),
'shortstr')
def test_basic_deliver_has_delivery_tag(self):
self.assertEqual(specification.Basic.Deliver.type('delivery_tag'),
'longlong')
def test_basic_deliver_has_redelivered(self):
self.assertEqual(specification.Basic.Deliver.type('redelivered'),
'bit')
def test_basic_deliver_has_exchange(self):
self.assertEqual(specification.Basic.Deliver.type('exchange'),
'shortstr')
def test_basic_deliver_has_routing_key(self):
self.assertEqual(specification.Basic.Deliver.type('routing_key'),
'shortstr')
def test_basic_get_has_ticket(self):
self.assertEqual(specification.Basic.Get.type('ticket'), 'short')
def test_basic_get_has_queue(self):
self.assertEqual(specification.Basic.Get.type('queue'), 'shortstr')
def test_basic_get_has_no_ack(self):
self.assertEqual(specification.Basic.Get.type('no_ack'), 'bit')
def test_basic_getempty_has_cluster_id(self):
self.assertEqual(specification.Basic.GetEmpty.type('cluster_id'),
'shortstr')
def test_basic_getok_has_delivery_tag(self):
self.assertEqual(specification.Basic.GetOk.type('delivery_tag'),
'longlong')
def test_basic_getok_has_redelivered(self):
self.assertEqual(specification.Basic.GetOk.type('redelivered'), 'bit')
def test_basic_getok_has_exchange(self):
self.assertEqual(specification.Basic.GetOk.type('exchange'),
'shortstr')
def test_basic_getok_has_routing_key(self):
self.assertEqual(specification.Basic.GetOk.type('routing_key'),
'shortstr')
def test_basic_getok_has_message_count(self):
self.assertEqual(specification.Basic.GetOk.type('message_count'),
'long')
def test_basic_nack_has_delivery_tag(self):
self.assertEqual(specification.Basic.Nack.type('delivery_tag'),
'longlong')
def test_basic_nack_has_multiple(self):
self.assertEqual(specification.Basic.Nack.type('multiple'), 'bit')
def test_basic_nack_has_requeue(self):
self.assertEqual(specification.Basic.Nack.type('requeue'), 'bit')
def test_basic_publish_has_ticket(self):
self.assertEqual(specification.Basic.Publish.type('ticket'), 'short')
def test_basic_publish_has_exchange(self):
self.assertEqual(specification.Basic.Publish.type('exchange'),
'shortstr')
def test_basic_publish_has_routing_key(self):
self.assertEqual(specification.Basic.Publish.type('routing_key'),
'shortstr')
def test_basic_publish_has_mandatory(self):
self.assertEqual(specification.Basic.Publish.type('mandatory'), 'bit')
def test_basic_publish_has_immediate(self):
self.assertEqual(specification.Basic.Publish.type('immediate'), 'bit')
def test_basic_qos_has_prefetch_size(self):
self.assertEqual(specification.Basic.Qos.type('prefetch_size'), 'long')
def test_basic_qos_has_prefetch_count(self):
self.assertEqual(specification.Basic.Qos.type('prefetch_count'),
'short')
def test_basic_qos_has_global_(self):
self.assertEqual(specification.Basic.Qos.type('global_'), 'bit')
def test_basic_recover_has_requeue(self):
self.assertEqual(specification.Basic.Recover.type('requeue'), 'bit')
def test_basic_recoverasync_has_requeue(self):
self.assertEqual(specification.Basic.RecoverAsync.type('requeue'),
'bit')
def test_basic_reject_has_delivery_tag(self):
self.assertEqual(specification.Basic.Reject.type('delivery_tag'),
'longlong')
def test_basic_reject_has_requeue(self):
self.assertEqual(specification.Basic.Reject.type('requeue'), 'bit')
def test_basic_return_has_reply_code(self):
self.assertEqual(specification.Basic.Return.type('reply_code'),
'short')
def test_basic_return_has_reply_text(self):
self.assertEqual(specification.Basic.Return.type('reply_text'),
'shortstr')
def test_basic_return_has_exchange(self):
self.assertEqual(specification.Basic.Return.type('exchange'),
'shortstr')
def test_basic_return_has_routing_key(self):
self.assertEqual(specification.Basic.Return.type('routing_key'),
'shortstr')
def test_channel_close_has_reply_code(self):
self.assertEqual(specification.Channel.Close.type('reply_code'),
'short')
def test_channel_close_has_reply_text(self):
self.assertEqual(specification.Channel.Close.type('reply_text'),
'shortstr')
def test_channel_close_has_class_id(self):
self.assertEqual(specification.Channel.Close.type('class_id'), 'short')
def test_channel_close_has_method_id(self):
self.assertEqual(specification.Channel.Close.type('method_id'),
'short')
def test_channel_flow_has_active(self):
self.assertEqual(specification.Channel.Flow.type('active'), 'bit')
def test_channel_flowok_has_active(self):
self.assertEqual(specification.Channel.FlowOk.type('active'), 'bit')
def test_channel_open_has_out_of_band(self):
self.assertEqual(specification.Channel.Open.type('out_of_band'),
'shortstr')
def test_channel_openok_has_channel_id(self):
self.assertEqual(specification.Channel.OpenOk.type('channel_id'),
'longstr')
def test_confirm_select_has_nowait(self):
self.assertEqual(specification.Confirm.Select.type('nowait'), 'bit')
def test_connection_blocked_has_reason(self):
self.assertEqual(specification.Connection.Blocked.type('reason'),
'shortstr')
def test_connection_close_has_reply_code(self):
self.assertEqual(specification.Connection.Close.type('reply_code'),
'short')
def test_connection_close_has_reply_text(self):
self.assertEqual(specification.Connection.Close.type('reply_text'),
'shortstr')
def test_connection_close_has_class_id(self):
self.assertEqual(specification.Connection.Close.type('class_id'),
'short')
def test_connection_close_has_method_id(self):
self.assertEqual(specification.Connection.Close.type('method_id'),
'short')
def test_connection_open_has_virtual_host(self):
self.assertEqual(specification.Connection.Open.type('virtual_host'),
'shortstr')
def test_connection_open_has_capabilities(self):
self.assertEqual(specification.Connection.Open.type('capabilities'),
'shortstr')
def test_connection_open_has_insist(self):
self.assertEqual(specification.Connection.Open.type('insist'), 'bit')
def test_connection_openok_has_known_hosts(self):
self.assertEqual(specification.Connection.OpenOk.type('known_hosts'),
'shortstr')
def test_connection_secure_has_challenge(self):
self.assertEqual(specification.Connection.Secure.type('challenge'),
'longstr')
def test_connection_secureok_has_response(self):
self.assertEqual(specification.Connection.SecureOk.type('response'),
'longstr')
def test_connection_start_has_version_major(self):
self.assertEqual(specification.Connection.Start.type('version_major'),
'octet')
def test_connection_start_has_version_minor(self):
self.assertEqual(specification.Connection.Start.type('version_minor'),
'octet')
def test_connection_start_has_server_properties(self):
self.assertEqual(
specification.Connection.Start.type('server_properties'), 'table')
def test_connection_start_has_mechanisms(self):
self.assertEqual(specification.Connection.Start.type('mechanisms'),
'longstr')
def test_connection_start_has_locales(self):
self.assertEqual(specification.Connection.Start.type('locales'),
'longstr')
def test_connection_startok_has_client_properties(self):
self.assertEqual(
specification.Connection.StartOk.type('client_properties'),
'table')
def test_connection_startok_has_mechanism(self):
self.assertEqual(specification.Connection.StartOk.type('mechanism'),
'shortstr')
def test_connection_startok_has_response(self):
self.assertEqual(specification.Connection.StartOk.type('response'),
'longstr')
def test_connection_startok_has_locale(self):
self.assertEqual(specification.Connection.StartOk.type('locale'),
'shortstr')
def test_connection_tune_has_channel_max(self):
self.assertEqual(specification.Connection.Tune.type('channel_max'),
'short')
def test_connection_tune_has_frame_max(self):
self.assertEqual(specification.Connection.Tune.type('frame_max'),
'long')
def test_connection_tune_has_heartbeat(self):
self.assertEqual(specification.Connection.Tune.type('heartbeat'),
'short')
def test_connection_tuneok_has_channel_max(self):
self.assertEqual(specification.Connection.TuneOk.type('channel_max'),
'short')
def test_connection_tuneok_has_frame_max(self):
self.assertEqual(specification.Connection.TuneOk.type('frame_max'),
'long')
def test_connection_tuneok_has_heartbeat(self):
self.assertEqual(specification.Connection.TuneOk.type('heartbeat'),
'short')
def test_exchange_bind_has_ticket(self):
self.assertEqual(specification.Exchange.Bind.type('ticket'), 'short')
def test_exchange_bind_has_destination(self):
self.assertEqual(specification.Exchange.Bind.type('destination'),
'shortstr')
def test_exchange_bind_has_source(self):
self.assertEqual(specification.Exchange.Bind.type('source'),
'shortstr')
def test_exchange_bind_has_routing_key(self):
self.assertEqual(specification.Exchange.Bind.type('routing_key'),
'shortstr')
def test_exchange_bind_has_nowait(self):
self.assertEqual(specification.Exchange.Bind.type('nowait'), 'bit')
def test_exchange_bind_has_arguments(self):
self.assertEqual(specification.Exchange.Bind.type('arguments'),
'table')
def test_exchange_declare_has_ticket(self):
self.assertEqual(specification.Exchange.Declare.type('ticket'),
'short')
def test_exchange_declare_has_exchange(self):
self.assertEqual(specification.Exchange.Declare.type('exchange'),
'shortstr')
def test_exchange_declare_has_exchange_type(self):
self.assertEqual(specification.Exchange.Declare.type('exchange_type'),
'shortstr')
def test_exchange_declare_has_passive(self):
self.assertEqual(specification.Exchange.Declare.type('passive'), 'bit')
def test_exchange_declare_has_durable(self):
self.assertEqual(specification.Exchange.Declare.type('durable'), 'bit')
def test_exchange_declare_has_auto_delete(self):
self.assertEqual(specification.Exchange.Declare.type('auto_delete'),
'bit')
def test_exchange_declare_has_internal(self):
self.assertEqual(specification.Exchange.Declare.type('internal'),
'bit')
def test_exchange_declare_has_nowait(self):
self.assertEqual(specification.Exchange.Declare.type('nowait'), 'bit')
def test_exchange_declare_has_arguments(self):
self.assertEqual(specification.Exchange.Declare.type('arguments'),
'table')
def test_exchange_delete_has_ticket(self):
self.assertEqual(specification.Exchange.Delete.type('ticket'), 'short')
def test_exchange_delete_has_exchange(self):
self.assertEqual(specification.Exchange.Delete.type('exchange'),
'shortstr')
def test_exchange_delete_has_if_unused(self):
self.assertEqual(specification.Exchange.Delete.type('if_unused'),
'bit')
def test_exchange_delete_has_nowait(self):
self.assertEqual(specification.Exchange.Delete.type('nowait'), 'bit')
def test_exchange_unbind_has_ticket(self):
self.assertEqual(specification.Exchange.Unbind.type('ticket'), 'short')
def test_exchange_unbind_has_destination(self):
self.assertEqual(specification.Exchange.Unbind.type('destination'),
'shortstr')
def test_exchange_unbind_has_source(self):
self.assertEqual(specification.Exchange.Unbind.type('source'),
'shortstr')
def test_exchange_unbind_has_routing_key(self):
self.assertEqual(specification.Exchange.Unbind.type('routing_key'),
'shortstr')
def test_exchange_unbind_has_nowait(self):
self.assertEqual(specification.Exchange.Unbind.type('nowait'), 'bit')
def test_exchange_unbind_has_arguments(self):
self.assertEqual(specification.Exchange.Unbind.type('arguments'),
'table')
def test_queue_bind_has_ticket(self):
self.assertEqual(specification.Queue.Bind.type('ticket'), 'short')
def test_queue_bind_has_queue(self):
self.assertEqual(specification.Queue.Bind.type('queue'), 'shortstr')
def test_queue_bind_has_exchange(self):
self.assertEqual(specification.Queue.Bind.type('exchange'), 'shortstr')
def test_queue_bind_has_routing_key(self):
self.assertEqual(specification.Queue.Bind.type('routing_key'),
'shortstr')
def test_queue_bind_has_nowait(self):
self.assertEqual(specification.Queue.Bind.type('nowait'), 'bit')
def test_queue_bind_has_arguments(self):
self.assertEqual(specification.Queue.Bind.type('arguments'), 'table')
def test_queue_declare_has_ticket(self):
self.assertEqual(specification.Queue.Declare.type('ticket'), 'short')
def test_queue_declare_has_queue(self):
self.assertEqual(specification.Queue.Declare.type('queue'), 'shortstr')
def test_queue_declare_has_passive(self):
self.assertEqual(specification.Queue.Declare.type('passive'), 'bit')
def test_queue_declare_has_durable(self):
self.assertEqual(specification.Queue.Declare.type('durable'), 'bit')
def test_queue_declare_has_exclusive(self):
self.assertEqual(specification.Queue.Declare.type('exclusive'), 'bit')
def test_queue_declare_has_auto_delete(self):
self.assertEqual(specification.Queue.Declare.type('auto_delete'),
'bit')
def test_queue_declare_has_nowait(self):
self.assertEqual(specification.Queue.Declare.type('nowait'), 'bit')
def test_queue_declare_has_arguments(self):
self.assertEqual(specification.Queue.Declare.type('arguments'),
'table')
def test_queue_declareok_has_queue(self):
self.assertEqual(specification.Queue.DeclareOk.type('queue'),
'shortstr')
def test_queue_declareok_has_message_count(self):
self.assertEqual(specification.Queue.DeclareOk.type('message_count'),
'long')
def test_queue_declareok_has_consumer_count(self):
self.assertEqual(specification.Queue.DeclareOk.type('consumer_count'),
'long')
def test_queue_delete_has_ticket(self):
self.assertEqual(specification.Queue.Delete.type('ticket'), 'short')
def test_queue_delete_has_queue(self):
self.assertEqual(specification.Queue.Delete.type('queue'), 'shortstr')
def test_queue_delete_has_if_unused(self):
self.assertEqual(specification.Queue.Delete.type('if_unused'), 'bit')
def test_queue_delete_has_if_empty(self):
self.assertEqual(specification.Queue.Delete.type('if_empty'), 'bit')
def test_queue_delete_has_nowait(self):
self.assertEqual(specification.Queue.Delete.type('nowait'), 'bit')
def test_queue_deleteok_has_message_count(self):
self.assertEqual(specification.Queue.DeleteOk.type('message_count'),
'long')
def test_queue_purge_has_ticket(self):
self.assertEqual(specification.Queue.Purge.type('ticket'), 'short')
def test_queue_purge_has_queue(self):
self.assertEqual(specification.Queue.Purge.type('queue'), 'shortstr')
def test_queue_purge_has_nowait(self):
self.assertEqual(specification.Queue.Purge.type('nowait'), 'bit')
def test_queue_purgeok_has_message_count(self):
self.assertEqual(specification.Queue.PurgeOk.type('message_count'),
'long')
def test_queue_unbind_has_ticket(self):
self.assertEqual(specification.Queue.Unbind.type('ticket'), 'short')
def test_queue_unbind_has_queue(self):
self.assertEqual(specification.Queue.Unbind.type('queue'), 'shortstr')
def test_queue_unbind_has_exchange(self):
self.assertEqual(specification.Queue.Unbind.type('exchange'),
'shortstr')
def test_queue_unbind_has_routing_key(self):
self.assertEqual(specification.Queue.Unbind.type('routing_key'),
'shortstr')
def test_queue_unbind_has_arguments(self):
self.assertEqual(specification.Queue.Unbind.type('arguments'), 'table')
class AttributeInMethodTests(unittest.TestCase):
def test_basic_ack_has_delivery_tag(self):
self.assertIn('delivery_tag', specification.Basic.Ack())
def test_basic_ack_has_multiple(self):
self.assertIn('multiple', specification.Basic.Ack())
def test_basic_cancel_has_consumer_tag(self):
self.assertIn('consumer_tag', specification.Basic.Cancel())
def test_basic_cancel_has_nowait(self):
self.assertIn('nowait', specification.Basic.Cancel())
def test_basic_cancelok_has_consumer_tag(self):
self.assertIn('consumer_tag', specification.Basic.CancelOk())
def test_basic_consume_has_ticket(self):
self.assertIn('ticket', specification.Basic.Consume())
def test_basic_consume_has_queue(self):
self.assertIn('queue', specification.Basic.Consume())
def test_basic_consume_has_consumer_tag(self):
self.assertIn('consumer_tag', specification.Basic.Consume())
def test_basic_consume_has_no_local(self):
self.assertIn('no_local', specification.Basic.Consume())
def test_basic_consume_has_no_ack(self):
self.assertIn('no_ack', specification.Basic.Consume())
def test_basic_consume_has_exclusive(self):
self.assertIn('exclusive', specification.Basic.Consume())
def test_basic_consume_has_nowait(self):
self.assertIn('nowait', specification.Basic.Consume())
def test_basic_consume_has_arguments(self):
self.assertIn('arguments', specification.Basic.Consume())
def test_basic_consumeok_has_consumer_tag(self):
self.assertIn('consumer_tag', specification.Basic.ConsumeOk())
def test_basic_deliver_has_consumer_tag(self):
self.assertIn('consumer_tag', specification.Basic.Deliver())
def test_basic_deliver_has_delivery_tag(self):
self.assertIn('delivery_tag', specification.Basic.Deliver())
def test_basic_deliver_has_redelivered(self):
self.assertIn('redelivered', specification.Basic.Deliver())
def test_basic_deliver_has_exchange(self):
self.assertIn('exchange', specification.Basic.Deliver())
def test_basic_deliver_has_routing_key(self):
self.assertIn('routing_key', specification.Basic.Deliver())
def test_basic_get_has_ticket(self):
self.assertIn('ticket', specification.Basic.Get())
def test_basic_get_has_queue(self):
self.assertIn('queue', specification.Basic.Get())
def test_basic_get_has_no_ack(self):
self.assertIn('no_ack', specification.Basic.Get())
def test_basic_getempty_has_cluster_id(self):
self.assertIn('cluster_id', specification.Basic.GetEmpty())
def test_basic_getok_has_delivery_tag(self):
self.assertIn('delivery_tag', specification.Basic.GetOk())
def test_basic_getok_has_redelivered(self):
self.assertIn('redelivered', specification.Basic.GetOk())
def test_basic_getok_has_exchange(self):
self.assertIn('exchange', specification.Basic.GetOk())
def test_basic_getok_has_routing_key(self):
self.assertIn('routing_key', specification.Basic.GetOk())
def test_basic_getok_has_message_count(self):
self.assertIn('message_count', specification.Basic.GetOk())
def test_basic_nack_has_delivery_tag(self):
self.assertIn('delivery_tag', specification.Basic.Nack())
def test_basic_nack_has_multiple(self):
self.assertIn('multiple', specification.Basic.Nack())
def test_basic_nack_has_requeue(self):
self.assertIn('requeue', specification.Basic.Nack())
def test_basic_publish_has_ticket(self):
self.assertIn('ticket', specification.Basic.Publish())
def test_basic_publish_has_exchange(self):
self.assertIn('exchange', specification.Basic.Publish())
def test_basic_publish_has_routing_key(self):
self.assertIn('routing_key', specification.Basic.Publish())
def test_basic_publish_has_mandatory(self):
self.assertIn('mandatory', specification.Basic.Publish())
def test_basic_publish_has_immediate(self):
self.assertIn('immediate', specification.Basic.Publish())
def test_basic_qos_has_prefetch_size(self):
self.assertIn('prefetch_size', specification.Basic.Qos())
def test_basic_qos_has_prefetch_count(self):
self.assertIn('prefetch_count', specification.Basic.Qos())
def test_basic_qos_has_global_(self):
self.assertIn('global_', specification.Basic.Qos())
def test_basic_recover_has_requeue(self):
self.assertIn('requeue', specification.Basic.Recover())
def test_basic_reject_has_delivery_tag(self):
self.assertIn('delivery_tag', specification.Basic.Reject())
def test_basic_reject_has_requeue(self):
self.assertIn('requeue', specification.Basic.Reject())
def test_basic_return_has_reply_code(self):
self.assertIn('reply_code', specification.Basic.Return())
def test_basic_return_has_reply_text(self):
self.assertIn('reply_text', specification.Basic.Return())
def test_basic_return_has_exchange(self):
self.assertIn('exchange', specification.Basic.Return())
def test_basic_return_has_routing_key(self):
self.assertIn('routing_key', specification.Basic.Return())
def test_channel_close_has_reply_code(self):
self.assertIn('reply_code', specification.Channel.Close())
def test_channel_close_has_reply_text(self):
self.assertIn('reply_text', specification.Channel.Close())
def test_channel_close_has_class_id(self):
self.assertIn('class_id', specification.Channel.Close())
def test_channel_close_has_method_id(self):
self.assertIn('method_id', specification.Channel.Close())
def test_channel_flow_has_active(self):
self.assertIn('active', specification.Channel.Flow())
def test_channel_flowok_has_active(self):
self.assertIn('active', specification.Channel.FlowOk())
def test_channel_open_has_out_of_band(self):
self.assertIn('out_of_band', specification.Channel.Open())
def test_channel_openok_has_channel_id(self):
self.assertIn('channel_id', specification.Channel.OpenOk())
def test_confirm_select_has_nowait(self):
self.assertIn('nowait', specification.Confirm.Select())
def test_connection_blocked_has_reason(self):
self.assertIn('reason', specification.Connection.Blocked())
def test_connection_close_has_reply_code(self):
self.assertIn('reply_code', specification.Connection.Close())
def test_connection_close_has_reply_text(self):
self.assertIn('reply_text', specification.Connection.Close())
def test_connection_close_has_class_id(self):
self.assertIn('class_id', specification.Connection.Close())
def test_connection_close_has_method_id(self):
self.assertIn('method_id', specification.Connection.Close())
def test_connection_open_has_virtual_host(self):
self.assertIn('virtual_host', specification.Connection.Open())
def test_connection_open_has_capabilities(self):
self.assertIn('capabilities', specification.Connection.Open())
def test_connection_open_has_insist(self):
self.assertIn('insist', specification.Connection.Open())
def test_connection_openok_has_known_hosts(self):
self.assertIn('known_hosts', specification.Connection.OpenOk())
def test_connection_secure_has_challenge(self):
self.assertIn('challenge', specification.Connection.Secure())
def test_connection_secureok_has_response(self):
self.assertIn('response', specification.Connection.SecureOk())
def test_connection_start_has_version_major(self):
self.assertIn('version_major', specification.Connection.Start())
def test_connection_start_has_version_minor(self):
self.assertIn('version_minor', specification.Connection.Start())
def test_connection_start_has_server_properties(self):
self.assertIn('server_properties', specification.Connection.Start())
def test_connection_start_has_mechanisms(self):
self.assertIn('mechanisms', specification.Connection.Start())
def test_connection_start_has_locales(self):
self.assertIn('locales', specification.Connection.Start())
def test_connection_startok_has_mechanism(self):
self.assertIn('mechanism', specification.Connection.StartOk())
def test_connection_startok_has_response(self):
self.assertIn('response', specification.Connection.StartOk())
def test_connection_startok_has_locale(self):
self.assertIn('locale', specification.Connection.StartOk())
def test_connection_tune_has_channel_max(self):
self.assertIn('channel_max', specification.Connection.Tune())
def test_connection_tune_has_frame_max(self):
self.assertIn('frame_max', specification.Connection.Tune())
def test_connection_tune_has_heartbeat(self):
self.assertIn('heartbeat', specification.Connection.Tune())
def test_connection_tuneok_has_channel_max(self):
self.assertIn('channel_max', specification.Connection.TuneOk())
def test_connection_tuneok_has_frame_max(self):
self.assertIn('frame_max', specification.Connection.TuneOk())
def test_connection_tuneok_has_heartbeat(self):
self.assertIn('heartbeat', specification.Connection.TuneOk())
def test_exchange_bind_has_ticket(self):
self.assertIn('ticket', specification.Exchange.Bind())
def test_exchange_bind_has_destination(self):
self.assertIn('destination', specification.Exchange.Bind())
def test_exchange_bind_has_source(self):
self.assertIn('source', specification.Exchange.Bind())
def test_exchange_bind_has_routing_key(self):
self.assertIn('routing_key', specification.Exchange.Bind())
def test_exchange_bind_has_nowait(self):
self.assertIn('nowait', specification.Exchange.Bind())
def test_exchange_bind_has_arguments(self):
self.assertIn('arguments', specification.Exchange.Bind())
def test_exchange_declare_has_ticket(self):
self.assertIn('ticket', specification.Exchange.Declare())
def test_exchange_declare_has_exchange(self):
self.assertIn('exchange', specification.Exchange.Declare())
def test_exchange_declare_has_exchange_type(self):
self.assertIn('exchange_type', specification.Exchange.Declare())
def test_exchange_declare_has_passive(self):
self.assertIn('passive', specification.Exchange.Declare())
def test_exchange_declare_has_durable(self):
self.assertIn('durable', specification.Exchange.Declare())
def test_exchange_declare_has_auto_delete(self):
self.assertIn('auto_delete', specification.Exchange.Declare())
def test_exchange_declare_has_internal(self):
self.assertIn('internal', specification.Exchange.Declare())
def test_exchange_declare_has_nowait(self):
self.assertIn('nowait', specification.Exchange.Declare())
def test_exchange_declare_has_arguments(self):
self.assertIn('arguments', specification.Exchange.Declare())
def test_exchange_delete_has_ticket(self):
self.assertIn('ticket', specification.Exchange.Delete())
def test_exchange_delete_has_exchange(self):
self.assertIn('exchange', specification.Exchange.Delete())
def test_exchange_delete_has_if_unused(self):
self.assertIn('if_unused', specification.Exchange.Delete())
def test_exchange_delete_has_nowait(self):
self.assertIn('nowait', specification.Exchange.Delete())
def test_exchange_unbind_has_ticket(self):
self.assertIn('ticket', specification.Exchange.Unbind())
def test_exchange_unbind_has_destination(self):
self.assertIn('destination', specification.Exchange.Unbind())
def test_exchange_unbind_has_source(self):
self.assertIn('source', specification.Exchange.Unbind())
def test_exchange_unbind_has_routing_key(self):
self.assertIn('routing_key', specification.Exchange.Unbind())
def test_exchange_unbind_has_nowait(self):
self.assertIn('nowait', specification.Exchange.Unbind())
def test_exchange_unbind_has_arguments(self):
self.assertIn('arguments', specification.Exchange.Unbind())
def test_queue_bind_has_ticket(self):
self.assertIn('ticket', specification.Queue.Bind())
def test_queue_bind_has_queue(self):
self.assertIn('queue', specification.Queue.Bind())
def test_queue_bind_has_exchange(self):
self.assertIn('exchange', specification.Queue.Bind())
def test_queue_bind_has_routing_key(self):
self.assertIn('routing_key', specification.Queue.Bind())
def test_queue_bind_has_nowait(self):
self.assertIn('nowait', specification.Queue.Bind())
def test_queue_bind_has_arguments(self):
self.assertIn('arguments', specification.Queue.Bind())
def test_queue_declare_has_ticket(self):
self.assertIn('ticket', specification.Queue.Declare())
def test_queue_declare_has_queue(self):
self.assertIn('queue', specification.Queue.Declare())
def test_queue_declare_has_passive(self):
self.assertIn('passive', specification.Queue.Declare())
def test_queue_declare_has_durable(self):
self.assertIn('durable', specification.Queue.Declare())
def test_queue_declare_has_exclusive(self):
self.assertIn('exclusive', specification.Queue.Declare())
def test_queue_declare_has_auto_delete(self):
self.assertIn('auto_delete', specification.Queue.Declare())
def test_queue_declare_has_nowait(self):
self.assertIn('nowait', specification.Queue.Declare())
def test_queue_declare_has_arguments(self):
self.assertIn('arguments', specification.Queue.Declare())
def test_queue_declareok_has_queue(self):
self.assertIn('queue', specification.Queue.DeclareOk())
def test_queue_declareok_has_message_count(self):
self.assertIn('message_count', specification.Queue.DeclareOk())
def test_queue_declareok_has_consumer_count(self):
self.assertIn('consumer_count', specification.Queue.DeclareOk())
def test_queue_delete_has_ticket(self):
self.assertIn('ticket', specification.Queue.Delete())
def test_queue_delete_has_queue(self):
self.assertIn('queue', specification.Queue.Delete())
def test_queue_delete_has_if_unused(self):
self.assertIn('if_unused', specification.Queue.Delete())
def test_queue_delete_has_if_empty(self):
self.assertIn('if_empty', specification.Queue.Delete())
def test_queue_delete_has_nowait(self):
self.assertIn('nowait', specification.Queue.Delete())
def test_queue_deleteok_has_message_count(self):
self.assertIn('message_count', specification.Queue.DeleteOk())
def test_queue_purge_has_ticket(self):
self.assertIn('ticket', specification.Queue.Purge())
def test_queue_purge_has_queue(self):
self.assertIn('queue', specification.Queue.Purge())
def test_queue_purge_has_nowait(self):
self.assertIn('nowait', specification.Queue.Purge())
def test_queue_purgeok_has_message_count(self):
self.assertIn('message_count', specification.Queue.PurgeOk())
def test_queue_unbind_has_ticket(self):
self.assertIn('ticket', specification.Queue.Unbind())
def test_queue_unbind_has_queue(self):
self.assertIn('queue', specification.Queue.Unbind())
def test_queue_unbind_has_exchange(self):
self.assertIn('exchange', specification.Queue.Unbind())
def test_queue_unbind_has_routing_key(self):
self.assertIn('routing_key', specification.Queue.Unbind())
def test_queue_unbind_has_arguments(self):
self.assertIn('arguments', specification.Queue.Unbind())
class DeprecationWarningTests(unittest.TestCase):
def test_basic_recoverasync_raises_deprecation_error(self):
with self.assertWarns(DeprecationWarning):
specification.Basic.RecoverAsync()
class BasicPropertiesTests(unittest.TestCase):
def test_basic_properties_has_content_type(self):
self.assertEqual(specification.Basic.Properties.type('content_type'),
'shortstr')
def test_basic_properties_has_content_encoding(self):
self.assertEqual(
specification.Basic.Properties.type('content_encoding'),
'shortstr')
def test_basic_properties_has_headers(self):
self.assertEqual(specification.Basic.Properties.type('headers'),
'table')
def test_basic_properties_has_delivery_mode(self):
self.assertEqual(specification.Basic.Properties.type('delivery_mode'),
'octet')
def test_basic_properties_has_priority(self):
self.assertEqual(specification.Basic.Properties.type('priority'),
'octet')
def test_basic_properties_has_correlation_id(self):
self.assertEqual(specification.Basic.Properties.type('correlation_id'),
'shortstr')
def test_basic_properties_has_reply_to(self):
self.assertEqual(specification.Basic.Properties.type('reply_to'),
'shortstr')
def test_basic_properties_has_expiration(self):
self.assertEqual(specification.Basic.Properties.type('expiration'),
'shortstr')
def test_basic_properties_has_message_id(self):
self.assertEqual(specification.Basic.Properties.type('message_id'),
'shortstr')
def test_basic_properties_has_timestamp(self):
self.assertEqual(specification.Basic.Properties.type('timestamp'),
'timestamp')
def test_basic_properties_has_message_type(self):
self.assertEqual(specification.Basic.Properties.type('message_type'),
'shortstr')
def test_basic_properties_has_user_id(self):
self.assertEqual(specification.Basic.Properties.type('user_id'),
'shortstr')
def test_basic_properties_has_app_id(self):
self.assertEqual(specification.Basic.Properties.type('app_id'),
'shortstr')
def test_basic_properties_has_cluster_id(self):
self.assertEqual(specification.Basic.Properties.type('cluster_id'),
'shortstr')
class MethodAttributeLengthTests(unittest.TestCase):
def test_basic_ack_attribute_count(self):
self.assertEqual(len(specification.Basic.Ack()), 2)
def test_basic_cancel_attribute_count(self):
self.assertEqual(len(specification.Basic.Cancel()), 2)
def test_basic_cancelok_attribute_count(self):
self.assertEqual(len(specification.Basic.CancelOk()), 1)
def test_basic_consume_attribute_count(self):
self.assertEqual(len(specification.Basic.Consume()), 8)
def test_basic_consumeok_attribute_count(self):
self.assertEqual(len(specification.Basic.ConsumeOk()), 1)
def test_basic_deliver_attribute_count(self):
self.assertEqual(len(specification.Basic.Deliver()), 5)
def test_basic_get_attribute_count(self):
self.assertEqual(len(specification.Basic.Get()), 3)
def test_basic_getempty_attribute_count(self):
self.assertEqual(len(specification.Basic.GetEmpty()), 1)
def test_basic_getok_attribute_count(self):
self.assertEqual(len(specification.Basic.GetOk()), 5)
def test_basic_nack_attribute_count(self):
self.assertEqual(len(specification.Basic.Nack()), 3)
def test_basic_publish_attribute_count(self):
self.assertEqual(len(specification.Basic.Publish()), 5)
def test_basic_qos_attribute_count(self):
self.assertEqual(len(specification.Basic.Qos()), 3)
def test_basic_qosok_attribute_count(self):
self.assertEqual(len(specification.Basic.QosOk()), 0)
def test_basic_recover_attribute_count(self):
self.assertEqual(len(specification.Basic.Recover()), 1)
def test_basic_recoverok_attribute_count(self):
self.assertEqual(len(specification.Basic.RecoverOk()), 0)
def test_basic_reject_attribute_count(self):
self.assertEqual(len(specification.Basic.Reject()), 2)
def test_basic_return_attribute_count(self):
self.assertEqual(len(specification.Basic.Return()), 4)
def test_channel_close_attribute_count(self):
self.assertEqual(len(specification.Channel.Close()), 4)
def test_channel_closeok_attribute_count(self):
self.assertEqual(len(specification.Channel.CloseOk()), 0)
def test_channel_flow_attribute_count(self):
self.assertEqual(len(specification.Channel.Flow()), 1)
def test_channel_flowok_attribute_count(self):
self.assertEqual(len(specification.Channel.FlowOk()), 1)
def test_channel_open_attribute_count(self):
self.assertEqual(len(specification.Channel.Open()), 1)
def test_channel_openok_attribute_count(self):
self.assertEqual(len(specification.Channel.OpenOk()), 1)
def test_confirm_select_attribute_count(self):
self.assertEqual(len(specification.Confirm.Select()), 1)
def test_confirm_selectok_attribute_count(self):
self.assertEqual(len(specification.Confirm.SelectOk()), 0)
def test_connection_blocked_attribute_count(self):
self.assertEqual(len(specification.Connection.Blocked()), 1)
def test_connection_close_attribute_count(self):
self.assertEqual(len(specification.Connection.Close()), 4)
def test_connection_closeok_attribute_count(self):
self.assertEqual(len(specification.Connection.CloseOk()), 0)
def test_connection_open_attribute_count(self):
self.assertEqual(len(specification.Connection.Open()), 3)
def test_connection_openok_attribute_count(self):
self.assertEqual(len(specification.Connection.OpenOk()), 1)
def test_connection_secure_attribute_count(self):
self.assertEqual(len(specification.Connection.Secure()), 1)
def test_connection_secureok_attribute_count(self):
self.assertEqual(len(specification.Connection.SecureOk()), 1)
def test_connection_start_attribute_count(self):
self.assertEqual(len(specification.Connection.Start()), 5)
def test_connection_startok_attribute_count(self):
self.assertEqual(len(specification.Connection.StartOk()), 4)
def test_connection_tune_attribute_count(self):
self.assertEqual(len(specification.Connection.Tune()), 3)
def test_connection_tuneok_attribute_count(self):
self.assertEqual(len(specification.Connection.TuneOk()), 3)
def test_connection_unblocked_attribute_count(self):
self.assertEqual(len(specification.Connection.Unblocked()), 0)
def test_exchange_bind_attribute_count(self):
self.assertEqual(len(specification.Exchange.Bind()), 6)
def test_exchange_bindok_attribute_count(self):
self.assertEqual(len(specification.Exchange.BindOk()), 0)
def test_exchange_declare_attribute_count(self):
self.assertEqual(len(specification.Exchange.Declare()), 9)
def test_exchange_declareok_attribute_count(self):
self.assertEqual(len(specification.Exchange.DeclareOk()), 0)
def test_exchange_delete_attribute_count(self):
self.assertEqual(len(specification.Exchange.Delete()), 4)
def test_exchange_deleteok_attribute_count(self):
self.assertEqual(len(specification.Exchange.DeleteOk()), 0)
def test_exchange_unbind_attribute_count(self):
self.assertEqual(len(specification.Exchange.Unbind()), 6)
def test_exchange_unbindok_attribute_count(self):
self.assertEqual(len(specification.Exchange.UnbindOk()), 0)
def test_queue_bind_attribute_count(self):
self.assertEqual(len(specification.Queue.Bind()), 6)
def test_queue_bindok_attribute_count(self):
self.assertEqual(len(specification.Queue.BindOk()), 0)
def test_queue_declare_attribute_count(self):
self.assertEqual(len(specification.Queue.Declare()), 8)
def test_queue_declareok_attribute_count(self):
self.assertEqual(len(specification.Queue.DeclareOk()), 3)
def test_queue_delete_attribute_count(self):
self.assertEqual(len(specification.Queue.Delete()), 5)
def test_queue_deleteok_attribute_count(self):
self.assertEqual(len(specification.Queue.DeleteOk()), 1)
def test_queue_purge_attribute_count(self):
self.assertEqual(len(specification.Queue.Purge()), 3)
def test_queue_purgeok_attribute_count(self):
self.assertEqual(len(specification.Queue.PurgeOk()), 1)
def test_queue_unbind_attribute_count(self):
self.assertEqual(len(specification.Queue.Unbind()), 5)
def test_queue_unbindok_attribute_count(self):
self.assertEqual(len(specification.Queue.UnbindOk()), 0)
def test_tx_commit_attribute_count(self):
self.assertEqual(len(specification.Tx.Commit()), 0)
def test_tx_commitok_attribute_count(self):
self.assertEqual(len(specification.Tx.CommitOk()), 0)
def test_tx_rollback_attribute_count(self):
self.assertEqual(len(specification.Tx.Rollback()), 0)
def test_tx_rollbackok_attribute_count(self):
self.assertEqual(len(specification.Tx.RollbackOk()), 0)
def test_tx_select_attribute_count(self):
self.assertEqual(len(specification.Tx.Select()), 0)
def test_tx_selectok_attribute_count(self):
self.assertEqual(len(specification.Tx.SelectOk()), 0)
class MethodAttributeDefaultTests(unittest.TestCase):
def test_basic_ack_default_for_delivery_tag(self):
obj = specification.Basic.Ack()
self.assertEqual(obj['delivery_tag'], 0)
def test_basic_ack_default_for_multiple(self):
obj = specification.Basic.Ack()
self.assertEqual(obj['multiple'], False)
def test_basic_cancel_default_for_consumer_tag(self):
obj = specification.Basic.Cancel()
self.assertEqual(obj['consumer_tag'], '')
def test_basic_cancel_default_for_nowait(self):
obj = specification.Basic.Cancel()
self.assertEqual(obj['nowait'], False)
def test_basic_cancelok_default_for_consumer_tag(self):
obj = specification.Basic.CancelOk()
self.assertEqual(obj['consumer_tag'], '')
def test_basic_consume_default_for_ticket(self):
obj = specification.Basic.Consume()
self.assertEqual(obj['ticket'], 0)
def test_basic_consume_default_for_queue(self):
obj = specification.Basic.Consume()
self.assertEqual(obj['queue'], '')
def test_basic_consume_default_for_consumer_tag(self):
obj = specification.Basic.Consume()
self.assertEqual(obj['consumer_tag'], '')
def test_basic_consume_default_for_no_local(self):
obj = specification.Basic.Consume()
self.assertEqual(obj['no_local'], False)
def test_basic_consume_default_for_no_ack(self):
obj = specification.Basic.Consume()
self.assertEqual(obj['no_ack'], False)
def test_basic_consume_default_for_exclusive(self):
obj = specification.Basic.Consume()
self.assertEqual(obj['exclusive'], False)
def test_basic_consume_default_for_nowait(self):
obj = specification.Basic.Consume()
self.assertEqual(obj['nowait'], False)
def test_basic_consume_default_for_arguments(self):
obj = specification.Basic.Consume()
self.assertDictEqual(obj['arguments'], {})
def test_basic_consumeok_default_for_consumer_tag(self):
obj = specification.Basic.ConsumeOk()
self.assertEqual(obj['consumer_tag'], '')
def test_basic_deliver_default_for_consumer_tag(self):
obj = specification.Basic.Deliver()
self.assertEqual(obj['consumer_tag'], '')
def test_basic_deliver_default_for_delivery_tag(self):
obj = specification.Basic.Deliver()
self.assertEqual(obj['delivery_tag'], None)
def test_basic_deliver_default_for_redelivered(self):
obj = specification.Basic.Deliver()
self.assertEqual(obj['redelivered'], False)
def test_basic_deliver_default_for_exchange(self):
obj = specification.Basic.Deliver()
self.assertEqual(obj['exchange'], '')
def test_basic_deliver_default_for_routing_key(self):
obj = specification.Basic.Deliver()
self.assertEqual(obj['routing_key'], '')
def test_basic_get_default_for_ticket(self):
obj = specification.Basic.Get()
self.assertEqual(obj['ticket'], 0)
def test_basic_get_default_for_queue(self):
obj = specification.Basic.Get()
self.assertEqual(obj['queue'], '')
def test_basic_get_default_for_no_ack(self):
obj = specification.Basic.Get()
self.assertEqual(obj['no_ack'], False)
def test_basic_getempty_default_for_cluster_id(self):
obj = specification.Basic.GetEmpty()
self.assertEqual(obj['cluster_id'], '')
def test_basic_getok_default_for_delivery_tag(self):
obj = specification.Basic.GetOk()
self.assertEqual(obj['delivery_tag'], None)
def test_basic_getok_default_for_redelivered(self):
obj = specification.Basic.GetOk()
self.assertEqual(obj['redelivered'], False)
def test_basic_getok_default_for_exchange(self):
obj = specification.Basic.GetOk()
self.assertEqual(obj['exchange'], '')
def test_basic_getok_default_for_routing_key(self):
obj = specification.Basic.GetOk()
self.assertEqual(obj['routing_key'], '')
def test_basic_getok_default_for_message_count(self):
obj = specification.Basic.GetOk()
self.assertEqual(obj['message_count'], 0)
def test_basic_nack_default_for_delivery_tag(self):
obj = specification.Basic.Nack()
self.assertEqual(obj['delivery_tag'], 0)
def test_basic_nack_default_for_multiple(self):
obj = specification.Basic.Nack()
self.assertEqual(obj['multiple'], False)
def test_basic_nack_default_for_requeue(self):
obj = specification.Basic.Nack()
self.assertEqual(obj['requeue'], True)
def test_basic_publish_default_for_ticket(self):
obj = specification.Basic.Publish()
self.assertEqual(obj['ticket'], 0)
def test_basic_publish_default_for_exchange(self):
obj = specification.Basic.Publish()
self.assertEqual(obj['exchange'], '')
def test_basic_publish_default_for_routing_key(self):
obj = specification.Basic.Publish()
self.assertEqual(obj['routing_key'], '')
def test_basic_publish_default_for_mandatory(self):
obj = specification.Basic.Publish()
self.assertEqual(obj['mandatory'], False)
def test_basic_publish_default_for_immediate(self):
obj = specification.Basic.Publish()
self.assertEqual(obj['immediate'], False)
def test_basic_qos_default_for_prefetch_size(self):
obj = specification.Basic.Qos()
self.assertEqual(obj['prefetch_size'], 0)
def test_basic_qos_default_for_prefetch_count(self):
obj = specification.Basic.Qos()
self.assertEqual(obj['prefetch_count'], 0)
def test_basic_qos_default_for_global_(self):
obj = specification.Basic.Qos()
self.assertEqual(obj['global_'], False)
def test_basic_recover_default_for_requeue(self):
obj = specification.Basic.Recover()
self.assertEqual(obj['requeue'], False)
def test_basic_reject_default_for_delivery_tag(self):
obj = specification.Basic.Reject()
self.assertEqual(obj['delivery_tag'], None)
def test_basic_reject_default_for_requeue(self):
obj = specification.Basic.Reject()
self.assertEqual(obj['requeue'], True)
def test_basic_return_default_for_reply_code(self):
obj = specification.Basic.Return()
self.assertEqual(obj['reply_code'], 0)
def test_basic_return_default_for_reply_text(self):
obj = specification.Basic.Return()
self.assertEqual(obj['reply_text'], '')
def test_basic_return_default_for_exchange(self):
obj = specification.Basic.Return()
self.assertEqual(obj['exchange'], '')
def test_basic_return_default_for_routing_key(self):
obj = specification.Basic.Return()
self.assertEqual(obj['routing_key'], '')
def test_channel_close_default_for_reply_code(self):
obj = specification.Channel.Close()
self.assertEqual(obj['reply_code'], 0)
def test_channel_close_default_for_reply_text(self):
obj = specification.Channel.Close()
self.assertEqual(obj['reply_text'], '')
def test_channel_close_default_for_class_id(self):
obj = specification.Channel.Close()
self.assertEqual(obj['class_id'], 0)
def test_channel_close_default_for_method_id(self):
obj = specification.Channel.Close()
self.assertEqual(obj['method_id'], 0)
def test_channel_flow_default_for_active(self):
obj = specification.Channel.Flow()
self.assertEqual(obj['active'], None)
def test_channel_flowok_default_for_active(self):
obj = specification.Channel.FlowOk()
self.assertEqual(obj['active'], None)
def test_channel_open_default_for_out_of_band(self):
obj = specification.Channel.Open()
self.assertEqual(obj['out_of_band'], '')
def test_channel_openok_default_for_channel_id(self):
obj = specification.Channel.OpenOk()
self.assertEqual(obj['channel_id'], '')
def test_confirm_select_default_for_nowait(self):
obj = specification.Confirm.Select()
self.assertEqual(obj['nowait'], False)
def test_connection_blocked_default_for_reason(self):
obj = specification.Connection.Blocked()
self.assertEqual(obj['reason'], '')
def test_connection_close_default_for_reply_code(self):
obj = specification.Connection.Close()
self.assertEqual(obj['reply_code'], 0)
def test_connection_close_default_for_reply_text(self):
obj = specification.Connection.Close()
self.assertEqual(obj['reply_text'], '')
def test_connection_close_default_for_class_id(self):
obj = specification.Connection.Close()
self.assertEqual(obj['class_id'], 0)
def test_connection_close_default_for_method_id(self):
obj = specification.Connection.Close()
self.assertEqual(obj['method_id'], 0)
def test_connection_open_default_for_virtual_host(self):
obj = specification.Connection.Open()
self.assertEqual(obj['virtual_host'], '/')
def test_connection_open_default_for_capabilities(self):
obj = specification.Connection.Open()
self.assertEqual(obj['capabilities'], '')
def test_connection_open_default_for_insist(self):
obj = specification.Connection.Open()
self.assertEqual(obj['insist'], False)
def test_connection_openok_default_for_known_hosts(self):
obj = specification.Connection.OpenOk()
self.assertEqual(obj['known_hosts'], '')
def test_connection_secure_default_for_challenge(self):
obj = specification.Connection.Secure()
self.assertEqual(obj['challenge'], '')
def test_connection_secureok_default_for_response(self):
obj = specification.Connection.SecureOk()
self.assertEqual(obj['response'], '')
def test_connection_start_default_for_version_major(self):
obj = specification.Connection.Start()
self.assertEqual(obj['version_major'], 0)
def test_connection_start_default_for_version_minor(self):
obj = specification.Connection.Start()
self.assertEqual(obj['version_minor'], 9)
def test_connection_start_default_for_mechanisms(self):
obj = specification.Connection.Start()
self.assertEqual(obj['mechanisms'], 'PLAIN')
def test_connection_start_default_for_locales(self):
obj = specification.Connection.Start()
self.assertEqual(obj['locales'], 'en_US')
def test_connection_startok_default_for_mechanism(self):
obj = specification.Connection.StartOk()
self.assertEqual(obj['mechanism'], 'PLAIN')
def test_connection_startok_default_for_response(self):
obj = specification.Connection.StartOk()
self.assertEqual(obj['response'], '')
def test_connection_startok_default_for_locale(self):
obj = specification.Connection.StartOk()
self.assertEqual(obj['locale'], 'en_US')
def test_connection_tune_default_for_channel_max(self):
obj = specification.Connection.Tune()
self.assertEqual(obj['channel_max'], 0)
def test_connection_tune_default_for_frame_max(self):
obj = specification.Connection.Tune()
self.assertEqual(obj['frame_max'], 0)
def test_connection_tune_default_for_heartbeat(self):
obj = specification.Connection.Tune()
self.assertEqual(obj['heartbeat'], 0)
def test_connection_tuneok_default_for_channel_max(self):
obj = specification.Connection.TuneOk()
self.assertEqual(obj['channel_max'], 0)
def test_connection_tuneok_default_for_frame_max(self):
obj = specification.Connection.TuneOk()
self.assertEqual(obj['frame_max'], 0)
def test_connection_tuneok_default_for_heartbeat(self):
obj = specification.Connection.TuneOk()
self.assertEqual(obj['heartbeat'], 0)
def test_exchange_bind_default_for_ticket(self):
obj = specification.Exchange.Bind()
self.assertEqual(obj['ticket'], 0)
def test_exchange_bind_default_for_destination(self):
obj = specification.Exchange.Bind()
self.assertEqual(obj['destination'], '')
def test_exchange_bind_default_for_source(self):
obj = specification.Exchange.Bind()
self.assertEqual(obj['source'], '')
def test_exchange_bind_default_for_routing_key(self):
obj = specification.Exchange.Bind()
self.assertEqual(obj['routing_key'], '')
def test_exchange_bind_default_for_nowait(self):
obj = specification.Exchange.Bind()
self.assertEqual(obj['nowait'], False)
def test_exchange_bind_default_for_arguments(self):
obj = specification.Exchange.Bind()
self.assertDictEqual(obj['arguments'], {})
def test_exchange_declare_default_for_ticket(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['ticket'], 0)
def test_exchange_declare_default_for_exchange(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['exchange'], '')
def test_exchange_declare_default_for_exchange_type(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['exchange_type'], 'direct')
def test_exchange_declare_default_for_passive(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['passive'], False)
def test_exchange_declare_default_for_durable(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['durable'], False)
def test_exchange_declare_default_for_auto_delete(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['auto_delete'], False)
def test_exchange_declare_default_for_internal(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['internal'], False)
def test_exchange_declare_default_for_nowait(self):
obj = specification.Exchange.Declare()
self.assertEqual(obj['nowait'], False)
def test_exchange_declare_default_for_arguments(self):
obj = specification.Exchange.Declare()
self.assertDictEqual(obj['arguments'], {})
def test_exchange_delete_default_for_ticket(self):
obj = specification.Exchange.Delete()
self.assertEqual(obj['ticket'], 0)
def test_exchange_delete_default_for_exchange(self):
obj = specification.Exchange.Delete()
self.assertEqual(obj['exchange'], '')
def test_exchange_delete_default_for_if_unused(self):
obj = specification.Exchange.Delete()
self.assertEqual(obj['if_unused'], False)
def test_exchange_delete_default_for_nowait(self):
obj = specification.Exchange.Delete()
self.assertEqual(obj['nowait'], False)
def test_exchange_unbind_default_for_ticket(self):
obj = specification.Exchange.Unbind()
self.assertEqual(obj['ticket'], 0)
def test_exchange_unbind_default_for_destination(self):
obj = specification.Exchange.Unbind()
self.assertEqual(obj['destination'], '')
def test_exchange_unbind_default_for_source(self):
obj = specification.Exchange.Unbind()
self.assertEqual(obj['source'], '')
def test_exchange_unbind_default_for_routing_key(self):
obj = specification.Exchange.Unbind()
self.assertEqual(obj['routing_key'], '')
def test_exchange_unbind_default_for_nowait(self):
obj = specification.Exchange.Unbind()
self.assertEqual(obj['nowait'], False)
def test_exchange_unbind_default_for_arguments(self):
obj = specification.Exchange.Unbind()
self.assertDictEqual(obj['arguments'], {})
def test_queue_bind_default_for_ticket(self):
obj = specification.Queue.Bind()
self.assertEqual(obj['ticket'], 0)
def test_queue_bind_default_for_queue(self):
obj = specification.Queue.Bind()
self.assertEqual(obj['queue'], '')
def test_queue_bind_default_for_exchange(self):
obj = specification.Queue.Bind()
self.assertEqual(obj['exchange'], '')
def test_queue_bind_default_for_routing_key(self):
obj = specification.Queue.Bind()
self.assertEqual(obj['routing_key'], '')
def test_queue_bind_default_for_nowait(self):
obj = specification.Queue.Bind()
self.assertEqual(obj['nowait'], False)
def test_queue_bind_default_for_arguments(self):
obj = specification.Queue.Bind()
self.assertDictEqual(obj['arguments'], {})
def test_queue_declare_default_for_ticket(self):
obj = specification.Queue.Declare()
self.assertEqual(obj['ticket'], 0)
def test_queue_declare_default_for_queue(self):
obj = specification.Queue.Declare()
self.assertEqual(obj['queue'], '')
def test_queue_declare_default_for_passive(self):
obj = specification.Queue.Declare()
self.assertEqual(obj['passive'], False)
def test_queue_declare_default_for_durable(self):
obj = specification.Queue.Declare()
self.assertEqual(obj['durable'], False)
def test_queue_declare_default_for_exclusive(self):
obj = specification.Queue.Declare()
self.assertEqual(obj['exclusive'], False)
def test_queue_declare_default_for_auto_delete(self):
obj = specification.Queue.Declare()
self.assertEqual(obj['auto_delete'], False)
def test_queue_declare_default_for_nowait(self):
obj = specification.Queue.Declare()
self.assertEqual(obj['nowait'], False)
def test_queue_declare_default_for_arguments(self):
obj = specification.Queue.Declare()
self.assertDictEqual(obj['arguments'], {})
def test_queue_declareok_default_for_queue(self):
obj = specification.Queue.DeclareOk()
self.assertEqual(obj['queue'], '')
def test_queue_declareok_default_for_message_count(self):
obj = specification.Queue.DeclareOk()
self.assertEqual(obj['message_count'], 0)
def test_queue_declareok_default_for_consumer_count(self):
obj = specification.Queue.DeclareOk()
self.assertEqual(obj['consumer_count'], 0)
def test_queue_delete_default_for_ticket(self):
obj = specification.Queue.Delete()
self.assertEqual(obj['ticket'], 0)
def test_queue_delete_default_for_queue(self):
obj = specification.Queue.Delete()
self.assertEqual(obj['queue'], '')
def test_queue_delete_default_for_if_unused(self):
obj = specification.Queue.Delete()
self.assertEqual(obj['if_unused'], False)
def test_queue_delete_default_for_if_empty(self):
obj = specification.Queue.Delete()
self.assertEqual(obj['if_empty'], False)
def test_queue_delete_default_for_nowait(self):
obj = specification.Queue.Delete()
self.assertEqual(obj['nowait'], False)
def test_queue_deleteok_default_for_message_count(self):
obj = specification.Queue.DeleteOk()
self.assertEqual(obj['message_count'], 0)
def test_queue_purge_default_for_ticket(self):
obj = specification.Queue.Purge()
self.assertEqual(obj['ticket'], 0)
def test_queue_purge_default_for_queue(self):
obj = specification.Queue.Purge()
self.assertEqual(obj['queue'], '')
def test_queue_purge_default_for_nowait(self):
obj = specification.Queue.Purge()
self.assertEqual(obj['nowait'], False)
def test_queue_purgeok_default_for_message_count(self):
obj = specification.Queue.PurgeOk()
self.assertEqual(obj['message_count'], 0)
def test_queue_unbind_default_for_ticket(self):
obj = specification.Queue.Unbind()
self.assertEqual(obj['ticket'], 0)
def test_queue_unbind_default_for_queue(self):
obj = specification.Queue.Unbind()
self.assertEqual(obj['queue'], '')
def test_queue_unbind_default_for_exchange(self):
obj = specification.Queue.Unbind()
self.assertEqual(obj['exchange'], '')
def test_queue_unbind_default_for_routing_key(self):
obj = specification.Queue.Unbind()
self.assertEqual(obj['routing_key'], '')
def test_queue_unbind_default_for_arguments(self):
obj = specification.Queue.Unbind()
self.assertDictEqual(obj['arguments'], {})
pamqp-2.3.0/tools/ 0000775 0000000 0000000 00000000000 13456152267 0014005 5 ustar 00root root 0000000 0000000 pamqp-2.3.0/tools/codegen.py 0000775 0000000 0000000 00000063637 13456152267 0016005 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
"""Generates the pamqp/specification.py file used as a foundation for AMQP
communication.
"""
import copy
import datetime
import json
import keyword
from os import path
import textwrap
import urllib
import lxml.etree
__author__ = 'Gavin M. Roy'
__email__ = 'gavinmroy@gmail.com'
__since__ = '2011-03-31'
CODEGEN_DIR = '../codegen/'
CODEGEN_IGNORE_CLASSES = ['access']
CODEGEN_JSON = CODEGEN_DIR + 'amqp-rabbitmq-0.9.1.json'
CODEGEN_XML = CODEGEN_DIR + 'amqp0-9-1.xml'
CODEGEN_OUTPUT = '../pamqp/specification.py'
CODEGEN_JSON_URL = ('https://raw.githubusercontent.com/rabbitmq/'
'rabbitmq-codegen/master/amqp-rabbitmq-0.9.1.json')
CODEGEN_XML_URL = 'http://www.rabbitmq.com/resources/specs/amqp0-9-1.xml'
XPATH_ORDER = ['class', 'constant', 'method', 'field']
PREPEND = [CODEGEN_DIR + 'include.py']
# Output buffer list
output = []
def new_line(text='', indent_value=0, secondary_indent=0):
"""Append a new line to the output buffer"""
global output
if not text:
output.append(text)
return
initial = ''.rjust(indent_value)
secondary = ''.rjust(secondary_indent or indent_value)
wrapper = textwrap.TextWrapper(
width=79, drop_whitespace=True, initial_indent=initial,
subsequent_indent=secondary)
for value in wrapper.wrap(text.rstrip()):
output.append(value)
def classify(text):
"""Replace the AMQP constant with a more pythonic classname"""
parts = text.split('-')
value = ''
for part in parts:
value += part.title()
return value
def comment(text, indent_value=0, prefix='# '):
"""Append a comment to the output buffer"""
for value in get_comments(text, indent_value + len(prefix), prefix):
new_line(value)
def get_comments(text, indent_value=0, prefix='# '):
"""Return a list of lines for a given comment with the comment prefix"""
indent_text = prefix.rjust(indent_value)
values = []
for value in textwrap.wrap(text, 79 - len(indent_text)):
values.append(indent_text + value)
return values
def dashify(text):
"""Replace a - with a _ for the passed in text"""
return text.replace('-', '_')
def pep8_class_name(value):
"""Returns a class name in the proper case per PEP8"""
return_value = []
parts = value.split('-')
for part in parts:
return_value.append(part[0:1].upper() + part[1:])
return ''.join(return_value)
def get_class_definition(cls_name, cls_list):
"""Iterates through class_list trying to match the name against what was
passed in.
"""
for cls_def in cls_list:
if cls_def['name'] == cls_name:
return cls_def
def get_documentation(search_path):
"""Find the documentation in the xpath
:param search_path:
:return:
"""
search = []
for k in XPATH_ORDER:
if k in search_path:
search.append('%s[@name="%s"]' % (k, search_path[k]))
node = xml.xpath('%s/doc' % '/'.join(search))
# Did we not find it? Look for a RabbitMQ extension
if not node:
node = rabbitmq.xpath('%s/doc' % '/'.join(search))
# Look for RabbitMQ extensions of methods
if not node and 'field' in search_path:
node = rabbitmq.xpath('field[@name="%s"]/doc' % search_path['method'])
# Look for RabbitMQ extensions of fields
if not node and 'field' in search_path:
node = rabbitmq.xpath('field[@name="%s"]/doc' % search_path['field'])
# if we found it, strip all the whitespace
if node:
return ' '.join([l.strip() for l in node[0].text.split('\n')]).strip()
def get_label(search_path):
"""Look to see if documented & if so, provide the doc as a comment
:param search_path:
:return:
"""
search = []
for k in XPATH_ORDER:
if k in search_path:
search.append('%s[@name="%s"]' % (k, search_path[k]))
node = xml.xpath('%s' % '/'.join(search))
if not node:
node = rabbitmq.xpath('%s' % '/'.join(search))
# Did it have a value by default?
if node and 'label' in node[0].attrib:
return (node[0].attrib['label'][0:1].upper() +
node[0].attrib['label'][1:])
elif node and node[0].text:
return (node[0].text.strip()[0:1].upper() +
node[0].text.strip()[1:].strip())
# Look in domains
if 'field' in search_path:
node = xml.xpath('//amqp/domain[@name="%s"]' % search_path['field'])
if node and 'label' in node[0].attrib:
return (node[0].attrib['label'][0:1].upper() +
node[0].attrib['label'][1:])
# Look for RabbitMQ extensions of fields
if 'field' in search_path:
node = rabbitmq.xpath('field[@name="%s"]' % search_path['field'])
if node and 'label' in node[0].attrib:
return (node[0].attrib['label'][0:1].upper() +
node[0].attrib['label'][1:])
elif node and node[0].text:
return (node[0].text.strip()[0:1].upper() +
node[0].text.strip()[1:].strip())
print('Label could not find %r' % search_path)
def argument_name(n):
"""Returns a valid python argument name for the AMQP argument passed in
:param str n: The argument name
"""
value = n.replace('-', '_')
if value in keyword.kwlist:
value += '_'
return value
def get_argument_type_doc(arg):
"""Get the type of the argument for the doc
:param arg:
:return: str
"""
if 'domain' in arg:
for d, dt in amqp['domains']:
if arg['domain'] == d:
arg['type'] = dt
break
if 'type' in arg:
if arg['type'] == 'bit':
return 'bool'
elif arg['type'] == 'long':
return 'int/long'
elif arg['type'] == 'longlong':
return 'int/long'
elif arg['type'] == 'longstr':
return 'str'
elif arg['type'] == 'octet':
return 'int'
elif arg['type'] == 'short':
return 'int'
elif arg['type'] == 'shortstr':
return 'str'
elif arg['type'] == 'table':
return 'dict'
elif arg['type'] == 'timestamp':
return 'struct_time'
return 'Unknown'
def get_argument_type(arg):
"""Get the argument type.
:param arg:
:return: str
"""
if 'domain' in arg:
for d, dt in amqp['domains']:
if arg['domain'] == d:
arg['type'] = dt
break
if 'type' in arg:
return arg['type']
return 'Unknown'
def new_function(function_name, args_in, indent_value=0):
"""Create a new function
:param function_name:
:param args_in:
:param indent_value:
:return:
"""
global output
args = ['self']
for a in args_in:
n = argument_name(a['name'])
if 'default-value' in a and a['default-value'] != '':
if a['default-value'] in keyword.kwlist or \
isinstance(a['default-value'], (bool, int)):
value = a['default-value']
else:
if isinstance(a['default-value'], basestring):
value = "'%s'" % str(a['default-value'])
else:
value = '%r' % a['default-value']
else:
if a['type'][-3:] == 'str':
value = "''"
elif a['type'] in ['short', 'long']:
value = 0
else:
value = 'None'
if value == '{}':
if a['type'][-3:] == 'str':
value = "''"
elif a['type'] in ['short', 'long']:
value = 0
else:
value = 'None'
args.append('%s=%s' % (n, value))
# Get the definition line built
def_line = 'def %s(%s):' % (function_name, ', '.join(args))
# Build the output of it with wrapping
indent_str = ''.join(
[' ' for _x in range(indent_value + len(function_name) + 5)])
lines = textwrap.wrap(
''.join([' ' for _x in range(indent_value)]) + def_line, 79,
subsequent_indent=indent_str)
for l in lines:
new_line(l)
# Check to see if we have the codegen json file in this directory
if not path.exists(CODEGEN_JSON):
# Retrieve the codegen archive
print('Downloading codegen JSON file to %s.' % CODEGEN_JSON)
json_data = urllib.urlopen(CODEGEN_JSON_URL)
# Write out the JSON file
with open(CODEGEN_JSON, 'w') as handle:
handle.write(json_data.read())
json_data.close()
# Read in the codegen JSON file
with open(CODEGEN_JSON, 'r') as handle:
amqp = json.load(handle)
# Check to see if we have the codegen xml file in this directory
if not path.exists(CODEGEN_XML):
# Retrieve the codegen XML definition
print('Downloading codegen XML file.')
handle = urllib.urlopen(CODEGEN_XML_URL)
xml_content = handle.read()
# Write out the XML file
with open(CODEGEN_XML, 'w') as handle:
handle.write(xml_content)
# Read in the codegen XML file
with open(CODEGEN_XML, 'r') as handle:
amqp_xml = lxml.etree.parse(handle)
xml = amqp_xml.xpath('//amqp')[0]
# Read in the codegen RabbitMQ Extension XML file
with open(CODEGEN_DIR + 'extensions.xml', 'r') as handle:
rabbitmq_xml = lxml.etree.parse(handle)
rabbitmq = rabbitmq_xml.xpath('//rabbitmq')[0]
# Start the output
output = ['''"""%s
Auto-generated AMQP Support Module
WARNING: DO NOT EDIT. To Generate run tools/codegen.py
"""
__since__ = '%s'
import struct
import warnings
from pamqp import decode, encode
''' % (CODEGEN_OUTPUT.split('/')[-1], datetime.date.today().isoformat())]
new_line()
# AMQP Version Header
comment('AMQP Protocol Version')
new_line('VERSION = (%i, %i, %i)' % (
amqp['major-version'], amqp['minor-version'], amqp['revision']))
new_line()
# Defaults
comment('RabbitMQ Defaults')
new_line("DEFAULT_HOST = 'localhost'")
new_line('DEFAULT_PORT = %i' % amqp['port'])
new_line("DEFAULT_USER = 'guest'")
new_line("DEFAULT_PASS = 'guest'")
new_line("DEFAULT_VHOST = '/'")
new_line()
# Constant
comment('AMQP Constants')
for constant in amqp['constants']:
if 'class' not in constant:
# Look to see if documented & if so, provide the doc as a comment
doc = get_documentation({'constant': constant['name'].lower()})
if doc:
comment(doc)
new_line('%s = %i' % (dashify(constant['name']), constant['value']))
new_line()
comment('Not included in the spec XML or JSON files.')
new_line('FRAME_MAX_SIZE = 131072')
new_line()
# Data types
data_types = []
domains = []
for domain, data_type in amqp['domains']:
if domain == data_type:
data_types.append(" '%s'," % domain)
else:
doc = get_documentation({'domain': domain})
if doc:
comments = get_comments(doc, 18)
for line in comments:
domains.append(line)
domains.append(" '%s': '%s'," % (domain, data_type))
comment('AMQP data types')
data_types[0] = data_types[0].replace(' ',
'DATA_TYPES = [')
data_types[-1] = data_types[-1].replace(',', ']')
output += data_types
new_line()
comment('AMQP domains')
domains[0] = domains[0].replace(' ',
'DOMAINS = {')
domains[-1] = domains[-1].replace(',', '}')
output += domains
new_line()
comment('Other constants')
# Deprecation Warning
AMQP_VERSION = ('-'.join([str(amqp['major-version']),
str(amqp['minor-version']),
str(amqp['revision'])]))
DEPRECATION_WARNING = 'This command is deprecated in AMQP %s' % AMQP_VERSION
new_line("DEPRECATION_WARNING = '%s'" % DEPRECATION_WARNING)
new_line()
# Prepend the content from the files specified
for filename in PREPEND:
with open(filename, 'r') as handle:
content = handle.read()
for line in content.split('\n'):
new_line(line)
# Warnings and Exceptions
new_line()
comment('AMQP Errors')
errors = {}
for constant in amqp['constants']:
if 'class' in constant:
class_name = classify(constant['name'])
if constant['class'] == 'soft-error':
extends = 'Warning'
elif constant['class'] == 'hard-error':
extends = 'Exception'
else:
raise ValueError('Unexpected class: %s', constant['class'])
new_line('class AMQP%s(%s):' % (class_name, extends))
new_line(' """')
# Look to see if documented & if so, provide the doc as a comment
doc = get_documentation({'constant': constant['name'].lower()})
if doc:
comment(doc, 4, '')
else:
if extends == 'Warning':
new_line(' Undocumented AMQP Soft Error')
else:
new_line(' Undocumented AMQP Hard Error')
new_line()
new_line(' """')
new_line(" name = '%s'" % constant['name'])
new_line(' value = %i' % constant['value'])
new_line()
new_line()
errors[constant['value']] = class_name
# Error mapping to class
error_lines = []
for error_code in errors.keys():
error_lines.append(
' %i: AMQP%s,' % (error_code, errors[error_code]))
comment('AMQP Error code to class mapping')
error_lines[0] = error_lines[0].replace(' ', 'ERRORS = {')
error_lines[-1] = error_lines[-1].replace(',', '}')
output += error_lines
# Get the pamqp class list so we can sort it
class_list = []
for amqp_class in amqp['classes']:
if amqp_class['name'] not in CODEGEN_IGNORE_CLASSES:
class_list.append(amqp_class['name'])
# Sort them alphabetically
# class_list.sort()
new_line()
comment('AMQP Classes and Methods')
new_line()
for class_name in class_list:
indent = 4
# Get the class from our JSON file
definition = get_class_definition(class_name, amqp['classes'])
new_line()
new_line('class %s(object):' % pep8_class_name(class_name))
doc = get_documentation({'class': class_name})
label = get_label({'class': class_name}) or 'Undefined label'
if doc:
new_line('"""' + label, indent)
new_line()
comment(doc, indent, '')
new_line()
new_line('"""', indent)
new_line('__slots__ = []', indent)
new_line()
comment('AMQP Class Number and Mapping Index', indent)
new_line('frame_id = %i' % definition['id'], indent)
new_line('index = 0x%08X' % (definition['id'] << 16), indent)
new_line()
# We use this later down in methods to get method xml to look for stuff
# that is not in the JSON spec file beyond docs
class_xml = xml.xpath('//amqp/class[@name="%s"]' % class_name)
# Build the list of methods
methods = []
for method in definition['methods']:
new_line('class %s(Frame):' %
pep8_class_name(method['name']), indent)
indent += 4
# No Confirm in AMQP spec
if class_xml:
doc = get_documentation({'class': class_name,
'method': method['name']})
label = get_label({'class': class_name,
'method': method['name']}) or 'Undefined label'
if doc:
new_line('"""%s' % label, indent)
new_line()
comment(doc, indent, '')
new_line()
new_line('"""', indent)
# Get the method's XML node
method_xml = None
if class_xml:
method_xml = class_xml[0].xpath('method[@name="%s"]' %
method['name'])
comment('AMQP Method Number and Mapping Index', indent)
new_line('frame_id = %i' % method['id'], indent)
index_value = definition['id'] << 16 | method['id']
new_line('index = 0x%08X' % index_value, indent)
new_line("name = '%s.%s'" % (pep8_class_name(class_name),
pep8_class_name(method['name'])),
indent)
# Add an attribute that signifies if it's a sync command
new_line()
comment('Specifies if this is a synchronous AMQP method', indent)
new_line('synchronous = %s' % method.get('synchronous', False),
indent)
# Add an attribute that signifies if it's a sync command
if method.get('synchronous'):
responses = []
if method_xml:
for response in method_xml[0].iter('response'):
response_name = "'%s.%s'" %\
(pep8_class_name(class_name),
pep8_class_name(response.attrib['name']))
responses.append(response_name)
if not responses:
responses.append("'%s.%sOk'" %
(pep8_class_name(class_name),
pep8_class_name(method['name'])))
new_line()
comment('Valid responses to this method', indent)
new_line('valid_responses = [%s]' % ', '.join(responses),
indent)
new_line()
arguments = []
type_keyword = False
for argument in method['arguments']:
name = argument_name(argument['name'])
if name == 'type' and class_name == 'exchange':
name = 'exchange_type'
type_keyword = True
arguments.append("'%s'," % name)
if arguments:
comment('AMQP Method Attributes', indent)
arguments[-1] = arguments[-1].replace(',', ']')
new_line('__slots__ = [' + arguments.pop(0), indent)
for line in arguments:
new_line(line, indent + 13)
new_line()
if method['arguments']:
comment('Class Attribute Types', indent)
for argument in method['arguments']:
name = argument_name(argument['name'])
if name == 'type' and class_name == 'exchange':
name = 'exchange_type'
new_line("_%s = '%s'" % (name, get_argument_type(argument)),
indent)
new_line()
# Function definition
arguments = copy.deepcopy(method['arguments'])
for offset in range(0, len(arguments)):
if arguments[offset]['name'] == 'type' and \
class_name == 'exchange':
arguments[offset]['name'] = 'exchange_type'
if arguments:
new_function('__init__', arguments, indent)
indent += 4
new_line('"""Initialize the %s.%s class' %
(pep8_class_name(class_name),
pep8_class_name(method['name'])),
indent)
if type_keyword:
new_line()
new_line('Note that the AMQP type argument is referred to as '
'"%s_type" ' % class_name, indent)
new_line('to not conflict with the Python type keyword.',
indent)
# List the arguments in the docblock
new_line()
for argument in method['arguments']:
name = argument_name(argument['name'])
if name == 'type' and class_name == 'exchange':
name = 'exchange_type'
label = get_label({'class': class_name,
'method': method['name'],
'field': argument['name']})
if label:
new_line(':param %s %s: %s' %
(get_argument_type_doc(argument), name, label),
indent, indent + 4)
else:
new_line(
':param %s %s:' % (
get_argument_type_doc(argument),
argument['name']),
indent, indent + 4)
# Note the deprecation warning in the docblock
if method_xml and 'deprecated' in method_xml[0].attrib and \
method_xml[0].attrib['deprecated']:
deprecated = True
new_line()
new_line(
'.. deprecated:: %s' % AMQP_VERSION, indent)
new_line(DEPRECATION_WARNING, indent + 4)
else:
deprecated = False
new_line()
new_line('"""', indent)
# Create assignments from the arguments to attributes of the object
for argument in method['arguments']:
name = argument_name(argument['name'])
if name == 'type' and class_name == 'exchange':
name = 'exchange_type'
doc = get_label({'class': class_name,
'method': method['name'],
'field': argument['name']})
if doc:
comment(doc, indent)
if (isinstance(argument.get('default-value'), dict) and
not argument.get('default-value')):
new_line('self.%s = %s or {}' % (name, name), indent)
else:
new_line('self.%s = %s' % (name, name), indent)
new_line()
# Check if we're deprecated and warn if so
if deprecated:
comment(DEPRECATION_WARNING, indent)
new_line('warnings.warn(DEPRECATION_WARNING, '
'category=DeprecationWarning)', indent)
new_line()
# End of function
indent -= 4
# End of class
indent -= 4
if 'properties' in definition and definition['properties']:
new_line('class Properties(PropertiesBase):', indent)
indent += 4
comment('"""Content Properties"""', indent, '')
new_line()
new_line("name = '%s.Properties'" % pep8_class_name(class_name),
indent)
new_line()
new_line("__slots__ = ['%s'," %
argument_name(definition['properties'][0]['name']),
indent)
for argument in definition['properties'][1:-1]:
name = argument_name(argument['name'])
if name == 'type':
name = 'message_type'
new_line("'%s'," % name, indent + 13)
new_line("'%s']" % argument_name(definition['properties'][-1]['name']),
indent + 13)
new_line()
comment('Flag Values', indent)
flag_value = 15
new_line("flags = {'%s': %i," %
(argument_name(definition['properties'][0]['name']),
1 << flag_value), indent)
for argument in definition['properties'][1:-1]:
name = argument_name(argument['name'])
if name == 'type':
name = 'message_type'
flag_value -= 1
new_line("'%s': %i," % (name, 1 << flag_value), indent + 9),
flag_value -= 1
new_line("'%s': %i}" %
(argument_name(definition['properties'][-1]['name']),
1 << flag_value), indent + 9)
new_line()
comment('Class Attribute Types', indent)
for argument in definition['properties']:
name = argument_name(argument['name'])
if name == 'type':
name = 'message_type'
new_line("_%s = '%s'" % (name, get_argument_type(argument)),
indent)
new_line()
new_line('frame_id = %i' % definition['id'], indent)
new_line('index = 0x%04X' % definition['id'], indent)
new_line()
# Function definition
properties = copy.deepcopy(definition['properties'])
for offset in range(0, len(properties)):
if properties[offset]['name'] == 'type':
properties[offset]['name'] = 'message_type'
new_function('__init__', properties, indent)
indent += 4
new_line('"""Initialize the %s.Properties class' %
pep8_class_name(class_name),
indent)
new_line()
new_line('Note that the AMQP property type is named message_type as '
'to ', indent)
new_line('not conflict with the Python type keyword', indent)
# List the arguments in the docblock
new_line()
for argument in definition['properties']:
name = argument_name(argument['name'])
if name == 'type':
name = 'message_type'
label = get_label({'class': class_name,
'field': argument['name']})
if label:
line = ':param %s %s: %s' % (get_argument_type_doc(argument),
name, label or None)
new_line(line.strip(), indent)
new_line()
new_line('"""', indent)
# Create assignments from the arguments to attributes of the object
for argument in definition['properties']:
name = argument_name(argument['name'])
if name == 'type':
name = 'message_type'
doc = get_label({'class': class_name,
'field': argument['name']})
if doc:
comment(doc, indent)
new_line('self.%s = %s' % (name, name), indent)
new_line()
# End of function
indent -= 4
new_line()
comment('AMQP Class.Method Index Mapping')
mapping = []
for amqp_class in amqp['classes']:
if amqp_class['name'] not in CODEGEN_IGNORE_CLASSES:
for method in amqp_class['methods']:
key = amqp_class['id'] << 16 | method['id']
mapping.append((' 0x%08X: %s.%s,' %
(key,
pep8_class_name(amqp_class['name']),
pep8_class_name(method['name']))))
mapping[0] = mapping[0].replace(' ',
'INDEX_MAPPING = {')
mapping[-1] = mapping[-1].replace(',', '}')
output += mapping
new_line()
# Spit out the file
output_string = '\n'.join(output)
with open(CODEGEN_OUTPUT, 'w') as handle:
handle.write(output_string)