Skip to content

Commit

Permalink
feat: got basic provider verifier working
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronald Holshausen committed Feb 21, 2021
1 parent d533bb7 commit 8d10d5a
Show file tree
Hide file tree
Showing 10 changed files with 417 additions and 79 deletions.
1 change: 1 addition & 0 deletions examples/v3/todo/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ json2xml==3.3.2
pytest==5.4.2
pact-python==2.0.0b0
requests==2.23.0
pytest-flask==1.1.0
83 changes: 45 additions & 38 deletions examples/v3/todo/src/todo_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,53 @@
from json2xml.utils import readfromstring
import json

app = Flask(__name__)

def create_app():
app = Flask(__name__)

@app.route('/projects')
def projects():
todo_response = [
{
'id': 1,
'name': "Project 1",
'type': "activity",
'due': "2016-02-11T09:46:56.023Z",
'tasks': [
{
'done': True,
'id': 1,
'name': "Task 1",
},
{
'done': True,
'id': 2,
'name': "Task 2",
},
{
'done': True,
'id': 3,
'name': "Task 3",
},
{
'done': True,
'id': 4,
'name': "Task 4",
},
]
}
]
if request.headers['accept'] == 'application/xml':
return json2xml.Json2xml(readfromstring(json.dumps(todo_response)), wrapper='projects').to_xml()
else:
return jsonify(todo_response)
@app.route('/')
def index():
return ''

@app.route('/projects')
def projects():
todo_response = [
{
'id': 1,
'name': "Project 1",
'type': "activity",
'due': "2016-02-11T09:46:56.023Z",
'tasks': [
{
'done': True,
'id': 1,
'name': "Task 1",
},
{
'done': True,
'id': 2,
'name': "Task 2",
},
{
'done': True,
'id': 3,
'name': "Task 3",
},
{
'done': True,
'id': 4,
'name': "Task 4",
},
]
}
]
if request.headers['accept'] == 'application/xml':
return json2xml.Json2xml(readfromstring(json.dumps(todo_response)), wrapper='projects').to_xml()
else:
return jsonify(todo_response)

return app


if __name__ == '__main__':
app.run(debug=True, port=5001)
create_app().run(debug=True, port=5001)
39 changes: 0 additions & 39 deletions examples/v3/todo/tests/provider.spec.js

This file was deleted.

19 changes: 19 additions & 0 deletions examples/v3/todo/tests/test_todo_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import pytest
from ..src.todo_provider import create_app
from pact import VerifierV3
from flask import url_for


@pytest.fixture(scope='session')
def app():
return create_app()


@pytest.mark.usefixtures('live_server')
def test_pact_verification():
verifier = VerifierV3(provider='TodoServiceV3',
provider_base_url=url_for('index', _external=True))
assert verifier.verify_pacts(
sources=['./pacts/TodoApp-TodoServiceV3.json']
)

5 changes: 5 additions & 0 deletions pact-python-v3/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions pact-python-v3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@ serde_json = "1.0"
uuid = { version = "0.8", features = ["v4"] }
lazy_static = "1.4.0"
bytes = { version = "1", features = ["serde"] }
url = "2.2.0"
ansi_term = "0.12.1"
async-trait = "0.1.24"
regex = "1"

[dependencies.cpython]
version = "0.5"
features = ["extension-module"]

[dependencies.reqwest]
version = "0.11.0"
default-features = false
features = ["rustls-tls"]

[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
Expand Down
35 changes: 34 additions & 1 deletion pact-python-v3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::cell::RefCell;
use std::collections::HashMap;
use std::fs;
use std::str::FromStr;
use std::sync::Mutex;
use std::sync::{Mutex, Arc};

use bytes::Bytes;
use cpython::*;
Expand All @@ -22,6 +22,9 @@ use pact_mock_server_ffi::bodies::{process_array, process_object};
use serde_json::{json, Value};
use serde_json::map::Map;
use uuid::Uuid;
use crate::verifier::{setup_provider_config, PythonProviderStateExecutor};

mod verifier;

lazy_static! {
static ref MANAGER: Mutex<ServerManager> = Mutex::new(ServerManager::new());
Expand All @@ -31,6 +34,7 @@ py_module_initializer!(pact_python_v3, |py, m| {
m.add(py, "__doc__", "Pact Python V3 support (provided by Pact-Rust FFI)")?;
m.add(py, "init", py_fn!(py, init_lib(*args, **kwargs)))?;
m.add(py, "generate_datetime_string", py_fn!(py, generate_datetime_string(format: &str)))?;
m.add(py, "verify_provider", py_fn!(py, verify_provider(*args, **kwargs)))?;
m.add_class::<PactNative>(py)?;
Ok(())
});
Expand Down Expand Up @@ -501,3 +505,32 @@ fn json_to_pyobj(py: Python, val: &Value) -> PyObject {
Value::Object(map) => map.iter().map(|(key, value)| (key.clone(), json_to_pyobj(py, value))).collect::<HashMap<String, PyObject>>().to_py_object(py).into_object()
}
}

fn verify_provider(
py: Python,
args: &PyTuple,
kwargs: Option<&PyDict>
) -> PyResult<PyBool> {
let arg1 = args.get_item(py, 0);
let provider = arg1.cast_as::<PyString>(py)?.to_string_lossy(py);
let arg2 = args.get_item(py, 1);
let base_url = arg2.cast_as::<PyString>(py)?.to_string_lossy(py);
let arg3 = args.get_item(py, 2);
let options = arg3.cast_as::<PyDict>(py)?;

debug!("Verifying provider '{}' running at '{}'", provider, base_url);
let (provider_info, source, options, filter, consumers) = setup_provider_config(py, provider.as_ref(), base_url.as_ref(), options)?;

debug!("Pact sources = {:?}", source);
let result = pact_verifier::verify_provider(
provider_info,
source,
filter,
consumers,
options,
&Arc::new(PythonProviderStateExecutor::new())
);
debug!("result = {}", result);

Ok(PyBool::get(py, result))
}
Loading

0 comments on commit 8d10d5a

Please sign in to comment.