Skip to content

Commit

Permalink
Utils fixes + add missing test coverage
Browse files Browse the repository at this point in the history
Make a few changes to utils usage to make them more testable and have
better APIs, and add missing test coverage for this module.

Fix a couple of edge cases with the pretty file size util discovered by
unit tests

Add nosetests and coverage config to simplify build script, and omit
cli.py for now pending issue #13.
  • Loading branch information
giftig committed Oct 20, 2021
1 parent acc55ad commit c1a2b16
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[report]
omit = s3_browser/cli.py
8 changes: 1 addition & 7 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ echo -n "$RESET"

echo ''

nosetests \
--with-coverage \
--cover-package s3_browser \
--cover-inclusive \
--cover-html \
--cover-min-percentage 85 \
--cover-html-dir build/coverage || exit 1
nosetests --with-coverage || exit 1

exit $EXIT_CODE
65 changes: 65 additions & 0 deletions s3_browser/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import datetime
import unittest

from s3_browser import utils


class UtilsTest(unittest.TestCase):
def test_pretty_size(self):
"""Test that the pretty-size util approximates filesizes correctly"""
cases = [
(0, '0 B'),
(233, '233 B'),
(1023, '1023 B'),
(1024, '1 KB'),
(1024 ** 2 - 1, '1 MB'),
(12345678, '12 MB'),
(1024 ** 3 + 100, '1 GB'),
(1024 ** 4 + 1, '1 TB'),
(1024 ** 5 * 2, '2048 TB'),
]

for v, expected in cases:
actual = utils.pretty_size(v)
self.assertEqual(actual, expected)

def test_strip_s3_metadata(self):
"""Test that full s3 metadata is correctly stripped to essentials"""

# Anonymised sample response from a head_object call with boto3
data = {
'ResponseMetadata': {
'RequestId': 'XXXXXXXXXXXXXXXX',
'HostId': 'hhhhhhhhhhhhhhhhhhhhhhhhhh',
'HTTPStatusCode': 200,
'HTTPHeaders': {
'x-amz-id-2': 'ababababababababaabababababab',
'x-amz-request-id': 'XXXXXXXXXXXXXXXX',
'date': 'Wed, 20 Oct 2021 00:00:00 GMT',
'last-modified': 'Fri, 22 May 2021 00:00:00 GMT',
'etag': '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"',
'accept-ranges': 'bytes',
'content-type': 'application/json',
'server': 'AmazonS3',
'content-length': '13337'
},
'RetryAttempts': 0
},
'AcceptRanges': 'bytes',
'LastModified': datetime.datetime(2021, 5, 22, 0, 0, 0),
'ContentLength': 13409,
'ETag': '"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"',
'ContentType': 'application/x-tar',
'Metadata': {}
}

expected = {
'Content-Length': '13 KB (13337 bytes)',
'Content-Type': 'application/json',
'Last-Modified': 'Fri, 22 May 2021 00:00:00 GMT',
'Metadata': {}
}

actual = utils.strip_s3_metadata(data)

self.assertEqual(actual, expected)
18 changes: 9 additions & 9 deletions s3_browser/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ def _format_key(k):
print_dict(v, indent_level=indent_level + 1)


def _pretty_size(n):
"""Convert a size in bytes to a human-readable string"""
if not n:
return None

def pretty_size(n):
"""
Convert a size in bytes to a human-readable string, rounded to nearest
whole number of suitable units (B, KB, MB, GB or TB)
"""
size = int(n)
shortened = None

for suffix in ('B', 'KB', 'MB', 'GB', 'TB'):
if size < 1024:
if size <= 1023 or suffix == 'TB':
shortened = '{} {}'.format(round(size), suffix)
break

Expand All @@ -78,12 +78,12 @@ def _pretty_size(n):


def strip_s3_metadata(data):
"""Strip s3 metadata down to the useful stuff"""
"""Strip s3 head_object metadata down to the useful stuff"""
metadata = data.get('Metadata', {})
http_head = data.get('ResponseMetadata', {}).get('HTTPHeaders', {})

content_length = http_head.get('content-length')
pretty_len = _pretty_size(content_length)
content_length = int(http_head.get('content-length') or 0)
pretty_len = pretty_size(content_length)
if pretty_len:
content_length = '{} ({} bytes)'.format(pretty_len, content_length)

Expand Down
6 changes: 6 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[nosetests]
cover-package=s3_browser
cover-inclusive=1
cover-html=1
cover-min-percentage=75
cover-html-dir=build/coverage

0 comments on commit c1a2b16

Please sign in to comment.