!  Purpose: Test the NOOP primitive
!   Author: Jay Hallam / Neon Ngo / J. Czechowski IV
!------------------------------------------------------------------------------
startmacro
  switch INTERACTIVE interAct GET DEF=TRUE
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE

  call setDatDir

  set testFile "testfile_noop"
  set nelsOrig 4k
  waveform out=testFile ELEM=nelsOrig

  call basicNoop
  call rateControl
  call pipeToFile
  call appendToFile
  call convertBtoN
  call reformatLargeFile
  call longColumnNames 3000
  call longColumnNames 5000
  call longColumnNames 6000
  erase testFile

  ! test noop file to SOCKET (STP) [server] and from SOCKET (STP) [client]
  calc L:randomPort random 100 * 9900 +   ! limit port to [9900-9999]
  pipe on
    call/bg serveFile randomPort
    pause 0.05  ! since 2013-10-07: give above NOOP (started in background) time to startup
    noop "stp://localhost:^{randomPort}{TIMEOUT=0}" temp_test_noop_socket_file.tmp
  pipe off
  assert/text="^reg.main.name: NOOP socket tests" temp_test_noop_socket_file.tmp feq/d/h/k/s ^{datDir}.apenny.prm
  erase/quiet temp_test_noop_socket_file.tmp

endmacro

!******************************************************************************!
! Set the dat directory
!******************************************************************************!
procedure setDatDir
  invoke nxmMajor env.nmversion.subString(0,1)
  invoke major java.lang.Integer.valueOf(nxmMajor)
  if major GE 4 then
    invoke s:datDir           nxm.sys.test.DatLocator.getDatDirLocation()
    invoke s:datDirSlash      nxm.sys.test.DatLocator.getDatDirSlashLocation()
    invoke z:sysDatFull       nxm.sys.test.DatLocator.sysDatFull()
    invoke z:sysTestDatExists nxm.sys.test.DatLocator.sysTestDatExists()
  else
    set s:datDir           "nxm.sys.dat"
    set s:datDirSlash      "nxm/sys/dat"
    set z:sysDatFull       true
    set z:sysTestDatExists false
  endif
return

!******************************************************************************!
! This MUST be backgrounded when called since the client and server need to run
! in parallel, otherwise everything will just lock up.
subroutine serveFile L:port
  noop ^{datDir}.apenny.prm "stp://localhost:^{port}{TIMEOUT=0}"
return

!******************************************************************************!
procedure basicNoop
  !  test basic noop capability
  result tempFile "temp_noop"
  noop testFile tempFile
  status tempFile size=nels
  assert/text="NOOP: Copy from one file to another" nels EQ nelsOrig
  if tempFile FEXISTS erase tempFile
return

!******************************************************************************!
procedure appendToFile
  noop ^{datDir}.apenny.prm ram:mypenny{FLAGS=append}
  assert/text="NOOP: Append to a file - 1st time" FILE(ram:mypenny).size eq 128

  noop ^{datDir}.apenny.prm ram:mypenny{FLAGS=append}
  assert/text="NOOP: Append to a file - 2nd time" FILE(ram:mypenny).size eq 256

  noop ^{datDir}.apenny.prm ram:mypenny{FLAGS=append}
  assert/text="NOOP: Append to a file - 3rd time" FILE(ram:mypenny).size eq 384
return

!******************************************************************************!
procedure rateControl
  !  test /RATE switch capability
  set rateTestIn  "temp_noop_rate_in"
  set rateTestOut "temp_noop_rate_out"
  set nels_rateTest 100k
  set desiredRate 50k
  waveform out=rateTestIn ELEM=nels_rateTest FORM=SB

  calc predictedTime nels_rateTest desiredRate /
  calc timeLimit predictedTime 2 *
  timer set
  noop/rt/rate=desiredRate rateTestIn rateTestOut
  timer elapsed actualTime
  status rateTestOut size=nels
  assert/text="NOOP: rate, predicted time = ^predictedTime, elapsed = ^actualTime" &
                                            actualTime GE predictedTime AND &
                                            actualTime LT timeLimit

  if rateTestIn  FEXISTS erase rateTestIn
  if rateTestOut FEXISTS erase rateTestOut
return

!******************************************************************************!
procedure pipeToFile
  set fileName1 "temp_noop_file1.tmp"
  set fileName2 "temp_noop_file2.tmp"

  ! Note: 7919 is a prime number
  waveform out=fileName2 ELEM=7919 FORM=SB
  pipe on
    waveform out=_mypipe ELEM=7919 FORM=SB
    noop _mypipe fileName1
  pipe wait
  pipe off

  assert/text="^reg.main.name: Copy pipe to file." fileName1 feq/b fileName2

  if fileName1 FEXISTS erase fileName1
  if fileName2 FEXISTS erase fileName2
return


!******************************************************************************!
! Tests packing/unpacking SN data, see Bug 925
procedure convertBtoN
  ! Check against a "gold" copy of the penny with FORM=SN (made by JC4 on 16APR07).
  ! This helps check for bugs in the Native vs Java-Only methods.

  noop ^{datDir}.apenny.prm         ram:apenny_sn{FORM=SN}
  noop nxm.sys.test.apenny_nibble.prm ram:apenny_sb{FORM=SB}

  fcalc ram:diff_val nxm.sys.test.apenny_nibble.prm ram:apenny_sn -
  fcalc ram:diff_sn  ^{datDir}.apenny.prm         ram:apenny_sn -
  fcalc ram:diff_sb  ^{datDir}.apenny.prm         ram:apenny_sb -

  statistics ram:diff_val TABLE=stats_val
  statistics ram:diff_sb  TABLE=stats_sb
  statistics ram:diff_sn  TABLE=stats_sn

  assert/text="NOOP: Convert B -> N (values)" stats_val.min eq 0 AND stats_val.max eq 0
  assert/text="NOOP: Convert B -> N (range)"  stats_sn.min  eq -119 AND stats_sn.max  eq 120
  assert/text="NOOP: Convert N -> B (range)"  stats_sb.min  eq -119 AND stats_sb.max  eq 120

return

!****************************************************************************!
! Tests reformat file with size greater than 32768 bytes, see Bug #118
!****************************************************************************!
procedure reformatLargeFile
  set file1 sin_d{AUX=RAM}
  set file2 sin_sf{AUX=RAM,FORM=SF}
  waveform OUT=^file1 FORM=SD ELEM=4096 SHAPE="SIN"
  noop ^file1 ^file2
  assert/text="NOOP: REFORMAT Large File " ^file2 FEXISTS AND ^file1 FEQ/S ^file2
return

!****************************************************************************!
! Tests file with long column names and many columns (see Bug ????)
!****************************************************************************!
procedure longColumnNames L:type
  set name "MY_SUPER_HUGE_FANTASTICALLY_LONG_RECORD_NAME_THAT_I_AM_USING_TODAY_" ! <-- must be longer than 24 chars
  set recs 32 ! <-- must be more than 26

  file open/n/f out ram:temp
  set out.type     type
  set out.timecode 0.0
  set out.xstart   2008:11:28::00:00:00
  set out.xdelta   300
  set out.xunits   TIME_S
  set out.size     recs

  do L:i 1 recs
    invoke ,, out.addSubRec("^{name}^{i}","SF")
  enddo

  do L:j 0 16
    set row {}
    do i 1 recs
      calc row.^{name}^{i} j 1000 * i +
    enddo
    invoke ,, out.setData(j,row)
  enddo
  file close out

  noop ram:temp ram:copy
  assert/text="^reg.main.name: Copy type ^type file, long column names, ^recs subrecs" &
              ram:temp FEQ/S/H/D ram:copy
  erase ram:temp
  erase ram:copy
return

!****************************************************************************!
! If an unexpected exception is caught, mark test as failed and stop the
! current pipe section to prevent it from "locking" the NeXtMidas session.
! @since NeXtMidas 2.5.0
!****************************************************************************!
procedure processException m:emsg
  !warning "^reg.main.name: Got Exception: ^emsg.name = ^emsg.data from = ^emsg.fid"
  if TRACE SUBS ENV.DEBUG invoke ,, emsg.data.printStackTrace
  assert/text="NOOP: Unexpected ^emsg.name: ^emsg.data ..." FALSE
  pipe stop
return
