diff options
| -rw-r--r-- | bitbake/lib/toaster/toastergui/tests.py | 223 |
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 | |||
| 33 | from orm.models import Branch | 33 | from orm.models import Branch |
| 34 | 34 | ||
| 35 | import toastermain | 35 | import toastermain |
| 36 | import inspect | ||
| 37 | import toastergui | ||
| 36 | 38 | ||
| 37 | from toastergui.tables import SoftwareRecipesTable | 39 | from toastergui.tables import SoftwareRecipesTable |
| 38 | import json | 40 | import json |
| 39 | from bs4 import BeautifulSoup | 41 | from bs4 import BeautifulSoup |
| 40 | import re | 42 | import re |
| 43 | import string | ||
| 41 | 44 | ||
| 42 | PROJECT_NAME = "test project" | 45 | PROJECT_NAME = "test project" |
| 43 | CLI_BUILDS_PROJECT_NAME = 'Command line builds' | 46 | CLI_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 | |||
| 363 | class LandingPageTests(TestCase): | 564 | class 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: |
