Failed: The logic managed to rollback the unit test transaction. Please remove the random rollback statement.


Userlevel 5
Badge +15

I'm testing the upgrade from SF 2021.1 to SF 2021.2 and I noticed something in the unit tests, there's an assertion message thrown:

Failed: The logic managed to rollback the unit test transaction. Please remove the random rollback statement.

 

I've discovered that this is caused by the tasks’ “atomic transaction” feature. For example I have a task with a dbo.tsf_send_message ‘some_error’, null, 1 which will call raiserror(), that will cause the task transaction to rollback. But as a side effect the unit test no longer succeeds where it would in previous versions. How can this be fixed?

 

I also did notice that there is a new “Is empty” assert. Which is nice, but why isn't it converted by default? I've performed this script to correct it:

update t 
set t.unit_test_condition = 10 -- Is empty
from unit_test_output_parmtr_overview t
where t.project_id = @project_id
and t.project_vrs_id = @project_vrs_id
and t.expected_output_value is null
and t.unit_test_condition = 0 -- Is equal to

 


5 replies

Userlevel 7
Badge +23

Hi René,

This is indeed a difficult situation as the Task code is inside a transaction while in another transaction because Unit tests are run inside a transaction of their own. For now we don't have a fix for this. Do you have a suggestion on how this could be handled?

"why isn't it converted by default”

I will find an answer to this for you. It's possibly for the reason that tempering with Unit tests can cause them to fail all of the sudden, which we of course wouldn't want to happen.

Userlevel 7
Badge +23

We have identified the problem regarding "why isn't it converted by default”. There was a scripting error in the Upgrade script causing all the updates to not function properly. We apologize for not seeing this earlier. We'll fix this in the Upgrade script when upgrading to 2021.2.

The correct script would be:

update t
set t.unit_test_condition = 10, -- is_empty
t.filter_value = null
from unit_test_col_filter t
where t.filter_value is null
or t.filter_value = ''

update t
set t.unit_test_condition = 10, -- is_empty
t.expected_output_value = null
from unit_test_col_output t
where t.expected_output_value is null
or t.expected_output_value = ''

update t
set t.unit_test_condition = 10, -- is_empty
t.expected_output_value = null
from unit_test_fixed_parmtr_output t
where t.expected_output_value is null
or t.expected_output_value = ''

update t
set t.unit_test_condition = 10, -- is_empty
t.expected_output_value = null
from unit_test_process_step_output t
where t.expected_output_value is null
or t.expected_output_value = ''

update t
set t.unit_test_condition = 10, -- is_empty
t.expected_output_value = null
from unit_test_process_variable_output t
where t.expected_output_value is null
or t.expected_output_value = ''

update t
set t.unit_test_condition = 10, -- is_empty
t.expected_output_value = null
from unit_test_report_parmtr_output t
where t.expected_output_value is null
or t.expected_output_value = ''

update t
set t.unit_test_condition = 10, -- is_empty
t.expected_output_value = null
from unit_test_subroutine_parmtr_output t
where t.expected_output_value = null
or t.expected_output_value = ''

update t
set t.unit_test_condition = 10, -- is_empty
t.expected_output_value = null
from unit_test_task_parmtr_output t
where t.expected_output_value is null
or t.expected_output_value = ''

go





 

Userlevel 5
Badge +15

Hi René,

This is indeed a difficult situation as the Task code is inside a transaction while in another transaction because Unit tests are run inside a transaction of their own. For now we don't have a fix for this. Do you have a suggestion on how this could be handled?

Hi,

I don't have a suggestion for that, I'm not a SF-developer ;-). It should work as in SF2021.1?

Userlevel 7
Badge +23

I do think it actually work the same way as in 2021.1 but in 2021.2 you do see the returned assertion message. To be fair, this is a scenario that we can't fix easily. If you wish, you can submit a ticket in TCP for this. We then can take a more closer look at it and see how we can avoid this problem.

For now I don't have a good solution other than not performing Unit tests on atomic Tasks or always making sure they don't fail.

Userlevel 5
Badge +15

I do think it actually work the same way as in 2021.1 but in 2021.2 you do see the returned assertion message. To be fair, this is a scenario that we can't fix easily. If you wish, you can submit a ticket in TCP for this. We then can take a more closer look at it and see how we can avoid this problem.

For now I don't have a good solution other than not performing Unit tests on atomic Tasks or always making sure they don't fail.

For some situations I can fix it by not doing an abort, but a tsf_send_message '’, null, 0 and a return statement, but in some situations I can't do that.

There is a slight difference between 2021.1 and 2021.2 I see (really like the new ‘see code’ feature):

There's a raiserror used in 2021.2, where it was tsf_send_assertion_msg in 2021.1.

I'm not sure what caused it. Is the atomic transaction feature maybe a bad practice? And should the transaction only be applied on the templates that do need a transaction, and not the ‘checking for valid input templates’? We also apply transactions in instead of triggers making sure all query's are performed, or rolled back, in case of an abort in a trigger of a table. Difficult to say if this is a bad practices as it would add a lot of extra code / checks on places it shouldn't be I think.

I'll add a ticket to TCP for some further investigation.

Reply