Пример #1
0
    def test_download_file_raise_access_denied_err(self, fake_session):
        """Test that downloading a fails when accessdenied occurs."""
        fake_response = {"Error": {"Code": "AccessDenied"}}
        fake_client = Mock()
        fake_client.get_object.side_effect = ClientError(fake_response, "masu-test")

        downloader = AWSReportDownloader(self.fake_customer_name, self.credentials, self.data_source)
        downloader.s3_client = fake_client

        with self.assertRaises(AWSReportDownloaderNoFileError):
            downloader.download_file(self.fake.file_path())
Пример #2
0
    def test_download_file_raise_nofile_err(self, fake_session):
        """Test that downloading a nonexistent file fails with AWSReportDownloaderNoFileError."""
        fake_response = {"Error": {"Code": "NoSuchKey"}}
        fake_client = Mock()
        fake_client.get_object.side_effect = ClientError(fake_response, "masu-test")

        downloader = AWSReportDownloader(self.fake_customer_name, self.credentials, self.data_source)
        downloader.s3_client = fake_client

        with self.assertRaises(AWSReportDownloaderNoFileError):
            downloader.download_file(self.fake.file_path())
Пример #3
0
    def test_download_file_raise_downloader_err(self, fake_session):
        """Test _check_size fails when there is a downloader error."""
        fake_response = {"Error": {"Code": self.fake.word()}}
        fake_client = Mock()
        fake_client.get_object.side_effect = ClientError(fake_response, "masu-test")

        downloader = AWSReportDownloader(self.fake_customer_name, self.credentials, self.data_source)
        downloader.s3_client = fake_client

        with self.assertRaises(AWSReportDownloaderError):
            downloader.download_file(self.fake.file_path())
Пример #4
0
 def test_download_file(self, fake_session, mock_copy, mock_remove,
                        mock_check_csvs, mock_mark_csvs, mock_check_size):
     """Test the download file method."""
     mock_check_csvs.return_value = False
     mock_check_size.return_value = True
     downloader = AWSReportDownloader(self.fake_customer_name,
                                      self.credentials, self.data_source)
     downloader.download_file(self.fake.file_path(), manifest_id=1)
     mock_check_csvs.assert_called()
     mock_copy.assert_called()
     mock_remove.assert_called()
     mock_mark_csvs.assert_called()
Пример #5
0
    def test_download_file_check_size_fail(self, fake_session, fake_shutil):
        """Test _check_size fails when key is fake."""
        fake_client = Mock()
        fake_client.get_object.return_value = {"ContentLength": 123456, "Body": io.BytesIO(b"\xd2\x02\x96I")}
        fake_shutil.disk_usage.return_value = (10, 10, 1234567)

        downloader = AWSReportDownloader(self.fake_customer_name, self.credentials, self.data_source)
        downloader.s3_client = fake_client

        fakekey = self.fake.file_path(depth=random.randint(1, 5), extension="csv.gz")
        with self.assertRaises(AWSReportDownloaderError):
            downloader.download_file(fakekey)
Пример #6
0
    def test_download_file_raise_nofile_err(self, fake_session):
        fake_response = {'Error': {'Code': 'NoSuchKey'}}
        fake_client = Mock()
        fake_client.get_object.side_effect = ClientError(fake_response, 'masu-test')

        auth_credential = fake_arn(service='iam', generate_account_id=True)
        downloader = AWSReportDownloader(
            self.mock_task, self.fake_customer_name, auth_credential, self.fake_bucket_name
        )
        downloader.s3_client = fake_client

        with self.assertRaises(AWSReportDownloaderNoFileError):
            downloader.download_file(self.fake.file_path())
Пример #7
0
    def test_download_file_raise_nofile_err(self, fake_session):
        """Test that downloading a nonexistent file fails with AWSReportDownloaderNoFileError."""
        fake_response = {"Error": {"Code": "NoSuchKey"}}
        fake_client = Mock()
        fake_client.get_object.side_effect = ClientError(fake_response, "masu-test")

        auth_credential = fake_arn(service="iam", generate_account_id=True)
        downloader = AWSReportDownloader(
            self.mock_task, self.fake_customer_name, auth_credential, self.fake_bucket_name
        )
        downloader.s3_client = fake_client

        with self.assertRaises(AWSReportDownloaderNoFileError):
            downloader.download_file(self.fake.file_path())
Пример #8
0
    def test_download_file_raise_downloader_err(self, fake_session):
        """Test _check_size fails when there is a downloader error."""
        fake_response = {"Error": {"Code": self.fake.word()}}
        fake_client = Mock()
        fake_client.get_object.side_effect = ClientError(fake_response, "masu-test")

        auth_credential = fake_arn(service="iam", generate_account_id=True)
        downloader = AWSReportDownloader(
            self.mock_task, self.fake_customer_name, auth_credential, self.fake_bucket_name
        )
        downloader.s3_client = fake_client

        with self.assertRaises(AWSReportDownloaderError):
            downloader.download_file(self.fake.file_path())
Пример #9
0
    def test_download_file_check_size_fail(self, fake_session, fake_shutil):
        """Test _check_size fails when key is fake."""
        fake_client = Mock()
        fake_client.get_object.return_value = {"ContentLength": 123456, "Body": io.BytesIO(b"\xd2\x02\x96I")}
        fake_shutil.disk_usage.return_value = (10, 10, 1234567)

        auth_credential = fake_arn(service="iam", generate_account_id=True)
        downloader = AWSReportDownloader(
            self.mock_task, self.fake_customer_name, auth_credential, self.fake_bucket_name
        )
        downloader.s3_client = fake_client

        fakekey = self.fake.file_path(depth=random.randint(1, 5), extension="csv.gz")
        with self.assertRaises(AWSReportDownloaderError):
            downloader.download_file(fakekey)
Пример #10
0
    def test_download_file_check_size_fail(self, fake_session, fake_shutil):
        fake_client = Mock()
        fake_client.get_object.return_value = {
            'ContentLength': 123456,
            'Body': io.BytesIO(b'\xd2\x02\x96I')
        }
        fake_shutil.disk_usage.return_value = (10, 10, 1234567)

        auth_credential = fake_arn(service='iam', generate_account_id=True)
        downloader = AWSReportDownloader(self.fake_customer_name,
                                         auth_credential,
                                         self.fake_bucket_name)
        downloader.s3_client = fake_client

        fakekey = self.fake.file_path(depth=random.randint(1, 5),
                                      extension='csv.gz')
        with self.assertRaises(AWSReportDownloaderError):
            downloader.download_file(fakekey)
Пример #11
0
class AWSReportDownloaderTest(MasuTestCase):
    """Test Cases for the AWS S3 functions."""

    fake = Faker()

    @patch('masu.external.downloader.aws.utils.get_assume_role_session',
           return_value=FakeSession)
    def setUp(self, fake_session):
        os.makedirs(DATA_DIR, exist_ok=True)

        self.fake_customer_name = CUSTOMER_NAME
        self.fake_report_name = REPORT
        self.fake_bucket_name = BUCKET
        self.fake_bucket_prefix = PREFIX
        self.selected_region = REGION

        auth_credential = fake_arn(service='iam', generate_account_id=True)

        self.report_downloader = AWSReportDownloader(
            **{
                'customer_name': self.fake_customer_name,
                'auth_credential': auth_credential,
                'bucket': self.fake_bucket_name,
                'report_name': self.fake_report_name
            })

    def tearDown(self):
        shutil.rmtree(DATA_DIR, ignore_errors=True)

    @mock_s3
    def test_download_bucket(self):
        fake_report_date = datetime.today().replace(day=1)
        fake_report_end_date = fake_report_date + relativedelta(months=+1)
        report_range = '{}-{}'.format(fake_report_date.strftime('%Y%m%d'),
                                      fake_report_end_date.strftime('%Y%m%d'))

        # Moto setup
        conn = boto3.resource('s3', region_name=self.selected_region)
        conn.create_bucket(Bucket=self.fake_bucket_name)

        # push mocked csvs into Moto env
        fake_csv_files = []
        fake_csv_files_with_key = {}
        for x in range(0, random.randint(2, 10)):
            csv_filename = '{}.csv'.format('-'.join(
                self.fake.words(random.randint(2, 5))))
            fake_csv_files.append(csv_filename)

            # mocked report file definition
            fake_report_file = '{}/{}/{}/{}/{}'.format(self.fake_bucket_prefix,
                                                       self.fake_report_name,
                                                       report_range,
                                                       uuid.uuid4(),
                                                       csv_filename)
            fake_csv_files_with_key[csv_filename] = fake_report_file
            fake_csv_body = ','.join(self.fake.words(random.randint(5, 10)))
            conn.Object(self.fake_bucket_name,
                        fake_report_file).put(Body=fake_csv_body)
            key = conn.Object(self.fake_bucket_name, fake_report_file).get()
            self.assertEqual(fake_csv_body, str(key['Body'].read(), 'utf-8'))

        # mocked Manifest definition
        fake_object = '{}/{}/{}/{}-Manifest.json'.format(
            self.fake_bucket_prefix, self.fake_report_name, report_range,
            self.fake_report_name)
        fake_object_body = {'reportKeys': fake_csv_files}

        # push mocked manifest into Moto env
        conn.Object(self.fake_bucket_name,
                    fake_object).put(Body=json.dumps(fake_object_body))
        key = conn.Object(self.fake_bucket_name, fake_object).get()
        self.assertEqual(fake_object_body, json.load(key['Body']))

        # actual test
        out = self.report_downloader.download_bucket()
        expected_files = []
        for csv_filename in fake_csv_files:
            report_key = fake_csv_files_with_key.get(csv_filename)
            expected_assembly_id = utils.get_assembly_id_from_cur_key(
                report_key)
            expected_csv = '{}/{}/aws/{}/{}-{}'.format(DATA_DIR,
                                                       self.fake_customer_name,
                                                       self.fake_bucket_name,
                                                       expected_assembly_id,
                                                       csv_filename)
            expected_files.append(expected_csv)
        expected_manifest = '{}/{}/aws/{}/{}-Manifest.json'.format(
            DATA_DIR, self.fake_customer_name, self.fake_bucket_name,
            self.fake_report_name)
        expected_files.append(expected_manifest)
        self.assertEqual(sorted(out), sorted(expected_files))

    @mock_s3
    def test_download_current_report(self):
        fake_report_date = datetime.today().replace(day=1)
        fake_report_end_date = fake_report_date + relativedelta(months=+1)
        report_range = '{}-{}'.format(fake_report_date.strftime('%Y%m%d'),
                                      fake_report_end_date.strftime('%Y%m%d'))

        # Moto setup
        conn = boto3.resource('s3', region_name=self.selected_region)
        conn.create_bucket(Bucket=self.fake_bucket_name)

        # push mocked csvs into Moto env
        fake_csv_files = {}
        for x in range(0, random.randint(2, 10)):
            csv_filename = '{}.csv'.format('-'.join(
                self.fake.words(random.randint(2, 5))))

            # mocked report file definition
            fake_report_file = '{}/{}/{}/{}/{}'.format(self.fake_bucket_prefix,
                                                       self.fake_report_name,
                                                       report_range,
                                                       uuid.uuid4(),
                                                       csv_filename)
            fake_csv_files[csv_filename] = fake_report_file

            fake_csv_body = ','.join(self.fake.words(random.randint(5, 10)))
            conn.Object(self.fake_bucket_name,
                        fake_report_file).put(Body=fake_csv_body)
            key = conn.Object(self.fake_bucket_name, fake_report_file).get()
            self.assertEqual(fake_csv_body, str(key['Body'].read(), 'utf-8'))

        # mocked Manifest definition
        selected_csv = random.choice(list(fake_csv_files.keys()))
        fake_object = '{}/{}/{}/{}-Manifest.json'.format(
            self.fake_bucket_prefix, self.fake_report_name, report_range,
            self.fake_report_name)
        fake_object_body = {'reportKeys': [fake_csv_files[selected_csv]]}

        # push mocked manifest into Moto env
        conn.Object(self.fake_bucket_name,
                    fake_object).put(Body=json.dumps(fake_object_body))
        key = conn.Object(self.fake_bucket_name, fake_object).get()
        self.assertEqual(fake_object_body, json.load(key['Body']))

        # actual test
        out = self.report_downloader.download_current_report()
        files_list = []
        for cur_dict in out:
            files_list.append(cur_dict['file'])
            self.assertIsNotNone(cur_dict['compression'])

        report_key = fake_object_body.get('reportKeys').pop()
        expected_assembly_id = utils.get_assembly_id_from_cur_key(report_key)
        expected_csv = '{}/{}/aws/{}/{}-{}'.format(DATA_DIR,
                                                   self.fake_customer_name,
                                                   self.fake_bucket_name,
                                                   expected_assembly_id,
                                                   selected_csv)
        self.assertEqual(files_list, [expected_csv])

        # Verify etag is stored
        for cur_dict in out:
            cur_file = cur_dict['file']
            file_name = cur_file.split('/')[-1]
            stats_recorder = ReportStatsDBAccessor(file_name)
            self.assertIsNotNone(stats_recorder.get_etag())

            # Cleanup
            stats_recorder.remove()
            stats_recorder.commit()

            stats_recorder2 = ReportStatsDBAccessor(file_name)
            self.assertIsNone(stats_recorder2.get_etag())
            stats_recorder.close_session()
            stats_recorder2.close_session()

    @mock_s3
    def test_download_file(self):
        fake_object = self.fake.word().lower()
        conn = boto3.resource('s3', region_name=self.selected_region)
        conn.create_bucket(Bucket=self.fake_bucket_name)
        conn.Object(self.fake_bucket_name, fake_object).put(Body='test')

        out, _ = self.report_downloader.download_file(fake_object)
        self.assertEqual(
            out, DATA_DIR + '/' + self.fake_customer_name + '/aws/' +
            self.fake_bucket_name + '/' + fake_object)

    @mock_s3
    def test_download_file_missing_key(self):
        fake_object = self.fake.word().lower()
        conn = boto3.resource('s3', region_name=self.selected_region)
        conn.create_bucket(Bucket=self.fake_bucket_name)
        conn.Object(self.fake_bucket_name, fake_object).put(Body='test')

        missing_key = 'missing' + fake_object
        with self.assertRaises(AWSReportDownloaderError) as error:
            self.report_downloader.download_file(missing_key)
        expected_err = 'Unable to find {} in S3 Bucket: {}'.format(
            missing_key, self.fake_bucket_name)
        self.assertEqual(expected_err, str(error.exception))

    @mock_s3
    def test_download_file_other_error(self):
        fake_object = self.fake.word().lower()
        # No S3 bucket created
        with self.assertRaises(AWSReportDownloaderError) as error:
            self.report_downloader.download_file(fake_object)
        self.assertTrue('NoSuchBucket' in str(error.exception))

    @mock_s3
    def test_download_report(self):
        fake_report_date = self.fake.date_time().replace(day=1)
        fake_report_end_date = fake_report_date + relativedelta(months=+1)
        report_range = '{}-{}'.format(fake_report_date.strftime('%Y%m%d'),
                                      fake_report_end_date.strftime('%Y%m%d'))

        # mocked report file definition
        fake_report_file = '{}/{}/{}/{}/{}.csv'.format(self.fake_bucket_prefix,
                                                       self.fake_report_name,
                                                       report_range,
                                                       uuid.uuid4(),
                                                       'mocked-report-file')

        fake_report_file2 = '{}/{}/{}/{}/{}.csv'.format(
            self.fake_bucket_prefix, self.fake_report_name, report_range,
            uuid.uuid4(), 'mocked-report-file2')

        # mocked Manifest definition
        fake_object = '{}/{}/{}/{}-Manifest.json'.format(
            self.fake_bucket_prefix, self.fake_report_name, report_range,
            self.fake_report_name)
        fake_object_body = {
            'reportKeys': [fake_report_file, fake_report_file2]
        }

        # Moto setup
        conn = boto3.resource('s3', region_name=self.selected_region)
        conn.create_bucket(Bucket=self.fake_bucket_name)

        # push mocked manifest into Moto env
        conn.Object(self.fake_bucket_name,
                    fake_object).put(Body=json.dumps(fake_object_body))
        key = conn.Object(self.fake_bucket_name, fake_object).get()
        self.assertEqual(fake_object_body, json.load(key['Body']))

        # push mocked csv into Moto env
        fake_csv_body = ','.join(self.fake.words(random.randint(5, 10)))
        conn.Object(self.fake_bucket_name,
                    fake_report_file).put(Body=fake_csv_body)
        conn.Object(self.fake_bucket_name,
                    fake_report_file2).put(Body=fake_csv_body)
        key = conn.Object(self.fake_bucket_name, fake_report_file).get()
        self.assertEqual(fake_csv_body, str(key['Body'].read(), 'utf-8'))

        # actual test. Run twice
        for _ in range(2):
            out = self.report_downloader.download_report(fake_report_date)
            files_list = []
            for cur_dict in out:
                files_list.append(cur_dict['file'])
                self.assertIsNotNone(cur_dict['compression'])

            expected_paths = []
            for report_key in fake_object_body.get('reportKeys'):
                expected_assembly_id = utils.get_assembly_id_from_cur_key(
                    report_key)

                expected_path_base = '{}/{}/{}/{}/{}-{}'
                file_name = os.path.basename(report_key)
                expected_path = expected_path_base.format(
                    DATA_DIR, self.fake_customer_name, 'aws',
                    self.fake_bucket_name, expected_assembly_id, file_name)
                expected_paths.append(expected_path)
            self.assertEqual(files_list, expected_paths)

    @mock_s3
    @patch('masu.external.downloader.aws.utils.get_assume_role_session',
           return_value=FakeSession)
    def test_missing_report_name(self, fake_session):
        """Test downloading a report with an invalid report name."""
        auth_credential = fake_arn(service='iam', generate_account_id=True)

        with self.assertRaises(MasuProviderError):
            AWSReportDownloader(self.fake_customer_name, auth_credential,
                                's3_bucket', 'wrongreport')

    @mock_s3
    @patch('masu.external.downloader.aws.utils.get_assume_role_session',
           return_value=FakeSession)
    def test_download_default_report(self, fake_session):
        fake_report_date = self.fake.date_time().replace(day=1)
        fake_report_end_date = fake_report_date + relativedelta(months=+1)
        report_range = '{}-{}'.format(fake_report_date.strftime('%Y%m%d'),
                                      fake_report_end_date.strftime('%Y%m%d'))

        # mocked report file definition
        fake_report_file = '{}/{}/{}/{}/{}.csv'.format(self.fake_bucket_prefix,
                                                       self.fake_report_name,
                                                       report_range,
                                                       uuid.uuid4(),
                                                       'mocked-report-file')

        # mocked Manifest definition
        fake_object = '{}/{}/{}/{}-Manifest.json'.format(
            self.fake_bucket_prefix, self.fake_report_name, report_range,
            self.fake_report_name)
        fake_object_body = {'reportKeys': [fake_report_file]}

        # Moto setup
        conn = boto3.resource('s3', region_name=self.selected_region)
        conn.create_bucket(Bucket=self.fake_bucket_name)

        # push mocked manifest into Moto env
        conn.Object(self.fake_bucket_name,
                    fake_object).put(Body=json.dumps(fake_object_body))
        key = conn.Object(self.fake_bucket_name, fake_object).get()
        self.assertEqual(fake_object_body, json.load(key['Body']))

        # push mocked csv into Moto env
        fake_csv_body = ','.join(self.fake.words(random.randint(5, 10)))
        conn.Object(self.fake_bucket_name,
                    fake_report_file).put(Body=fake_csv_body)
        key = conn.Object(self.fake_bucket_name, fake_report_file).get()
        self.assertEqual(fake_csv_body, str(key['Body'].read(), 'utf-8'))

        # actual test
        auth_credential = fake_arn(service='iam', generate_account_id=True)
        downloader = AWSReportDownloader(self.fake_customer_name,
                                         auth_credential,
                                         self.fake_bucket_name)
        self.assertEqual(downloader.report_name, self.fake_report_name)

    @mock_s3
    @patch('masu.external.downloader.aws.utils.get_assume_role_session',
           return_value=FakeSessionNoReport)
    @patch('masu.external.downloader.aws.utils.get_cur_report_definitions',
           return_value=[])
    def test_download_default_report_no_report_found(self, fake_session,
                                                     fake_report_list):
        auth_credential = fake_arn(service='iam', generate_account_id=True)

        with self.assertRaises(MasuProviderError):
            AWSReportDownloader(self.fake_customer_name, auth_credential,
                                self.fake_bucket_name)