-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON Templates Tests, S3 Events Support, and Moar Unit Tests #188
Conversation
* modularize tf generate methods * fix bug in main.tf region loading * coverage for tf_generate methods
33310b6
to
3e03747
Compare
nit - typo: moar --> more 🤣 |
wow it's not a typo @ryandeivert |
Related: #176 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great additions overall! Much needed stuff in here. A few comments in line.
} | ||
# doing this because after kinesis_data is read in, types are casted per the schema | ||
for alert in alerts: | ||
assert_equal(set(alert['record'].keys()), set(kinesis_data.keys())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import and use assert_list_equal
here instead of casting to set
. Not essential, but makes what is being tested more clear and avoid casting
def test_load_config_invalid(): | ||
"""Config Validator - Load Config - Invalid""" | ||
m = mock_open() | ||
with patch('__builtin__.open', m, create=True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏 👏 👏 👏 👏 👏 👏 👏 👏 👏 👏 🎬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should remove the argument to load_config
(it was originally added for tests)
"""Test class for the Terraform Cluster Generating""" | ||
|
||
@classmethod | ||
def setup_class(cls): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setup_class
and teardown_class
class are not actually required for nose
to pick up a class and process tests within it. In fact teardown_class
only gets called if setup_class
is present, but if there is nothing in either they should be omitted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
stream_alert_cli/helpers.py
Outdated
return False | ||
try: | ||
subprocess.check_call(runner_args, stdout=stdout_option, cwd=cwd) | ||
except subprocess.CalledProcessError as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change var name e
here to something... not one character long
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🆗
stream_alert_cli/helpers.py
Outdated
cwd (string): A path to execute commands from | ||
error_message (string): Message to show if command fails | ||
quiet (boolean): Whether to show command output or hide it | ||
def run_command(cls, runner_args, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cls
should be removed with refactor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
} | ||
} | ||
|
||
def teardown(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again not necessary
|
||
def test_generate_stream_alert(self): | ||
"""CLI - Terraform Generate stream_alert Module""" | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where's the test bruh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a TODO
|
||
def test_generate_cluster_advanced(self): | ||
"""CLI - Terraform Generate 'Advanced' Cluster""" | ||
config = self.config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by reassigning to config
here, you're essentially just creating a pointer to the self.config
object anyway. omit this and just pass config=self.config
in the generate_cluster
call. the self.config
is re-created in setup
with each new method test anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah it was just left in after a replace, I know how pointers work ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JUST CHECKIN
def test_generate_main(self): | ||
"""CLI - Terraform Generate Main""" | ||
init = False | ||
config = self.config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
def test_generate_cluster_test(self): | ||
"""CLI - Terraform Generate 'Test' Cluster""" | ||
config = self.config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import base64 | ||
import json | ||
|
||
from nose.tools import assert_equal, assert_not_equal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_not_equal
is unused here
'id': 'test', | ||
'modules': { | ||
'cloudwatch_monitoring': { | ||
'enabled': True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird indentation on this line.
'id': 'advanced', | ||
'modules': { | ||
'cloudwatch_monitoring': { | ||
'enabled': True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another weird indentation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0_0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not weird, it's alt-proper
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alt facts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more comments
default_error_message = "An error occurred while running: {}".format( | ||
' '.join(runner_args) | ||
) | ||
error_message = kwargs.get('error_message', default_error_message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like error_message
is unused :hmm:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this little fella is still hangin around
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's being used now.. check below
stream_alert_cli/helpers.py
Outdated
|
||
elif service == 'kinesis': | ||
if compress: | ||
kinesis_data = base64.b64encode(zlib.compress(data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zlib
import is missing here
|
||
if service == 's3': | ||
# Set the S3 object key to a random value for testing | ||
test_record['key'] = ('{:032X}'.format(random.randrange(16**32))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import random
is missing after migrating this function to helpers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting, when testing it locally, it must have never made it into this if
body
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually just checked to see why this passed integration tests - none of the rules
we have in the integration tests are configured with "service": "s3"
. There are also none from kinesis configured to use compress
, so that's also why that's not failing.
We should either add more encompassing integration tests or we should (need to) add cli unit tests that would have caught this.
@@ -306,77 +305,6 @@ def test_rule(rule_name, test_record, formatted_record): | |||
|
|||
return alerts, expected_alert_count | |||
|
|||
@staticmethod |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember to remove zlib
and random
from imports in this file now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to pylint the whole cli module
|
||
account = config['global']['account'] | ||
prefix = account['prefix'] | ||
logging_bucket = '{}.streamalert.s3-logging'.format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefix
, logging_bucket
, & account_id
are unused variables
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
""" | ||
logging_bucket = '{}.streamalert.s3-logging'.format( | ||
config['global']['account']['prefix']) | ||
firehose_suffix = config['clusters'][cluster_name]['modules']['kinesis']['firehose']['s3_bucket_suffix'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
V long line. make this something like:
firehose_suffix = config['clusters'][cluster_name]['modules'] \
['kinesis']['firehose']['s3_bucket_suffix']
There are a few others like this pylint picks up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conf_logs.write('test logs string that will throw an error') | ||
with open('conf/sources.json', 'w') as conf_sources: | ||
conf_sources.write('test sources string that will throw an error') | ||
config = load_config() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can just call the load_config
here and not assign to variable since it's unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point
PTAL @ryandeivert |
stream_alert_cli/helpers.py
Outdated
except subprocess.CalledProcessError as e: | ||
LOGGER_CLI.error('Return Code %s - %s', e.returncode, e.cmd) | ||
except subprocess.CalledProcessError as err: | ||
LOGGER_CLI.error('%s\n%s', error_message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are there two %s
format strings in this logging message but only one arg?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nm looks like this got changed in the next commit.
stream_alert_cli/helpers.py
Outdated
kms_client = boto3.client('kms', region_name=region) | ||
response = kms_client.encrypt(KeyId=alias, | ||
Plaintext=data) | ||
|
||
return response['CiphertextBlob'] | ||
|
||
|
||
def _make_lambda_package(): | ||
def make_lambda_package(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one isn't used outside of this helper file (not imported elsewhere) and could be kept private. It's only used by the create_lambda_function
function.
default_error_message = "An error occurred while running: {}".format( | ||
' '.join(runner_args) | ||
) | ||
error_message = kwargs.get('error_message', default_error_message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this little fella is still hangin around
@jacknagz some comments |
aba4870
to
32326a4
Compare
again, PTAL @ryandeivert |
to @ryandeivert
cc @airbnb/streamalert-maintainers
Changes
format_lambda_test_record
into thecli.helpers
package: This is an effort to share this method across tests (for main/handler, which will come soon). I also removed the nesting of helper methods within aCLIHelpers
class since that paradigm wasn't being adopted.config
module.