class BucketTest(unittest.TestCase):
    ##
    ## Name: setUp
    ## Description: Setup fixture for the BucketTest class
    ##
    ## Parameters:
    ## None
    ##
    @patch('Bucket.Bucket.__initData__')
    def setUp(self, mock1):
        mock1.return_value = None

    ##
    ## Name: testSuccess
    ## Description: Test the success leg for the Bucket class
    ##
    ## Parameters:
    ## None
    ##
    @patch('Bucket.Bucket.__listBucketObjects__')
    @patch('Bucket.Bucket.__loadJsonData__')
    def testSuccess(self, mock2, mock1):
        self.bucket = Bucket()
        mock1.return_value = [S3Object()]
        mock2.return_value = json.loads(jsonData)
        self.bucket.append('AWSLogs/210811600188/CloudTrail/us-east-1/2018/03/07')
        df = self.bucket.data()
        self.assertEqual(len(df.index), 1)
        self.assertEqual(df['userName'][0], Bucket.TARGET_USER)
        self.assertEqual(df['eventName'][0], "DescribeInstanceStatus")
        self.assertEqual(df['errorCode'][0], None)
        self.assertEqual(df['errorMessage'][0], None)
        self.assertEqual(df['date'][0], "2018-03-06T23:58:55Z")

    ##
    ## Name: testNotTargetUser
    ## Description: Test the case where it is a log entry not associated with the target user.
    ##
    ## Parameters:
    ## None
    ##
    @patch('Bucket.Bucket.__listBucketObjects__')
    @patch('Bucket.Bucket.__loadJsonData__')
    def testNotTargetUser(self, mock2, mock1):
        self.bucket = Bucket()
        mock1.return_value = [S3Object()]
        mock2.return_value = json.loads(jsonData_not_terget_user)
        self.bucket.append('AWSLogs/210811600188/CloudTrail/us-east-1/2018/03/07')
        df = self.bucket.data()
        self.assertEqual(len(df.index), 0)
def main(argv):
    # Command line argument parsing
    c_args = argparse.ArgumentParser(description='Explore Cloud Trail Logs')
    c_args.add_argument('--region',
                        help='AWS region',
                        default="us-east-1",
                        dest="region",
                        required=False)
    c_args.add_argument('--start',
                        help='Start date in month/day/year format',
                        default=None)
    c_args.add_argument('--end',
                        help='End date in month/day/year format',
                        default=None)
    c_args.add_argument('--format',
                        help='Output format: TEXT | HTML. Case insensitive',
                        default="TEXT",
                        dest="format",
                        required=False)
    cli_args = c_args.parse_args()
    region = cli_args.region
    start = cli_args.start
    end = cli_args.end
    format = cli_args.format

    # Initializations
    formatter = ReportFormatterFactory.create(
        ReportFormatterType.fromString(format))
    bucket = Bucket()

    # Validity checks
    if None == start:
        print "Error: missing parameter - start"
        print cli_args.echo
        exit(-1)

    if not re.match(r'[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}', start):
        print "Error: incorrect date format - start: " + start
        print cli_args.echo
        exit(-1)

    if None == end:
        print "Error: missing parameter - end"
        print cli_args.echo
        exit(-1)

    if not re.match(r'[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}', end):
        print "Error: incorrect date format - end: " + end
        print cli_args.echo
        exit(-1)

    if None == formatter:
        print "Error: invalid format type - format: " + format
        print cli_args.echo
        exit(-1)

    # Main processing loop based on range of dates
    start = datetime.datetime.strptime(start, "%m/%d/%Y")
    end = datetime.datetime.strptime(end, "%m/%d/%Y")
    for date in [
            start + datetime.timedelta(days=x)
            for x in range(0, (end - start).days)
    ]:
        date_arr = "{:%m/%d/%Y}".format(date).split('/')
        if len(date_arr) != 3:
            print "Error: incorrect format - date: " + date
            exit(-1)
        month = int(date_arr[-3])
        day = int(date_arr[-2])
        year = int(date_arr[-1])

        bucket_path = CLOUDTRAIL_BUCKET_PATH_FMT.format(
            region, year, month, day)
        bucket.append(bucket_path)

    # Output report
    df = bucket.data()
    formatter.printHeader()
    formatter.eventSummary(df)
    formatter.errorSummary(df)
    formatter.errorsByDateSummary(df)
    formatter.printTrailer()