-
Notifications
You must be signed in to change notification settings - Fork 187
Closed
Labels
Description
How to cover the sleep branch with a test: dbms_session.sleep(1). The test should work quickly.
We have the code
/*
calculation log table
status 0-the calculation has started and is continuing now
status 1-the calculation was completed successfully
status 2-the calculation failed with an error
*/
create table log_calc_tbl
(
id number not null enable,
startdate date not null enable,
enddate date,
status number(1) not null enable,
id_calc_type number not null enable,
calcdate date
);
create or replace procedure wait_end_calcul is
l_enddate log_calc_tbl.t_enddate%type;
l_status log_calc_tbl.t_status%type;
begin
loop
-- смотрим последний запуск за сегодня
select max(l.t_enddate) keep(dense_rank first order by l.t_startdate desc)
,max(l.t_status) keep(dense_rank first order by l.t_startdate desc)
into l_enddate
,l_status
from log_calc_tbl l
where l.t_id_calc_type = 99
and l.t_startdate >= trunc(sysdate)
and l.t_startdate < trunc(sysdate) + 1;
if (l_status = 1 and l_enddate is not null)
then
--if the calculation was completed successfully then we exit
exit;
elsif l_status = 2
then
--if the calculation was completed with an error, we will return an error message
raise_application_error(-20213,
'Oh, something fell');
elsif l_status = 0 or
l_status is null
then
-- if the calculation is not completed or has not started, then we are waiting
dbms_session.sleep(60);
end if;
end loop;
end;
/
delete log_calc_tbl;
--calculation number 99 begins
insert into log_calc_tbl(t_id,t_startdate,t_enddate,t_status,t_id_calc_type,t_calcdate)values(1,sysdate,null,0,99,trunc(sysdate));
select * From log_calc_tbl;
begin
wait_end_calcul;
end;
--in another session, we will set the successful completion of the calculation
update log_calc_tbl
set t_status = 1
,t_enddate = sysdate
where t_id = 1;
--in another session, we will set an error in the calculation
update log_calc_tbl
set t_status = 2
,t_enddate = sysdate
where t_id = 1;
Or will I have to change the production code?
Add parameters: sleep_time, loop_count
create or replace procedure wait_end_calcul(p_sleep_time number default 60, p_loop_count number default 180) is
l_enddate log_calc_tbl.t_enddate%type;
l_status log_calc_tbl.t_status%type;
i number := 0;
begin
loop
-- смотрим последний запуск за сегодня
select max(l.t_enddate) keep(dense_rank first order by l.t_startdate desc)
,max(l.t_status) keep(dense_rank first order by l.t_startdate desc)
into l_enddate
,l_status
from log_calc_tbl l
where l.t_id_calc_type = 99
and l.t_startdate >= trunc(sysdate)
and l.t_startdate < trunc(sysdate) + 1;
if (l_status = 1 and l_enddate is not null)
then
--if the calculation was completed successfully then we exit
exit;
elsif l_status = 2
then
--if the calculation was completed with an error, we will return an error message
raise_application_error(-20213,
'something fell');
elsif i > p_loop_count
then
--How long can I wait? It's time to fall!
raise_application_error(-20215,
'time to fall');
elsif l_status = 0 or
l_status is null
then
-- if the calculation is not completed or has not started, then we are waiting
dbms_session.sleep(p_sleep_time);
i := i + 1;
end if;
end loop;
end;
/
Change the procedure call to
begin
wait_end_calcul(p_sleep_time => 1, p_loop_count => 1);
end;
and add test
--%test
--%throws(-20215)
procedure long_sleep;