Source code for changes.models.testartifact
import uuid
import logging
import mimetypes
from base64 import b64decode
from cStringIO import StringIO
from datetime import datetime
from enum import Enum
from sqlalchemy import Column, DateTime, ForeignKey, String
from sqlalchemy.schema import Index
from sqlalchemy.orm import relationship
from changes.config import db
from changes.db.types.enum import Enum as EnumType
from changes.db.types.filestorage import FileStorage, FileData
from changes.db.types.guid import GUID
from changes.db.utils import model_repr
from changes.storage.artifactstore import ArtifactStoreFileStorage
logger = logging.getLogger('models.testartifact')
TESTARTIFACT_STORAGE_OPTIONS = {
'path': 'test-artifacts',
}
class TestArtifactType(Enum):
unknown = 0
text = 1
image = 2
html = 3
def __str__(self):
return TYPE_LABELS[self]
TYPE_LABELS = {
TestArtifactType.unknown: 'Unknown',
TestArtifactType.text: 'Text',
TestArtifactType.image: 'Image',
TestArtifactType.html: 'Html',
}
[docs]class TestArtifact(db.Model):
"""
Represents any artifacts generated by a single run of a single test. used
e.g. in server-selenium to store screenshots and large log dumps for
later debugging.
"""
__tablename__ = 'testartifact'
__tableargs__ = (
Index('idx_test_id', 'test_id'),
)
id = Column(GUID, nullable=False, primary_key=True, default=uuid.uuid4)
test_id = Column(GUID, ForeignKey('test.id', ondelete="CASCADE"), nullable=False)
name = Column('name', String(length=256), nullable=False)
type = Column(EnumType(TestArtifactType),
default=TestArtifactType.unknown,
nullable=False, server_default='0')
file = Column(FileStorage(**TESTARTIFACT_STORAGE_OPTIONS))
date_created = Column(DateTime, default=datetime.utcnow, nullable=False)
test = relationship('TestCase', backref='artifacts')
__repr__ = model_repr('name', 'type', 'file')
def __init__(self, **kwargs):
super(TestArtifact, self).__init__(**kwargs)
if self.id is None:
self.id = uuid.uuid4()
if self.date_created is None:
self.date_created = datetime.utcnow()
if isinstance(self.type, basestring):
self.type = TestArtifactType[self.type]
if self.file is None:
# TODO(dcramer): this is super hacky but not sure a better way to
# do it with SQLAlchemy
self.file = FileData({}, TESTARTIFACT_STORAGE_OPTIONS)
def save_base64_content(self, base64, bucket_name):
content = b64decode(base64)
self.file.storage = 'changes.storage.artifactstore.ArtifactStoreFileStorage'
filename = ArtifactStoreFileStorage.get_filename_from_artifact_name(bucket_name, self.id.hex)
self.file.save(StringIO(content), filename, content_type=self._get_content_type(), path=self.name)
def _get_content_type(self):
content_type, encoding = mimetypes.guess_type(self.name)
if content_type == 'text/html':
# upload html artifacts as plain text so the browser doesn't try to
# render them when viewing them raw
content_type = 'text/plain'
return content_type