summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Wood <michael.g.wood@intel.com>2015-11-26 16:44:35 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-12-07 17:01:20 +0000
commit71ede7b689475a09ee14cfb94a0ad6458be87738 (patch)
tree09bac3ab347b2e32dea44573085b2789861f2109
parent34b22cf8971d244d0dd6ac10769915e1f455fd9e (diff)
downloadpoky-71ede7b689475a09ee14cfb94a0ad6458be87738.tar.gz
bitbake: toaster: toastergui tests Add generic test for ToasterTables widget
For each of the ToasterTables defined test: - Data returned - Search - Order by - Limit - Paginate - Filter These tests test that the functions on all tables work, it does not validate the content of the data in the tables themselves, this needs to be done in table specific tests. (Bitbake rev: 649d563f95ffc57d0fe3dbf494e7dbffcc99a1b4) Signed-off-by: Michael Wood <michael.g.wood@intel.com> Signed-off-by: Elliot Smith <elliot.smith@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/toaster/toastergui/tests.py223
1 files changed, 212 insertions, 11 deletions
diff --git a/bitbake/lib/toaster/toastergui/tests.py b/bitbake/lib/toaster/toastergui/tests.py
index 9e6c46a253..a6312034a8 100644
--- a/bitbake/lib/toaster/toastergui/tests.py
+++ b/bitbake/lib/toaster/toastergui/tests.py
@@ -33,11 +33,14 @@ from orm.models import CustomImageRecipe, ProjectVariable
33from orm.models import Branch 33from orm.models import Branch
34 34
35import toastermain 35import toastermain
36import inspect
37import toastergui
36 38
37from toastergui.tables import SoftwareRecipesTable 39from toastergui.tables import SoftwareRecipesTable
38import json 40import json
39from bs4 import BeautifulSoup 41from bs4 import BeautifulSoup
40import re 42import re
43import string
41 44
42PROJECT_NAME = "test project" 45PROJECT_NAME = "test project"
43CLI_BUILDS_PROJECT_NAME = 'Command line builds' 46CLI_BUILDS_PROJECT_NAME = 'Command line builds'
@@ -69,32 +72,68 @@ class ViewTests(TestCase):
69 layer = Layer.objects.create(name="base-layer", layer_source=layersrc, 72 layer = Layer.objects.create(name="base-layer", layer_source=layersrc,
70 vcs_url="/tmp/") 73 vcs_url="/tmp/")
71 74
75 layer_two = Layer.objects.create(name="z-layer",
76 layer_source=layersrc,
77 vcs_url="git://two/")
78
79
72 branch = Branch.objects.create(name="master", layer_source=layersrc) 80 branch = Branch.objects.create(name="master", layer_source=layersrc)
73 81
74 lver = Layer_Version.objects.create(layer=layer, project=self.project, 82 self.lver = Layer_Version.objects.create(layer=layer,
75 layer_source=layersrc, commit="master", 83 project=self.project,
76 up_branch=branch) 84 layer_source=layersrc,
85 commit="master",
86 up_branch=branch)
87
88 lver_two = Layer_Version.objects.create(layer=layer_two,
89 layer_source=layersrc,
90 commit="master",
91 up_branch=branch)
92
93 Recipe.objects.create(layer_source=layersrc,
94 name="z recipe",
95 version="5.2",
96 summary="z recipe",
97 description="G recipe",
98 license="Z GPL",
99 section="h section",
100 layer_version=lver_two)
77 101
78 self.recipe1 = Recipe.objects.create(layer_source=layersrc, 102 self.recipe1 = Recipe.objects.create(layer_source=layersrc,
79 name="base-recipe", 103 name="base-recipe",
80 version="1.2", 104 version="1.2",
81 summary="one recipe", 105 summary="one recipe",
82 description="recipe", 106 description="recipe",
83 layer_version=lver) 107 section="A section",
108 license="Apache",
109 layer_version=self.lver)
84 110
85 Machine.objects.create(layer_version=lver, name="wisk", 111 Machine.objects.create(layer_version=self.lver, name="wisk",
86 description="wisking machine") 112 description="wisking machine")
113 Machine.objects.create(layer_version=self.lver, name="zap",
114 description="zap machine")
115 Machine.objects.create(layer_version=lver_two, name="xray",
116 description="xray machine")
117
87 118
88 ProjectLayer.objects.create(project=self.project, layercommit=lver) 119
120 ProjectLayer.objects.create(project=self.project, layercommit=self.lver)
89 121
90 122
91 self.customr = CustomImageRecipe.objects.create(\ 123 self.customr = CustomImageRecipe.objects.create(\
92 name="custom recipe", project=self.project, 124 name="custom recipe", project=self.project,
93 base_recipe=self.recipe1) 125 base_recipe=self.recipe1)
94 126
95 self.package = Package.objects.create(name='pkg1', recipe=self.recipe1, 127 CustomImageRecipe.objects.create(name="z custom recipe",
128 project=self.project,
129 base_recipe=self.recipe1)
130
131 self.package = Package.objects.create(name='pkg1',
132 size=999,
133 recipe=self.recipe1,
96 build=build) 134 build=build)
97 135
136 Package.objects.create(name='zpkg1', recipe=self.recipe1, build=build)
98 137
99 # recipe with project for testing AvailableRecipe table 138 # recipe with project for testing AvailableRecipe table
100 self.recipe2 = Recipe.objects.create(layer_source=layersrc, 139 self.recipe2 = Recipe.objects.create(layer_source=layersrc,
@@ -102,10 +141,35 @@ class ViewTests(TestCase):
102 version="1.4", 141 version="1.4",
103 summary="a fancy recipe", 142 summary="a fancy recipe",
104 description="fancy recipe", 143 description="fancy recipe",
105 layer_version=lver, 144 license="MIT",
145 layer_version=self.lver,
146 section="Z section",
106 file_path='/home/foo') 147 file_path='/home/foo')
107 148
108 self.assertTrue(lver in self.project.compatible_layerversions()) 149 Recipe.objects.create(layer_source=layersrc,
150 is_image=True,
151 name="Test image one",
152 version="1.2",
153 summary="one recipe",
154 description="recipe",
155 section="A",
156 license="A",
157 file_path="/one/",
158 layer_version=self.lver)
159
160 Recipe.objects.create(layer_source=layersrc,
161 is_image=True,
162 name="Z Test image two",
163 version="1.3",
164 summary="two image recipe",
165 description="recipe two",
166 section="B",
167 license="Z",
168 file_path="/two/",
169 layer_version=lver_two)
170
171
172
109 173
110 def test_get_base_call_returns_html(self): 174 def test_get_base_call_returns_html(self):
111 """Basic test for all-projects view""" 175 """Basic test for all-projects view"""
@@ -181,7 +245,6 @@ class ViewTests(TestCase):
181 245
182 return False 246 return False
183 247
184 import string
185 248
186 for url in urls: 249 for url in urls:
187 results = False 250 results = False
@@ -344,7 +407,7 @@ class ViewTests(TestCase):
344 row2 = next(x for x in rows if x['name'] == self.recipe2.name) 407 row2 = next(x for x in rows if x['name'] == self.recipe2.name)
345 408
346 self.assertEqual(response.status_code, 200, 'should be 200 OK status') 409 self.assertEqual(response.status_code, 200, 'should be 200 OK status')
347 self.assertEqual(len(rows), 2, 'should be 2 recipes') 410 self.assertTrue(row2, 'should be 2 recipes')
348 411
349 # check other columns have been populated correctly 412 # check other columns have been populated correctly
350 self.assertEqual(row1['name'], self.recipe1.name) 413 self.assertEqual(row1['name'], self.recipe1.name)
@@ -360,6 +423,144 @@ class ViewTests(TestCase):
360 self.assertEqual(row2['layer_version__layer__name'], 423 self.assertEqual(row2['layer_version__layer__name'],
361 self.recipe2.layer_version.layer.name) 424 self.recipe2.layer_version.layer.name)
362 425
426 def test_toaster_tables(self):
427 """Test all ToasterTables instances"""
428
429 def get_data(table, options={}):
430 """Send a request and parse the json response"""
431 options['format'] = "json"
432 options['nocache'] = "true"
433 request = RequestFactory().get('/', options)
434 # Add any kwargs that are needed by any of the possible tables
435 response = table.get(request,
436 pid=self.project.id,
437 layerid=self.lver.pk,
438 recipeid=self.recipe1.pk)
439 return json.loads(response.content)
440
441 # Get a list of classes in tables module
442 tables = inspect.getmembers(toastergui.tables, inspect.isclass)
443
444 for name, table_cls in tables:
445 # Filter out the non ToasterTables from the tables module
446 if not issubclass(table_cls, toastergui.widgets.ToasterTable) or \
447 table_cls == toastergui.widgets.ToasterTable:
448 continue
449
450 # Get the table data without any options, this also does the
451 # initialisation of the table i.e. setup_columns,
452 # setup_filters and setup_queryset that we can use later
453 table = table_cls()
454 all_data = get_data(table)
455
456 self.assertTrue(len(all_data['rows']) > 1,
457 "Cannot test on a table with < 1 row")
458
459 if table.default_orderby:
460 row_one = all_data['rows'][0][table.default_orderby.strip("-")]
461 row_two = all_data['rows'][1][table.default_orderby.strip("-")]
462
463 if '-' in table.default_orderby:
464 self.assertTrue(row_one >= row_two,
465 "Default ordering not working on %s" % name)
466 else:
467 self.assertTrue(row_one <= row_two,
468 "Default ordering not working on %s" % name)
469
470 # Test the column ordering and filtering functionality
471 for column in table.columns:
472 if column['orderable']:
473 # If a column is orderable test it in both order
474 # directions ordering on the columns field_name
475 ascending = get_data(table_cls(),
476 {"orderby" : column['field_name']})
477
478 row_one = ascending['rows'][0][column['field_name']]
479 row_two = ascending['rows'][1][column['field_name']]
480
481 self.assertTrue(row_one <= row_two,
482 "Ascending sort applied but row 0 is less "
483 "than row 1")
484
485 descending = get_data(table_cls(),
486 {"orderby" :
487 '-'+column['field_name']})
488
489 row_one = descending['rows'][0][column['field_name']]
490 row_two = descending['rows'][1][column['field_name']]
491
492 self.assertTrue(row_one >= row_two,
493 "Descending sort applied but row 0 is "
494 "greater than row 1")
495
496 # If the two start rows are the same we haven't actually
497 # changed the order
498 self.assertNotEqual(ascending['rows'][0],
499 descending['rows'][0],
500 "An orderby %s has not changed the "
501 "order of the data in table %s" %
502 (column['field_name'], name))
503
504 if column['filter_name']:
505 # If a filter is available for the column get the filter
506 # info. This contains what filter actions are defined.
507 filter_info = get_data(table_cls(),
508 {"cmd": "filterinfo",
509 "name": column['filter_name']})
510 self.assertTrue(len(filter_info['filter_actions']) > 0,
511 "Filter %s was defined but no actions "
512 "added to it" % column['filter_name'])
513
514 for filter_action in filter_info['filter_actions']:
515 # filter string to pass as the option
516 # This is the name of the filter:action
517 # e.g. project_filter:not_in_project
518 filter_string = "%s:%s" % (column['filter_name'],
519 filter_action['name'])
520 # Now get the data with the filter applied
521 filtered_data = get_data(table_cls(),
522 {"filter" : filter_string})
523 self.assertEqual(len(filtered_data['rows']),
524 int(filter_action['count']),
525 "We added a table filter for %s but "
526 "the number of rows returned was not "
527 "what the filter info said there "
528 "would be" % name)
529
530
531 # Test search functionality on the table
532 something_found = False
533 for search in list(string.ascii_letters):
534 search_data = get_data(table_cls(), {'search' : search})
535
536 if len(search_data['rows']) > 0:
537 something_found = True
538 break
539
540 self.assertTrue(something_found,
541 "We went through the whole alphabet and nothing"
542 " was found for the search of table %s" % name)
543
544 # Test the limit functionality on the table
545 limited_data = get_data(table_cls(), {'limit' : "1"})
546 self.assertEqual(len(limited_data['rows']),
547 1,
548 "Limit 1 set on table %s but not 1 row returned"
549 % name)
550
551 # Test the pagination functionality on the table
552 page_one_data = get_data(table_cls(), {'limit' : "1",
553 "page": "1"})['rows'][0]
554
555 page_two_data = get_data(table_cls(), {'limit' : "1",
556 "page": "2"})['rows'][0]
557
558 self.assertNotEqual(page_one_data,
559 page_two_data,
560 "Changed page on table %s but first row is the "
561 "same as the previous page" % name)
562
563
363class LandingPageTests(TestCase): 564class LandingPageTests(TestCase):
364 """ Tests for redirects on the landing page """ 565 """ Tests for redirects on the landing page """
365 # disable bogus pylint message error: 566 # disable bogus pylint message error: