| 1 : |
tobias
|
1.1
|
from django.db import models |
| 2 : |
tobias
|
1.4
|
from django.contrib.auth.models import User |
| 3 : |
|
|
from lkrtweb.lkrt.helpers import db |
| 4 : |
|
|
from django.core.exceptions import ObjectDoesNotExist |
| 5 : |
tobias
|
1.1
|
|
| 6 : |
tobias
|
1.3
|
import os |
| 7 : |
|
|
|
| 8 : |
tobias
|
1.1
|
class UserProfile(models.Model): |
| 9 : |
|
|
user = models.OneToOneField(User, related_name='profile') |
| 10 : |
|
|
url = models.URLField() |
| 11 : |
|
|
|
| 12 : |
|
|
class Architecture(models.Model): |
| 13 : |
|
|
safename = models.CharField(maxlength=15) |
| 14 : |
|
|
name = models.CharField(maxlength=30) |
| 15 : |
|
|
# summary = models.TextField() |
| 16 : |
tobias
|
1.2
|
|
| 17 : |
|
|
def status_for_kern(self, kern): |
| 18 : |
|
|
tests = FunctionalTest.objects.filter(kversion__id=kern.id, client__arch__id=self.id) |
| 19 : |
|
|
|
| 20 : |
|
|
if tests.count() > 0: |
| 21 : |
|
|
val = 0 |
| 22 : |
|
|
for test in tests: |
| 23 : |
|
|
val = max(val, test.status_id) |
| 24 : |
|
|
result = Status.objects.get(id=val) |
| 25 : |
|
|
else: |
| 26 : |
|
|
result = None |
| 27 : |
|
|
|
| 28 : |
|
|
return result |
| 29 : |
tobias
|
1.1
|
|
| 30 : |
|
|
def __str__(self): |
| 31 : |
|
|
return self.name |
| 32 : |
|
|
|
| 33 : |
tobias
|
1.2
|
class Meta: |
| 34 : |
|
|
ordering = ['name'] |
| 35 : |
|
|
|
| 36 : |
tobias
|
1.1
|
class Admin: |
| 37 : |
tobias
|
1.2
|
list_display = ('safename', 'name') |
| 38 : |
tobias
|
1.1
|
|
| 39 : |
tobias
|
1.5
|
class JobScheduler(models.Model): |
| 40 : |
|
|
owner = models.ForeignKey(User) |
| 41 : |
|
|
name = models.CharField(maxlength=30) |
| 42 : |
|
|
info = models.TextField() |
| 43 : |
|
|
|
| 44 : |
|
|
def __str__(self): |
| 45 : |
|
|
return self.name |
| 46 : |
|
|
|
| 47 : |
|
|
class Admin: |
| 48 : |
|
|
pass |
| 49 : |
|
|
|
| 50 : |
tobias
|
1.1
|
class ClientMachine(models.Model): |
| 51 : |
|
|
owner = models.ForeignKey(User) |
| 52 : |
tobias
|
1.2
|
arch = models.ForeignKey(Architecture, verbose_name='architecture') |
| 53 : |
tobias
|
1.5
|
scheduler = models.ForeignKey(JobScheduler, related_name='clients') |
| 54 : |
tobias
|
1.1
|
name = models.CharField(maxlength=30) |
| 55 : |
tobias
|
1.2
|
hostname = models.CharField(maxlength=200) |
| 56 : |
|
|
info_url = models.URLField(blank=True) |
| 57 : |
|
|
last_seen = models.DateTimeField(null=True ) |
| 58 : |
|
|
|
| 59 : |
|
|
def all_archs(): |
| 60 : |
|
|
client_tbl = ClientMachine._meta.db_table # 'lkrt_clientmachine' |
| 61 : |
|
|
arch_tbl = Architecture._meta.db_table # 'lkrt_architecture' |
| 62 : |
|
|
return Architecture.objects.extra(tables=[client_tbl], where=['%s.arch_id=%s.id' % (client_tbl, arch_tbl)] ).distinct() |
| 63 : |
|
|
all_archs = staticmethod(all_archs) |
| 64 : |
tobias
|
1.1
|
|
| 65 : |
|
|
def __str__(self): |
| 66 : |
tobias
|
1.2
|
return self.hostname |
| 67 : |
tobias
|
1.1
|
|
| 68 : |
|
|
class Admin: |
| 69 : |
tobias
|
1.2
|
list_display = ('name', 'hostname', 'arch', 'owner', 'last_seen') |
| 70 : |
tobias
|
1.1
|
|
| 71 : |
|
|
class ToolchainProfile(models.Model): |
| 72 : |
|
|
manufacturer = models.CharField(maxlength=60) |
| 73 : |
|
|
cc_version = models.CharField(maxlength=30) |
| 74 : |
|
|
ld_version = models.CharField(maxlength=30) |
| 75 : |
|
|
|
| 76 : |
|
|
def __str__(self): |
| 77 : |
|
|
return self.name |
| 78 : |
|
|
|
| 79 : |
tobias
|
1.2
|
class Admin: |
| 80 : |
|
|
list_display = ('manufacturer', 'cc_version', 'ld_version') |
| 81 : |
|
|
|
| 82 : |
tobias
|
1.1
|
class SourceTree(models.Model): |
| 83 : |
tobias
|
1.2
|
safename = models.CharField(maxlength=30) |
| 84 : |
tobias
|
1.1
|
name = models.CharField(maxlength=200) |
| 85 : |
tobias
|
1.2
|
url = models.URLField() |
| 86 : |
tobias
|
1.1
|
|
| 87 : |
|
|
watchers = models.ManyToManyField(User, related_name='trees_watching') |
| 88 : |
|
|
|
| 89 : |
|
|
def __str__(self): |
| 90 : |
|
|
return self.name |
| 91 : |
|
|
|
| 92 : |
|
|
class Admin: |
| 93 : |
tobias
|
1.2
|
list_display = ('safename', 'name', 'url') |
| 94 : |
|
|
|
| 95 : |
|
|
class File(models.Model): |
| 96 : |
|
|
# is there a need for both name and url, or can name be extracted from url? |
| 97 : |
|
|
#name = models.CharField(maxlength=20) |
| 98 : |
|
|
url = models.URLField(unique=True) |
| 99 : |
|
|
|
| 100 : |
|
|
def get_name(self): |
| 101 : |
|
|
return os.path.basename(self.url) |
| 102 : |
|
|
name = property(get_name) |
| 103 : |
|
|
|
| 104 : |
|
|
def __str__(self): |
| 105 : |
|
|
return self.name |
| 106 : |
|
|
|
| 107 : |
|
|
class Admin: |
| 108 : |
tobias
|
1.1
|
pass |
| 109 : |
|
|
|
| 110 : |
|
|
class KernelVersion(models.Model): |
| 111 : |
tobias
|
1.2
|
tree = models.ForeignKey(SourceTree, related_name='kernel_versions') |
| 112 : |
tobias
|
1.1
|
base = models.CharField(maxlength=30) |
| 113 : |
tobias
|
1.2
|
|
| 114 : |
|
|
patches = models.ManyToManyField(File) |
| 115 : |
|
|
|
| 116 : |
|
|
def save(self): |
| 117 : |
|
|
# try to figure out tree if it wasn't already set |
| 118 : |
|
|
if self.base != None and self.tree_id == None: |
| 119 : |
|
|
if self.base.count('git') > 0: |
| 120 : |
|
|
self.tree = SourceTree.objects.get(safename='snapshot') |
| 121 : |
|
|
elif self.base.count('ac') > 0: |
| 122 : |
|
|
self.tree = SourceTree.objects.get(safename='ac') |
| 123 : |
|
|
elif self.base.count('dj') > 0: |
| 124 : |
|
|
self.tree = SourceTree.objects.get(safename='dj') |
| 125 : |
|
|
elif self.base.count('mm') > 0: |
| 126 : |
|
|
self.tree = SourceTree.objects.get(safename='mm') |
| 127 : |
|
|
elif self.base.count('rc') > 0: |
| 128 : |
|
|
self.tree = SourceTree.objects.get(safename='pre') |
| 129 : |
|
|
else: |
| 130 : |
|
|
self.tree = SourceTree.objects.get(safename='main') |
| 131 : |
|
|
|
| 132 : |
|
|
super(KernelVersion, self).save() |
| 133 : |
|
|
|
| 134 : |
|
|
def status_for_arch(self, arch): |
| 135 : |
tobias
|
1.4
|
objs = db.query('''SELECT max(status_id) as status_id |
| 136 : |
|
|
FROM $FunctionalTest$, $ClientMachine$ |
| 137 : |
|
|
WHERE $FunctionalTest$.client_id = $ClientMachine$.id |
| 138 : |
|
|
AND $ClientMachine$.arch_id=%s |
| 139 : |
|
|
AND $FunctionalTest$.kversion_id=%s''' % (arch.id, self.id)) |
| 140 : |
|
|
|
| 141 : |
|
|
stat = None |
| 142 : |
|
|
|
| 143 : |
|
|
if objs[0][0] != None: |
| 144 : |
|
|
try: |
| 145 : |
|
|
stat = Status.objects.get(id=objs[0][0]) |
| 146 : |
|
|
except ObjectDoesNotExist: |
| 147 : |
|
|
pass |
| 148 : |
|
|
|
| 149 : |
|
|
return stat |
| 150 : |
|
|
|
| 151 : |
|
|
# tests = FunctionalTest.objects.filter(kversion__id=self.id, client__arch__id=arch.id) |
| 152 : |
|
|
# |
| 153 : |
|
|
# if tests.count() > 0: |
| 154 : |
|
|
# val = 0 |
| 155 : |
|
|
# for test in tests: |
| 156 : |
|
|
# val = max(val, test.status_id) |
| 157 : |
|
|
# result = Status.objects.get(id=val) |
| 158 : |
|
|
# else: |
| 159 : |
|
|
# result = None |
| 160 : |
|
|
# |
| 161 : |
|
|
# return result |
| 162 : |
tobias
|
1.2
|
|
| 163 : |
tobias
|
1.5
|
def archs(self): |
| 164 : |
|
|
client_tbl = ClientMachine._meta.db_table # 'lkrt_clientmachine' |
| 165 : |
|
|
arch_tbl = Architecture._meta.db_table # 'lkrt_architecture' |
| 166 : |
|
|
kversion_tbl = KernelVersion._meta.db_table # 'lkrt_kernelversion' |
| 167 : |
|
|
ft_tbl = FunctionalTest._meta.db_table # 'lkrt_functionaltest' |
| 168 : |
|
|
return Architecture.objects.extra(tables = [ client_tbl, kversion_tbl, ft_tbl ], |
| 169 : |
|
|
where = [ '%s.arch_id=%s.id' % (client_tbl, arch_tbl), |
| 170 : |
|
|
'%s.client_id=%s.id' % (ft_tbl, client_tbl), |
| 171 : |
|
|
'%s.kversion_id=%s' % (ft_tbl, self.id)] |
| 172 : |
|
|
).distinct() |
| 173 : |
|
|
|
| 174 : |
tobias
|
1.2
|
def add_patch_at_url(self, url): |
| 175 : |
|
|
patch, created = File.objects.get_or_create(url=url) |
| 176 : |
|
|
self.patches.add(patch) |
| 177 : |
|
|
|
| 178 : |
|
|
def get_printable(self): |
| 179 : |
|
|
result = self.base |
| 180 : |
|
|
for patch in self.patches.all(): |
| 181 : |
|
|
result = "%s +%s" % (result, patch.name) |
| 182 : |
|
|
return result |
| 183 : |
|
|
printable = property(get_printable) |
| 184 : |
tobias
|
1.1
|
|
| 185 : |
|
|
def __str__(self): |
| 186 : |
tobias
|
1.2
|
return self.printable |
| 187 : |
tobias
|
1.1
|
|
| 188 : |
tobias
|
1.2
|
class Meta: |
| 189 : |
|
|
ordering = ['id'] |
| 190 : |
tobias
|
1.1
|
|
| 191 : |
tobias
|
1.2
|
class Admin: |
| 192 : |
|
|
list_display = ('printable', 'tree') |
| 193 : |
tobias
|
1.1
|
|
| 194 : |
tobias
|
1.2
|
class Status(models.Model): |
| 195 : |
|
|
name = models.CharField(maxlength=15) |
| 196 : |
tobias
|
1.1
|
|
| 197 : |
|
|
def __str__(self): |
| 198 : |
|
|
return self.name |
| 199 : |
tobias
|
1.2
|
|
| 200 : |
|
|
class Meta: |
| 201 : |
|
|
verbose_name_plural = 'statuses' |
| 202 : |
|
|
|
| 203 : |
|
|
class Admin: |
| 204 : |
|
|
pass |
| 205 : |
tobias
|
1.1
|
|
| 206 : |
tobias
|
1.2
|
# what's the difference between this and the FunctionalJob |
| 207 : |
|
|
#class Job(models.Model): |
| 208 : |
|
|
# tag = models.CharField(maxlength=15) |
| 209 : |
|
|
# kversion = models.ForeignKey(KernelVersion) |
| 210 : |
|
|
# status = models.ForeignKey(Status) |
| 211 : |
|
|
# reason = models.CharField(maxlength=100) |
| 212 : |
|
|
# machine = models.ForeignKey(ClientMachine) |
| 213 : |
|
|
|
| 214 : |
|
|
# def __str__(self): |
| 215 : |
|
|
# return self.machine, self.kversion, self.status |
| 216 : |
|
|
|
| 217 : |
|
|
class TestType(models.Model): |
| 218 : |
|
|
name = models.CharField(maxlength=30, unique=True) |
| 219 : |
tobias
|
1.1
|
|
| 220 : |
|
|
def __str__(self): |
| 221 : |
|
|
return self.name |
| 222 : |
|
|
|
| 223 : |
tobias
|
1.2
|
class Admin: |
| 224 : |
|
|
pass |
| 225 : |
|
|
|
| 226 : |
|
|
class FunctionalTest(models.Model): |
| 227 : |
|
|
type = models.ForeignKey(TestType) |
| 228 : |
|
|
# subdir = models.CharField(maxlength=60) |
| 229 : |
|
|
kversion = models.ForeignKey(KernelVersion, verbose_name='kernel version', related_name='functional_tests') |
| 230 : |
|
|
client = models.ForeignKey(ClientMachine) |
| 231 : |
|
|
status = models.ForeignKey(Status) |
| 232 : |
|
|
reason = models.CharField(maxlength=1024) |
| 233 : |
tobias
|
1.1
|
|
| 234 : |
|
|
def __str__(self): |
| 235 : |
tobias
|
1.2
|
return "%s test of %s: %s" % (self.type, self.kversion, self.status) |
| 236 : |
tobias
|
1.1
|
|
| 237 : |
tobias
|
1.2
|
class Admin: |
| 238 : |
|
|
list_display = ('id', 'kversion', 'client', 'type', 'status', 'reason') |
| 239 : |
tobias
|
1.1
|
|
| 240 : |
tobias
|
1.2
|
#class TestAttribute(models.Model): |
| 241 : |
|
|
# name = models.CharField(maxlength=20) |
| 242 : |
|
|
# |
| 243 : |
|
|
# def __str__(self): |
| 244 : |
|
|
# return self.name |
| 245 : |
|
|
|
| 246 : |
|
|
#class Result(models.Model): |
| 247 : |
|
|
# job = models.ForeignKey(Job) |
| 248 : |
|
|
# test = models.ForeignKey(Test) |
| 249 : |
|
|
# subdir = models.CharField(maxlength=60) |
| 250 : |
|
|
# kversion = models.ForeignKey(KernelVersion) |
| 251 : |
|
|
# attribute = models.ForeignKey(TestAttribute) |
| 252 : |
|
|
# value = models.IntegerField() |
| 253 : |
tobias
|
1.1
|
|
| 254 : |
tobias
|
1.2
|
# def __str__(self): |
| 255 : |
|
|
# return self.test, self.kversion |
| 256 : |
tobias
|
1.1
|
|
| 257 : |
|
|
def create_initial_data(): |
| 258 : |
tobias
|
1.2
|
if Status.objects.count() > 0: |
| 259 : |
tobias
|
1.1
|
return |
| 260 : |
|
|
|
| 261 : |
tobias
|
1.2
|
Status ( name='GOOD' ).save() |
| 262 : |
|
|
Status ( name='WARN' ).save() |
| 263 : |
|
|
Status ( name='FAIL' ).save() |
| 264 : |
|
|
Status ( name='ABORT' ).save() |
| 265 : |
|
|
|
| 266 : |
tobias
|
1.1
|
Architecture( safename='alpha', name='Alpha' ).save() |
| 267 : |
|
|
Architecture( safename='arm', name='ARM' ).save() |
| 268 : |
|
|
Architecture( safename='arm26', name='ARM26' ).save() |
| 269 : |
|
|
Architecture( safename='cris', name='CRIS' ).save() |
| 270 : |
|
|
Architecture( safename='frv', name='FRV' ).save() |
| 271 : |
|
|
Architecture( safename='h8300', name='H8300 ' ).save() |
| 272 : |
|
|
Architecture( safename='i386', name='i386' ).save() |
| 273 : |
|
|
Architecture( safename='ia64', name='IA-64' ).save() |
| 274 : |
|
|
Architecture( safename='m32r', name='M32R' ).save() |
| 275 : |
|
|
Architecture( safename='m68k', name='m68k' ).save() |
| 276 : |
|
|
Architecture( safename='m68knommu', name='m68knommu' ).save() |
| 277 : |
|
|
Architecture( safename='mips', name='MIPS' ).save() |
| 278 : |
|
|
Architecture( safename='parisc', name='PA-RISC' ).save() |
| 279 : |
|
|
Architecture( safename='powerpc', name='PowerPC' ).save() |
| 280 : |
|
|
Architecture( safename='s390', name='s390' ).save() |
| 281 : |
|
|
Architecture( safename='sh', name='SH' ).save() |
| 282 : |
|
|
Architecture( safename='sh64', name='SH64' ).save() |
| 283 : |
|
|
Architecture( safename='sparc', name='SPARC' ).save() |
| 284 : |
|
|
Architecture( safename='sparc64', name='SPARC-64' ).save() |
| 285 : |
|
|
Architecture( safename='um', name='User Mode Linux' ).save() |
| 286 : |
|
|
Architecture( safename='v850', name='v850' ).save() |
| 287 : |
|
|
Architecture( safename='x86_64', name='x86_64' ).save() |
| 288 : |
|
|
Architecture( safename='xtensa', name='Xtensa' ).save() |
| 289 : |
tobias
|
1.2
|
|
| 290 : |
|
|
SourceTree( safename='main', name='main line', url='http://kernel.org' ).save() |
| 291 : |
|
|
SourceTree( safename='ac', name="-ac patch line" , url='http://kernel.org/patchtypes/ac.html' ).save() |
| 292 : |
|
|
SourceTree( safename='dj', name="-dj patch line", url='http://kernel.org/patchtypes/dj.html' ).save() |
| 293 : |
|
|
SourceTree( safename='mm', name="-mm patch line", url='http://kernel.org/patchtypes/mm.html' ).save() |
| 294 : |
|
|
SourceTree( safename='pre', name='prepatch', url='http://kernel.org/patchtypes/pre.html' ).save() |
| 295 : |
|
|
SourceTree( safename='snapshot', name='snapshot', url='http://kernel.org/patchtypes/pre.html' ).save() |
| 296 : |
|
|
|
| 297 : |
|
|
tobias = User.objects.get(username='tobias') |
| 298 : |
|
|
|
| 299 : |
|
|
x86_64 = Architecture.objects.get(safename='x86_64') |
| 300 : |
|
|
ppc = Architecture.objects.get(safename='powerpc') |
| 301 : |
|
|
x86 = Architecture.objects.get(safename='i386') |
| 302 : |
|
|
|
| 303 : |
tobias
|
1.5
|
abat = JobScheduler( owner=tobias, name='abat', info='IBM\'s proprietary job scheduler' ) |
| 304 : |
|
|
abat.save() |
| 305 : |
|
|
|
| 306 : |
|
|
ClientMachine( name='elm3b6', scheduler=abat, owner=tobias, arch=x86_64, hostname='elm3b6').save() |
| 307 : |
|
|
ClientMachine( name='moe', scheduler=abat, owner=tobias, arch=x86, hostname='moe').save() |
| 308 : |
|
|
ClientMachine( name='elm3b132', scheduler=abat, owner=tobias, arch=x86, hostname='elm3b132').save() |
| 309 : |
|
|
ClientMachine( name='elm3b133', scheduler=abat, owner=tobias, arch=x86, hostname='elm3b133').save() |
| 310 : |
|
|
ClientMachine( name='gekko-lp1', scheduler=abat, owner=tobias, arch=ppc, hostname='gekko-lp1').save() |
| 311 : |
|
|
ClientMachine( name='pSeries-101', scheduler=abat, owner=tobias, arch=ppc , hostname='pSeries-101').save() |
| 312 : |
|
|
ClientMachine( name='bl6-13', scheduler=abat, owner=tobias, arch=x86_64, hostname='bl6-13').save() |
| 313 : |
|
|
ClientMachine( name='elm3b239', scheduler=abat, owner=tobias, arch=x86_64, hostname='elm3b239').save() |
| 314 : |
tobias
|
1.2
|
|
| 315 : |
|
|
|