Skip to content

Commit

Permalink
Merge pull request #7 from colinhoglund/fix_source_trimming
Browse files Browse the repository at this point in the history
BUGFIX: Fix source trimming when source is CWD ('.') and refactor test suite
  • Loading branch information
colinhoglund authored Apr 23, 2018
2 parents 5ecc2f2 + 3e96198 commit d48445c
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 103 deletions.
2 changes: 1 addition & 1 deletion piprepo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = '0.1.0'
__version__ = '0.1.1'
__description__ = 'piprepo creates PEP-503 compliant package repositories.'
5 changes: 1 addition & 4 deletions piprepo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,6 @@ def sync_to_destination(self):

# hidden helper methods
def _put_object(self, filename, content_type):
if self.prefix:
key = self.prefix + filename.split(self.source)[1]
else:
key = self.prefix + filename.split(self.source)[1].lstrip('/')
key = os.path.join(self.prefix, filename[len(self.source):].lstrip('/'))
body = open(filename, 'rb')
self.bucket.put_object(Key=key, Body=body, ContentType=content_type)
Empty file added tests/__init__.py
Empty file.
31 changes: 31 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os
import pytest
import shutil
import tempfile

PACKAGES = [
'Django-1.11.2-py2.py3-none-any.whl',
'ansible-2.0.0.0.tar.gz',
'ansible-2.3.1.0.tar.gz',
'python_http_client-2.2.1-py2.py3-none-any.whl',
'avocado-framework-plugin-varianter-yaml-to-mux-53.0.tar.gz',
'affinitic.recipe.fakezope2eggs-0.3-py2.4.egg',
'foursquare-1!2016.9.12.tar.gz'
]


@pytest.yield_fixture(scope="function")
def tempindex():
temp = tempfile.mkdtemp()
index = {
'packages': PACKAGES,
'source': os.path.join(temp, 'source'),
'destination': os.path.join(temp, 'destination'),
}
os.mkdir(index['source'])
os.mkdir(index['destination'])
for package in index['packages']:
with open(os.path.join(index['source'], package), 'w') as f:
f.write(package)
yield index
shutil.rmtree(temp)
103 changes: 5 additions & 98 deletions tests/test_command.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,13 @@
import boto3
import os
import pytest
import shutil
import sys
import tempfile
from botocore.exceptions import ClientError
from moto import mock_s3
from piprepo import command, models
from piprepo import command
from piprepo.utils import get_project_name_from_file
from .test_s3 import assert_s3_bucket_contents

PACKAGES = [
'Django-1.11.2-py2.py3-none-any.whl',
'ansible-2.0.0.0.tar.gz',
'ansible-2.3.1.0.tar.gz',
'python_http_client-2.2.1-py2.py3-none-any.whl',
'avocado-framework-plugin-varianter-yaml-to-mux-53.0.tar.gz',
'affinitic.recipe.fakezope2eggs-0.3-py2.4.egg',
'foursquare-1!2016.9.12.tar.gz'
]


# Fixtures
@pytest.yield_fixture(scope="function")
def tempindex():
temp = tempfile.mkdtemp()
index = {
'packages': PACKAGES,
'source': os.path.join(temp, 'source'),
'destination': os.path.join(temp, 'destination'),
}
os.mkdir(index['source'])
os.mkdir(index['destination'])
for package in index['packages']:
with open(os.path.join(index['source'], package), 'w') as f:
f.write(package)
yield index
shutil.rmtree(temp)


# Tests
def test_bare_command():
with pytest.raises(SystemExit) as ex:
sys.argv = ['piprepo']
Expand Down Expand Up @@ -77,72 +46,10 @@ def test_dir_sync(tempindex):


@mock_s3
def test_s3_sync_with_prefix(tempindex):
conn = boto3.resource("s3")
bucket = conn.create_bucket(Bucket='fake-piprepo-bucket')
sys.argv = ['', 'sync', tempindex['source'], 's3://{}/piprepo'.format(bucket.name)]
command.main()

for package in tempindex['packages']:
package_obj = conn.Object(bucket.name, os.path.join('piprepo', package))
package_index_obj = conn.Object(
bucket.name, os.path.join('piprepo', 'simple', get_project_name_from_file(package), 'index.html')
)
root_index_obj = conn.Object(bucket.name, os.path.join('piprepo', 'simple', 'index.html'))

assert s3_object_exists(package_obj)
assert s3_object_exists(package_index_obj)
assert s3_object_exists(root_index_obj)
assert get_project_name_from_file(package).encode() in root_index_obj.get()['Body'].read()
assert package.encode() in package_index_obj.get()['Body'].read()


@mock_s3
def test_s3_sync_without_prefix(tempindex):
def test_s3_sync(tempindex):
conn = boto3.resource("s3")
bucket = conn.create_bucket(Bucket='fake-piprepo-bucket')
bucket = conn.create_bucket(Bucket='piprepo')
sys.argv = ['', 'sync', tempindex['source'], 's3://{}'.format(bucket.name)]
command.main()

for package in tempindex['packages']:
package_obj = conn.Object(bucket.name, package)
package_index_obj = conn.Object(
bucket.name, os.path.join('simple', get_project_name_from_file(package), 'index.html')
)
root_index_obj = conn.Object(bucket.name, os.path.join('simple', 'index.html'))

assert s3_object_exists(package_obj)
assert s3_object_exists(package_index_obj)
assert s3_object_exists(root_index_obj)
assert get_project_name_from_file(package).encode() in root_index_obj.get()['Body'].read()
assert package.encode() in package_index_obj.get()['Body'].read()


def test_project_names():
expected = {
'affinitic-recipe-fakezope2eggs',
'ansible',
'avocado-framework-plugin-varianter-yaml-to-mux',
'django',
'foursquare',
'python-http-client'
}

assert {get_project_name_from_file(p) for p in PACKAGES} == expected


def test_skip_invalid_package(tempindex):
index = models.LocalIndex(tempindex['source'], tempindex['destination'])
index._build_packages(['invalidpackage.txt'])
assert index.packages == {}


def s3_object_exists(obj):
try:
obj.load()
except ClientError as e:
if e.response['Error']['Code'] == "404":
return False
else:
raise
return True
assert_s3_bucket_contents(conn, bucket)
68 changes: 68 additions & 0 deletions tests/test_s3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import boto3
import os
from botocore.exceptions import ClientError
from moto import mock_s3
from piprepo.models import S3Index
from piprepo.utils import get_project_name_from_file
from .conftest import PACKAGES


def assert_s3_bucket_contents(conn, bucket, prefix=''):
for package in PACKAGES:
package_obj = conn.Object(bucket.name, os.path.join(prefix, package))
package_index_obj = conn.Object(
bucket.name, os.path.join(prefix, 'simple', get_project_name_from_file(package), 'index.html')
)
root_index_obj = conn.Object(bucket.name, os.path.join(prefix, 'simple', 'index.html'))

assert s3_object_exists(package_obj)
assert s3_object_exists(package_index_obj)
assert s3_object_exists(root_index_obj)
assert get_project_name_from_file(package).encode() in root_index_obj.get()['Body'].read()
assert package.encode() in package_index_obj.get()['Body'].read()


@mock_s3
def assert_s3_sync(source, destination):
conn = boto3.resource("s3")
bucket = conn.create_bucket(Bucket='piprepo')
with S3Index(source, destination) as index:
prefix = index.prefix
assert_s3_bucket_contents(conn, bucket, prefix)


def test_s3_sync_with_prefix(tempindex):
assert_s3_sync(tempindex['source'], 's3://piprepo/prefix')


def test_s3_sync_with_prefix_trailing_slash(tempindex):
assert_s3_sync(tempindex['source'] + '/', 's3://piprepo/prefix/')


def test_s3_sync_with_prefix_from_source_dir(tempindex):
os.chdir(tempindex['source'])
assert_s3_sync('.', 's3://piprepo/prefix')


def test_s3_sync_without_prefix(tempindex):
assert_s3_sync(tempindex['source'], 's3://piprepo')


def test_s3_sync_without_prefix_trailing_slash(tempindex):
assert_s3_sync(tempindex['source'] + '/', 's3://piprepo/')


def test_s3_sync_without_prefix_from_source_dir(tempindex):
os.chdir(tempindex['source'])
assert_s3_sync('.', 's3://piprepo')


def s3_object_exists(obj):
try:
obj.load()
except ClientError as e:
if e.response['Error']['Code'] == "404":
return False
else:
raise
return True
21 changes: 21 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from piprepo import models, utils
from .conftest import PACKAGES


def test_project_names():
expected = {
'affinitic-recipe-fakezope2eggs',
'ansible',
'avocado-framework-plugin-varianter-yaml-to-mux',
'django',
'foursquare',
'python-http-client'
}

assert {utils.get_project_name_from_file(p) for p in PACKAGES} == expected


def test_skip_invalid_package(tempindex):
index = models.LocalIndex(tempindex['source'], tempindex['destination'])
index._build_packages(['invalidpackage.txt'])
assert index.packages == {}

0 comments on commit d48445c

Please sign in to comment.