Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Dev-Sec-Ops Demo/Assignment

[![codecov](https://codecov.io/gh/PGCSEDS-IIITH/devsecops-iris/branch/master/graph/badge.svg?token=EILEH8L7R5)](https://codecov.io/gh/PGCSEDS-IIITH/devsecops-iris)
[![codecov](https://codecov.io/gh/vineeth964/devsecops-iris/branch/master/graph/badge.svg?token=EILEH8L7R5)](https://codecov.io/gh/vineeth964/devsecops-iris)

This repository contains code which demonstrates Dev-Sec-Ops using a `FastAPI` application which predicts the flower class using the IRIS dataset (https://scikit-learn.org/stable/auto_examples/datasets/plot_iris_dataset.html)

Expand Down
89 changes: 89 additions & 0 deletions results.sariff
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
"runs": [
{
"tool": {
"driver": {
"name": "Bandit",
"rules": [
{
"id": "B104",
"name": "hardcoded_bind_all_interfaces",
"helpUri": "https://bandit.readthedocs.io/en/latest/plugins/b104_hardcoded_bind_all_interfaces.html"
}
]
}
},
"invocations": [
{
"executionSuccessful": true,
"endTimeUtc": "2021-09-25T13:05:38Z"
}
],
"properties": {
"metrics": {
"_totals": {
"loc": 33,
"nosec": 0,
"SEVERITY.UNDEFINED": 0.0,
"CONFIDENCE.UNDEFINED": 0.0,
"SEVERITY.LOW": 0.0,
"CONFIDENCE.LOW": 0.0,
"SEVERITY.MEDIUM": 1.0,
"CONFIDENCE.MEDIUM": 1.0,
"SEVERITY.HIGH": 0.0,
"CONFIDENCE.HIGH": 0.0
},
"./main.py": {
"loc": 33,
"nosec": 0,
"SEVERITY.UNDEFINED": 0.0,
"SEVERITY.LOW": 0.0,
"SEVERITY.MEDIUM": 1.0,
"SEVERITY.HIGH": 0.0,
"CONFIDENCE.UNDEFINED": 0.0,
"CONFIDENCE.LOW": 0.0,
"CONFIDENCE.MEDIUM": 1.0,
"CONFIDENCE.HIGH": 0.0
}
}
},
"results": [
{
"message": {
"text": "Possible binding to all interfaces."
},
"locations": [
{
"physicalLocation": {
"region": {
"snippet": {
"text": " uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8888, reload=True)\n"
},
"startLine": 64
},
"artifactLocation": {
"uri": "main.py"
},
"contextRegion": {
"snippet": {
"text": " # Uvicorn is used to run the server and listen for incoming API requests on 0.0.0.0:8888\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8888, reload=True)\n"
},
"endLine": 64,
"startLine": 63
}
}
}
],
"properties": {
"issue_confidence": "MEDIUM",
"issue_severity": "MEDIUM"
},
"ruleId": "B104",
"ruleIndex": 0
}
]
}
],
"version": "2.1.0",
"$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.4.json"
}
108 changes: 108 additions & 0 deletions test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,111 @@ def test_pred_virginica():
# asserting the correct response is received
assert response.status_code == 200
assert response.json() == {"flower_class": "Iris Virginica"}


# test to check if Iris Virginica is classified correctly
def test_pred_virginica_diff():
# defining a sample payload for the testcase
payload = {
"sepal_length": 3.1,
"sepal_width": 5.7,
"petal_length": 6,
"petal_width": 6,
}
with TestClient(app) as client:
response = client.post("/predict_flower", json=payload)
# asserting the correct response is received
assert response.status_code == 200
assert response.json() == {"flower_class": "Iris Virginica"}


# test to check if invalid param in payload is passed
def test_pred_invalid_payload():
# defining a sample payload for the testcase
payload = {
"sepal_length": 2,
"sepal_wid": 3.5,
"petal_length": 1.4,
"petal_width": 0.2,
}
with TestClient(app) as client:
response = client.post("/predict_flower", json=payload)
# asserting the correct response is received
assert response.status_code == 422
assert response.json() == {'detail': [{'loc': ['body', 'sepal_width'], 'msg': 'field required', 'type': 'value_error.missing'}]}


# test to check if invalid param in payload is passed
def test_pred_empty_payload():
# defining a sample payload for the testcase
payload = {

}
with TestClient(app) as client:
response = client.post("/predict_flower", json=payload)
# asserting the correct response is received
assert response.status_code == 422
assert response.json() == {'detail': [{'loc': ['body', 'sepal_length'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'sepal_width'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'petal_length'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'petal_width'], 'msg': 'field required', 'type': 'value_error.missing'}]}


# test to check if Iris Setosa is classified correctly
def test_pred_setosa():
# defining a sample payload for the testcase
payload = {
"sepal_length": 5.1,
"sepal_width": 3.5,
"petal_length": 1.4,
"petal_width": 0.2,
}
with TestClient(app) as client:
response = client.post("/predict_flower", json=payload)
# asserting the correct response is received
assert response.status_code == 200
assert response.json()["flower_class"] == "Iris Setosa"

# test to check if Iris Virginica is classified correctly with different payload
def test_pred_virginica_diff_payload():
# defining a sample payload for the testcase
payload = {
"sepal_length": 5.2,
"sepal_width": 5.4,
"petal_length": 10.4,
"petal_width": 6.2,
}
with TestClient(app) as client:
response = client.post("/predict_flower", json=payload)
# asserting the correct response is received
assert response.status_code == 200
assert response.json()["flower_class"] == "Iris Virginica"

#test to check feedback_loop method for Iris Virginica
def test_feedback_loop_virginica():
# defining a sample payload for the testcase
payload = [{
"sepal_length": 3,
"sepal_width": 5,
"petal_length": 3.2,
"petal_width": 4.4,
"flower_class":"Iris Virginica"
}]
with TestClient(app) as client:
response = client.post("/feedback_loop", json=payload)
# asserting the correct response is received
assert response.status_code == 200
assert response.json() == {"detail": "Feedback loop successful"}

#test to check feedback_loop method
def test_feedback_loop():
# defining a sample payload for the testcase
payload = [{
"sepal_length": 3.8,
"sepal_width": 8,
"petal_length": 5.2,
"petal_width": 4.4,
"flower_class":"Iris Setosa"
}]
with TestClient(app) as client:
response = client.post("/feedback_loop", json=payload)
# asserting the correct response is received
assert response.status_code == 200
assert response.json() == {"detail": "Feedback loop successful"}