fellowship package

Module contents

fellowship.rest_tester module

Usage example:

>>> from fellowship.rest_tester import RestTester
>>> rest_tester = RestTester(path_to_contract_directory)
>>> rest_tester.make_requests_and_validates()
Will print report that shows contracts that validation failed for, validation is
lazy so all contracts will be validated before result is shown.
If you would like more information about the validation set the logging level
to info. Example report:
ERROR    fellowship.reporter:reporter.py:69 Contract validation failed for:
/invalid_contracts/contract_wrong_type.json
ERROR    fellowship.reporter:reporter.py:69 Contract validation failed for:
/invalid_contracts/contract_missing_required.json
ERROR    fellowship.reporter:reporter.py:70 Total result: 0 / 2
class fellowship.rest_tester.RestTester(contract_dir)

Validates Rest endpoints based on contracts. Inherits EndpointTester

exception fellowship.rest_tester.RestTesterException

Exception raised when contract validation fails

fellowship.contract_generator module

Usage example:

>>> import logging
>>> from fellowship.rest_contract_generator import ContractGenerator
>>> logging.basicConfig(level=logging.INFO)
>>> path_to_contract = os.path.join("contracts", "test_contract.json")
>>> request_kwargs = {"url": "/test?id=123","method": "GET"}
>>> expected_json = {"name": "Bob", "age": 72, "id": 123}
>>> contract_generator = ContractGenerator(path_to_contract)
>>> contract_generator.generate_and_save_contract(request_kwargs, expected_json)
The example output:
INFO:fellowship.contract_generator:The generated schema: {
    "$schema": "http://json-schema.org/schema#",
    "request": {
        "url": "{{ config.protocol }}://{{ config.host }}/test?id=123",
        "method": "GET",
        "headers": "{{ config.default_headers }}"
    },
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "age": {
            "type": "integer"
        },
        "id": {
            "type": "integer"
        }
    },
    "required": [
        "age",
        "id",
        "name"
    ]
}
Saved to file: test.json
class fellowship.contract_generator.ContractGenerator(output_path, type_of_contract='rest')

Generates a json contract based on a request and its expected output.

contract_path

The path of file that will be generated

Type

str

type_of_contract

The type to write to contract in field contract_type can be either rest or grpc. Default value: rest

Type

str

generate_and_save_contract(request_kwargs, expected_json)

Function that generates a new contract and saves it to specified location

Parameters
  • request_kwargs (dict) – A dictionary that describes the request that should return the expected_json. The dictionary needs to contain url (at least endpoint) and method. Optional parameters include headers and data

  • expected_json (dict) – Is the Json response that is expected when the request from the request_kwargs dictionary is sent.

Return type

None

set_type_of_schema_builder(type_of_schema_builder='type')

Sets the type of schema builder can be either type or strict

Type builder is the default and generates the contract with type validation. The Other type of builder supported is strict which will generate contract with expected value for each field.

Parameters

type_of_schema_builder (str) – The type of builder to use when generating schema can be either type or strict. Default value: type

Return type

None

fellowship.grpc_tester module

Usage example:

>>> from fellowship.rest_tester import GrpcTester
>>> grpc_tester = GrpcTester(args.path)
>>> grpc_tester.make_requests_and_validates()
Will print report that shows contracts that validation failed for, validation is
lazy so all contracts will be validated before result is shown.
If you would like more information about the validation set the logging level
to info. Example report:
ERROR    fellowship.reporter:reporter.py:69 Contract validation failed for:
/invalid_contracts/contract_wrong_type.json
ERROR    fellowship.reporter:reporter.py:69 Contract validation failed for:
/invalid_contracts/contract_missing_required.json
ERROR    fellowship.reporter:reporter.py:70 Total result: 0 / 2
class fellowship.grpc_tester.GrpcTester(contract_dir)

Validates gRPC endpoints based on contracts. Inherits EndpointTester

Supports two different gRPC communication methods reflection and stub. In the stub method, the user must provide the corresponding proto so Fellowship can generate the stub for requests. If the gRPC server support reflection, you do not need the proto file, since Fellowship can directly request the endpoints returned by the reflection endpoint.

grpc_address

The address that the request targets. Format: ip:port

Type

str

fellowship.grpc_generator module

Usage example:

>>> from fellowship.grpc_generator import GrpcGenerator
>>> grpc_generator = GrpcGenerator(path_to_protofile, output_dir)
>>> grpc_generator.generate_grpc_contracts()
class fellowship.grpc_generator.GrpcGenerator(proto_file, output_dir='')

Generates a skeleton for the gRPC, as a base for generation it uses the proto file

Goes through a proto file, finding all endpoints and their responses, generates a contract per endpoint. Supports also nested message objects. The generation is done by complying the proto file and parsing the corresponding descriptor objects. After the expected response is obtained it calls ContractGenerator

proto_file

The proto file that generation will be based on.

Type

str

output_dir

Directory to output the contracts to. Default value is current directory.

Type

str

generate_grpc_contracts()

Function that generates a new contracts and saves it to output_dir

Makes a contract for each end point available in the proto file and saves it to the output dir. The name convention is package_endpoint_function.json

fellowship.endpoint_tester module

class fellowship.endpoint_tester.EndpointTester(contract_dir)

Validates endpoints based on contracts

contract_dir

Path to directory of contracts to validate

Type

str

contract_renderer

Contract render module used to fill the Jinja2 template of the contracts.

Type

object

make_requests_and_validates()

Functions goes through contracts in contract directory. For each contract a request is made corresponding to the request portion in the contract. The response is validated against json schema portion of the contract. A report gets printed to the shell

Return type

None

exception fellowship.endpoint_tester.EndpointTesterException

Exception raised when contract validation fails

fellowship.reporter module

class fellowship.reporter.Reporter

Reports test results of the contract testing.

total_tests

The total amount of tests conducted. Default value 0

Type

int

failed

A list of failed tests. Default value empty list

Type

list

marginals()

Generator that prints header/footer, and yields a reporter instance

The reporter instance can be used to print the report, with the function print_report_results

Yields

Reporter

an instance of the reporter which can be used to print the result

of test cases

Return type

typing.Generator[fellowship.reporter.Reporter, None, None]

print_report_results(contract_title, exception=None)

Function is used to print the result of each contract to the cli

Parameters
  • contract_title (str) – The title of the contract used for logging

  • exception (Exception) – Exception raised when validating contract. Defaults to None when validation is successful

Return type

None

fellowship.contract module

class fellowship.contract.Contract(title, content)

Class to save the contents of a contract and a title for it

title

Title of the contract

Type

str

content

Json contents of the contract

Type

dict

fellowship.utilis module

fellowship.utilis.get_descriptor_name(proto_file)

Returns the name of the grpc _descriptor based on protocol buffer file

Parameters

proto_file (str) – path to proto_file

Returns

Name of the _descriptor service

Return type

str

fellowship.utilis.get_grpc_service_descriptor(proto_file)

Compiles and parses proto file to find service descriptor

Function also needs to add the directory of the proto file to sys path otherwise import of the compiled grpc module will fail.

Parameters

proto_file (str) – path to proto_file

Returns

The grpc descriptor class from the proto file

fellowship.utilis.get_type_of_contract(contract_dict)
Return type

str

fellowship.utilis.load_config()

Loads the configuration dictionary that is used to fill contracts

Function loads the config yaml, given at the path of environment variable contract_test_config, if this variable is not present. It will load default config from configs/rest_config.yaml. Yaml should always be structured like a dictionary

Returns

configuration dict

Return type

dict

fellowship.utilis.load_custom_schema(schema_file)

Loads custom meta schema from the schemas directory

Parameters

schema_file (str) – Name of the schema file located in schemas directory

Returns

The loaded schema

Return type

dict

fellowship.utilis.read_yaml(path)

Loads yaml at given path

Parameters

path (str) – path to yaml file

Returns

dictionary or list loaded from yaml depending on the yaml

Return type

Union[dict, list]

fellowship.utilis.validate_contract(contract_dict)

Validates contracts against custom meta json schema

Meta scheme is based on the Draft7 from json schema with an extension for request dict. Which meta to use is based on contract_type field in schema that is being validated. If the field is missing defaults to REST.

Parameters

contract_dict (dict) –

Return type

None