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): content = b64decode(base64) self.file.save( StringIO(content), '{0}/{1}_{2}'.format( self.test_id, self.id.hex, self.name ), self._get_content_type() ) 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
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, str): 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): content = b64decode(base64) self.file.save( StringIO(content), '{0}/{1}_{2}'.format( self.test_id, self.id.hex, self.name ), self._get_content_type() ) 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
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 make_AS_file(): return FileData({ 'filename': 'foo', 'storage': 'changes.storage.artifactstore.ArtifactStoreFileStorage' })
def __init__(self, **kwargs): super(Artifact, self).__init__(**kwargs) if self.id is None: self.id = uuid.uuid4() if self.date_created is None: self.date_created = datetime.utcnow() if self.data is None: self.data = {} 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({}, ARTIFACT_STORAGE_OPTIONS)
def test_get_artifacts_to_sync(self): project = self.create_project() build = self.create_build(project=project) job = self.create_job(build=build) plan = self.create_plan(project) self.create_step(plan, implementation='test', order=0) self.create_job_plan(job, plan) phase = self.create_jobphase(job) step = self.create_jobstep(phase, status=Status.finished, result=Result.passed) make_AS_file = lambda: FileData({ 'filename': 'foo', 'storage': 'changes.storage.artifactstore.ArtifactStoreFileStorage' }) artstore_junit = self.create_artifact(step, 'artifactstore/foo/junit.xml', file=make_AS_file()) artstore_junit2 = self.create_artifact(step, 'artifactstore/junit.xml', file=make_AS_file()) artstore_coverage = self.create_artifact(step, 'artifactstore/coverage.xml', file=make_AS_file()) other_junit = self.create_artifact(step, 'bar/junit.xml') other_manifest = self.create_artifact(step, 'manifest.json') arts = Artifact.query.filter(Artifact.step_id == step.id).all() assert (sorted(_get_artifacts_to_sync( arts, prefer_artifactstore=True)) == sorted([ artstore_junit, artstore_junit2, artstore_coverage, other_manifest ])) assert (sorted(_get_artifacts_to_sync( arts, prefer_artifactstore=False)) == sorted( [artstore_coverage, other_junit, other_manifest]))