2

In an unit test, I need to verify that the program skip locked records when processing a table. I have been unable to setup a locked records because the test can't lock itself which make a lot of sense.

Here is a sample of what I'm trying to achieve.

  DEV VAR v_isCommitted        AS LOGI NO-UNDO.
  DEF VAR hl                   AS HANDLE   NO-UNDO.
  DEF BUFFER bufl              FOR tablename. 
  hl = BUFFER bufl:HANDLE. 

  LOCKED_RECORDS:
  DO TRANSACTION ON ERROR UNDO, LEAVE LOCKED_RECORDS:
      /*Setup : Create record not committed yet*/
      CREATE tablename.
      ASSIGN tablename.fields = fieldsvalue.



      /*ACT :  Code I'm trying to test*/   
      /*...some code...*/  
      v_isCommitted = hl:FIND-BY-ROWID(ROWID(tablename), EXCLUSIVE-LOCK, NO-WAIT)
                                AND AVAILABLE(bufl) 
                                AND NOT LOCKED(bufl).
      /*...some code touching the record if it is commited...*/   

      /*ASSERT :  program left new record tablename AS IS.*/

  END.

The problem is that the record is available and not locked to the test because it was created by it.
Is there a way I could have the test lock a record from itself so the act part can actually skip the record like it was created by someone else?

Progress: 11.7.1

Tom Bascom
  • 13,405
  • 2
  • 27
  • 33
AXMIM
  • 2,424
  • 1
  • 20
  • 38

1 Answers1

5

A session can not lock itself. So you will need to start a second session. For example:

/* code to set things up ... */

/* spawn a sub process to try to lock the record */

os-command silent value( substitute( '_progres -b -db &1 -p lockit.p -param "&2" && > logfile 2>&&1', dbname, "key" )).

In lockit.p use session:parameter to get the key for the record to test (or hard code it I suppose).

Or, as mentioned in the comments below:

/* locktest.p
 */

define variable lockStatus as character no-undo format "x(20)".

find first customer exclusive-lock.

input through value( "_progres /data/sports120/sports120 -b -p ./lockit.p" ).
repeat:
  import unformatted lockStatus.
end.

display lockStatus.

and:

/* lockit.p
 */

find first customer exclusive-lock no-wait no-error.
if locked( customer ) then
  put "locked".
 else
  put "not locked".

quit.
Tom Bascom
  • 13,405
  • 2
  • 27
  • 33
  • Interresting, in the end, I didn't use this, because I fear the silent process could mess up others tests running subsequently. Instead, I rewrote the code to make it more obvious that a verification on record's availability is required. – AXMIM Jun 15 '20 at 17:31
  • It all depends on what you're trying to accomplish but you could just drop the "silent" and omit the "&&". I would imagine that "lockit.p", at its simplest, would try to get the record, if successful then update it in a way that the parent can detect. It could also just write a message to stdout saying whether the lock was successful or not. In that case you might prefer using INPUT THROUGH to OS-COMMAND. – Tom Bascom Jun 15 '20 at 18:48
  • I've added a more complete example showing that as well. – Tom Bascom Jun 15 '20 at 19:00