Skip to content

Commit 9a32004

Browse files
authored
Merge pull request #22102 from mvdbeek/fix-transient-ci-failures
Fix transient ci failures
2 parents 027bd4b + 10f0c16 commit 9a32004

File tree

8 files changed

+58
-38
lines changed

8 files changed

+58
-38
lines changed

client/src/components/BaseComponents/GTabs.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@ const TabTitleContent = defineComponent({
167167
role="tab"
168168
href="#"
169169
:aria-selected="index === activeIndex"
170+
:aria-controls="tab.id"
170171
:aria-disabled="tab.disabled"
172+
:data-tab-title="tab.title"
171173
v-bind="tab.titleLinkAttributes"
172174
@click.prevent="!tab.disabled && setActive(index)">
173175
<TabTitleContent :tab="tab" />

client/src/components/FilesDialog/FilesDialog.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ function load() {
265265
if (urlTracker.isAtRoot.value || errorMessage.value) {
266266
itemsProvider.value = undefined;
267267
errorMessage.value = undefined;
268+
isBusy.value = true;
268269
fetchFileSources(props.filterOptions)
269270
.then((results) => {
270271
const convertedItems = results
@@ -274,13 +275,15 @@ function load() {
274275
const sortedItems = convertedItems.sort(sortPrivateFileSourcesFirst);
275276
items.value = sortedItems;
276277
formatRows();
277-
optionsShow.value = true;
278278
showTime.value = false;
279279
showDetails.value = true;
280280
totalItems.value = convertedItems.length;
281+
isBusy.value = false;
282+
optionsShow.value = true;
281283
})
282284
.catch((error) => {
283285
errorMessage.value = errorMessageAsString(error);
286+
isBusy.value = false;
284287
});
285288
} else {
286289
if (!urlTracker.current.value) {
@@ -303,17 +306,20 @@ function load() {
303306
return;
304307
}
305308
309+
isBusy.value = true;
306310
browseRemoteFiles(urlTracker.current.value?.url, false, props.requireWritable)
307311
.then((result) => {
308312
items.value = filterByMode(result.entries).map(entryToRecord);
309313
totalItems.value = result.totalMatches;
310314
formatRows();
311-
optionsShow.value = true;
312315
showTime.value = true;
313316
showDetails.value = false;
317+
isBusy.value = false;
318+
optionsShow.value = true;
314319
})
315320
.catch((error) => {
316321
errorMessage.value = errorMessageAsString(error);
322+
isBusy.value = false;
317323
});
318324
}
319325
}

client/src/components/SelectionDialog/SelectionDialog.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ defineExpose({
196196
{{ errorMessage }}
197197
</BAlert>
198198
<div v-else>
199-
<div v-if="optionsShow">
199+
<div v-if="optionsShow" data-description="selection dialog options">
200200
<BTable
201201
small
202202
hover

client/src/utils/navigation/navigation.yml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ files_dialog:
552552
ftp_details: 'span[title="details-gxftp://"]'
553553
row: 'span[title="label-${uri}"]'
554554
back_btn: '#back-btn'
555+
options_ready: '[data-description="selection dialog options"] .selection-dialog-table[aria-busy="false"]'
555556

556557
history_export:
557558
selectors:
@@ -1159,18 +1160,10 @@ custom_tools:
11591160
admin:
11601161
allowlist:
11611162
selectors:
1162-
toolshed:
1163-
type: xpath
1164-
selector: '//a[contains(text(), "Toolshed Tools")]'
1165-
local:
1166-
type: xpath
1167-
selector: '//a[contains(text(), "Local Tools")]'
1168-
sanitized:
1169-
type: xpath
1170-
selector: '//a[contains(text(), "HTML Sanitized")]'
1171-
rendered_active:
1172-
type: xpath
1173-
selector: '//div[contains(@class, "active")]//a[contains(text(), "HTML Rendered")]'
1163+
toolshed: 'a[data-tab-title="Toolshed Tools"]'
1164+
local: 'a[data-tab-title="Local Tools"]'
1165+
sanitized: 'a[data-tab-title="HTML Sanitized"]'
1166+
rendered_active: '.tab-pane.active a[data-tab-title="HTML Rendered"]'
11741167

11751168
manage_dependencies:
11761169
selectors:

client/src/utils/navigation/schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ interface Rootfiles_dialog extends Component {
301301
ftp_details: SelectorTemplate;
302302
row: SelectorTemplate;
303303
back_btn: SelectorTemplate;
304+
options_ready: SelectorTemplate;
304305
}
305306
interface Roothistory_export extends Component {
306307
export_link: SelectorTemplate;

lib/galaxy/jobs/__init__.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,24 +2231,27 @@ def fail(message=job.info, exception=None):
22312231
dataset.full_delete()
22322232
collected_bytes = 0
22332233

2234-
# Calculate dataset hash
2235-
for dataset_assoc in output_dataset_associations:
2236-
dataset = dataset_assoc.dataset.dataset
2237-
if not dataset.purged and dataset.state == Dataset.states.OK and not dataset.hashes:
2238-
if self.app.config.calculate_dataset_hash == "always" or (
2239-
self.app.config.calculate_dataset_hash == "upload" and job.tool_id in ("upload1", "__DATA_FETCH__")
2240-
):
2241-
# Calculate dataset hash via a celery task
2242-
if self.app.config.enable_celery_tasks:
2243-
from galaxy.celery.tasks import compute_dataset_hash
2244-
2245-
extra_files_path = dataset.extra_files_path if dataset.extra_files_path_exists() else None
2246-
request = ComputeDatasetHashTaskRequest(
2247-
dataset_id=dataset.id,
2248-
extra_files_path=extra_files_path,
2249-
hash_function=self.app.config.hash_function,
2250-
)
2251-
compute_dataset_hash.delay(request=request)
2234+
# Calculate dataset hash - only if the job completed successfully,
2235+
# otherwise dataset files may be missing/invalid (e.g. failed fetch from 404 URL).
2236+
if final_job_state == job.states.OK:
2237+
for dataset_assoc in output_dataset_associations:
2238+
dataset = dataset_assoc.dataset.dataset
2239+
if not dataset.purged and dataset.state == Dataset.states.OK and not dataset.hashes:
2240+
if self.app.config.calculate_dataset_hash == "always" or (
2241+
self.app.config.calculate_dataset_hash == "upload"
2242+
and job.tool_id in ("upload1", "__DATA_FETCH__")
2243+
):
2244+
# Calculate dataset hash via a celery task
2245+
if self.app.config.enable_celery_tasks:
2246+
from galaxy.celery.tasks import compute_dataset_hash
2247+
2248+
extra_files_path = dataset.extra_files_path if dataset.extra_files_path_exists() else None
2249+
request = ComputeDatasetHashTaskRequest(
2250+
dataset_id=dataset.id,
2251+
extra_files_path=extra_files_path,
2252+
hash_function=self.app.config.hash_function,
2253+
)
2254+
compute_dataset_hash.delay(request=request)
22522255

22532256
user = job.user
22542257
if user and collected_bytes > 0 and quota_source_info is not None and quota_source_info.use:

lib/galaxy/managers/datasets.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
model,
1919
)
2020
from galaxy.datatypes import sniff
21+
from galaxy.exceptions import ObjectInvalid
2122
from galaxy.managers import (
2223
base,
2324
deletable,
@@ -164,11 +165,18 @@ def compute_hash(self, request: ComputeDatasetHashTaskRequest):
164165
return
165166
# For files in extra_files_path
166167
extra_files_path = request.extra_files_path
167-
if extra_files_path:
168-
extra_dir = dataset.extra_files_path_name
169-
file_path = self.app.object_store.get_filename(dataset, extra_dir=extra_dir, alt_name=extra_files_path)
170-
else:
171-
file_path = dataset.get_file_name()
168+
try:
169+
if extra_files_path:
170+
extra_dir = dataset.extra_files_path_name
171+
file_path = self.app.object_store.get_filename(dataset, extra_dir=extra_dir, alt_name=extra_files_path)
172+
else:
173+
file_path = dataset.get_file_name()
174+
except ObjectInvalid:
175+
log.warning(
176+
"Unable to calculate hash for dataset [%s]: object is invalid (dataset may have failed or been purged).",
177+
dataset.id,
178+
)
179+
return
172180
hash_function = request.hash_function
173181
calculated_hash_value = memory_bound_hexdigest(hash_func_name=hash_function, path=file_path)
174182
dataset_hash = model.DatasetHash(

test/integration_selenium/test_history_import_export_ftp.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ def create_user_ftp_dir(self):
3030
user_ftp_dir = os.path.join(self.ftp_dir(), email)
3131
os.makedirs(user_ftp_dir)
3232

33+
def _wait_for_files_dialog_ready(self):
34+
"""Wait for the files dialog to finish loading and display its options."""
35+
self.components.files_dialog.options_ready.wait_for_visible()
36+
3337
def _export_to_ftp_with_filename(self, filename: str):
3438
self.components.history_export.directory_input.wait_for_and_click()
39+
self._wait_for_files_dialog_ready()
3540
self.components.files_dialog.ftp_label.wait_for_and_click()
3641
self.components.upload.file_dialog_ok.wait_for_and_click()
3742
self.components.history_export.name_input.wait_for_and_send_keys(filename)
@@ -72,6 +77,7 @@ def test_history_import_export(self):
7277
history_import = gx_selenium_context.components.history_import
7378
history_import.radio_button_remote_files.wait_for_and_click()
7479
history_import.open_files_dialog.wait_for_and_click()
80+
self._wait_for_files_dialog_ready()
7581
files_dialog.ftp_label.wait_for_and_click()
7682
files_dialog.row(uri="gxftp://my_export.tar.gz").wait_for_and_click()
7783

@@ -128,6 +134,7 @@ def test_history_export_tracking(self):
128134

129135
# Select FTP file source
130136
self.components.history_export.directory_input.wait_for_and_click()
137+
self._wait_for_files_dialog_ready()
131138
self.components.files_dialog.ftp_label.wait_for_and_click()
132139
self.components.upload.file_dialog_ok.wait_for_and_click()
133140

0 commit comments

Comments
 (0)