Merge lp:~dpniel/ubiquity/autopilot_fix_custominstall into lp:ubiquity

Proposed by Dan Chapman 
Status: Merged
Merged at revision: 6126
Proposed branch: lp:~dpniel/ubiquity/autopilot_fix_custominstall
Merge into: lp:ubiquity
Diff against target: 193 lines (+128/-3)
2 files modified
autopilot/ubiquity_autopilot_tests/emulators/gtkcontrols.py (+73/-0)
autopilot/ubiquity_autopilot_tests/tests/__init__.py (+55/-3)
To merge this branch: bzr merge lp:~dpniel/ubiquity/autopilot_fix_custominstall
Reviewer Review Type Date Requested Status
Jean-Baptiste Lallement Approve
Review via email: mp+208605@code.launchpad.net

Description of the change

Ok so this should fix the custom install tests and get them passing again. It still needs some further work to get rid of one more sleep.

The changes I made were to generate a dictionary of namedtuples from the all the items in the partition page treeview

Using the Row number as the dictionary key and and column headers as the access names for the named tuple

So now we get a mapped dictionary to any cell in the partition tree by something simple like

>>> table['Row2'].Mountpoint

which gives us the introspectable object of that cell so we can access any of it properties etc.

This fix doesn't fully use the above atm (soon it will) but basically to fix the current error I use the number of rows in the dict to assert it increments after creating a partition. Instead of blindly sleeping. But for now it's a good thing we can test the number of partitions are correct.

In the end I want to map the partition config file to the dict to assert the tree is displaying partitions correctly but that will take a fair bit more work.

Anyway this gets it going for now :-)

To post a comment you must log in.
Revision history for this message
Jean-Baptiste Lallement (jibel) wrote :

168 + if num == self.part_table_rows:
...
172 + if num is not self.part_table_rows + 1:

This is inconsistent, in the first comparison you use the operator '==' and 4 lines below the operator 'is'. They have different meanings. '==' would be more appropriate since you're comparing 2 numbers which are the return len()

This line is unused and pyflakes tests will fail
144 + item_table = tree_view.get_partition_table_dict()

Okay for the TODO, it is still enhancements to the tests but it is not regressing compared to the previous version

I ran the test on ubuntu-desktop and it works fine.

review: Needs Fixing
6141. By Dan Chapman 

changed 'is' to == in _update_table_row_count and removed uneeded todo's and unused assignment

6142. By Dan Chapman 

fix pep8/ pyflakes and style inconsistencies

Revision history for this message
Dan Chapman  (dpniel) wrote :

I have made the suggested changes,

I will try and figure out a way to find the 'freespace' row and wait for it to change so we can remove the sleep

Revision history for this message
Jean-Baptiste Lallement (jibel) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'autopilot/ubiquity_autopilot_tests/emulators/gtkcontrols.py'
2--- autopilot/ubiquity_autopilot_tests/emulators/gtkcontrols.py 2013-11-19 09:07:08 +0000
3+++ autopilot/ubiquity_autopilot_tests/emulators/gtkcontrols.py 2014-02-27 15:58:05 +0000
4@@ -20,6 +20,8 @@
5 from ubiquity_autopilot_tests.tools.compare import expectThat
6 from ubiquity_autopilot_tests.emulators import gtkaccessible
7 import logging
8+import re
9+from collections import namedtuple
10 logger = logging.getLogger(__name__)
11
12
13@@ -254,6 +256,77 @@
14 raise ValueError("NoneType: Could not get list of items")
15 return items
16
17+ def get_partition_table_dict(self, ):
18+ """ Returns a dict of named tuples generated by the list
19+ of items returned from get_all_items.
20+
21+ This enables us to access any available table cell
22+ using the Row number and column name
23+
24+ example usage:
25+
26+ >>> treeview = self.app.select_single('GtkTreeView')
27+ >>> table = treeview.get_partition_table_dict()
28+ # we can now access any cell using Row number as Key and
29+ column name
30+ i.e table['Row Number'].ColumnName
31+
32+ >>> item = table['Row2'].Mount
33+
34+ We now have an introspectable object for that particular
35+ cell which we can use
36+ to either assert the properties of the cell and also click etc....
37+
38+ >>> self.assertThat(item.accessible_name, Equals('/home'))
39+ >>> self.mouse.click(item)
40+ """
41+ #first get accessible tree
42+ treeview = self._get_gail_treeview()
43+ # Now each column header is a GtkButton, so we get the label from each
44+ # one and create a list
45+ tree_column_objects = treeview.select_many('GtkButtonAccessible')
46+ column_names = []
47+ for column in tree_column_objects:
48+ #We are only interested in columns with headers. Blank columns
49+ # seem to usually be used for spacing and contain no cells
50+ if column.accessible_name == '':
51+ pass
52+ else:
53+ #strip all non alpaha chars
54+ name = re.sub(r'\W+', '', column.accessible_name)
55+ column_names.append(name)
56+ # Create a named tuple using the column headers, which enables access
57+ # to the column by name
58+ Columns = namedtuple('Columns', column_names)
59+ #generate a list of items
60+ tree_items = treeview.get_all_items()
61+ # lets create a temp list
62+ temp_list = []
63+ #TODO: we actually don't really need this
64+ for item in tree_items:
65+ temp_list.append(item)
66+ # so we want to create a Columns tuple for each row in the table
67+ # therefore picking only the n items where n is the number of column
68+ # names
69+ start, end = 0, len(column_names)
70+ row_list, table_dict = [], {}
71+ for i in range(0, int(len(temp_list) / len(column_names))):
72+ # fill columns tuple
73+ row = Columns(*temp_list[start:end])
74+ # create a new tuple adding the current row number
75+ # which we will use as dict key
76+ row_list.append(('Row{0}'.format(i+1), row))
77+ # update our table dict
78+ table_dict.update(row_list)
79+ # remove the items we just added from the temp list
80+ del temp_list[start:end]
81+ # return table_dict
82+ return table_dict
83+
84+ def get_number_of_rows(self, ):
85+ items = self.get_partition_table_dict()
86+ return len(items)
87+
88 def _get_gail_treeview(self, ):
89 """
90 Gets the GtkTreeViews corresponding GtkTreeViewAccessible object
91
92=== modified file 'autopilot/ubiquity_autopilot_tests/tests/__init__.py'
93--- autopilot/ubiquity_autopilot_tests/tests/__init__.py 2014-02-26 10:57:42 +0000
94+++ autopilot/ubiquity_autopilot_tests/tests/__init__.py 2014-02-27 15:58:05 +0000
95@@ -70,6 +70,9 @@
96 self.english_config.read('/tmp/english_config.ini')
97 #delete config at end of test
98 self.addCleanup(os.remove, '/tmp/english_config.ini')
99+ # always starts with 1 row ('/dev/sda')
100+ self.part_table_rows = 1
101+ self.total_number_partitions = 0
102
103 def tearDown(self):
104 self._check_no_visible_dialogs()
105@@ -413,6 +416,9 @@
106 "load")
107 time.sleep(5) # need to give time for all UI elements to load
108 custom_page.create_new_partition_table()
109+ #update number of table rows
110+ self.part_table_rows = treeview.get_number_of_rows()
111+ logger.debug("TOTAL NUMBER OF ROWS: {0}".format(self.part_table_rows))
112 #lets create the partitions from here
113 if part_config:
114 logger.debug("Setting the given partition config")
115@@ -420,6 +426,16 @@
116 else:
117 logger.debug("Selecting a random partition config")
118 config = random.choice(custom_configs)
119+ logger.debug("LENGTH OF CONFIG IS: {0}".format(len(config)))
120+
121+ logger.debug(
122+ "TOTAL NUMBER OF PARTITIONS IN CONFIG: {0}".format(len(config))
123+ )
124+ self.total_number_partitions = len(config)
125+ logger.debug(
126+ "TOTAL NUMBER OF PARTITIONS TO BE IN TABLE: {0}".format(
127+ self.total_number_partitions)
128+ )
129 for elem in config:
130 self._add_new_partition()
131
132@@ -812,15 +828,17 @@
133 def _check_partition_created(self, config):
134 """ Checks that the partition was created properly
135 """
136- #before checking lets just wait a little while to ensure everything
137- # has finished loading, this doesn't affect outcome
138- time.sleep(7)
139 logger.debug("Checking partition was created.....")
140 custom_page = self.main_window.select_single(
141 'GtkAlignment',
142 BuilderName='stepPartAdvanced')
143 tree_view = custom_page.select_single('GtkTreeView')
144+ #assert a new row has been added to the partition table
145+ total_rows = self._update_table_row_count(config)
146+ logger.debug("TOTAL NUMBER OF ROWS: {0}".format(self.part_table_rows))
147+ self.assertThat(total_rows, Equals(self.part_table_rows))
148 items = tree_view.get_all_items()
149+
150 fsFormat = config['FileSystemType']
151 mount_point = config['MountPoint']
152 size_obj = config['PartitionSize']
153@@ -906,6 +924,40 @@
154 # Lets print current step
155 print("Current step = {0}".format(self.current_step))
156
157+ def _update_table_row_count(self, config):
158+ " Returns number of rows in table"
159+
160+ custom_page = self.main_window.select_single(
161+ 'GtkAlignment',
162+ BuilderName='stepPartAdvanced')
163+ tree_view = custom_page.select_single('GtkTreeView')
164+ num = tree_view.get_number_of_rows()
165+ if num == self.total_number_partitions:
166+ #TODO: assert 'free space' changes to a partition
167+ # this will take some further work.
168+ time.sleep(15)
169+ return num
170+
171+ if num == self.part_table_rows:
172+
173+ timeout = 30
174+ while True:
175+ if num is not self.part_table_rows + 1:
176+ time.sleep(1)
177+
178+ num = tree_view.get_number_of_rows()
179+ if num is self.part_table_rows + 1:
180+ break
181+ elif not timeout:
182+
183+ raise ValueError("No new rows in partition table")
184+ else:
185+ timeout -= 1
186+
187+ self.assertThat(num, Equals(self.part_table_rows + 1))
188+ self.part_table_rows = num
189+ return num
190+
191 def _update_page_titles(self, ):
192 self.previous_page_title = self.current_page_title
193 self.current_page_title = self.main_window.select_single(

Subscribers

People subscribed via source and target branches

to status/vote changes: