mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Merge pull request #891 from bigchaindb/generate-http-docs-examples
Auto generate examples in http server API docs
This commit is contained in:
commit
e4026db85f
4
.gitignore
vendored
4
.gitignore
vendored
@ -77,3 +77,7 @@ benchmarking-tests/ssh_key.py
|
||||
# Ansible-specific files
|
||||
ntools/one-m/ansible/hosts
|
||||
ntools/one-m/ansible/ansible.cfg
|
||||
|
||||
# Just in time documentation
|
||||
docs/server/source/schema
|
||||
docs/server/source/drivers-clients/samples
|
||||
|
0
docs/generate/__init__.py
Normal file
0
docs/generate/__init__.py
Normal file
87
docs/server/generate_http_server_api_documentation.py
Normal file
87
docs/server/generate_http_server_api_documentation.py
Normal file
@ -0,0 +1,87 @@
|
||||
""" Script to build http examples for http server api docs """
|
||||
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
|
||||
from bigchaindb.common.transaction import Asset, Transaction
|
||||
|
||||
|
||||
TPLS = {}
|
||||
|
||||
TPLS['post-tx-request'] = """\
|
||||
POST /transactions/ HTTP/1.1
|
||||
Host: example.com
|
||||
Content-Type: application/json
|
||||
|
||||
%(tx)s
|
||||
"""
|
||||
|
||||
|
||||
TPLS['post-tx-response'] = """\
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
%(tx)s
|
||||
"""
|
||||
|
||||
|
||||
TPLS['get-tx-status-request'] = """\
|
||||
GET /transactions/%(txid)s/status HTTP/1.1
|
||||
Host: example.com
|
||||
|
||||
"""
|
||||
|
||||
|
||||
TPLS['get-tx-status-response'] = """\
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"status": "valid"
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
TPLS['get-tx-request'] = """\
|
||||
GET /transactions/%(txid)s HTTP/1.1
|
||||
Host: example.com
|
||||
|
||||
"""
|
||||
|
||||
|
||||
TPLS['get-tx-response'] = """\
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
%(tx)s
|
||||
"""
|
||||
|
||||
|
||||
def main():
|
||||
""" Main function """
|
||||
pubkey = '9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb'
|
||||
asset = Asset(None, 'e6969f87-4fc9-4467-b62a-f0dfa1c85002')
|
||||
tx = Transaction.create([pubkey], [([pubkey], 1)], asset=asset)
|
||||
tx_json = json.dumps(tx.to_dict(), indent=2, sort_keys=True)
|
||||
|
||||
base_path = os.path.join(os.path.dirname(__file__),
|
||||
'source/drivers-clients/samples')
|
||||
|
||||
if not os.path.exists(base_path):
|
||||
os.makedirs(base_path)
|
||||
|
||||
for name, tpl in TPLS.items():
|
||||
path = os.path.join(base_path, name + '.http')
|
||||
code = tpl % {'tx': tx_json, 'txid': tx.id}
|
||||
with open(path, 'w') as handle:
|
||||
handle.write(code)
|
||||
|
||||
|
||||
def setup(*_):
|
||||
""" Fool sphinx into think it's an extension muahaha """
|
||||
main()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -168,12 +168,20 @@ def main():
|
||||
'file': os.path.basename(__file__),
|
||||
}
|
||||
|
||||
path = os.path.join(os.path.dirname(__file__),
|
||||
'source/schema/transaction.rst')
|
||||
base_path = os.path.join(os.path.dirname(__file__), 'source/schema')
|
||||
path = os.path.join(base_path, 'transaction.rst')
|
||||
|
||||
if not os.path.exists(base_path):
|
||||
os.makedirs(base_path)
|
||||
|
||||
with open(path, 'w') as handle:
|
||||
handle.write(doc)
|
||||
|
||||
|
||||
def setup(*_):
|
||||
""" Fool sphinx into think it's an extension muahaha """
|
||||
main()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -35,6 +35,10 @@ _version = {}
|
||||
with open('../../../bigchaindb/version.py') as fp:
|
||||
exec(fp.read(), _version)
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/..'))
|
||||
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
@ -44,6 +48,10 @@ extensions = [
|
||||
'sphinx.ext.napoleon',
|
||||
'sphinxcontrib.httpdomain',
|
||||
'sphinx.ext.autosectionlabel',
|
||||
# Below are actually build steps made to look like sphinx extensions.
|
||||
# It was the easiest way to get it running with ReadTheDocs.
|
||||
'generate_schema_documentation',
|
||||
'generate_http_server_api_documentation',
|
||||
]
|
||||
|
||||
# autodoc settings
|
||||
|
@ -64,108 +64,13 @@ POST /transactions/
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /transactions/ HTTP/1.1
|
||||
Host: example.com
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"transaction": {
|
||||
"conditions": [
|
||||
{
|
||||
"cid": 0,
|
||||
"condition": {
|
||||
"uri": "cc:4:20:fSlVCKNSzSl0meiwwuUk5JpJ0KLlECTqbd25KyQefFY:96",
|
||||
"details": {
|
||||
"signature": null,
|
||||
"type": "fulfillment",
|
||||
"type_id": 4,
|
||||
"bitmask": 32,
|
||||
"public_key": "9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
}
|
||||
},
|
||||
"amount": 1,
|
||||
"owners_after": [
|
||||
"9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
]
|
||||
}
|
||||
],
|
||||
"operation": "CREATE",
|
||||
"asset": {
|
||||
"divisible": false,
|
||||
"updatable": false,
|
||||
"data": null,
|
||||
"id": "b57801f8-b865-4360-9d1a-3e3009f5ce01",
|
||||
"refillable": false
|
||||
},
|
||||
"metadata": null,
|
||||
"fulfillments": [
|
||||
{
|
||||
"fid": 0,
|
||||
"input": null,
|
||||
"fulfillment": "cf:4:fSlVCKNSzSl0meiwwuUk5JpJ0KLlECTqbd25KyQefFaf8bQVH1gesZGEGZepCE8_kgo-UfBrCHPlvBsnAsfq56GWjrLTyZ9NXISwcyJ3zmygnVhCMG8xzE6c9fj1-6wK",
|
||||
"owners_before": [
|
||||
"9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "65f1f69b6ebf995a7b2c5ae8a6fb480ce20f0e8f1eb1d77d75f37ab00ccdeec3",
|
||||
"version": 1
|
||||
}
|
||||
.. literalinclude:: samples/post-tx-request.http
|
||||
:language: http
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 201 Created
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"id": "65f1f69b6ebf995a7b2c5ae8a6fb480ce20f0e8f1eb1d77d75f37ab00ccdeec3",
|
||||
"version": 1,
|
||||
"transaction": {
|
||||
"conditions": [
|
||||
{
|
||||
"amount": 1,
|
||||
"condition": {
|
||||
"uri": "cc:4:20:fSlVCKNSzSl0meiwwuUk5JpJ0KLlECTqbd25KyQefFY:96",
|
||||
"details": {
|
||||
"signature": null,
|
||||
"type_id": 4,
|
||||
"type": "fulfillment",
|
||||
"bitmask": 32,
|
||||
"public_key": "9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
}
|
||||
},
|
||||
"owners_after": [
|
||||
"9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
],
|
||||
"cid": 0
|
||||
}
|
||||
],
|
||||
"fulfillments": [
|
||||
{
|
||||
"input": null,
|
||||
"fulfillment": "cf:4:fSlVCKNSzSl0meiwwuUk5JpJ0KLlECTqbd25KyQefFaf8bQVH1gesZGEGZepCE8_kgo-UfBrCHPlvBsnAsfq56GWjrLTyZ9NXISwcyJ3zmygnVhCMG8xzE6c9fj1-6wK",
|
||||
"fid": 0,
|
||||
"owners_before": [
|
||||
"9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
]
|
||||
}
|
||||
],
|
||||
"operation": "CREATE",
|
||||
"asset": {
|
||||
"updatable": false,
|
||||
"refillable": false,
|
||||
"divisible": false,
|
||||
"data": null,
|
||||
"id": "b57801f8-b865-4360-9d1a-3e3009f5ce01"
|
||||
},
|
||||
"metadata": null
|
||||
}
|
||||
}
|
||||
.. literalinclude:: samples/post-tx-response.http
|
||||
:language: http
|
||||
|
||||
:statuscode 201: A new transaction was created.
|
||||
:statuscode 400: The transaction was invalid and not created.
|
||||
@ -187,21 +92,13 @@ GET /transactions/{tx_id}/status
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /transactions/65f1f69b6ebf995a7b2c5ae8a6fb480ce20f0e8f1eb1d77d75f37ab00ccdeec3/status HTTP/1.1
|
||||
Host: example.com
|
||||
.. literalinclude:: samples/get-tx-status-request.http
|
||||
:language: http
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"status": "valid"
|
||||
}
|
||||
.. literalinclude:: samples/get-tx-status-response.http
|
||||
:language: http
|
||||
|
||||
:statuscode 200: A transaction with that ID was found and the status is returned.
|
||||
:statuscode 404: A transaction with that ID was not found.
|
||||
@ -222,62 +119,13 @@ GET /transactions/{tx_id}
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
GET /transactions/65f1f69b6ebf995a7b2c5ae8a6fb480ce20f0e8f1eb1d77d75f37ab00ccdeec3 HTTP/1.1
|
||||
Host: example.com
|
||||
.. literalinclude:: samples/get-tx-request.http
|
||||
:language: http
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"transaction": {
|
||||
"conditions": [
|
||||
{
|
||||
"cid": 0,
|
||||
"condition": {
|
||||
"uri": "cc:4:20:fSlVCKNSzSl0meiwwuUk5JpJ0KLlECTqbd25KyQefFY:96",
|
||||
"details": {
|
||||
"signature": null,
|
||||
"type": "fulfillment",
|
||||
"type_id": 4,
|
||||
"bitmask": 32,
|
||||
"public_key": "9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
}
|
||||
},
|
||||
"amount": 1,
|
||||
"owners_after": [
|
||||
"9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
]
|
||||
}
|
||||
],
|
||||
"operation": "CREATE",
|
||||
"asset": {
|
||||
"divisible": false,
|
||||
"updatable": false,
|
||||
"data": null,
|
||||
"id": "b57801f8-b865-4360-9d1a-3e3009f5ce01",
|
||||
"refillable": false
|
||||
},
|
||||
"metadata": null,
|
||||
"fulfillments": [
|
||||
{
|
||||
"fid": 0,
|
||||
"input": null,
|
||||
"fulfillment": "cf:4:fSlVCKNSzSl0meiwwuUk5JpJ0KLlECTqbd25KyQefFaf8bQVH1gesZGEGZepCE8_kgo-UfBrCHPlvBsnAsfq56GWjrLTyZ9NXISwcyJ3zmygnVhCMG8xzE6c9fj1-6wK",
|
||||
"owners_before": [
|
||||
"9RaWxppkP9UyYWA7NJb5FcgkzfJNPfvPX3FCNw2T5Pwb"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "65f1f69b6ebf995a7b2c5ae8a6fb480ce20f0e8f1eb1d77d75f37ab00ccdeec3",
|
||||
"version": 1
|
||||
}
|
||||
.. literalinclude:: samples/get-tx-response.http
|
||||
:language: http
|
||||
|
||||
:statuscode 200: A transaction with that ID was found.
|
||||
:statuscode 404: A transaction with that ID was not found.
|
||||
|
@ -1,307 +0,0 @@
|
||||
.. This file was auto generated by generate_schema_documentation.py
|
||||
|
||||
==================
|
||||
Transaction Schema
|
||||
==================
|
||||
|
||||
* `Transaction`_
|
||||
|
||||
* `Transaction Body`_
|
||||
|
||||
* Condition_
|
||||
|
||||
* Fulfillment_
|
||||
|
||||
* Asset_
|
||||
|
||||
* Metadata_
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<style>
|
||||
#transaction-schema h2 {
|
||||
border-top: solid 3px #6ab0de;
|
||||
background-color: #e7f2fa;
|
||||
padding: 5px;
|
||||
}
|
||||
#transaction-schema h3 {
|
||||
background: #f0f0f0;
|
||||
border-left: solid 3px #ccc;
|
||||
font-weight: bold;
|
||||
padding: 6px;
|
||||
font-size: 100%;
|
||||
font-family: monospace;
|
||||
}
|
||||
</style>
|
||||
|
||||
Transaction
|
||||
-----------
|
||||
|
||||
This is the outer transaction wrapper. It contains the ID, version and the body of the transaction, which is also called ``transaction``.
|
||||
|
||||
|
||||
Transaction.id
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
**type:** string
|
||||
|
||||
A sha3 digest of the transaction. The ID is calculated by removing all
|
||||
derived hashes and signatures from the transaction, serializing it to
|
||||
JSON with keys in sorted order and then hashing the resulting string
|
||||
with sha3.
|
||||
|
||||
|
||||
|
||||
Transaction.transaction
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** object
|
||||
|
||||
See: `Transaction Body`_.
|
||||
|
||||
|
||||
|
||||
Transaction.version
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** integer
|
||||
|
||||
BigchainDB transaction schema version.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Transaction Body
|
||||
----------------
|
||||
|
||||
See: `Transaction Body`_.
|
||||
|
||||
|
||||
Transaction.operation
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** string
|
||||
|
||||
Type of the transaction:
|
||||
|
||||
A ``CREATE`` transaction creates an asset in BigchainDB. This
|
||||
transaction has outputs (conditions) but no inputs (fulfillments),
|
||||
so a dummy fulfillment is used.
|
||||
|
||||
A ``TRANSFER`` transaction transfers ownership of an asset, by providing
|
||||
fulfillments to conditions of earlier transactions.
|
||||
|
||||
A ``GENESIS`` transaction is a special case transaction used as the
|
||||
sole member of the first block in a BigchainDB ledger.
|
||||
|
||||
|
||||
|
||||
Transaction.asset
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** object
|
||||
|
||||
Description of the asset being transacted.
|
||||
|
||||
See: `Asset`_.
|
||||
|
||||
|
||||
|
||||
Transaction.fulfillments
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** array (object)
|
||||
|
||||
Array of the fulfillments (inputs) of a transaction.
|
||||
|
||||
See: Fulfillment_.
|
||||
|
||||
|
||||
|
||||
Transaction.conditions
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** array (object)
|
||||
|
||||
Array of conditions (outputs) provided by this transaction.
|
||||
|
||||
See: Condition_.
|
||||
|
||||
|
||||
|
||||
Transaction.metadata
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** object or null
|
||||
|
||||
User provided transaction metadata. This field may be ``null`` or may
|
||||
contain an object with freeform metadata.
|
||||
|
||||
See: `Metadata`_.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Condition
|
||||
----------
|
||||
|
||||
An output of a transaction. A condition describes a quantity of an asset
|
||||
and what conditions must be met in order for it to be fulfilled. See also:
|
||||
fulfillment_.
|
||||
|
||||
|
||||
Condition.cid
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
**type:** integer
|
||||
|
||||
Index of this condition's appearance in the `Transaction.conditions`_
|
||||
array. In a transaction with 2 conditions, the ``cid``s will be 0 and 1.
|
||||
|
||||
|
||||
|
||||
Condition.condition
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** object
|
||||
|
||||
Body of the condition. Has the properties:
|
||||
|
||||
- **details**: Details of the condition.
|
||||
- **uri**: Condition encoded as an ASCII string.
|
||||
|
||||
|
||||
|
||||
Condition.owners_after
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** array (string) or null
|
||||
|
||||
List of public keys associated with asset ownership at the time
|
||||
of the transaction.
|
||||
|
||||
|
||||
|
||||
Condition.amount
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** integer
|
||||
|
||||
Integral amount of the asset represented by this condition.
|
||||
In the case of a non divisible asset, this will always be 1.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Fulfillment
|
||||
-----------
|
||||
|
||||
A fulfillment is an input to a transaction, named as such because it fulfills a condition of a previous transaction. In the case of a ``CREATE`` transaction, a fulfillment may provide no ``input``.
|
||||
|
||||
Fulfillment.fid
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** integer
|
||||
|
||||
The offset of the fulfillment within the fulfillents array.
|
||||
|
||||
|
||||
|
||||
Fulfillment.owners_before
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** array (string) or null
|
||||
|
||||
List of public keys of the previous owners of the asset.
|
||||
|
||||
|
||||
|
||||
Fulfillment.fulfillment
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** object or string
|
||||
|
||||
Fulfillment of a condition_, or put a different way, this is a
|
||||
payload that satisfies a condition in order to spend the associated
|
||||
asset.
|
||||
|
||||
|
||||
|
||||
Fulfillment.input
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** object or null
|
||||
|
||||
Reference to a condition of a previous transaction
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Asset
|
||||
-----
|
||||
|
||||
Description of the asset being transacted. In the case of a ``TRANSFER``
|
||||
transaction, this field contains only the ID of asset. In the case
|
||||
of a ``CREATE`` transaction, this field may contain properties:
|
||||
|
||||
|
||||
Asset.id
|
||||
^^^^^^^^
|
||||
|
||||
**type:** string
|
||||
|
||||
A `UUID <https://tools.ietf.org/html/rfc4122.html>`_
|
||||
of type 4 (random).
|
||||
|
||||
|
||||
|
||||
Asset.divisible
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** boolean
|
||||
|
||||
Whether or not the asset has a quantity that may be partially spent.
|
||||
|
||||
|
||||
|
||||
Asset.updatable
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** boolean
|
||||
|
||||
Whether or not the description of the asset may be updated. Defaults to false.
|
||||
|
||||
|
||||
|
||||
Asset.refillable
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
**type:** boolean
|
||||
|
||||
Whether the amount of the asset can change after its creation. Defaults to false.
|
||||
|
||||
|
||||
|
||||
Asset.data
|
||||
^^^^^^^^^^
|
||||
|
||||
**type:** object or null
|
||||
|
||||
User provided metadata associated with the asset. May also be ``null``.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Metadata
|
||||
--------
|
||||
|
||||
User provided transaction metadata. This field may be ``null`` or may
|
||||
contain an non empty object with freeform metadata.
|
||||
|
||||
|
||||
|
23
setup.py
23
setup.py
@ -27,18 +27,6 @@ def check_setuptools_features():
|
||||
|
||||
check_setuptools_features()
|
||||
|
||||
|
||||
tests_require = [
|
||||
'coverage',
|
||||
'pep8',
|
||||
'flake8',
|
||||
'pylint',
|
||||
'pytest',
|
||||
'pytest-cov>=2.2.1',
|
||||
'pytest-xdist',
|
||||
'pytest-flask',
|
||||
]
|
||||
|
||||
dev_require = [
|
||||
'ipdb',
|
||||
'ipython',
|
||||
@ -52,6 +40,17 @@ docs_require = [
|
||||
'sphinxcontrib-napoleon>=0.4.4',
|
||||
]
|
||||
|
||||
tests_require = [
|
||||
'coverage',
|
||||
'pep8',
|
||||
'flake8',
|
||||
'pylint',
|
||||
'pytest',
|
||||
'pytest-cov>=2.2.1',
|
||||
'pytest-xdist',
|
||||
'pytest-flask',
|
||||
] + docs_require
|
||||
|
||||
benchmarks_require = [
|
||||
'line-profiler==1.0',
|
||||
]
|
||||
|
16
tests/test_docs.py
Normal file
16
tests/test_docs.py
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
import subprocess
|
||||
|
||||
|
||||
def test_build_server_docs():
|
||||
proc = subprocess.Popen(['bash'], stdin=subprocess.PIPE)
|
||||
proc.stdin.write('cd docs/server; make html'.encode())
|
||||
proc.stdin.close()
|
||||
assert proc.wait() == 0
|
||||
|
||||
|
||||
def test_build_root_docs():
|
||||
proc = subprocess.Popen(['bash'], stdin=subprocess.PIPE)
|
||||
proc.stdin.write('cd docs/root; make html'.encode())
|
||||
proc.stdin.close()
|
||||
assert proc.wait() == 0
|
Loading…
x
Reference in New Issue
Block a user