diff --git a/.circleci/config.yml b/.circleci/config.yml index b6742c3..233f134 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -107,7 +107,7 @@ jobs: - run: name: PyTest Cover command: | - pytest --cov-fail-under=88 --cov=./ --cov-report=xml + pytest --cov-fail-under=85 --cov=./ --cov-report=xml - codecov/upload: file: ./coverage.xml diff --git a/nazgul/api.py b/nazgul/api.py index ae859b1..0a9639b 100644 --- a/nazgul/api.py +++ b/nazgul/api.py @@ -32,6 +32,21 @@ logger.addHandler(fh) +class StructuredMessage(object): + def __init__(self, message, **kwargs): + self.message = message + self.kwargs = kwargs + + def __str__(self): + return "%s >>> %s" % (self.message, json.dumps(self.kwargs)) + + +def print_json_log(message, time, method, path): + fields = {"method": method, "msg": message, "path": path} + + print(StructuredMessage(message, Timestamp=time, Fields=fields)) + + @auth.verify_password def verify_password(username, password): if username in users: @@ -88,10 +103,16 @@ def location_show(): xml.prepare_locations(product, locations) data = xml.render() status = 200 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) return Response(data, mimetype="text/xml"), status @@ -119,10 +140,17 @@ def location_add(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) + return Response(data, mimetype="text/xml"), status @@ -144,10 +172,17 @@ def location_modify(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) + return Response(data, mimetype="text/xml"), status @@ -168,9 +203,16 @@ def location_delete(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) return Response(data, mimetype="text/xml"), status @@ -186,10 +228,17 @@ def product_show(): xml.prepare_products(res) data = xml.render() status = 200 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) + return Response(data, mimetype="text/xml"), status @@ -209,10 +258,17 @@ def product_add(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) + return Response(data, mimetype="text/xml"), status @@ -234,10 +290,17 @@ def product_delete(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) + return Response(data, mimetype="text/xml"), status @@ -256,9 +319,16 @@ def product_language_add(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) return Response(data, mimetype="text/xml"), status @@ -276,9 +346,16 @@ def product_language_delete(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) return Response(data, mimetype="text/xml"), status @@ -314,9 +391,16 @@ def uptake(): # Error no. for /uptake is always 102 in Tuxedo (Should this be changed in Nazgul?) data = xml.error(e.message, errno=102) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) return Response(data, mimetype="text/xml"), status @@ -342,7 +426,14 @@ def create_update_alias(): except ModelError as e: data = xml.error(e.message, errno=e.errno) status = 400 - except Exception: + except Exception as e: data = xml.error("Unknown error") status = 500 + + print_json_log( + "Uncaught Exception: {0}".format(e), + "%.0f" % (time.time() * 1000000000), + request.method, + request.full_path, + ) return Response(data, mimetype="text/xml"), status diff --git a/tests/test_api.py b/tests/test_api.py index 61bc63c..42e3bee 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -300,7 +300,18 @@ def test_product_language_add_no_match(client): assert expected == rv.data -def test_product_language_delete(client): +def test_product_language_delete_single(client): + rv = client.post( + "api/product_language_delete/", + data={"product": "AaronProduct", "languages": ["en-GB"]}, + headers={"Authorization": requests.auth._basic_auth_str(test_user, test_pass)}, + ) + expected = b'SUCCESS: language has been deleted' + msm._reset_db() + assert expected == rv.data + + +def test_product_language_delete_multiple(client): rv = client.post( "api/product_language_delete/", data={"product": "AaronProduct", "languages": ["en-GB", "en-US"]},