Exemple #1
0
class Artifact(RepositoryBoundMixin, StandardAttributes, db.Model):
    job_id = db.Column(GUID,
                       db.ForeignKey('job.id', ondelete='CASCADE'),
                       nullable=False)
    testcase_id = db.Column(GUID,
                            db.ForeignKey('testcase.id', ondelete='CASCADE'),
                            nullable=True)
    name = db.Column(db.String(length=256), nullable=False)
    type = db.Column(Enum(ArtifactType),
                     default=ArtifactType.UNKNOWN,
                     nullable=False,
                     server_default='0')
    file = db.Column(
        File(**ARTIFACT_STORAGE_OPTIONS),
        nullable=False,
        # TODO(dcramer): this is super hacky but not sure a better way to
        # do it with SQLAlchemy
        default=lambda: FileData({}, ARTIFACT_STORAGE_OPTIONS))

    job = db.relationship('Job', innerjoin=True, uselist=False)
    testcase = db.relationship('TestCase', uselist=False)

    __tablename__ = 'artifact'

    def save_base64_content(self, base64):
        content = b64decode(base64)
        self.file.save(
            BytesIO(content), '{0}/{1}_{2}'.format(self.job_id.hex,
                                                   self.id.hex, self.name))
Exemple #2
0
class Artifact(RepositoryBoundMixin, StandardAttributes, db.Model):
    job_id = db.Column(GUID, db.ForeignKey(
        'job.id', ondelete='CASCADE'), nullable=False)
    testcase_id = db.Column(GUID, db.ForeignKey(
        'testcase.id', ondelete='CASCADE'), nullable=True)
    name = db.Column(db.String(length=256), nullable=False)
    type = db.Column(db.String(length=64), nullable=True)
    file = db.Column(
        File(path='artifacts'),
        nullable=False,
        # TODO(dcramer): this is super hacky but not sure a better way to
        # do it with SQLAlchemy
        default=lambda: FileData({}, default_path='artifacts')
    )
    status = db.Column(Enum(Status), nullable=False, default=Status.unknown)
    date_started = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    date_updated = db.Column(db.TIMESTAMP(
        timezone=True), nullable=True, onupdate=timezone.now)
    date_finished = db.Column(db.TIMESTAMP(timezone=True), nullable=True)

    job = db.relationship('Job', innerjoin=True, uselist=False)
    testcase = db.relationship('TestCase', uselist=False)

    __tablename__ = 'artifact'

    def save_base64_content(self, base64):
        content = b64decode(base64)
        self.file.save(
            BytesIO(
                content), '{0}/{1}_{2}'.format(self.job_id.hex, self.id.hex, self.name)
        )
Exemple #3
0
class FailureReason(RepositoryBoundMixin, StandardAttributes, db.Model):
    class Reason(enum.Enum):
        failing_tests = "failing_tests"
        missing_tests = "missing_tests"
        no_jobs = "no_jobs"
        unresolvable_ref = "unresolvable_ref"

    build_id = db.Column(GUID,
                         db.ForeignKey("build.id", ondelete="CASCADE"),
                         nullable=True)
    job_id = db.Column(GUID,
                       db.ForeignKey("job.id", ondelete="CASCADE"),
                       nullable=True)
    reason = db.Column(StrEnum(Reason), nullable=False)

    build = db.relationship("Build")
    job = db.relationship("Job")

    __tablename__ = "failurereason"
    __table_args__ = (
        db.UniqueConstraint("build_id",
                            "job_id",
                            "reason",
                            name="unq_failurereason_key"),
        db.Index(
            "unq_failurereason_buildonly",
            build_id,
            reason,
            unique=True,
            postgresql_where=job_id.is_(None),
        ),
    )
    __repr__ = model_repr("reason")
Exemple #4
0
class RepositoryAccess(db.Model):
    repository_id = db.Column(GUID, db.ForeignKey('repository.id'), primary_key=True)
    user_id = db.Column(GUID, db.ForeignKey('user.id'), primary_key=True)

    repository = db.relationship('Repository', innerjoin=True, uselist=False)
    user = db.relationship('User', innerjoin=True, uselist=False)

    __tablename__ = 'repository_access'
    __repr__ = model_repr('repository_id', 'user_id')
Exemple #5
0
class OrganizationAccess(db.Model):
    organization_id = db.Column(GUID, db.ForeignKey('organization.id'), primary_key=True)
    user_id = db.Column(GUID, db.ForeignKey('user.id'), primary_key=True)

    organization = db.relationship('Organization', innerjoin=True, uselist=False)
    user = db.relationship('User', innerjoin=True, uselist=False)

    __tablename__ = 'organization_access'
    __repr__ = model_repr('organization_id', 'user_id')
Exemple #6
0
class ApiTokenRepositoryAccess(db.Model):
    repository_id = db.Column(GUID, db.ForeignKey('repository.id'), primary_key=True)
    api_token_id = db.Column(GUID, db.ForeignKey('api_token.id'), primary_key=True)

    repository = db.relationship('Repository', innerjoin=True, uselist=False)
    api_token = db.relationship('ApiToken', innerjoin=True, uselist=False)

    __tablename__ = 'api_token_repository_access'
    __repr__ = model_repr('repository_id', 'api_token_id')
Exemple #7
0
class Source(RepositoryBoundMixin, StandardAttributes, db.Model):
    """
    A source represents the canonical parameters that a build is running against.
    """

    patch_id = db.Column(GUID,
                         db.ForeignKey("patch.id", ondelete="CASCADE"),
                         unique=True,
                         nullable=True)
    revision_sha = db.Column(db.String(40), nullable=False)
    data = db.Column(JSONEncodedDict, nullable=True)
    author_id = db.Column(GUID,
                          db.ForeignKey("author.id", ondelete="SET NULL"),
                          index=True,
                          nullable=True)

    author = db.relationship("Author")
    patch = db.relationship("Patch")
    revision = db.relationship(
        "Revision",
        foreign_keys="[Source.repository_id, Source.revision_sha]",
        viewonly=True,
    )

    __tablename__ = "source"
    __table_args__ = (
        db.ForeignKeyConstraint(
            ("repository_id", "revision_sha"),
            ("revision.repository_id", "revision.sha"),
        ),
        db.Index("idx_source_repo_sha", "repository_id", "revision_sha"),
        db.UniqueConstraint("repository_id",
                            "revision_sha",
                            "patch_id",
                            name="unq_source_revision"),
    )
    __repr__ = model_repr("repository_id", "revision_sha", "patch_id")

    def is_commit(self):
        return self.patch_id is None and self.revision_sha

    def generate_diff(self):
        if self.patch:
            return self.patch.diff

        try:
            vcs = self.repository.get_vcs()
        except UnknownRepositoryBackend:
            return None

        try:
            return vcs.export(self.revision_sha)
        except Exception:
            # TODO
            pass
Exemple #8
0
class Revision(db.Model):
    # XXX(dcramer): the primary_key doesnt include repo_id at the moment, which is wrong, but
    # we need to deal w/ that in a followup change
    repository_id = db.Column(
        GUID, db.ForeignKey("repository.id", ondelete="CASCADE"), primary_key=True
    )
    sha = db.Column(db.String(40), primary_key=True)
    author_id = db.Column(
        GUID, db.ForeignKey("author.id", ondelete="SET NULL"), index=True, nullable=True
    )
    committer_id = db.Column(
        GUID, db.ForeignKey("author.id", ondelete="SET NULL"), index=True, nullable=True
    )
    message = db.Column(db.Text, nullable=True)
    parents = db.Column(ARRAY(db.String(40)), nullable=True)
    # TODO: remove this column, we dont use it and its wrong
    branches = db.Column(ARRAY(db.String(128)), nullable=True)
    date_created = db.Column(
        db.TIMESTAMP(timezone=True),
        default=timezone.now,
        server_default=func.now(),
        nullable=False,
    )
    date_committed = db.Column(
        db.TIMESTAMP(timezone=True),
        default=timezone.now,
        server_default=func.now(),
        nullable=False,
    )

    authors = db.relationship(
        "Author", secondary=revision_author_table, backref="revisions"
    )
    committer = db.relationship("Author", foreign_keys=[committer_id])
    repository = db.relationship("Repository", foreign_keys=[repository_id])

    query_class = RepositoryBoundQuery

    __tablename__ = "revision"
    # XXX(dcramer): the primary_key doesnt include repo_id at the moment, which is wrong, but
    # we need to deal w/ that in a followup change
    __table_args__ = (db.UniqueConstraint("repository_id", "sha", name="unq_revision"),)
    __repr__ = model_repr("repository_id", "sha", "subject")

    @property
    def subject(self):
        return self.message.splitlines()[0]

    def generate_diff(self):
        from zeus.vcs import vcs_client

        try:
            return vcs_client.export(self.repository_id, self.sha)
        except Exception:
            current_app.logger.exception("generate_diff failure")
Exemple #9
0
class ApiTokenRepositoryAccess(db.Model):
    repository_id = db.Column(
        GUID, db.ForeignKey("repository.id", ondelete="CASCADE"), primary_key=True
    )
    api_token_id = db.Column(
        GUID, db.ForeignKey("api_token.id", ondelete="CASCADE"), primary_key=True
    )
    permission = db.Column(Enum(Permission), nullable=False, default=Permission.read)

    repository = db.relationship("Repository", innerjoin=True, uselist=False)
    api_token = db.relationship("ApiToken", innerjoin=True, uselist=False)

    __tablename__ = "api_token_repository_access"
    __repr__ = model_repr("repository_id", "api_token_id")
Exemple #10
0
class RepositoryAccess(db.Model):
    repository_id = db.Column(GUID,
                              db.ForeignKey("repository.id"),
                              primary_key=True)
    user_id = db.Column(GUID, db.ForeignKey("user.id"), primary_key=True)

    repository = db.relationship("Repository", innerjoin=True, uselist=False)
    user = db.relationship("User", innerjoin=True, uselist=False)
    permission = db.Column(Enum(Permission),
                           nullable=False,
                           default=Permission.read,
                           server_default="1")

    __tablename__ = "repository_access"
    __repr__ = model_repr("repository_id", "user_id")
Exemple #11
0
class Source(RepositoryBoundMixin, StandardAttributes, db.Model):
    """
    A source represents the canonical parameters that a build is running against.
    """
    patch_id = db.Column(GUID,
                         db.ForeignKey('patch.id'),
                         unique=True,
                         nullable=True)
    revision_sha = db.Column(db.String(40), nullable=False)
    data = db.Column(JSONEncodedDict, nullable=True)
    author_id = db.Column(GUID, db.ForeignKey('author.id'), index=True)

    author = db.relationship('Author')
    patch = db.relationship('Patch', )
    revision = db.relationship(
        'Revision',
        foreign_keys='[Source.repository_id, Source.revision_sha]',
        viewonly=True)

    __tablename__ = 'source'
    __table_args__ = (
        db.ForeignKeyConstraint(('repository_id', 'revision_sha'),
                                ('revision.repository_id', 'revision.sha')),
        db.Index('idx_source_repo_sha', 'repository_id', 'revision_sha'),
        db.UniqueConstraint(
            'repository_id',
            'revision_sha',
            'patch_id',
            name='unq_source_revision',
        ),
    )
    __repr__ = model_repr('repository_id', 'revision_sha', 'patch_id')

    def is_commit(self):
        return self.patch_id is None and self.revision_sha

    def generate_diff(self):
        if self.patch:
            return self.patch.diff

        vcs = self.repository.get_vcs()
        if vcs:
            try:
                return vcs.export(self.revision_sha)
            except Exception:
                pass

        return None
Exemple #12
0
class Build(ProjectBoundMixin, StandardAttributes, db.Model):
    """
    A single build linked to a source.

    Each Build contains many Jobs.
    """
    source_id = db.Column(
        GUID, db.ForeignKey('source.id', ondelete='CASCADE'), nullable=False, index=True
    )
    number = db.Column(db.Integer, nullable=False)
    label = db.Column(db.String, nullable=False)
    status = db.Column(Enum(Status), nullable=False, default=Status.unknown)
    result = db.Column(Enum(Result), nullable=False, default=Result.unknown)
    date_started = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    date_finished = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    data = db.Column(JSONEncodedDict, nullable=True)
    provider = db.Column(db.String, nullable=True)
    external_id = db.Column(db.String(64), nullable=True)

    source = db.relationship('Source')
    stats = db.relationship(
        'ItemStat',
        foreign_keys='[ItemStat.item_id]',
        primaryjoin='ItemStat.item_id == Build.id',
        lazy='subquery',
        viewonly=True,
        uselist=True
    )

    __tablename__ = 'build'
    __table_args__ = (
        db.UniqueConstraint('project_id', 'number', name='unq_build_number'),
        db.UniqueConstraint('project_id', 'provider', 'external_id', name='unq_build_provider')
    )
    __repr__ = model_repr('number', 'status', 'result')
Exemple #13
0
 def repository_id(cls):
     return db.Column(
         GUID,
         db.ForeignKey("repository.id", ondelete="CASCADE"),
         nullable=False,
         index=True,
     )
Exemple #14
0
class PendingArtifact(RepositoryBoundMixin, StandardAttributes, db.Model):
    provider = db.Column(db.String, nullable=False)
    external_job_id = db.Column(db.String(64), nullable=False)
    external_build_id = db.Column(db.String(64), nullable=False)
    hook_id = db.Column(GUID,
                        db.ForeignKey("hook.id", ondelete="CASCADE"),
                        nullable=False,
                        index=True)
    name = db.Column(db.String(length=256), nullable=False)
    type = db.Column(db.String(length=64), nullable=True)
    file = db.Column(
        File(path="artifacts"),
        nullable=False,
        # TODO(dcramer): this is super hacky but not sure a better way to
        # do it with SQLAlchemy
        default=lambda: FileData({}, default_path="artifacts"),
    )

    hook = db.relationship("Hook")

    __tablename__ = "pending_artifact"
    __table_args__ = (db.Index(
        "idx_pending_artifact",
        "repository_id",
        "provider",
        "external_job_id",
        "external_build_id",
    ), )
Exemple #15
0
class ChangeRequest(RepositoryBoundMixin, StandardAttributes, db.Model):
    number = db.Column(db.Integer, nullable=False)
    # the parent revision is our base commit that this change request applies to
    parent_revision_sha = db.Column(db.String(40), nullable=False)
    # for branch-style change requests (e.g. GitHub Pull Requests) we capture
    # the 'current revision' in addition to the 'parent revision'
    head_revision_sha = db.Column(db.String(40), nullable=True)
    message = db.Column(db.String, nullable=False)
    author_id = db.Column(GUID,
                          db.ForeignKey("author.id"),
                          index=True,
                          nullable=True)
    provider = db.Column(db.String, nullable=True)
    external_id = db.Column(db.String(64), nullable=True)
    url = db.Column(db.String, nullable=True)
    data = db.Column(JSONEncodedDict, nullable=True)
    date_updated = db.Column(db.TIMESTAMP(timezone=True),
                             nullable=True,
                             onupdate=timezone.now)

    head_revision = db.relationship(
        "Revision",
        foreign_keys=
        "[ChangeRequest.repository_id, ChangeRequest.head_revision_sha]",
        viewonly=True,
    )
    parent_revision = db.relationship(
        "Revision",
        foreign_keys=
        "[ChangeRequest.repository_id, ChangeRequest.parent_revision_sha]",
        viewonly=True,
    )
    author = db.relationship("Author")

    __tablename__ = "change_request"
    __table_args__ = (
        db.ForeignKeyConstraint(
            ("repository_id", "parent_revision_sha"),
            ("revision.repository_id", "revision.sha"),
        ),
        db.ForeignKeyConstraint(
            ("repository_id", "head_revision_sha"),
            ("revision.repository_id", "revision.sha"),
        ),
        db.Index("idx_cr_parent_revision", "repository_id",
                 "parent_revision_sha"),
        db.Index("idx_cr_head_revision", "repository_id", "head_revision_sha"),
        db.UniqueConstraint("repository_id", "number", name="unq_cr_number"),
        db.UniqueConstraint("repository_id",
                            "provider",
                            "external_id",
                            name="unq_cr_provider"),
    )
    __repr__ = model_repr("repository_id", "parent_revision_sha")

    @property
    def subject(self):
        return self.message.splitlines()[0]
Exemple #16
0
class BundleAsset(RepositoryBoundMixin, StandardAttributes, db.Model):
    bundle_id = db.Column(GUID,
                          db.ForeignKey('bundle.id', ondelete='CASCADE'),
                          nullable=False)
    job_id = db.Column(GUID,
                       db.ForeignKey('job.id', ondelete='CASCADE'),
                       nullable=False)
    name = db.Column(db.Text, nullable=False)
    size = db.Column(db.Integer, nullable=True)

    job = db.relationship('Job')
    bundle = db.relationship('Bundle')

    __tablename__ = 'bundle_asset'
    __table_args__ = (db.UniqueConstraint('bundle_id',
                                          'name',
                                          name='unq_bundle_asset'), )
    __repr__ = model_repr('repository_id', 'job_id', 'bundle_id', 'name')
Exemple #17
0
class BundleAsset(RepositoryBoundMixin, StandardAttributes, db.Model):
    bundle_id = db.Column(GUID,
                          db.ForeignKey("bundle.id", ondelete="CASCADE"),
                          nullable=False)
    job_id = db.Column(GUID,
                       db.ForeignKey("job.id", ondelete="CASCADE"),
                       nullable=False)
    name = db.Column(db.Text, nullable=False)
    size = db.Column(db.Integer, nullable=True)

    job = db.relationship("Job")
    bundle = db.relationship("Bundle")

    __tablename__ = "bundle_asset"
    __table_args__ = (db.UniqueConstraint("bundle_id",
                                          "name",
                                          name="unq_bundle_asset"), )
    __repr__ = model_repr("repository_id", "job_id", "bundle_id", "name")
Exemple #18
0
class Job(RepositoryBoundMixin, StandardAttributes, db.Model):
    """
    A single job, which is the actual execution unit for a build.
    """

    id = db.Column(GUID, primary_key=True, default=GUID.default_value)
    build_id = db.Column(GUID,
                         db.ForeignKey("build.id", ondelete="CASCADE"),
                         nullable=False,
                         index=True)
    number = db.Column(db.Integer, nullable=False)
    label = db.Column(db.String, nullable=True)
    status = db.Column(Enum(Status), nullable=False, default=Status.unknown)
    result = db.Column(Enum(Result), nullable=False, default=Result.unknown)
    allow_failure = db.Column(db.Boolean,
                              nullable=False,
                              default=False,
                              server_default="0")
    date_started = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    date_updated = db.Column(db.TIMESTAMP(timezone=True),
                             nullable=True,
                             onupdate=timezone.now)
    date_finished = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    data = db.Column(JSONEncodedDict, nullable=True)
    provider = db.Column(db.String, nullable=True)
    external_id = db.Column(db.String(64), nullable=True)
    url = db.Column(db.String, nullable=True)

    build = db.relationship("Build",
                            backref=db.backref("jobs",
                                               order_by="Job.date_created"),
                            innerjoin=True)
    stats = db.relationship(
        "ItemStat",
        foreign_keys="[ItemStat.item_id]",
        primaryjoin="ItemStat.item_id == Job.id",
        viewonly=True,
        uselist=True,
    )
    failures = db.relationship(
        "FailureReason",
        foreign_keys="[FailureReason.job_id]",
        primaryjoin="FailureReason.job_id == Job.id",
        viewonly=True,
        uselist=True,
    )

    __tablename__ = "job"
    __table_args__ = (
        db.UniqueConstraint("build_id", "number", name="unq_job_number"),
        db.UniqueConstraint("build_id",
                            "provider",
                            "external_id",
                            name="unq_job_provider"),
    )
    __repr__ = model_repr("build_id", "number", "status", "result")
Exemple #19
0
class Revision(RepositoryBoundMixin, db.Model):
    sha = db.Column(db.String(40), primary_key=True)
    author_id = db.Column(GUID,
                          db.ForeignKey("author.id"),
                          index=True,
                          nullable=True)
    committer_id = db.Column(GUID,
                             db.ForeignKey("author.id"),
                             index=True,
                             nullable=True)
    message = db.Column(db.Text, nullable=True)
    parents = db.Column(ARRAY(db.String(40)), nullable=True)
    branches = db.Column(ARRAY(db.String(128)), nullable=True)
    date_created = db.Column(
        db.TIMESTAMP(timezone=True),
        default=timezone.now,
        server_default=func.now(),
        nullable=False,
    )
    date_committed = db.Column(
        db.TIMESTAMP(timezone=True),
        default=timezone.now,
        server_default=func.now(),
        nullable=False,
    )

    author = db.relationship("Author", foreign_keys=[author_id])
    committer = db.relationship("Author", foreign_keys=[committer_id])

    __tablename__ = "revision"
    __table_args__ = (db.UniqueConstraint("repository_id",
                                          "sha",
                                          name="unq_revision"), )
    __repr__ = model_repr("repository_id", "sha", "subject")

    @property
    def subject(self):
        return self.message.splitlines()[0]
Exemple #20
0
class Build(RepositoryBoundMixin, StandardAttributes, db.Model):
    """
    A single build linked to a source.

    Each Build contains many Jobs.
    """

    source_id = db.Column(GUID,
                          db.ForeignKey("source.id", ondelete="CASCADE"),
                          nullable=False,
                          index=True)
    number = db.Column(db.Integer, nullable=False)
    label = db.Column(db.String, nullable=False)
    status = db.Column(Enum(Status), nullable=False, default=Status.unknown)
    result = db.Column(Enum(Result), nullable=False, default=Result.unknown)
    date_created = db.Column(
        db.TIMESTAMP(timezone=True),
        nullable=False,
        default=timezone.now,
        server_default=func.now(),
        index=True,
    )
    date_started = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    date_finished = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    data = db.Column(JSONEncodedDict, nullable=True)
    provider = db.Column(db.String, nullable=True)
    external_id = db.Column(db.String(64), nullable=True)
    url = db.Column(db.String, nullable=True)

    source = db.relationship("Source", innerjoin=True)
    stats = db.relationship(
        "ItemStat",
        foreign_keys="[ItemStat.item_id]",
        primaryjoin="ItemStat.item_id == Build.id",
        viewonly=True,
        uselist=True,
    )

    __tablename__ = "build"
    __table_args__ = (
        db.UniqueConstraint("repository_id", "number",
                            name="unq_build_number"),
        db.UniqueConstraint("repository_id",
                            "provider",
                            "external_id",
                            name="unq_build_provider"),
    )
    __repr__ = model_repr("number", "status", "result")
Exemple #21
0
class FailureReason(RepositoryBoundMixin, StandardAttributes, db.Model):
    __tablename__ = 'failurereason'
    __table_args__ = (db.UniqueConstraint('job_id',
                                          'reason',
                                          name='unq_failurereason_key'), )

    class Reason(enum.Enum):
        failing_tests = 'failing_tests'
        missing_tests = 'missing_tests'

    job_id = db.Column(GUID,
                       db.ForeignKey('job.id', ondelete="CASCADE"),
                       nullable=False)
    reason = db.Column(StrEnum(Reason), nullable=False)

    job = db.relationship('Job')
Exemple #22
0
class FileCoverage(ProjectBoundMixin, db.Model):
    id = db.Column(GUID, nullable=False, primary_key=True, default=GUID.default_value)
    job_id = db.Column(GUID, db.ForeignKey('job.id', ondelete='CASCADE'), nullable=False)
    filename = db.Column(db.String(256), nullable=False, primary_key=True)
    data = db.Column(db.Text, nullable=False)

    lines_covered = db.Column(db.Integer, nullable=False)
    lines_uncovered = db.Column(db.Integer, nullable=False)
    diff_lines_covered = db.Column(db.Integer, nullable=False)
    diff_lines_uncovered = db.Column(db.Integer, nullable=False)

    job = db.relationship('Job', innerjoin=True, uselist=False)

    __tablename__ = 'filecoverage'
    __table_args__ = (db.UniqueConstraint('job_id', 'filename', name='unq_job_filname'), )
    __repr__ = model_repr('job_id', 'filename')
Exemple #23
0
class FailureReason(RepositoryBoundMixin, StandardAttributes, db.Model):
    __tablename__ = "failurereason"
    __table_args__ = (db.UniqueConstraint("job_id",
                                          "reason",
                                          name="unq_failurereason_key"), )

    class Reason(enum.Enum):
        failing_tests = "failing_tests"
        missing_tests = "missing_tests"

    job_id = db.Column(GUID,
                       db.ForeignKey("job.id", ondelete="CASCADE"),
                       nullable=False)
    reason = db.Column(StrEnum(Reason), nullable=False)

    job = db.relationship("Job")
Exemple #24
0
class Job(RepositoryBoundMixin, StandardAttributes, db.Model):
    """
    A single job, which is the actual execution unit for a build.
    """
    id = db.Column(GUID, primary_key=True, default=GUID.default_value)
    build_id = db.Column(GUID,
                         db.ForeignKey('build.id', ondelete='CASCADE'),
                         nullable=False,
                         index=True)
    number = db.Column(db.Integer, nullable=False)
    label = db.Column(db.String, nullable=True)
    status = db.Column(Enum(Status), nullable=False, default=Status.unknown)
    result = db.Column(Enum(Result), nullable=False, default=Result.unknown)
    date_started = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    date_finished = db.Column(db.TIMESTAMP(timezone=True), nullable=True)
    data = db.Column(JSONEncodedDict, nullable=True)
    provider = db.Column(db.String, nullable=True)
    external_id = db.Column(db.String(64), nullable=True)
    url = db.Column(db.String, nullable=True)

    build = db.relationship('Build',
                            backref=db.backref('jobs',
                                               order_by='Job.date_created'),
                            innerjoin=True)
    stats = db.relationship('ItemStat',
                            foreign_keys='[ItemStat.item_id]',
                            primaryjoin='ItemStat.item_id == Job.id',
                            viewonly=True,
                            uselist=True)
    failures = db.relationship(
        'FailureReason',
        foreign_keys='[FailureReason.job_id]',
        primaryjoin='FailureReason.job_id == Job.id',
        viewonly=True,
        uselist=True,
    )

    __tablename__ = 'job'
    __table_args__ = (db.UniqueConstraint('build_id',
                                          'number',
                                          name='unq_job_number'),
                      db.UniqueConstraint('build_id',
                                          'provider',
                                          'external_id',
                                          name='unq_job_provider'))
    __repr__ = model_repr('build_id', 'number', 'status', 'result')
Exemple #25
0
class Email(StandardAttributes, db.Model):
    """
    An email address associated with a user.
    """
    user_id = db.Column(GUID,
                        db.ForeignKey('user.id', ondelete="CASCADE"),
                        nullable=False,
                        index=True)
    email = db.Column(db.String(128), nullable=False)
    verified = db.Column(db.Boolean, default=False, nullable=False)

    user = db.relationship('User')

    __tablename__ = 'email'
    __table_args__ = (db.UniqueConstraint('user_id',
                                          'email',
                                          name='unq_user_email'), )
    __repr__ = model_repr('user_id', 'email', 'verified')
Exemple #26
0
class Identity(StandardAttributes, db.Model):
    """
    Identities associated with a user. Primarily used for Single Sign-On.
    """
    user_id = db.Column(
        GUID, db.ForeignKey('user.id', ondelete="CASCADE"), nullable=False, index=True
    )
    external_id = db.Column(db.String(64), unique=True, nullable=False)
    provider = db.Column(db.String(32), nullable=False)
    config = db.Column(JSONEncodedDict, nullable=False)
    scopes = db.Column(ARRAY(db.String(64)), nullable=True)

    user = db.relationship('User')

    __tablename__ = 'identity'
    __table_args__ = (db.UniqueConstraint(
        'user_id', 'provider', name='unq_identity_user'), )
    __repr__ = model_repr('user_id', 'provider', 'external_id')
Exemple #27
0
class StyleViolation(RepositoryBoundMixin, StandardAttributes, db.Model):
    """
    A single style violation.
    """
    job_id = db.Column(
        GUID, db.ForeignKey("job.id", ondelete="CASCADE"), nullable=False
    )
    filename = db.Column(db.Text, nullable=False)
    severity = db.Column(Enum(Severity), default=Severity.error, nullable=False)
    message = db.Column(db.Text, nullable=False)
    lineno = db.Column(db.Integer, nullable=True)
    colno = db.Column(db.Integer, nullable=True)
    source = db.Column(db.Text, nullable=True)

    job = db.relationship("Job")

    __tablename__ = "styleviolation"
    __repr__ = model_repr("repository_id", "job_id", "filename", "message")
Exemple #28
0
class UserApiToken(StandardAttributes, db.Model, ApiTokenMixin):
    """
    An API token associated to users.
    """

    user_id = db.Column(GUID,
                        db.ForeignKey("user.id", ondelete="CASCADE"),
                        nullable=False,
                        unique=True)

    user = db.relationship("User",
                           backref=db.backref("tokens", uselist=False),
                           innerjoin=True)

    __tablename__ = "user_api_token"
    __repr__ = model_repr("user_id", "key")

    def get_token_key(self):
        return "u"
Exemple #29
0
class TestCase(RepositoryBoundMixin, db.Model):
    """
    A single run of a single test.
    """

    id = db.Column(GUID,
                   nullable=False,
                   primary_key=True,
                   default=GUID.default_value)
    job_id = db.Column(GUID,
                       db.ForeignKey("job.id", ondelete="CASCADE"),
                       nullable=False)
    hash = db.Column(db.String(40), nullable=False)
    name = db.Column(db.Text, nullable=False)
    result = db.Column(Enum(Result), default=Result.unknown, nullable=False)
    # duration, in milliseconds
    duration = db.Column(db.Integer, default=0, nullable=True)
    message = db.deferred(db.Column(db.Text, nullable=True))

    job = db.relationship("Job")

    __tablename__ = "testcase"
    __table_args__ = (db.UniqueConstraint("job_id",
                                          "hash",
                                          name="unq_testcase_hash"), )
    __repr__ = model_repr("repository_id", "job_id", "name", "result")

    @classmethod
    def calculate_sha(self, name):
        assert name
        return sha1(name.encode("utf-8")).hexdigest()

    @property
    def sep(self):
        name = self.name
        # handle the case where it might begin with some special character
        if not re.match(r"^[a-zA-Z0-9]", name):
            return "/"

        elif "/" in name:
            return "/"

        return "."
Exemple #30
0
class StyleViolation(RepositoryBoundMixin, StandardAttributes, db.Model):
    """
    A single style violation.
    """
    job_id = db.Column(GUID,
                       db.ForeignKey('job.id', ondelete='CASCADE'),
                       nullable=False)
    filename = db.Column(db.Text, nullable=False)
    severity = db.Column(Enum(Severity),
                         default=Severity.error,
                         nullable=False)
    message = db.Column(db.Text, nullable=False)
    lineno = db.Column(db.Integer, nullable=True)
    colno = db.Column(db.Integer, nullable=True)
    source = db.Column(db.Text, nullable=True)

    job = db.relationship('Job')

    __tablename__ = 'styleviolation'
    __repr__ = model_repr('repository_id', 'job_id', 'filename', 'message')