Add tests for image sharing

This commit is contained in:
Joseph Schorr 2014-02-18 16:46:10 -05:00
parent 46de02a9ec
commit a897fb1dd3
14 changed files with 18558 additions and 18370 deletions

View file

@ -884,7 +884,7 @@ def create_repository(namespace, name, creating_user, visibility='private'):
return repo
def create_or_link_image(docker_image_id, repository, username, create=True):
def create_or_link_image(docker_image_id, repository, username):
with transaction_factory(db):
query = (ImageStorage
.select()

View file

@ -250,6 +250,10 @@ def populate_database():
new_user_3.verified = True
new_user_3.save()
new_user_4 = model.create_user('randomuser', 'password', 'no4@thanks.com')
new_user_4.verified = True
new_user_4.save()
reader = model.create_user('reader', 'password', 'no1@thanks.com')
reader.verified = True
reader.save()
@ -258,6 +262,9 @@ def populate_database():
outside_org.verified = True
outside_org.save()
__generate_repository(new_user_4, 'randomrepo', 'Random repo repository.', False,
[], (4, [], ['latest', 'prod']))
__generate_repository(new_user_1, 'simple', 'Simple repository.', False,
[], (4, [], ['latest', 'prod']))
@ -283,6 +290,11 @@ def populate_database():
'Public repository pullable by the world.', True,
[], (10, [], 'latest'))
__generate_repository(outside_org, 'coolrepo',
'Some cool repo.', False,
[],
(5, [], 'latest'))
__generate_repository(new_user_1, 'shared',
'Shared repository, another user can write.', False,
[(new_user_2, 'write'), (reader, 'read')],
@ -315,6 +327,11 @@ def populate_database():
[(outside_org, 'read')],
(4, [], ['latest', 'prod']))
org_repo2 = __generate_repository(org, 'anotherorgrepo',
'Another repository owned by an org.', False,
[],
(4, [], ['latest', 'prod']))
reader_team = model.create_team('readers', org, 'member',
'Readers of orgrepo.')
model.set_team_repo_permission(reader_team.name, org_repo.namespace,

View file

@ -1,5 +1,7 @@
{
"removed": [],
"added": [],
"added": [
"/elasticsearch-0.90.5.tar.gz"
],
"changed": []
}

View file

@ -1,7 +1,8 @@
{
"removed": [],
"added": [
"/elasticsearch-0.90.5.tar.gz"
"/root/.bash_history",
"/usr/sbin/policy-rc.d"
],
"changed": []
}

View file

@ -1,45 +1,5 @@
{
"removed": [],
"added": [
"/opt/elasticsearch-0.90.5/LICENSE.txt",
"/opt/elasticsearch-0.90.5/NOTICE.txt",
"/opt/elasticsearch-0.90.5/README.textile",
"/opt/elasticsearch-0.90.5/bin/elasticsearch",
"/opt/elasticsearch-0.90.5/bin/elasticsearch.in.sh",
"/opt/elasticsearch-0.90.5/bin/plugin",
"/opt/elasticsearch-0.90.5/config/elasticsearch.yml",
"/opt/elasticsearch-0.90.5/config/logging.yml",
"/opt/elasticsearch-0.90.5/lib/elasticsearch-0.90.5.jar",
"/opt/elasticsearch-0.90.5/lib/jna-3.3.0.jar",
"/opt/elasticsearch-0.90.5/lib/jts-1.12.jar",
"/opt/elasticsearch-0.90.5/lib/log4j-1.2.17.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-analyzers-common-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-codecs-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-core-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-grouping-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-highlighter-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-join-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-memory-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-misc-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-queries-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-queryparser-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-sandbox-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-spatial-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-suggest-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-amd64-freebsd-6.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-amd64-linux.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-amd64-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-ia64-linux.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-sparc-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-sparc64-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-universal-macosx.dylib",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-universal64-macosx.dylib",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-freebsd-5.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-freebsd-6.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-linux.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/sigar-1.6.4.jar",
"/opt/elasticsearch-0.90.5/lib/spatial4j-0.3.jar"
],
"added": [],
"changed": []
}

View file

@ -1,8 +1,85 @@
{
"removed": [],
"removed": [
"/opt/elasticsearch-0.90.5/LICENSE.txt",
"/opt/elasticsearch-0.90.5/NOTICE.txt",
"/opt/elasticsearch-0.90.5/README.textile",
"/opt/elasticsearch-0.90.5/bin/elasticsearch",
"/opt/elasticsearch-0.90.5/bin/elasticsearch.in.sh",
"/opt/elasticsearch-0.90.5/bin/plugin",
"/opt/elasticsearch-0.90.5/config/elasticsearch.yml",
"/opt/elasticsearch-0.90.5/config/logging.yml",
"/opt/elasticsearch-0.90.5/lib/elasticsearch-0.90.5.jar",
"/opt/elasticsearch-0.90.5/lib/jna-3.3.0.jar",
"/opt/elasticsearch-0.90.5/lib/jts-1.12.jar",
"/opt/elasticsearch-0.90.5/lib/log4j-1.2.17.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-analyzers-common-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-codecs-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-core-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-grouping-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-highlighter-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-join-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-memory-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-misc-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-queries-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-queryparser-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-sandbox-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-spatial-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/lucene-suggest-4.4.0.jar",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-amd64-freebsd-6.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-amd64-linux.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-amd64-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-ia64-linux.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-sparc-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-sparc64-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-universal-macosx.dylib",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-universal64-macosx.dylib",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-freebsd-5.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-freebsd-6.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-linux.so",
"/opt/elasticsearch-0.90.5/lib/sigar/libsigar-x86-solaris.so",
"/opt/elasticsearch-0.90.5/lib/sigar/sigar-1.6.4.jar",
"/opt/elasticsearch-0.90.5/lib/spatial4j-0.3.jar"
],
"added": [
"/root/.bash_history",
"/usr/sbin/policy-rc.d"
"/opt/elasticsearch/LICENSE.txt",
"/opt/elasticsearch/NOTICE.txt",
"/opt/elasticsearch/README.textile",
"/opt/elasticsearch/bin/elasticsearch",
"/opt/elasticsearch/bin/elasticsearch.in.sh",
"/opt/elasticsearch/bin/plugin",
"/opt/elasticsearch/config/elasticsearch.yml",
"/opt/elasticsearch/config/logging.yml",
"/opt/elasticsearch/lib/elasticsearch-0.90.5.jar",
"/opt/elasticsearch/lib/jna-3.3.0.jar",
"/opt/elasticsearch/lib/jts-1.12.jar",
"/opt/elasticsearch/lib/log4j-1.2.17.jar",
"/opt/elasticsearch/lib/lucene-analyzers-common-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-codecs-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-core-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-grouping-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-highlighter-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-join-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-memory-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-misc-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-queries-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-queryparser-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-sandbox-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-spatial-4.4.0.jar",
"/opt/elasticsearch/lib/lucene-suggest-4.4.0.jar",
"/opt/elasticsearch/lib/sigar/libsigar-amd64-freebsd-6.so",
"/opt/elasticsearch/lib/sigar/libsigar-amd64-linux.so",
"/opt/elasticsearch/lib/sigar/libsigar-amd64-solaris.so",
"/opt/elasticsearch/lib/sigar/libsigar-ia64-linux.so",
"/opt/elasticsearch/lib/sigar/libsigar-sparc-solaris.so",
"/opt/elasticsearch/lib/sigar/libsigar-sparc64-solaris.so",
"/opt/elasticsearch/lib/sigar/libsigar-universal-macosx.dylib",
"/opt/elasticsearch/lib/sigar/libsigar-universal64-macosx.dylib",
"/opt/elasticsearch/lib/sigar/libsigar-x86-freebsd-5.so",
"/opt/elasticsearch/lib/sigar/libsigar-x86-freebsd-6.so",
"/opt/elasticsearch/lib/sigar/libsigar-x86-linux.so",
"/opt/elasticsearch/lib/sigar/libsigar-x86-solaris.so",
"/opt/elasticsearch/lib/sigar/sigar-1.6.4.jar",
"/opt/elasticsearch/lib/spatial4j-0.3.jar"
],
"changed": []
}

Binary file not shown.

204
test/test_image_sharing.py Normal file
View file

@ -0,0 +1,204 @@
import unittest
import json as py_json
from flask import url_for
from endpoints.api import api
from app import app
from initdb import setup_database_for_testing, finished_database_for_testing
from data import model
NO_ACCESS_USER = 'freshuser'
READ_ACCESS_USER = 'reader'
ADMIN_ACCESS_USER = 'devtable'
PUBLIC_USER = 'public'
RANDOM_USER = 'randomuser'
OUTSIDE_ORG_USER = 'outsideorg'
ADMIN_ROBOT_USER = 'devtable+dtrobot'
ORGANIZATION = 'buynlarge'
REPO = 'devtable/simple'
PUBLIC_REPO = 'public/publicrepo'
RANDOM_REPO = 'randomuser/randomrepo'
OUTSIDE_ORG_REPO = 'outsideorg/coolrepo'
ORG_REPO = 'buynlarge/orgrepo'
ANOTHER_ORG_REPO = 'buynlarge/anotherorgrepo'
# Note: The shared repo has devtable as admin, public as a writer and reader as a reader.
SHARED_REPO = 'devtable/shared'
class TestImageSharing(unittest.TestCase):
def setUp(self):
setup_database_for_testing(self)
self.app = app.test_client()
self.ctx = app.test_request_context()
self.ctx.__enter__()
def tearDown(self):
finished_database_for_testing(self)
self.ctx.__exit__(True, None, None)
def createStorage(self, docker_image_id, repository=REPO, username=ADMIN_ACCESS_USER):
repository_obj = model.get_repository(repository.split('/')[0], repository.split('/')[1])
image = model.create_or_link_image(docker_image_id, repository_obj, username)
return image.storage.id
def assertSameStorage(self, docker_image_id, storage_id, repository=REPO, username=ADMIN_ACCESS_USER):
new_storage_id = self.createStorage(docker_image_id, repository, username)
self.assertEquals(storage_id, new_storage_id)
def assertDifferentStorage(self, docker_image_id, storage_id, repository=REPO, username=ADMIN_ACCESS_USER):
new_storage_id = self.createStorage(docker_image_id, repository, username)
self.assertNotEquals(storage_id, new_storage_id)
def test_same_user(self):
""" The same user creates two images, each which should be shared in the same repo. This is a sanity check. """
# Create a reference to a new docker ID => new image.
first_storage_id = self.createStorage('first-image')
# Create a reference to the same docker ID => same image.
self.assertSameStorage('first-image', first_storage_id)
# Create a reference to another new docker ID => new image.
second_storage_id = self.createStorage('second-image')
# Create a reference to that same docker ID => same image.
self.assertSameStorage('second-image', second_storage_id)
# Make sure the images are different.
self.assertNotEquals(first_storage_id, second_storage_id)
def test_no_user_private_repo(self):
""" If no user is specified (token case usually), then no sharing can occur on a private repo. """
# Create a reference to a new docker ID => new image.
first_storage_id = self.createStorage('the-image', username=None, repository=SHARED_REPO)
# Create a areference to the same docker ID, but since no username => new image.
self.assertDifferentStorage('the-image', first_storage_id, username=None, repository=RANDOM_REPO)
def test_no_user_public_repo(self):
""" If no user is specified (token case usually), then no sharing can occur on a private repo except when the image is first public. """
# Create a reference to a new docker ID => new image.
first_storage_id = self.createStorage('the-image', username=None, repository=PUBLIC_REPO)
# Create a areference to the same docker ID. Since no username, we'd expect different but the first image is public so => shaed image.
self.assertSameStorage('the-image', first_storage_id, username=None, repository=RANDOM_REPO)
def test_different_user_same_repo(self):
""" Two different users create the same image in the same repo. """
# Create a reference to a new docker ID under the first user => new image.
first_storage_id = self.createStorage('the-image', username=PUBLIC_USER, repository=SHARED_REPO)
# Create a reference to the *same* docker ID under the second user => same image.
self.assertSameStorage('the-image', first_storage_id, username=ADMIN_ACCESS_USER, repository=SHARED_REPO)
def test_different_repo_no_shared_access(self):
""" Neither user has access to the other user's repository. """
# Create a reference to a new docker ID under the first user => new image.
first_storage_id = self.createStorage('the-image', username=RANDOM_USER, repository=RANDOM_REPO)
# Create a reference to the *same* docker ID under the second user => new image.
second_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=REPO)
# Verify that the users do not share storage.
self.assertNotEquals(first_storage_id, second_storage_id)
def test_public_than_private(self):
""" An image is created publicly then used privately, so it should be shared. """
# Create a reference to a new docker ID under the first user => new image.
first_storage_id = self.createStorage('the-image', username=PUBLIC_USER, repository=PUBLIC_REPO)
# Create a reference to the *same* docker ID under the second user => same image, since the first was public.
self.assertSameStorage('the-image', first_storage_id, username=ADMIN_ACCESS_USER, repository=REPO)
def test_private_than_public(self):
""" An image is created privately then used publicly, so it should *not* be shared. """
# Create a reference to a new docker ID under the first user => new image.
first_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=REPO)
# Create a reference to the *same* docker ID under the second user => new image, since the first was private.
self.assertDifferentStorage('the-image', first_storage_id, username=PUBLIC_USER, repository=PUBLIC_REPO)
def test_different_repo_with_access(self):
""" An image is created in one repo (SHARED_REPO) which the user (PUBLIC_USER) has access to. Later, the
image is created in another repo (PUBLIC_REPO) that the user also has access to. The image should
be shared since the user has access.
"""
# Create the image in the shared repo => new image.
first_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=SHARED_REPO)
# Create the image in the other user's repo, but since the user (PUBLIC) still has access to the shared
# repository, they should reuse the storage.
self.assertSameStorage('the-image', first_storage_id, username=PUBLIC_USER, repository=PUBLIC_REPO)
def test_org_access(self):
""" An image is accessible by being a member of the organization. """
# Create the new image under the org's repo => new image.
first_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=ORG_REPO)
# Create an image under the user's repo, but since the user has access to the organization => shared image.
self.assertSameStorage('the-image', first_storage_id, username=ADMIN_ACCESS_USER, repository=REPO)
# Ensure that the user's robot does not have access, since it is not on the permissions list for the repo.
self.assertDifferentStorage('the-image', first_storage_id, username=ADMIN_ROBOT_USER, repository=SHARED_REPO)
def test_org_access_different_user(self):
""" An image is accessible by being a member of the organization. """
# Create the new image under the org's repo => new image.
first_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=ORG_REPO)
# Create an image under a user's repo, but since the user has access to the organization => shared image.
self.assertSameStorage('the-image', first_storage_id, username=PUBLIC_USER, repository=PUBLIC_REPO)
# Also verify for reader.
self.assertSameStorage('the-image', first_storage_id, username=READ_ACCESS_USER, repository=PUBLIC_REPO)
def test_org_no_access(self):
""" An image is not accessible if not a member of the organization. """
# Create the new image under the org's repo => new image.
first_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=ORG_REPO)
# Create an image under a user's repo. Since the user is not a member of the organization => new image.
self.assertDifferentStorage('the-image', first_storage_id, username=RANDOM_USER, repository=RANDOM_REPO)
def test_org_not_team_member_with_access(self):
""" An image is accessible to a user specifically listed as having permission on the org repo. """
# Create the new image under the org's repo => new image.
first_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=ORG_REPO)
# Create an image under a user's repo. Since the user has read access on that repo, they can see the image => shared image.
self.assertSameStorage('the-image', first_storage_id, username=OUTSIDE_ORG_USER, repository=OUTSIDE_ORG_REPO)
def test_org_not_team_member_with_no_access(self):
""" A user that has access to one org repo but not another and is not a team member. """
# Create the new image under the org's repo => new image.
first_storage_id = self.createStorage('the-image', username=ADMIN_ACCESS_USER, repository=ANOTHER_ORG_REPO)
# Create an image under a user's repo. The user doesn't have access to the repo (ANOTHER_ORG_REPO) so => new image.
self.assertDifferentStorage('the-image', first_storage_id, username=OUTSIDE_ORG_USER, repository=OUTSIDE_ORG_REPO)