Merge lp:~dooferlad/linaro-ci-dashboard/add_ci_job_loop into lp:linaro-ci-dashboard

Proposed by James Tunnicliffe
Status: Merged
Merged at revision: 70
Proposed branch: lp:~dooferlad/linaro-ci-dashboard/add_ci_job_loop
Merge into: lp:linaro-ci-dashboard
Diff against target: 562 lines (+349/-17)
18 files modified
HACKING (+12/-0)
Makefile (+2/-0)
README (+1/-0)
config_template/config.xml (+2/-2)
dashboard/frontend/api/api.py (+19/-2)
dashboard/frontend/api/urls.py (+1/-0)
dashboard/frontend/ci_job/migrations/0001_initial.py (+60/-0)
dashboard/frontend/ci_job/models/__init__.py (+1/-0)
dashboard/frontend/ci_job/models/ci_job.py (+107/-0)
dashboard/frontend/ci_job/urls.py (+31/-0)
dashboard/frontend/ci_job/views/ci_job_build_view.py (+25/-0)
dashboard/frontend/ci_job/views/ci_job_detail_view.py (+24/-0)
dashboard/frontend/models/loop_reference.py (+1/-0)
dashboard/frontend/tests/test_api.py (+58/-13)
dashboard/frontend/views/index_view.py (+2/-0)
dashboard/settings.py (+1/-0)
dashboard/urls.py (+1/-0)
requirements.txt (+1/-0)
To merge this branch: bzr merge lp:~dooferlad/linaro-ci-dashboard/add_ci_job_loop
Reviewer Review Type Date Requested Status
Linaro Infrastructure Pending
Review via email: mp+147694@code.launchpad.net
To post a comment you must log in.
Revision history for this message
James Tunnicliffe (dooferlad) wrote :

Crumbs. Got old tests in this. Will remove.

75. By James Tunnicliffe

Removed invalid tests

76. By James Tunnicliffe

Removed commented out code

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'HACKING'
--- HACKING 2012-09-21 09:24:01 +0000
+++ HACKING 2013-02-11 15:46:21 +0000
@@ -49,6 +49,18 @@
4949
50Tests should be written and defined inside each sub-application.50Tests should be written and defined inside each sub-application.
5151
52When defining a new application, make sure the model app_label matches what is
53listed in settings.py:
54
55class CIJob(Loop):
56 """Defines the base class for a CI Job."""
57 class Meta:
58 app_label = 'ci_job'
59
60INSTALLED_APPS = (
61...
62 'frontend.ci_job',
63
52== Class Hierarchy ==64== Class Hierarchy ==
5365
54=== Templates & Views ===66=== Templates & Views ===
5567
=== modified file 'Makefile'
--- Makefile 2012-09-24 13:18:02 +0000
+++ Makefile 2013-02-11 15:46:21 +0000
@@ -24,6 +24,8 @@
24 echo "No changes to android_textfield_loop models."24 echo "No changes to android_textfield_loop models."
25 python dashboard/manage.py schemamigration hwpack_loop --auto || \25 python dashboard/manage.py schemamigration hwpack_loop --auto || \
26 echo "No changes to hwpack_loop models."26 echo "No changes to hwpack_loop models."
27 python dashboard/manage.py schemamigration ci_job --auto || \
28 echo "No changes to ci_job models."
27 python dashboard/manage.py migrate29 python dashboard/manage.py migrate
2830
29migrate: syncdb31migrate: syncdb
3032
=== modified file 'README'
--- README 2013-02-01 11:49:24 +0000
+++ README 2013-02-11 15:46:21 +0000
@@ -17,6 +17,7 @@
17 build-essential17 build-essential
18 openjdk-6-jre-headless18 openjdk-6-jre-headless
19 python-tastypie19 python-tastypie
20 python-simplejson
2021
21To unit test the API that tastypie provides you need Django version of at least22To unit test the API that tastypie provides you need Django version of at least
221.4. If you have Django 1.3 the API will still work, but not be unit tested.231.4. If you have Django 1.3 the API will still work, but not be unit tested.
2324
=== modified file 'config_template/config.xml'
--- config_template/config.xml 2012-09-20 08:46:37 +0000
+++ config_template/config.xml 2013-02-11 15:46:21 +0000
@@ -50,7 +50,7 @@
50 </views>50 </views>
51 <primaryView>All</primaryView>51 <primaryView>All</primaryView>
52 <slaveAgentPort>0</slaveAgentPort>52 <slaveAgentPort>0</slaveAgentPort>
53 <label>IntegrationLoop AndroidLoop KernelLoop AndroidTextFieldLoop HwpackLoop</label>53 <label>IntegrationLoop AndroidLoop KernelLoop AndroidTextFieldLoop HwpackLoop CIJob</label>
54 <nodeProperties/>54 <nodeProperties/>
55 <globalNodeProperties/>55 <globalNodeProperties/>
56</hudson>
57\ No newline at end of file56\ No newline at end of file
57</hudson>
5858
=== modified file 'dashboard/frontend/api/api.py'
--- dashboard/frontend/api/api.py 2013-02-04 10:59:49 +0000
+++ dashboard/frontend/api/api.py 2013-02-11 15:46:21 +0000
@@ -16,9 +16,10 @@
16# along with linaro-ci-dashboard. If not, see <http://www.gnu.org/licenses/>.16# along with linaro-ci-dashboard. If not, see <http://www.gnu.org/licenses/>.
1717
18from tastypie.resources import ModelResource18from tastypie.resources import ModelResource
19from tastypie.authorization import DjangoAuthorization19from tastypie.authorization import DjangoAuthorization, Authorization
20from tastypie.authentication import ApiKeyAuthentication20from tastypie.authentication import ApiKeyAuthentication, Authentication
21from dashboard.frontend.models.loop import Loop21from dashboard.frontend.models.loop import Loop
22from frontend.ci_job.models.ci_job import CIJob
2223
23"""24"""
24Add API endpoint logic here. The documentation to do this can be found here:25Add API endpoint logic here. The documentation to do this can be found here:
@@ -54,3 +55,19 @@
54 resource_name = 'loops'55 resource_name = 'loops'
55 authorization = DjangoAuthorization()56 authorization = DjangoAuthorization()
56 authentication = ApiKeyAuthentication()57 authentication = ApiKeyAuthentication()
58
59class CIJobResource(ModelResource):
60 class Meta:
61 """Returns a list of all loops."""
62 queryset = CIJob.objects.all()
63 resource_name = 'jobs'
64 list_allowed_methods = ['get', 'post']
65 detail_allowed_methods = ['get', 'post', 'put', 'delete']
66
67 #http://django-tastypie.readthedocs.org/en/latest/authorization.html
68 # Currently everyone who has an API key is equal. Suggest we tie this
69 # down using a custom Authorization class (see above link) so anyone
70 # can create and modify their own jobs, but only some users have
71 # the ability to delete and modify other users' jobs.
72 authorization = Authorization() #DjangoAuthorization()
73 authentication = ApiKeyAuthentication()
5774
=== modified file 'dashboard/frontend/api/urls.py'
--- dashboard/frontend/api/urls.py 2013-02-04 17:55:49 +0000
+++ dashboard/frontend/api/urls.py 2013-02-11 15:46:21 +0000
@@ -7,6 +7,7 @@
7# Register new resources here (probably defined in api.py)7# Register new resources here (probably defined in api.py)
8v1_api.register(LoginTestResource())8v1_api.register(LoginTestResource())
9v1_api.register(LoopsResource())9v1_api.register(LoopsResource())
10v1_api.register(CIJobResource())
1011
11urlpatterns = patterns('',12urlpatterns = patterns('',
12 (r'^api/', include(v1_api.urls)),13 (r'^api/', include(v1_api.urls)),
1314
=== added directory 'dashboard/frontend/ci_job'
=== added file 'dashboard/frontend/ci_job/__init__.py'
=== added directory 'dashboard/frontend/ci_job/migrations'
=== added file 'dashboard/frontend/ci_job/migrations/0001_initial.py'
--- dashboard/frontend/ci_job/migrations/0001_initial.py 1970-01-01 00:00:00 +0000
+++ dashboard/frontend/ci_job/migrations/0001_initial.py 2013-02-11 15:46:21 +0000
@@ -0,0 +1,60 @@
1# -*- coding: utf-8 -*-
2import datetime
3from south.db import db
4from south.v2 import SchemaMigration
5from django.db import models
6
7
8class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Adding model 'CIJob'
12 db.create_table('ci_job_cijob', (
13 ('loop_ptr', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['frontend.Loop'], unique=True, primary_key=True)),
14 ('vcs_url', self.gf('django.db.models.fields.CharField')(max_length=255)),
15 ('vcs_branch', self.gf('django.db.models.fields.CharField')(default='', max_length=255)),
16 ('vcs_tag', self.gf('django.db.models.fields.CharField')(default='', max_length=255)),
17 ('file_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
18 ('class_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
19 ('run_when_ready', self.gf('django.db.models.fields.BooleanField')(default=False)),
20 ))
21 db.send_create_signal('ci_job', ['CIJob'])
22
23
24 def backwards(self, orm):
25 # Deleting model 'CIJob'
26 db.delete_table('ci_job_cijob')
27
28
29 models = {
30 'ci_job.cijob': {
31 'Meta': {'object_name': 'CIJob', '_ormbases': ['frontend.Loop']},
32 'class_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
33 'file_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
34 'loop_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['frontend.Loop']", 'unique': 'True', 'primary_key': 'True'}),
35 'run_when_ready': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
36 'vcs_branch': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
37 'vcs_tag': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
38 'vcs_url': ('django.db.models.fields.CharField', [], {'max_length': '255'})
39 },
40 'frontend.loop': {
41 'Meta': {'object_name': 'Loop'},
42 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
43 'is_official': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
44 'is_restricted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
45 'lava_tests': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
46 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}),
47 'next_loop': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'previous_loop'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['frontend.Loop']", 'blank': 'True', 'unique': 'True'}),
48 'server': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['jenkinsserver.JenkinsServer']", 'null': 'True', 'on_delete': 'models.SET_NULL'}),
49 'type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'})
50 },
51 'jenkinsserver.jenkinsserver': {
52 'Meta': {'object_name': 'JenkinsServer'},
53 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
54 'password': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
55 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
56 'username': ('django.db.models.fields.CharField', [], {'max_length': '100'})
57 }
58 }
59
60 complete_apps = ['ci_job']
0\ No newline at end of file61\ No newline at end of file
162
=== added file 'dashboard/frontend/ci_job/migrations/__init__.py'
=== added directory 'dashboard/frontend/ci_job/models'
=== added file 'dashboard/frontend/ci_job/models/__init__.py'
--- dashboard/frontend/ci_job/models/__init__.py 1970-01-01 00:00:00 +0000
+++ dashboard/frontend/ci_job/models/__init__.py 2013-02-11 15:46:21 +0000
@@ -0,0 +1,1 @@
1from frontend.ci_job.models.ci_job import *
02
=== added file 'dashboard/frontend/ci_job/models/ci_job.py'
--- dashboard/frontend/ci_job/models/ci_job.py 1970-01-01 00:00:00 +0000
+++ dashboard/frontend/ci_job/models/ci_job.py 2013-02-11 15:46:21 +0000
@@ -0,0 +1,107 @@
1# Copyright (C) 2012 Linaro
2#
3# This file is part of linaro-ci-dashboard.
4#
5# linaro-ci-dashboard is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Affero General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# linaro-ci-dashboard is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with linaro-ci-dashboard. If not, see <http://www.gnu.org/licenses/>.
17
18from django.db import models
19from frontend.models.loop import Loop
20from jenkinsserver.models.jenkins_server import JenkinsServer
21#from django.contrib.auth.models import User
22
23
24class CIJob(Loop):
25 """Defines the base class for a CI Job."""
26 class Meta:
27 app_label = 'ci_job'
28
29 vcs_url = models.CharField(max_length=255,
30 verbose_name='Configuration repository')
31 vcs_branch = models.CharField(max_length=255,
32 verbose_name='Configuration branch',
33 default='')
34 vcs_tag = models.CharField(max_length=255,
35 verbose_name='Configuration tag',
36 default='')
37 file_name = models.CharField(max_length=255,
38 verbose_name='Configuration file name')
39 class_name = models.CharField(max_length=255,
40 verbose_name='Configuration class name')
41 run_when_ready = models.BooleanField(default=False)
42
43 #job_owner = models.ForeignKey(User, editable=False,
44 # verbose_name='Job Owner')
45
46 def save(self, *args, **kwargs):
47 self.server = JenkinsServer.objects.get(id=1)
48 self.type = self.__class__.__name__
49 super(self.__class__, self).save(*args, **kwargs)
50 # We do not want a failure in remote server to affect the
51 # CI Loop flow.
52 try:
53 self.server.create_or_update_loop(self)
54 except:
55 # TODO: Log error.
56 pass
57
58 def schedule_build(self, parameters=None):
59 parameters = {'parameter': [{'delay': '0'}]}
60 return super(self.__class__, self).schedule_build(parameters)
61
62 def base64_config(self,
63 include=None,
64 exclude=None,
65 capitalize=False,
66 upper=False):
67 exclude = ['id', 'server', 'loop_ptr', 'next_loop', 'name', 'type']
68 return super(CIJob, self).base64_config(include=include,
69 exclude=exclude,
70 capitalize=capitalize,
71 upper=True)
72
73 def preconfigure(self, configuration=None):
74 """Makes a build parameter dict from build result configuration.
75
76 This method should be overridden by subclasses.
77 """
78 if isinstance(configuration, dict):
79 # The name is the name of the loop that is calling the chained one,
80 # not the one we want to actually configure, we drop it.
81 configuration.pop('name')
82 unmatched_values = u''
83 for key, value in configuration.iteritems():
84 if hasattr(self, key.lower()):
85 setattr(self, key.lower(), value)
86 else:
87 # If the attr cannot be found, we throw everything in
88 # user_defined_values since the text field is free form.
89 unmatched_values = u'%s=%s\n' % (key.upper(), str(value))
90
91 self.user_defined_values = unmatched_values
92 self.save()
93 else:
94 self.log.error("Parameter was not a 'dict' instance.")
95 return {}
96
97 @models.permalink
98 def get_detail_url(self):
99 return 'CIJobDetail', (), {'slug': self.name}
100
101 @models.permalink
102 def get_build_url(self):
103 return 'CIJobBuild', (), {'slug': self.name}
104
105 @models.permalink
106 def get_update_url(self):
107 return 'CIJobUpdate', (), {'slug': self.name}
0108
=== added file 'dashboard/frontend/ci_job/urls.py'
--- dashboard/frontend/ci_job/urls.py 1970-01-01 00:00:00 +0000
+++ dashboard/frontend/ci_job/urls.py 2013-02-11 15:46:21 +0000
@@ -0,0 +1,31 @@
1# Copyright (C) 2012 Linaro
2#
3# This file is part of linaro-ci-dashboard.
4#
5# linaro-ci-dashboard is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Affero General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# linaro-ci-dashboard is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with linaro-ci-dashboard. If not, see <http://www.gnu.org/licenses/>.
17
18from django.conf.urls.defaults import patterns, url
19
20from frontend.ci_job.views.ci_job_detail_view \
21 import CIJobDetailView
22from frontend.ci_job.views.ci_job_build_view \
23 import CIJobBuildView
24
25
26urlpatterns = patterns('',
27 url(r'^ci_job/detail/(?P<slug>[\w|\W]+)/$',
28 CIJobDetailView.as_view(), name='CIJobDetail'),
29 url(r'^ci_job/build/(?P<slug>[\w|\W]+)/$',
30 CIJobBuildView.as_view(), name='CIJobBuild'),
31)
032
=== added directory 'dashboard/frontend/ci_job/views'
=== added file 'dashboard/frontend/ci_job/views/__init__.py'
=== added file 'dashboard/frontend/ci_job/views/ci_job_build_view.py'
--- dashboard/frontend/ci_job/views/ci_job_build_view.py 1970-01-01 00:00:00 +0000
+++ dashboard/frontend/ci_job/views/ci_job_build_view.py 2013-02-11 15:46:21 +0000
@@ -0,0 +1,25 @@
1#!/usr/bin/env python
2# Copyright (C) 2012 Linaro
3#
4# This file is part of linaro-ci-dashboard.
5#
6# linaro-ci-dashboard is free software: you can redistribute it and/or modify
7# it under the terms of the GNU Affero General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# linaro-ci-dashboard is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU Affero General Public License for more details.
15#
16# You should have received a copy of the GNU Affero General Public License
17# along with linaro-ci-dashboard. If not, see <http://www.gnu.org/licenses/>.
18
19from frontend.ci_job.models.ci_job import CIJob
20from frontend.views.loop_build_view import LoopBuildView
21
22
23class CIJobBuildView(LoopBuildView):
24
25 model = CIJob
026
=== added file 'dashboard/frontend/ci_job/views/ci_job_detail_view.py'
--- dashboard/frontend/ci_job/views/ci_job_detail_view.py 1970-01-01 00:00:00 +0000
+++ dashboard/frontend/ci_job/views/ci_job_detail_view.py 2013-02-11 15:46:21 +0000
@@ -0,0 +1,24 @@
1# Copyright (C) 2012 Linaro
2#
3# This file is part of linaro-ci-dashboard.
4#
5# linaro-ci-dashboard is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Affero General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# linaro-ci-dashboard is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU Affero General Public License for more details.
14#
15# You should have received a copy of the GNU Affero General Public License
16# along with linaro-ci-dashboard. If not, see <http://www.gnu.org/licenses/>.
17
18from frontend.ci_job.models.ci_job import CIJob
19from frontend.views.loop_detail_view import LoopDetailView
20
21
22class CIJobDetailView(LoopDetailView):
23
24 model = CIJob
025
=== modified file 'dashboard/frontend/models/loop_reference.py'
--- dashboard/frontend/models/loop_reference.py 2012-09-18 12:16:59 +0000
+++ dashboard/frontend/models/loop_reference.py 2013-02-11 15:46:21 +0000
@@ -23,3 +23,4 @@
23INTEGRATION_LOOP = ('IntegrationLoop')23INTEGRATION_LOOP = ('IntegrationLoop')
24ANDROID_TEXTFIELD_LOOP = ('AndroidTextFieldLoop')24ANDROID_TEXTFIELD_LOOP = ('AndroidTextFieldLoop')
25HWPACK_LOOP = ('HwpackLoop')25HWPACK_LOOP = ('HwpackLoop')
26CI_JOB = ('CIJob')
2627
=== modified file 'dashboard/frontend/tests/test_api.py'
--- dashboard/frontend/tests/test_api.py 2013-02-04 17:55:49 +0000
+++ dashboard/frontend/tests/test_api.py 2013-02-11 15:46:21 +0000
@@ -20,8 +20,10 @@
20from tastypie.models import ApiKey20from tastypie.models import ApiKey
21from dashboard.frontend.models.loop import Loop21from dashboard.frontend.models.loop import Loop
22from dashboard.frontend.android_build.models.android_loop import AndroidLoop22from dashboard.frontend.android_build.models.android_loop import AndroidLoop
23from dashboard.frontend.ci_job.models.ci_job import CIJob
23import requests24import requests
24from urlparse import urljoin25from urlparse import urljoin
26import simplejson
2527
2628
27class ApiTests(LiveServerTestCase):29class ApiTests(LiveServerTestCase):
@@ -32,13 +34,18 @@
32 def setUp(self):34 def setUp(self):
33 super(ApiTests, self).setUp()35 super(ApiTests, self).setUp()
3436
37 self.settings = {}
38 self.settings["ci_server"] = "http://localhost:8081"
39 self.settings["api_prefix"] = "/api/dev/"
40 self.settings["username"] = 'daniel'
41 self.settings["password"] = 'pass'
42 self.settings["api_key"] = "0"
43
35 # Create a user.44 # Create a user.
36 self.username = 'daniel'
37 self.password = 'pass'
38 self.user = User.objects.create_user(45 self.user = User.objects.create_user(
39 self.username, 'daniel@example.com', self.password)46 self.settings["username"],
4047 'daniel@example.com',
41 self.api_key = "0"48 self.settings["password"])
4249
43 # Add a couple of jobs to test against.50 # Add a couple of jobs to test against.
44 self.android_loop = AndroidLoop()51 self.android_loop = AndroidLoop()
@@ -51,16 +58,35 @@
51 self.loop.type = Loop.__class__.__name__58 self.loop.type = Loop.__class__.__name__
52 self.loop.save()59 self.loop.save()
5360
54 def get(self, url):61 def get(self, url, in_params=None):
55 payload = {"username": self.username,62 url, params = self._prep_request(url, in_params)
56 "api_key": self.api_key,63 return requests.get(url, params=params)
57 "format": "json"}64
58 url = urljoin("http://localhost:8081", "/api/dev/" + url)65 def post(self, url, data, in_params=None):
59 return requests.get(url, params=payload)66 url, params = self._prep_request(url, in_params)
67 return requests.post(url, data=data, params=params,
68 headers={"content-type": "application/json"})
69
70 def _prep_request(self, url, in_params=None):
71 params = {"username": self.settings["username"],
72 "api_key": self.settings["api_key"],
73 "format": "json"}
74
75 url = urljoin(self.settings["ci_server"],
76 self.settings["api_prefix"] + url)
77
78 # If we don't have a trailing slash, we will just be redirected. Avoid
79 # the extra call.
80 if url[-1] != "/":
81 url += "/"
82
83 if in_params:
84 params.update(in_params)
85
86 return url, params
6087
61 def login(self):88 def login(self):
62 self.api_key = ApiKey.objects.create(user=self.user).key89 self.settings["api_key"] = ApiKey.objects.create(user=self.user).key
63 #self.create_apikey(self.username, self.api_key)
6490
65 def test_login_test_unauthorzied(self):91 def test_login_test_unauthorzied(self):
66 r = self.get("login_test")92 r = self.get("login_test")
@@ -93,3 +119,22 @@
93 api_test_names = {json[0]['name'], json[1]['name']}119 api_test_names = {json[0]['name'], json[1]['name']}
94 test_names = {self.android_loop.name, self.loop.name}120 test_names = {self.android_loop.name, self.loop.name}
95 self.assertEqual(api_test_names, test_names)121 self.assertEqual(api_test_names, test_names)
122
123 def test_add_job(self):
124 self.login()
125 data = {
126 "vcs_url": "vcsurl",
127 "file_name": "filename",
128 "class_name": "classname",
129 "run": False,
130 "name": "jobname"
131 }
132 json_data = simplejson.dumps(data)
133
134 r = self.post("jobs", json_data, {})
135 self.assertEqual(r.status_code, requests.codes.created)
136
137 jobs = CIJob.objects.all()
138
139 self.assertEqual(len(jobs), 1)
140 self.assertEqual(jobs[0].name, data["name"])
96141
=== modified file 'dashboard/frontend/views/index_view.py'
--- dashboard/frontend/views/index_view.py 2012-09-13 11:37:13 +0000
+++ dashboard/frontend/views/index_view.py 2013-02-11 15:46:21 +0000
@@ -25,6 +25,7 @@
25from frontend.android_textfield_loop.models.android_textfield_loop \25from frontend.android_textfield_loop.models.android_textfield_loop \
26 import AndroidTextFieldLoop26 import AndroidTextFieldLoop
27from frontend.hwpack_loop.models.hwpack_loop import HwpackLoop27from frontend.hwpack_loop.models.hwpack_loop import HwpackLoop
28from frontend.ci_job.models.ci_job import CIJob
2829
29class IndexView(TemplateView):30class IndexView(TemplateView):
3031
@@ -42,4 +43,5 @@
42 context['kernel_loops'] = KernelLoop.objects.all()43 context['kernel_loops'] = KernelLoop.objects.all()
43 context['android_textfield_loops'] = AndroidTextFieldLoop.objects.all()44 context['android_textfield_loops'] = AndroidTextFieldLoop.objects.all()
44 context['hwpack_loops'] = HwpackLoop.objects.all()45 context['hwpack_loops'] = HwpackLoop.objects.all()
46 context['ci_jobs'] = CIJob.objects.all()
45 return context47 return context
4648
=== modified file 'dashboard/settings.py'
--- dashboard/settings.py 2013-01-30 17:20:40 +0000
+++ dashboard/settings.py 2013-02-11 15:46:21 +0000
@@ -158,6 +158,7 @@
158 'frontend.android_textfield_loop',158 'frontend.android_textfield_loop',
159 'frontend.hwpack_loop',159 'frontend.hwpack_loop',
160 'frontend.api',160 'frontend.api',
161 'frontend.ci_job',
161 'tastypie',162 'tastypie',
162 'south',163 'south',
163 # Uncomment the next line to enable admin documentation:164 # Uncomment the next line to enable admin documentation:
164165
=== modified file 'dashboard/urls.py'
--- dashboard/urls.py 2013-01-21 16:16:03 +0000
+++ dashboard/urls.py 2013-02-11 15:46:21 +0000
@@ -40,4 +40,5 @@
40 url(r'^', include('dashboard.frontend.android_textfield_loop.urls')),40 url(r'^', include('dashboard.frontend.android_textfield_loop.urls')),
41 url(r'^', include('dashboard.frontend.hwpack_loop.urls')),41 url(r'^', include('dashboard.frontend.hwpack_loop.urls')),
42 url(r'^', include('dashboard.frontend.api.urls')),42 url(r'^', include('dashboard.frontend.api.urls')),
43 url(r'^', include('dashboard.frontend.ci_job.urls')),
43)44)
4445
=== modified file 'requirements.txt'
--- requirements.txt 2013-02-01 11:39:17 +0000
+++ requirements.txt 2013-02-11 15:46:21 +0000
@@ -12,4 +12,5 @@
12python-jenkins==0.212python-jenkins==0.2
13python-openid==2.2.513python-openid==2.2.5
14requests==1.1.014requests==1.1.0
15simplejson==3.0.7
15wsgiref==0.1.216wsgiref==0.1.2

Subscribers

People subscribed via source and target branches