Skip to content

Commit 9cbaed5

Browse files
Updated service class unit tests (#31)
* Package layout updates * Package updates * Cleaning up tabs * README and LICENSE updates * More package testing * Broken link fixes * Uber class custom headers, Content-Type retained * v0.1.8 - Uber class custom headers * Uber class fix for octet-stream file uploads * README.md updates * Package development status alignment * Typo fix in README.md * Minor README.md text edits * Initial unit tests: Service and Uber Auth / Revoke * Initial unit tests: CCAWS - GetAWSSettings * Uber class fix for non-JSON API responses * Updated to support GitHub workflow execution * Working directory fix * Fixed authorization unit test 500 error * Adjusted workflow directory * Added working directory * Changed working directory * Working directory debugging * Debugging workflows * Lessee if this werks... * Reverted linting.yml change * Now there's a test package * Pytest debugging * Trying it another way * Another variation * Fix to reduce flakiness in test_authorization.py * Comment typo * New unit tests for: AWS Accounts APIs * New unit tests, requires updated svc classes * Added coverage to test workflow * GitHub workflow debugging * Workaround for GitHub to CS API rate limiting * Added pytest skips for rate limit barriers * Added pytest skips for rate limit barriers * Added pytest skips for rate limit barriers Co-authored-by: Shawn Wells <[email protected]>
1 parent 85d5782 commit 9cbaed5

19 files changed

+1080
-15
lines changed

.github/workflows/linting.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: Install dependencies
2727
run: |
2828
python -m pip install --upgrade pip
29-
python -m pip install flake8 pytest
29+
python -m pip install flake8 pytest coverage
3030
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
3131
- name: Lint with flake8
3232
run: |
@@ -39,4 +39,5 @@ jobs:
3939
DEBUG_API_ID: ${{ secrets.DEBUG_API_ID }}
4040
DEBUG_API_SECRET: ${{ secrets.DEBUG_API_SECRET }}
4141
run: |
42-
pytest
42+
coverage run --source src -m pytest -s -W ignore::Warning
43+
coverage report

tests/test_cloud_connect_aws.py

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
# A valid CrowdStrike Falcon API key is required to run these tests.
2-
# API client ID & secret should be stored in tests/test.config in JSON format.
3-
# {
4-
# "falcon_client_id": "CLIENT_ID_GOES_HERE",
5-
# "falcon_client_secret": "CLIENT_SECRET_GOES_HERE"
6-
# }
1+
# test_cloud_connect_aws.py
2+
# This class tests the cloud_connect_aws service class
3+
74
import json
85
import os
96
import sys
7+
import pytest
108
# Authentication via the test_authorization.py
119
from tests import test_authorization as Authorization
1210

@@ -15,19 +13,58 @@
1513
# Classes to test - manually imported from sibling folder
1614
from falconpy import cloud_connect_aws as FalconAWS
1715

16+
auth = Authorization.TestAuthorization()
17+
auth.serviceAuth()
18+
falcon = FalconAWS.Cloud_Connect_AWS(access_token=auth.token)
19+
AllowedResponses = [200, 429] #Adding rate-limiting as an allowed response for now
1820

19-
# The TestCloudConnectAWS class tests the cloud_connect_aws service class
2021
class TestCloudConnectAWS:
2122
def serviceCCAWS_GetAWSSettings(self):
22-
auth = Authorization.TestAuthorization()
23-
auth.serviceAuth()
24-
falcon = FalconAWS.Cloud_Connect_AWS(access_token=auth.token)
25-
if falcon.GetAWSSettings()["status_code"] > 0:
26-
auth.serviceRevoke()
23+
if falcon.GetAWSSettings()["status_code"] in AllowedResponses:
2724
return True
2825
else:
29-
auth.serviceRevoke()
3026
return False
3127

28+
def serviceCCAWS_QueryAWSAccounts(self):
29+
if falcon.QueryAWSAccounts()["status_code"] in AllowedResponses:
30+
return True
31+
else:
32+
return False
33+
34+
@pytest.mark.skipif(falcon.QueryAWSAccounts(parameters={"limit":1})["status_code"] == 429, reason="API rate limit reached")
35+
def serviceCCAWS_GetAWSAccounts(self):
36+
if falcon.GetAWSAccounts(ids=falcon.QueryAWSAccounts(parameters={"limit":1})["body"]["resources"][0]["id"])["status_code"] in AllowedResponses:
37+
return True
38+
else:
39+
return False
40+
41+
@pytest.mark.skipif(falcon.QueryAWSAccounts(parameters={"limit":1})["status_code"] == 429, reason="API rate limit reached")
42+
def serviceCCAWS_VerifyAWSAccountAccess(self):
43+
if falcon.VerifyAWSAccountAccess(ids=falcon.QueryAWSAccounts(parameters={"limit":1})["body"]["resources"][0]["id"])["status_code"] in AllowedResponses:
44+
return True
45+
else:
46+
return False
47+
48+
def serviceCCAWS_QueryAWSAccountsForIDs(self):
49+
if falcon.QueryAWSAccountsForIDs(parameters={"limit":1})["status_code"] in AllowedResponses:
50+
return True
51+
else:
52+
return False
53+
3254
def test_GetAWSSettings(self):
3355
assert self.serviceCCAWS_GetAWSSettings() == True
56+
57+
def test_QueryAWSAccounts(self):
58+
assert self.serviceCCAWS_QueryAWSAccounts() == True
59+
60+
def test_GetAWSAccounts(self):
61+
assert self.serviceCCAWS_GetAWSAccounts() == True
62+
63+
def test_VerifyAWSAccountAccess(self):
64+
assert self.serviceCCAWS_VerifyAWSAccountAccess() == True
65+
66+
def test_QueryAWSAccountsForIDs(self):
67+
assert self.serviceCCAWS_QueryAWSAccountsForIDs() == True
68+
69+
def test_logout(self):
70+
assert auth.serviceRevoke() == True

tests/test_detects.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# test_detects.py
2+
# This class tests the detects service class
3+
4+
import json
5+
import os
6+
import sys
7+
import pytest
8+
# Authentication via the test_authorization.py
9+
from tests import test_authorization as Authorization
10+
11+
#Import our sibling src folder into the path
12+
sys.path.append(os.path.abspath('src'))
13+
# Classes to test - manually imported from sibling folder
14+
from falconpy import detects as FalconDetections
15+
16+
auth = Authorization.TestAuthorization()
17+
auth.serviceAuth()
18+
falcon = FalconDetections.Detects(access_token=auth.token)
19+
AllowedResponses = [200, 429] #Adding rate-limiting as an allowed response for now
20+
21+
class TestDetects:
22+
23+
def serviceDetects_QueryDetects(self):
24+
if falcon.QueryDetects(parameters={"limit":1})["status_code"] in AllowedResponses:
25+
return True
26+
else:
27+
return False
28+
29+
@pytest.mark.skipif(falcon.QueryDetects(parameters={"limit":1})["status_code"] == 429, reason="API rate limit reached")
30+
def serviceDetects_GetDetectSummaries(self):
31+
if falcon.GetDetectSummaries(body={"ids":falcon.QueryDetects(parameters={"limit":1})["body"]["resources"]})["status_code"] in AllowedResponses:
32+
return True
33+
else:
34+
return False
35+
36+
# def serviceDetects_GetAggregateDetects(self):
37+
# auth, falcon = self.authenticate()
38+
# if falcon.GetAggregateDetects(body={"ids":falcon.QueryDetects(parameters={"limit":1})["body"]["resources"]})["status_code"] in AllowedResponses:
39+
# auth.serviceRevoke()
40+
# return True
41+
# else:
42+
# auth.serviceRevoke()
43+
# return False
44+
45+
def test_QueryDetects(self):
46+
assert self.serviceDetects_QueryDetects() == True
47+
48+
def test_GetDetectSummaries(self):
49+
assert self.serviceDetects_GetDetectSummaries() == True
50+
51+
# def test_GetAggregateDetects(self):
52+
# assert self.serviceDetects_GetAggregateDetects() == True
53+
54+
def test_logout(self):
55+
assert auth.serviceRevoke() == True
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# test_device_control_poligies.py
2+
# This class tests the device_control_policies service class
3+
4+
import json
5+
import os
6+
import sys
7+
import pytest
8+
# Authentication via the test_authorization.py
9+
from tests import test_authorization as Authorization
10+
11+
#Import our sibling src folder into the path
12+
sys.path.append(os.path.abspath('src'))
13+
# Classes to test - manually imported from sibling folder
14+
from falconpy import device_control_policies as FalconDeviceControlPolicy
15+
16+
auth = Authorization.TestAuthorization()
17+
auth.serviceAuth()
18+
falcon = FalconDeviceControlPolicy.Device_Control_Policies(access_token=auth.token)
19+
AllowedResponses = [200, 429] #Adding rate-limiting as an allowed response for now
20+
21+
class TestDeviceControlPolicy:
22+
23+
def serviceDeviceControlPolicies_queryDeviceControlPolicies(self):
24+
if falcon.queryDeviceControlPolicies(parameters={"limit":1})["status_code"] in AllowedResponses:
25+
return True
26+
else:
27+
return False
28+
29+
@pytest.mark.skipif(falcon.queryDeviceControlPolicies(parameters={"limit":1})["status_code"] == 429, reason="API rate limit reached")
30+
def serviceDeviceControlPolicies_queryDeviceControlPolicyMembers(self):
31+
if falcon.queryDeviceControlPolicyMembers(parameters={"id": falcon.queryDeviceControlPolicies(parameters={"limit":1})["body"]["resources"][0]})["status_code"] in AllowedResponses:
32+
return True
33+
else:
34+
return False
35+
36+
@pytest.mark.skipif(falcon.queryDeviceControlPolicies(parameters={"limit":1})["status_code"] == 429, reason="API rate limit reached")
37+
def serviceDeviceControlPolicies_getDeviceControlPolicies(self):
38+
if falcon.getDeviceControlPolicies(ids=falcon.queryDeviceControlPolicies(parameters={"limit":1})["body"]["resources"][0])["status_code"] in AllowedResponses:
39+
return True
40+
else:
41+
return False
42+
43+
def serviceDeviceControlPolicies_queryCombinedDeviceControlPolicies(self):
44+
if falcon.queryCombinedDeviceControlPolicies(parameters={"limit":1})["status_code"] in AllowedResponses:
45+
return True
46+
else:
47+
return False
48+
49+
@pytest.mark.skipif(falcon.queryCombinedDeviceControlPolicies(parameters={"limit":1})["status_code"] == 429, reason="API rate limit reached")
50+
def serviceDeviceControlPolicies_queryCombinedDeviceControlPolicyMembers(self):
51+
if falcon.queryCombinedDeviceControlPolicyMembers(parameters={"id": falcon.queryCombinedDeviceControlPolicies(parameters={"limit":1})["body"]["resources"][0]["id"]})["status_code"] in AllowedResponses:
52+
return True
53+
else:
54+
return False
55+
56+
def test_queryDeviceControlPolicies(self):
57+
assert self.serviceDeviceControlPolicies_queryDeviceControlPolicies() == True
58+
59+
def test_queryDeviceControlPolicyMembers(self):
60+
assert self.serviceDeviceControlPolicies_queryDeviceControlPolicyMembers() == True
61+
62+
def test_getDeviceControlPolicies(self):
63+
assert self.serviceDeviceControlPolicies_getDeviceControlPolicies() == True
64+
65+
def test_queryCombinedDeviceControlPolicies(self):
66+
assert self.serviceDeviceControlPolicies_queryCombinedDeviceControlPolicies() == True
67+
68+
def test_queryCombinedDeviceControlPolicyMembers(self):
69+
assert self.serviceDeviceControlPolicies_queryCombinedDeviceControlPolicyMembers() == True
70+
71+
def test_logout(self):
72+
assert auth.serviceRevoke() == True

tests/test_event_streams.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# test_event_streams.py
2+
# This class tests the event_streams service class
3+
4+
import json
5+
import os
6+
import sys
7+
import datetime
8+
import requests
9+
import pytest
10+
# Authentication via the test_authorization.py
11+
from tests import test_authorization as Authorization
12+
13+
#Import our sibling src folder into the path
14+
sys.path.append(os.path.abspath('src'))
15+
# Classes to test - manually imported from sibling folder
16+
from falconpy import event_streams as FalconStream
17+
18+
auth = Authorization.TestAuthorization()
19+
auth.serviceAuth()
20+
falcon = FalconStream.Event_Streams(access_token=auth.token)
21+
AllowedResponses = [200, 429] #Adding rate-limiting as an allowed response for now
22+
appId = "pytest-event_streams-unit-test"
23+
class TestEventStreams:
24+
25+
def serviceStream_listAvailableStreamsOAuth2(self):
26+
if falcon.listAvailableStreamsOAuth2(parameters={"appId":appId})["status_code"] in AllowedResponses:
27+
return True
28+
else:
29+
return False
30+
@pytest.mark.skipif(falcon.listAvailableStreamsOAuth2(parameters={"appId":appId})["status_code"] == 429, reason="API rate limit reached")
31+
def serviceStream_refreshActiveStreamSession(self):
32+
avail = falcon.listAvailableStreamsOAuth2(parameters={"appId":appId})
33+
t1 = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S +0000')
34+
headers = {'Authorization': 'Token %s' % (avail["body"]["resources"][0]["sessionToken"]["token"]), 'Date': t1, 'Connection': 'Keep-Alive'}
35+
stream = requests.get(avail["body"]["resources"][0]["dataFeedURL"], headers=headers, stream=True)
36+
with stream:
37+
if falcon.refreshActiveStreamSession(parameters={"appId": appId, "action_name":"refresh_active_stream_session"}, partition=0)["status_code"] in AllowedResponses:
38+
return True
39+
else:
40+
return False
41+
42+
def test_listAvailableStreamsOAuth2(self):
43+
assert self.serviceStream_listAvailableStreamsOAuth2() == True
44+
45+
def test_refreshActiveStreamSession(self):
46+
assert self.serviceStream_refreshActiveStreamSession() == True
47+
48+
def test_logout(self):
49+
assert auth.serviceRevoke() == True

tests/test_falconx_sandbox.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# test_falconx_sandbox.py
2+
# This class tests the falconx_sandbox service class
3+
4+
import json
5+
import os
6+
import sys
7+
import pytest
8+
# Authentication via the test_authorization.py
9+
from tests import test_authorization as Authorization
10+
11+
#Import our sibling src folder into the path
12+
sys.path.append(os.path.abspath('src'))
13+
# Classes to test - manually imported from sibling folder
14+
from falconpy import falconx_sandbox as FalconXSandbox
15+
16+
auth = Authorization.TestAuthorization()
17+
auth.serviceAuth()
18+
falcon = FalconXSandbox.FalconX_Sandbox(access_token=auth.token)
19+
AllowedResponses = [200, 429] #Adding rate-limiting as an allowed response for now
20+
21+
class TestFalconX:
22+
23+
def serviceFalconX_QueryReports(self):
24+
if falcon.QueryReports(parameters={"limit":1})["status_code"] in AllowedResponses:
25+
return True
26+
else:
27+
return False
28+
29+
def serviceFalconX_QuerySubmissions(self):
30+
if falcon.QuerySubmissions(parameters={"limit":1})["status_code"] in AllowedResponses:
31+
return True
32+
else:
33+
return False
34+
35+
@pytest.mark.skipif(falcon.QueryReports(parameters={"limit":1})["status_code"] == 429, reason="API rate limit reached")
36+
def serviceFalconX_GetSummaryReports(self):
37+
if falcon.GetSummaryReports(ids=falcon.QueryReports(parameters={"limit":1})["body"]["resources"])["status_code"] in AllowedResponses:
38+
return True
39+
else:
40+
return False
41+
42+
def test_QueryReports(self):
43+
assert self.serviceFalconX_QueryReports() == True
44+
45+
def test_QuerySubmissions(self):
46+
assert self.serviceFalconX_QuerySubmissions() == True
47+
48+
def test_GetSummaryReports(self):
49+
assert self.serviceFalconX_GetSummaryReports() == True
50+
51+
def test_logout(self):
52+
assert auth.serviceRevoke() == True

tests/test_firewall_management.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# test_firewall_management.py
2+
# This class tests the firewall_management service class
3+
4+
import json
5+
import os
6+
import sys
7+
# Authentication via the test_authorization.py
8+
from tests import test_authorization as Authorization
9+
#Import our sibling src folder into the path
10+
sys.path.append(os.path.abspath('src'))
11+
# Classes to test - manually imported from sibling folder
12+
from falconpy import firewall_management as FalconFirewall
13+
14+
auth = Authorization.TestAuthorization()
15+
auth.serviceAuth()
16+
falcon = FalconFirewall.Firewall_Management(access_token=auth.token)
17+
AllowedResponses = [200, 429] #Adding rate-limiting as an allowed response for now
18+
19+
class TestFirewallManagement:
20+
21+
def serviceFirewall_query_rules(self):
22+
if falcon.query_rules(parameters={"limit":1})["status_code"] in AllowedResponses:
23+
return True
24+
else:
25+
return False
26+
27+
# def test_query_rules(self):
28+
# assert self.serviceFirewall_query_rules() == True
29+
30+
def test_logout(self):
31+
assert auth.serviceRevoke() == True
32+
33+
#TODO: My current API key can't hit this API. Pending additional unit testing for now.

0 commit comments

Comments
 (0)