Bug 1159831 - Make treeherder use in-tree copy of treeherder-client

This commit is contained in:
William Lachance 2015-04-30 18:03:12 -04:00
Родитель 01d54ee72a
Коммит 0e6e61fbbe
27 изменённых файлов: 168 добавлений и 541 удалений

Просмотреть файл

@ -10,9 +10,7 @@ treeherder-service
Treeherder is comprised of this repo for providing those back end services, and several other component repos:
* [treeherder-ui](https://github.com/mozilla/treeherder-ui) for the front end UI.
* [treeherder-client](https://github.com/mozilla/treeherder-client) for data submission.
* [treeherder-node](https://github.com/mozilla/treeherder-node) NodeJS interface.
* [treeherder-node](https://github.com/mozilla/treeherder-node) NodeJS interface for submitting data to Treeherder (a python interface is maintained inside this repository, see the documentation for more information)
#### Instances
Treeherder exists on three instances, [dev](http://treeherder-dev.allizom.org) for treeherder development, [stage](https://treeherder.allizom.org) for pre-deployment validation, and [production](https://treeherder.mozilla.org) for actual use.

Просмотреть файл

@ -17,6 +17,7 @@ Contents:
ui_integration
list_of_services
common_tasks
submitting_data
troubleshooting

Просмотреть файл

@ -1,15 +1,37 @@
#treeherder-client
Submitting Data
===============
A set of client libraries to support data submission to https://github.com/mozilla/treeherder-service. There are two types of data
structures supported: job and resultset collections. Both classes have support methods for building a data structure that https://github.com/mozilla/treeherder-service accepts. Data structures can be extended with new properties as needed, there is a minimal validation protocol applied that confirms the bare minimum parts of the structures are defined.
Treeherder Python Client Library
--------------------------------
##Resultset Collection
We provide a library, called treeherder-client, to support data
submission to the treeherder service. It is maintained inside the
treeherder repository, but you can install your own copy from pypi
using pip:
.. code-block:: bash
Resultset collections contain meta data associated with a github pull request or a push to mercurial or any event that requires tests to be run on a repository.
The most critical part of each resultset is the `revision_hash`. This is used as an identifier to associate test job data with. It can be any unique string of 50 characters at most. A resultset collection has the following data structure
pip install treeherder-client
There are two types of data structures you can submit with this
library: job and resultset collections. The library provides methods
for building a data structure that treeherder will accept. Data
structures can be extended with new properties as needed, there is a
minimal validation protocol applied that confirms the bare minimum
parts of the structures are defined.
Resultset Collections
---------------------
Resultset collections contain meta data associated with a github pull request
or a push to mercurial or any event that requires tests to be run on a
repository. The most critical part of each resultset is the `revision_hash`.
This is used as an identifier to associate test job data with. It can be any
unique string of 50 characters at most. A resultset collection has the
following data structure:
.. code-block:: python
```python
[
{
# unique identifier for a result set, can be any unique character string no longer than 50 characters
@ -45,36 +67,17 @@ The most critical part of each resultset is the `revision_hash`. This is used a
}
}
]
```
##Job Collection
Job Collections
---------------
Job collections can contain test results from any kind of test. The
`revision_hash` provided should match the associated `revision_hash`
in the resultset structure. The `job_guid` provided can be any unique
string of 50 characters at most.
Job collections can contain test results from any kind of test. The
`revision_hash` provided should match the associated `revision_hash` in the
resultset structure. The `job_guid` provided can be any unique string of 50
characters at most. A job collection has the following data structure.
.. code-block:: python
###Parsing your own logs
It is now possible to post jobs with log references that you have already
parsed. You are then responsible for submitting an artifact named
``text_log_summary``. This artifact is what would normally be the result of
Treeherder's internal log parsing.
To do this, add ``parse_status: 'parsed'`` to the applicable ``log_reference``
object (shown below). When you then post your artifact named ``text_log_summary``,
Treeherder will automatically generate the applicable ``Bug suggestions``
artifact for it.
If the ``parse_status`` of a ``log_reference`` is not specified, it defaults to
``pending`` and will, therefore, be parsed by Treeherder. Treeherder will then
generate the ``text_log_summary`` and ``Bug suggestions`` artifacts.
A job collection has the following data structure.
```python
[
{
'project': 'mozilla-inbound',
@ -126,7 +129,6 @@ A job collection has the following data structure.
{
'url': 'http://ftp.mozilla.org/pub/mozilla.org/spidermonkey/...',
'name': 'builds-4h'
'parse_status': 'parsed'
}
],
@ -142,13 +144,16 @@ A job collection has the following data structure.
},
...
]
```
##Artifact Collection
Artifact Collections
--------------------
Artifact collections contain arbitrary data associated with a job. This is usually a json blob of structured data produced by the build system during the job execution.
Artifact collections contain arbitrary data associated with a job. This is
usually a json blob of structured data produced by the build system during the
job execution.
.. code-block:: python
```python
[
{
'type': 'json',
@ -158,13 +163,15 @@ Artifact collections contain arbitrary data associated with a job. This is usual
'job_guid': 'd22c74d4aa6d2a1dcba96d95dccbd5fdca70cf33'
}
]
```
###Usage
Usage
-----
If you want to use `TreeherderResultSetCollection` to build up the resultset data structures to send, do something like this.
If you want to use `TreeherderResultSetCollection` to build up the resultset
data structures to send, do something like this.
.. code-block:: python
```python
from thclient import TreeherderRequest, TreeherderResultSetCollection, TreeherderClientError
trsc = TreeherderResultSetCollection()
@ -209,17 +216,19 @@ If you want to use `TreeherderResultSetCollection` to build up the resultset dat
# data structure validation is automatically performed here, if validation
# fails a TreeherderClientError is raised
req.post(trc)
```
At any time in building a data structure, you can examine what has been created by looking at the `data` property.
You can also call the `validate` method at any time before sending a collection.
All treeherder data classes have `validate` methods that can be used for testing.
The `validate` method is called on every structure in a collection when a `send` is called on a `TreeherderRequest`.
If validation fails a `TreeherderClientError` is raised.
At any time in building a data structure, you can examine what has been
created by looking at the `data` property. You can also call the `validate`
method at any time before sending a collection. All treeherder data classes
have `validate` methods that can be used for testing. The `validate` method
is called on every structure in a collection when a `send` is called on a
`TreeherderRequest`. If validation fails a `TreeherderClientError` is raised.
If you want to use `TreeherderJobCollection` to build up the job data structures to send, do something like this.
If you want to use `TreeherderJobCollection` to build up the job data
structures to send, do something like this:
.. code-block:: python
```python
from thclient import TreeherderRequest, TreeherderJobCollection, TreeherderClientError
#####
@ -266,8 +275,7 @@ If you want to use `TreeherderJobCollection` to build up the job data structures
tj.add_option_collection( data['option_collection'] )
# parse_status can be one of 'pending', 'parsed' or 'failed'. Default: 'pending'
tj.add_log_reference( 'builds-4h', data['log_reference'], 'pending' )
tj.add_log_reference( 'builds-4h', data['log_reference'] )
# data['artifact'] is a list of artifacts
for artifact_data in data['artifact']:
@ -290,11 +298,12 @@ If you want to use `TreeherderJobCollection` to build up the job data structures
# data structure validation is automatically performed here, if validation
# fails a TreeherderClientError is raised
req.post(tjc)
```
If you want to use `TreeherderArtifactCollection` to build up the job artifacts data structures to send, do something like this.
If you want to use `TreeherderArtifactCollection` to build up the job
artifacts data structures to send, do something like this:
.. code-block:: python
```python
from thclient import TreeherderRequest, TreeherderArtifactCollection, TreeherderClientError
tac = TreeherderArtifactCollection()
@ -324,12 +333,13 @@ If you want to use `TreeherderArtifactCollection` to build up the job artifacts
# data structure validation is automatically performed here, if validation
# fails a TreeherderClientError is raised
req.post(tac)
```
If you don't want to use `TreeherderResultCollection` or `TreeherderJobCollection` to build up the data structure
to send, build the data structures directly and add them to the collection.
If you don't want to use `TreeherderResultCollection` or
`TreeherderJobCollection` to build up the data structure to send, build the
data structures directly and add them to the collection.
.. code-block:: python
```python
from thclient import TreeherderRequest, TreeherderResultSetCollection
trc = TreeherderResultSetCollection()
@ -378,11 +388,13 @@ to send, build the data structures directly and add them to the collection.
# data structure validation is automatically performed here, if validation
# fails a TreeherderClientError is raised
req.post(tjc)
```
In the same way, if you don't want to use `TreeherderArtifactCollection` to build up the data structure to send, build the data structures directly and add them to the collection.
In the same way, if you don't want to use `TreeherderArtifactCollection` to
build up the data structure to send, build the data structures directly and
add them to the collection.
.. code-block:: python
```python
from thclient import TreeherderRequest, TreeherderArtifactCollection
tac = TreeherderArtifactCollection()
@ -405,64 +417,60 @@ In the same way, if you don't want to use `TreeherderArtifactCollection` to buil
# Post the request to treeherder
req.post(tac)
```
##Job artifacts format
Job artifacts format
--------------------
Artifacts can have name, type and blob. The blob property can contain any valid data structure accordingly to type attribute.
For example if you use the json type, your blob must be json-serializable to be valid.
The name attribute can be any arbitrary string identifying the artifact.
Here is an example of what a job artifact looks like in the context of a job object:
Artifacts can have name, type and blob. The blob property can contain any
valid data structure accordingly to type attribute. For example if you use
the json type, your blob must be json-serializable to be valid. The name
attribute can be any arbitrary string identifying the artifact. Here is an
example of what a job artifact looks like in the context of a job object:
```python
[
{
'project': 'mozilla-inbound',
.. code-block:: python
'revision_hash': '4317d9e5759d58852485a7a808095a44bc806e19',
[
{
'project': 'mozilla-inbound',
'revision_hash': '4317d9e5759d58852485a7a808095a44bc806e19',
'job': {
'job_guid': 'd22c74d4aa6d2a1dcba96d95dccbd5fdca70cf33',
# ...
# other job properties here
# ...
'job': {
'job_guid': 'd22c74d4aa6d2a1dcba96d95dccbd5fdca70cf33',
# ...
# other job properties here
# ...
'artifacts': [
{
"type": "json",
"name": "my first artifact",
'blob': {
k1:v1,
k2: v2,
...
}
},
{
'type': 'json',
'name': 'my second artifact',
'blob': {
k1:v1,
k2: v2,
...
'artifacts': [
{
"type": "json",
"name": "my first artifact",
'blob': {
k1: v1,
k2: v2,
...
}
},
{
'type': 'json',
'name': 'my second artifact',
'blob': {
k1: v1,
k2: v2,
...
}
}
]
}
]
}
},
...
]
},
...
]
```
A special case of job artifact is a "Job Info" artifact. This kind of artifact
will be retrieved by the UI and rendered in the job detail panel. This
is what a Job Info artifact looks like:
A special case of job artifact is a "Job Info" artifact. This kind of artifact will be retrieved by the UI
(see https://github.com/mozilla/treeherder-ui) and rendered in the job detail panel.
This is what a Job Info artifact looks like:
.. code-block:: python
```python
{
{
"blob": {
"job_details": [
@ -486,35 +494,29 @@ This is what a Job Info artifact looks like:
},
"type": "json",
"name": "Job Info"
}
```
}
All the elements in the job_details attribute of this artifact have a mandatory title attribute and a set of optional attributes depending on ``content_type``.
The ``content_type`` drives the way this kind of artifact will be rendered. Here are the possible values:
All the elements in the job_details attribute of this artifact have a
mandatory title attribute and a set of optional attributes depending on
`content_type`. The `content_type` drives the way this kind of artifact
will be rendered. Here are the possible values:
* **Text** - This is the simplest content type you can render and is the one used by default if the content type
specified is not recognised or is missing.
* **Text** - This is the simplest content type you can render and is the one
used by default if the content type specified is not recognised or is missing.
This content type renders as:
```html
<label>{{title}}</label><span>{{value}}</span>
```
.. code-block:: html
* **Link** - This content type renders as an anchor html tag with the following format:
<label>{{title}}</label><span>{{value}}</span>
```html
{{title}}: <a title="{{value}}" href="{{url}}" target="_blank">{{value}}</a>
```
* **Link** - This content type renders as an anchor html tag with the
following format:
* **Raw Html** - The last resource for when you need to show some formatted content.
.. code-block:: html
{{title}}: <a title="{{value}}" href="{{url}}" target="_blank">{{value}}</a>
* **Raw Html** - The last resource for when you need to show some formatted
content.
##Development
To run the `treeherder-client` test suite, run `python setup.py test`.
If you have `python2.5`, `python2.6`, or `python2.7` available on your system
under those names, you can also `pip install tox` and then run `tox` to test
`treeherder-client` under all of those Python versions.

Просмотреть файл

@ -71,9 +71,6 @@ mozlog==2.10
# sha256: EdbpC9WxbfhNw4c3kDfij8HZ-pkkUnv5Oe07q0cSH4w
https://github.com/jeads/datasource/archive/v0.6.tar.gz#egg=datasource
# sha256: skLqFXw4utP2xroQl6SdFJbvm66fd6-J-xMJTiveHGU
treeherder-client==1.2
# Required by django-rest-swagger
# sha256: 7wE5rDCRO0Po04ij53blNKIvgZdZZpaNKDaewDOKabc
Unipath==1.0

Просмотреть файл

@ -10,11 +10,12 @@ import json
from mock import patch
from thclient import (TreeherderJob, TreeherderJobCollection,
TreeherderRevision, TreeherderResultSet,
TreeherderResultSetCollection, TreeherderClientError,
TreeherderRequest, TreeherderArtifact,
TreeherderArtifactCollection)
from treeherder.client import (TreeherderJob, TreeherderJobCollection,
TreeherderRevision, TreeherderResultSet,
TreeherderResultSetCollection,
TreeherderClientError, TreeherderRequest,
TreeherderArtifact,
TreeherderArtifactCollection)
class DataSetup(unittest.TestCase):
@ -452,9 +453,9 @@ class TreeherderRequestTest(DataSetup, unittest.TestCase):
mock_send.call_args_list[0][1]["data"]
)
@patch("thclient.client.oauth.generate_nonce")
@patch("thclient.client.oauth.time.time")
@patch("thclient.client.requests.post")
@patch("treeherder.client.client.oauth.generate_nonce")
@patch("treeherder.client.client.oauth.time.time")
@patch("treeherder.client.client.requests.post")
def test_send(self, mock_post, mock_time, mock_generate_nonce):
"""Can send data to the server."""
@ -494,9 +495,9 @@ class TreeherderRequestTest(DataSetup, unittest.TestCase):
'application/json',
)
@patch("thclient.client.oauth.generate_nonce")
@patch("thclient.client.oauth.time.time")
@patch("thclient.client.requests.post")
@patch("treeherder.client.client.oauth.generate_nonce")
@patch("treeherder.client.client.oauth.time.time")
@patch("treeherder.client.client.requests.post")
def test_send_without_oauth(self, mock_post, mock_time,
mock_generate_nonce):

Просмотреть файл

@ -397,7 +397,7 @@ def mock_send_request(monkeypatch, set_oauth_credentials):
response.getcode = lambda: response.status_int
return response
from thclient.client import TreeherderRequest
from treeherder.client import TreeherderRequest
monkeypatch.setattr(TreeherderRequest, 'send', _send)

Просмотреть файл

@ -7,7 +7,7 @@ import os
import pytest
import simplejson as json
from django.template import Context, Template
from thclient import (TreeherderJobCollection)
from treeherder.client import (TreeherderJobCollection)
from tests import test_utils

Просмотреть файл

@ -2,7 +2,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
import thclient
from treeherder import client
from treeherder.etl.oauth_utils import OAuthCredentials
from treeherder.model.derived import JobsModel
@ -17,8 +17,8 @@ def test_post_job_with_parsed_log(test_project, result_set_stored,
credentials = OAuthCredentials.get_credentials(test_project)
tjc = thclient.TreeherderJobCollection()
tj = thclient.TreeherderJob({
tjc = client.TreeherderJobCollection()
tj = client.TreeherderJob({
'project': test_project,
'revision_hash': result_set_stored[0]['revision_hash'],
'job': {
@ -34,7 +34,7 @@ def test_post_job_with_parsed_log(test_project, result_set_stored,
tjc.add(tj)
req = thclient.TreeherderRequest(
req = client.TreeherderRequest(
protocol='http',
host='localhost',
project=test_project,

Просмотреть файл

@ -9,7 +9,7 @@ from treeherder.etl.mixins import OAuthLoaderMixin
from treeherder.etl.oauth_utils import OAuthCredentials
from treeherder.webapp.wsgi import application
from thclient import TreeherderRequest
from treeherder.client import TreeherderRequest
from tests.sampledata import SampleData

Просмотреть файл

@ -10,7 +10,7 @@ from treeherder.model.derived.refdata import RefDataManager
from treeherder.etl.oauth_utils import OAuthCredentials
from treeherder.webapp.wsgi import application
from thclient import TreeherderRequest
from treeherder.client import TreeherderRequest
from tests.sampledata import SampleData

Просмотреть файл

@ -7,7 +7,7 @@ import pytest
from django.core.urlresolvers import reverse
import thclient
from treeherder import client
from treeherder.etl.oauth_utils import OAuthCredentials
from treeherder.model.derived import ArtifactsModel
@ -97,8 +97,8 @@ def test_artifact_create_text_log_summary(webapp, eleven_jobs_processed,
job = jm.get_job_list(0, 1)[0]
tls = sample_data.text_log_summary
tac = thclient.TreeherderArtifactCollection()
ta = thclient.TreeherderArtifact({
tac = client.TreeherderArtifactCollection()
ta = client.TreeherderArtifact({
'type': 'json',
'name': 'text_log_summary',
'blob': json.dumps(tls['blob']),
@ -106,7 +106,7 @@ def test_artifact_create_text_log_summary(webapp, eleven_jobs_processed,
})
tac.add(ta)
req = thclient.TreeherderRequest(
req = client.TreeherderRequest(
protocol='http',
host='localhost',
project=jm.project,

Просмотреть файл

@ -4,7 +4,7 @@
from django.core.urlresolvers import reverse
from thclient import TreeherderJobCollection
from treeherder.client import TreeherderJobCollection
from tests import test_utils

Просмотреть файл

@ -6,7 +6,7 @@ from django.core.urlresolvers import reverse
from rest_framework.test import APIClient
from django.contrib.auth.models import User
from thclient import TreeherderResultSetCollection
from treeherder.client import TreeherderResultSetCollection
from tests import test_utils
from treeherder.webapp.api import utils

Просмотреть файл

@ -1,354 +0,0 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. “Contributor”
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. “Contributor Version”
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributors Contribution.
1.3. “Contribution”
means Covered Software of a particular Contributor.
1.4. “Covered Software”
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. “Incompatible With Secondary Licenses”
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of version
1.1 or earlier of the License, but not also under the terms of a
Secondary License.
1.6. “Executable Form”
means any form of the work other than Source Code Form.
1.7. “Larger Work”
means a work that combines Covered Software with other material, in a separate
file or files, that is not Covered Software.
1.8. “License”
means this document.
1.9. “Licensable”
means having the right to grant, to the maximum extent possible, whether at the
time of the initial grant or subsequently, any and all of the rights conveyed by
this License.
1.10. “Modifications”
means any of the following:
a. any file in Source Code Form that results from an addition to, deletion
from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. “Patent Claims” of a Contributor
means any patent claim(s), including without limitation, method, process,
and apparatus claims, in any patent Licensable by such Contributor that
would be infringed, but for the grant of the License, by the making,
using, selling, offering for sale, having made, import, or transfer of
either its Contributions or its Contributor Version.
1.12. “Secondary License”
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. “Source Code Form”
means the form of the work preferred for making modifications.
1.14. “You” (or “Your”)
means an individual or a legal entity exercising rights under this
License. For legal entities, “You” includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, “control” means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or as
part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its Contributions
or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution become
effective for each Contribution on the date the Contributor first distributes
such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under this
License. No additional rights or licenses will be implied from the distribution
or licensing of Covered Software under this License. Notwithstanding Section
2.1(b) above, no patent license is granted by a Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third partys
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of its
Contributions.
This License does not grant any rights in the trademarks, service marks, or
logos of any Contributor (except as may be necessary to comply with the
notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this License
(see Section 10.2) or under the terms of a Secondary License (if permitted
under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its Contributions
are its original creation(s) or it has sufficient rights to grant the
rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under applicable
copyright doctrines of fair use, fair dealing, or other equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under the
terms of this License. You must inform recipients that the Source Code Form
of the Covered Software is governed by the terms of this License, and how
they can obtain a copy of this License. You may not attempt to alter or
restrict the recipients rights in the Source Code Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this License,
or sublicense it under different terms, provided that the license for
the Executable Form does not attempt to limit or alter the recipients
rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for the
Covered Software. If the Larger Work is a combination of Covered Software
with a work governed by one or more Secondary Licenses, and the Covered
Software is not Incompatible With Secondary Licenses, this License permits
You to additionally distribute such Covered Software under the terms of
such Secondary License(s), so that the recipient of the Larger Work may, at
their option, further distribute the Covered Software under the terms of
either this License or such Secondary License(s).
3.4. Notices
You may not remove or alter the substance of any license notices (including
copyright notices, patent notices, disclaimers of warranty, or limitations
of liability) contained within the Source Code Form of the Covered
Software, except that You may alter any license notices to the extent
required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on behalf
of any Contributor. You must make it absolutely clear that any such
warranty, support, indemnity, or liability obligation is offered by You
alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute, judicial
order, or regulation then You must: (a) comply with the terms of this License
to the maximum extent possible; and (b) describe the limitations and the code
they affect. Such description must be placed in a text file included with all
distributions of the Covered Software under this License. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
if such Contributor fails to notify You of the non-compliance by some
reasonable means prior to 60 days after You have come back into compliance.
Moreover, Your grants from a particular Contributor are reinstated on an
ongoing basis if such Contributor notifies You of the non-compliance by
some reasonable means, this is the first time You have received notice of
non-compliance with this License from such Contributor, and You become
compliant prior to 30 days after Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions, counter-claims,
and cross-claims) alleging that a Contributor Version directly or
indirectly infringes any patent, then the rights granted to You by any and
all Contributors for the Covered Software under Section 2.1 of this License
shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an “as is” basis, without
warranty of any kind, either expressed, implied, or statutory, including,
without limitation, warranties that the Covered Software is free of defects,
merchantable, fit for a particular purpose or non-infringing. The entire
risk as to the quality and performance of the Covered Software is with You.
Should any Covered Software prove defective in any respect, You (not any
Contributor) assume the cost of any necessary servicing, repair, or
correction. This disclaimer of warranty constitutes an essential part of this
License. No use of any Covered Software is authorized under this License
except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from such
partys negligence to the extent applicable law prohibits such limitation.
Some jurisdictions do not allow the exclusion or limitation of incidental or
consequential damages, so this exclusion and limitation may not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts of
a jurisdiction where the defendant maintains its principal place of business
and such litigation shall be governed by laws of that jurisdiction, without
reference to its conflict-of-law provisions. Nothing in this Section shall
prevent a partys ability to bring cross-claims or counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject matter
hereof. If any provision of this License is held to be unenforceable, such
provision shall be reformed only to the extent necessary to make it
enforceable. Any law or regulation which provides that the language of a
contract shall be construed against the drafter shall not be used to construe
this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version of
the License under which You originally received the Covered Software, or
under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a modified
version of this License if you rename the license and remove any
references to the name of the license steward (except to note that such
modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then
You may include the notice in a location (such as a LICENSE file in a relevant
directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - “Incompatible With Secondary Licenses” Notice
This Source Code Form is “Incompatible
With Secondary Licenses”, as defined by
the Mozilla Public License, v. 2.0.

Просмотреть файл

@ -0,0 +1 @@
from thclient import *

Просмотреть файл

@ -27,7 +27,5 @@ setup(name='treeherder-client',
license='MPL',
packages=['thclient'],
zip_safe=False,
install_requires=['oauth2', 'requests'],
test_suite='thclient.tests',
tests_require=["mock"],
install_requires=['oauth2', 'requests']
)

Просмотреть файл

@ -2,8 +2,4 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from .client import (TreeherderJob, TreeherderJobCollection,
TreeherderRevision, TreeherderResultSet,
TreeherderResultSetCollection, TreeherderArtifact,
TreeherderArtifactCollection, TreeherderClientError,
TreeherderRequest)
from .client import *

Просмотреть файл

Просмотреть файл

@ -1,11 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
[tox]
envlist=py25,py26,py27
[testenv]
deps=
mock
commands=python setup.py test

Просмотреть файл

@ -11,7 +11,7 @@ import copy
from collections import defaultdict
from django.conf import settings
from thclient import TreeherderJobCollection
from treeherder.client import TreeherderJobCollection
from treeherder.etl import common, buildbot
from treeherder.etl.mixins import JsonExtractorMixin, OAuthLoaderMixin

Просмотреть файл

@ -7,7 +7,7 @@ from django.conf import settings
import requests
import logging
from thclient import TreeherderResultSetCollection
from treeherder.client import TreeherderResultSetCollection
from .mixins import JsonExtractorMixin, OAuthLoaderMixin
from treeherder.etl.common import generate_revision_hash, get_not_found_onhold_push

Просмотреть файл

@ -3,7 +3,7 @@ import logging
from django.utils.encoding import python_2_unicode_compatible
from django.conf import settings
from thclient import TreeherderRequest
from treeherder.client import TreeherderRequest
from treeherder.etl.oauth_utils import OAuthCredentials

Просмотреть файл

@ -13,7 +13,7 @@ from treeherder.log_parser.artifactbuildercollection import \
ArtifactBuilderCollection
from treeherder.log_parser.artifactbuilders import MozlogArtifactBuilder
from thclient import TreeherderArtifactCollection, TreeherderRequest
from treeherder.client import TreeherderArtifactCollection, TreeherderRequest
from treeherder.etl.oauth_utils import OAuthCredentials
logger = logging.getLogger(__name__)

Просмотреть файл

@ -213,7 +213,6 @@ class ArtifactsModel(TreeherderModelBase):
Comes in through the web service as the "artifacts" property
in a job in a job collection
(https://github.com/mozilla/treeherder-client#job-collection)
A list of lists
[
@ -223,7 +222,6 @@ class ArtifactsModel(TreeherderModelBase):
job_artifact_collection:
Comes in through the web service as an artifact collection.
(https://github.com/mozilla/treeherder-client#artifact-collection)
A list of job artifacts:
[