Question
Mihai Radu · Aug 31, 2017

Cache Studio freezes on line Use $io::("^"_$ZNAME)

I am trying to capture the write of a method to test the response in an unit test. I know everything works because one of my colleagues ran the code and did not froze on his machine.

I don't what is the cause of the freeze. I know that at line Use $io::("^"_$ZNAME) it stopes because i have put some write functions after every line in WriteCapture method and i only saw the first write function in terminal

I also used debug and in this case it didn't froze

PS: forgot to put the status in the XECUTE (vstrCommand , .status)

This is my method that captures the write:

ClassMethod WriteCapture(vstrCommand As %String, Output strOutput As %String, Output status As %Status) [ ProcedureBlock = 0 ]
{
 
//Redirect IO to the current routine - makes use of the labels defined below
    Use $io::("^"_$ZNAME)
    //Enable redirection
    Do ##class(%Device).ReDirectIO(1)
Try
{
XECUTE (vstrCommand , .status)
}
Catch ex
{
//Set st = ex.AsStatus()
//w "st = " _ st
WRITE "Name: ",$ZCVT(ex.Name,"O","HTML"),!
}
  
    //Disable redirection
    Do ##class(%Device).ReDirectIO(0)
    //Labels that allow for IO redirection
    //Read Character - we don't care about reading
rchr(c) quit
    //Read a string - we don't care about reading
rstr(sz,to) quit
    //Write a character - call the output label
wchr(s) do output($char(s)) quit
    //Write a form feed - call the output label
wff() do output($char(12)) quit
    //Write a newline - call the output label
wnl() do output($char(13,10)) quit
    //Write a string - call the output label
wstr(s) do output(s) quit
    //Write a tab - call the output label
wtab(s) do output($char(9)) quit
    //Output label - this is where you would handle what you actually want to do.
    // in our case, we want to write to myStr. myStream commented out.
    // do myStream.Write(s) 
output(s) set strOutput =strOutput_s quit
}

 and this i where i call it :

ClassMethod TestGetAllChats2()
{
#Dim strOutput As %String
#Dim status As %Status = $$$OK
Set strOutput = ""

Set strCmd = "(status) Set status = $CLASSMETHOD(""Apps.Apo.ChefApp.ChatInfo.ChatModule"",""GetDifferencesAllChats"",""1"",""5"", 1)"
w !, "strCmd = " _strCmd


    Do ##class(Apps.Apo.Miscellaneous.Helper).WriteCapture(strCmd, .strOutput, .status)
    w strOutput
}
0
0 402
Discussion (7)1
Log in or sign up to continue

Does it work like this?

ClassMethod WriteCapture(vstrCommand As %String) As %String
{
    set tOldIORedirected = ##class(%Device).ReDirectIO()
    set tOldMnemonic = ##class(%Device).GetMnemonicRoutine()
    set tOldIO = $io
    try {
        set str=""

        //Redirect IO to the current routine - makes use of the labels defined below
        use $io::("^"_$ZNAME)

        //Enable redirection
        do ##class(%Device).ReDirectIO(1)

        XECUTE (vstrCommand)
        
    } catch ex {
        set str = ""
    }

    //Return to original redirection/mnemonic routine settings
    if (tOldMnemonic '= "") {
        use tOldIO::("^"_tOldMnemonic)
    } else {
        use tOldIO
    }
    do ##class(%Device).ReDirectIO(tOldIORedirected)

    quit str

    //Labels that allow for IO redirection
    //Read Character - we don't care about reading
rchr(c)      quit
    //Read a string - we don't care about reading
rstr(sz,to)  quit
    //Write a character - call the output label
wchr(s)      do output($char(s))  quit
    //Write a form feed - call the output label
wff()        do output($char(12))  quit
    //Write a newline - call the output label
wnl()        do output($char(13,10))  quit
    //Write a string - call the output label
wstr(s)      do output(s)  quit
    //Write a tab - call the output label
wtab(s)      do output($char(9))  quit
    //Output label - this is where you would handle what you actually want to do.
    //  in our case, we want to write to str
output(s)    set str=str_s   quit
}

What does your $$$AssertEquals macro do?

Both that macro and your WriteCapture classmethod get turned into INT code at some point, and you can view this from Studio if you make sure class compilation preserves INT. Maybe if you post the relevant INT fragments here someone will be able to spot why the presence of $$$AssertEquals is breaking things.

Yes, it's working, thank you very much

PS: i had to modify it a little and its working for just one method at a time,  but if i call it multiple times for different methods its freezing again

Assuming you're using Studio, look at the View menu where there's an option called "View Other Code". This will open the generated INT if it is available. If it isn't, look on your Build menu and pick "Compile With Options". In the dialog that appears, set the checkbox named "Keep generated source code". Then click OK. After compilation finishes, try "View Other Code" (there's also usually a toolbar button for this).

You can get output from %ToJSON() into a variable without any redirection:

set jsonString = dynamicObj.%ToJSON()

I had to modify it a little and now its freezing because of the $$$AssertEquals. How can i make it work with the asserts?

 

ClassMethod WriteCapture(vstrCommand As %String, Output strOutput As %String, Output status As %Status) [ ProcedureBlock = 0 ]
{
    set tOldIORedirected = ##class(%Device).ReDirectIO()
    set tOldMnemonic = ##class(%Device).GetMnemonicRoutine()
    set tOldIO = $io
    try {
        set strOutput=""

        //Redirect IO to the current routine - makes use of the labels defined below
        use $io::("^"_$ZNAME)

        //Enable redirection
        do ##class(%Device).ReDirectIO(1)

        XECUTE (vstrCommand, .status)
        
    catch ex {
        set strOutput = ""
    }

    //Return to original redirection/mnemonic routine settings
    if (tOldMnemonic '= "") {
        use tOldIO::("^"_tOldMnemonic)
    else {
        use tOldIO
    }
    do ##class(%Device).ReDirectIO(tOldIORedirected)

    //Labels that allow for IO redirection
    //Read Character - we don't care about reading
rchr(c) quit
    //Read a string - we don't care about reading
rstr(sz,to) quit
    //Write a character - call the output label
wchr(s) do output($char(s)) quit
    //Write a form feed - call the output label
wff() do output($char(12)) quit
    //Write a newline - call the output label
wnl() do output($char(13,10)) quit
    //Write a string - call the output label
wstr(s) do output(s) quit
    //Write a tab - call the output label
wtab(s) do output($char(9)) quit
    //Output label - this is where you would handle what you actually want to do.
    // in our case, we want to write to str
output(s) set strOutput=strOutput_s   quit
}

Do $$$AssertEquals(strExpectedResult,strOutputRechtsinfo)

strExpectedResult,  this was a %Library.DynamicObject i converted with %ToJSON()

strOutputRechtsinfo this is what the method i'm trying to test returns

I dont know how to get the INT fragments you speak of