Switching testers in specs tests - origen-sdk

I’ve been having a lot of trouble trying to figure out how to use the V93K for spec testing. For the J750 it was easy, I just did this:
before(:context) do
Origen.environment.temporary = 'j750.rb'
Origen.load_target('default')
c = Class.new do
include OrigenTesters::ProgramGenerators
include TIPShared::Interfaces::AnalogTestBase
def func(name, options={})
#current_test_config = test_instances.functional(name, options)
#current_test_config
end
def t
#current_test_config
end
end
#test_interface = c.new
end
Then I could call #test_interface.func and do whatever with it.
Trying something similar with the 93K, I’m having all sorts of problems, the latest of which makes no sense as its still looking for IGXL stuff. So far what I have is:
before(:context) do
Origen.environment.temporary = 'v93k.rb'
Origen.load_target('default')
Origen.app.load_target!
#c = Class.new do
include OrigenTesters::ProgramGenerators
include OrigenTesters::SmartestBasedTester
#include OrigenTesters::SmartestBasedTester::V93K
#include OrigenTesters::SmartestBasedTester::Base
include TIPShared::Interfaces::AnalogTestBase
def func(name, options={})
#current_test_config = test_suites.add(name, options)
#current_test_config.test_method = test_methods.origen.functional_test
#current_test_config
end
def t
#current_test_config
end
end
#test_interface = #c.new
Origen.file_handler.current_file = Pathname.new("#{Origen.app.root}/temp.rb")
end
But trying #test_interface.func just gives:
Which is very confusing to me because I thought OrigenTesters::ProgramGenerators would pick the V93K instead. I can’t figure out if this is a problem/shortcoming of testers or if this is specs. I thought specs would basically ‘restart’ the application in the next context, so IGXL anything shouldn’t be loaded.
Failure/Error: #current_test_config = test_suites.add(name, options)
NameError:
uninitialized constant OrigenTesters::IGXLBasedTester::J750::TestSuite
Did you mean? OrigenTesters::IGXLBasedTester::J750::TestInstance
# /proj/.tec_k3s/users/cengelken_b50956/tr_origen/gems/ruby/2.3.0/gems/origen_testers-0.10.0/lib/origen_testers/smartest_based_tester/base/test_suites.rb:21:in `add'
# ./spec/analog_test_base_spec.rb:262:in `func'
# ./spec/analog_test_base_spec.rb:281:in `block (5 levels) in <top (required)>'
# ./config/commands.rb:27:in `<top (required)>'
# /proj/.tec_k3s/users/cengelken_b50956/tr_origen/gems/ruby/2.3.0/gems/origen-0.24.0/lib/origen/commands.rb:183:in `require'
# /proj/.tec_k3s/users/cengelken_b50956/tr_origen/gems/ruby/2.3.0/gems/origen-0.24.0/lib/origen/commands.rb:183:in `<top (required)>'
Any help would be appreciated.
Thanks,
Corey

I wonder if the way the class is being defined here is causing the assignment of the platform-specific API not to occur, see here: https://github.com/Origen-SDK/origen_testers/blob/master/lib/origen_testers/program_generators.rb#L23
You might try calling c._load_generator manually to see if that helps.
Alternatively, include the generators explicitly: include OrigenTesters::V93K::Generator
Could your TIPShared::Interfaces::AnalogTestBase module be including the Teradyne generators?
EDIT:
After further discussion it appears that the problem is that the new interface being created is not being assigned to Origen.interface.
There is an existing example of how to deal with multiple interface creation in a test situation here: https://github.com/Origen-SDK/origen_testers/blob/master/spec/interface_spec.rb#L22

Thanks, #ginty. That did end up being the problem. I had previously messed with the interface by just clearing them and adding them back but it wasn't actually setting Origen.interface.
I managed to get this to work. Its not the prettiest, but seems to be working. To switch from J750 to 93K I did:
# Create a dummy file for the V93K interface to use. Doesn't need to exists, it won't actually be used, just needs to be set.
Origen.file_handler.current_file = Pathname.new("#{Origen.app.root}/temp.rb")
# Load V93K environment and reload the target.
Origen.environment.temporary = 'v93k.rb'
Origen.load_target('default')
# Clear the existing interface and reset Origen's current interface.
# ASIDE: this must be done after setting the current tester.
Origen.interfaces.clear
Origen.reset_interface
This is actually clearing the interface and setting it to 'NoInterface', but seems to be working all the same, at least for Specs testing purposes. Not sure if this will be a problem when I start actually generating sheets, but we'll find out.

Related

What does --frozen-intrinsics flag do in node.js?

The documentation for --frozen-intrinsics says:
Only the root context is supported. There is no guarantee that globalThis.Array is indeed the default intrinsic reference. Code may break under this flag
I couldn't understand this. Can someone help me understand this in simple words with an example?
Background: I was checking nicolo-ribaudo/jest-light-runner where there is a mention of --frozen-intrinsics.
When you use --frozen-intrinsics, all the built-in JavaScript objects and functions are recursively frozen, except for globalThis.
If you run node --frozen-intrinsics, you can check it:
> Object.isFrozen(Array)
true
> Object.isFrozen(Array.prototype)
true
> Object.isFrozen(globalThis);
false
> Array.isArray = () => true; Array.isArray(2); // you cannot modify built-in properties, this will not return true
false
> globalThis.foo = 3; foo; // you can still define new globals
3
> globalThis.Array = 4; Array; // However, you can also replace existing globals
4
This prevents your code from accidentally modifying globals, so I recommended it in jest-light-runner to prevent tests from accidentally influencing each other (since it doesn't isolate test files like Jest's default runner does).
Note that you still have a communication channel by attaching new properties to the global object, so it's not an isolation mechanism.
Now, lets take a look at the docs you quoted.
Only the root context is supported.
In Node.js, you can create multiple "global contexts" using the vm built-in module. --frozen-intrinsics does not affect those contexts, so if you run node with --frozen-intrinsics:
> Object.isFrozen(Array)
true
> Object.isFrozen(require("vm").runInNewContext("Array"))
false
There is no guarantee that globalThis.Array is indeed the default intrinsic reference.
As mentioned earlier, globalThis.Array could still be replaced. However, if you have a "safe reference" to an object (either using syntax, or by storing the original Array global in a local variable), you can be sure that it's not modified:
let OriginalArray = Array;
require("untrusted-module");
globalThis.Array; // this might have been replaces
[].push; // this is still the original one
OriginalArray.isArray; // this is still the original one
Code may break under this flag
If code needs to modify built-ins, it would obviously stop working. For example, you cannot use polyfills that modify the global objects.

Excel add-in with logging class: How to react to VBA state loss?

The setup
I'm developing and maintaining an Excel add-in that comes with its own tab of controls within Excel's Ribbon UI. I've come across the problem of state loss before (meaning loss of all variables with global scope, static variables, etc, which of course includes my reference to the RibbonUI). With regards to the ribbon reference I've "solved" the problem by including a "Reset Ribbon" button that restores the reference from a persistently stored pointer and then invalidates the ribbon. Although certainly not the most elegant, this part works just fine.
However, after the introduction of a logging class, the state loss issue haunts me once again. The logger is instantiated in ThisWorkbook's module:
Private Sub Workbook_Open()
Set LogToFile = SingletonFactory.getToFileLogger
End Sub
and is then put to work, for example, as follows:
Private Sub buttonReloadObjects_onAction(ByVal control As IRibbonControl)
LogToFile.trace "Event firing: buttonReloadObjects_onAction"
' more stuff happening...
invalidateRibbon ' restores ribbon object and invalidates it
End Sub
The logger is instantiated when the add-in is loaded so that I have the freedom to log whatever I want within the confines of my add-in's code. It has several logging levels like trace/debug/error/... and a couple of other methods. Usually it works just fine - until the state loss hits (usually caused by an unrelated error, followed by clicking "End").
State loss
At this point the VBA environment forgets about the very existence of my LogToFile object and nothing works any more, because every click on the ribbon controls will trigger a runtime error 91: Object variable or with block variable not set pointing to whatever line is the first to contain a reference to LogToFile.
A solution?
Now, short of doing crazy workarounds like placing
if not isObject(LogToFile) then
Set LogToFile = SingletonFactory.getToFileLogger
end if
LogToFile.trace "Message"
before any occurrence of LogToFile, the only real "solution" I was able to come up with is to wrap all my logger calls in functions (residing in a standard module) and call these functions any time I want to send something to the log. This way I could catch the missing object reference right before the object is needed and I avoid calling methods of uninstantiated objects.
However, after having everything neatly encapsulated in class modules, it strikes me as odd, maybe even wrong(?), going down this route.
So, is there a "proper" solution to the problem of a lost logger instance? Or is my suggested approach already as proper as it can get?
Note: This problem is of course not specific to logging classes. It affects all global variables, most notably my ApplicationEventClass. The issue just happens to be the most glaring with the logger due to its frequent usage around all entry points to the code.
You only need one function that either returns the original variable or resets it. If you call that function LogToFile you don't need to change any of the other code other than removing the Workbook_Open code which is then superfluous. So:
Function LogToFile() As WhateverVariableType
Static temp as WhateverVariableType
If temp is Nothing then Set temp = SingletonFactory.getToFileLogger
Set LogToFile = temp
End Function
This way you will also still benefit from Intellisense when writing the code.
Note: you may not actually need the temp variable - it depends on whether there are settings that you want persisted. If there are, you may want to reset them in the function too.

node-soap: "Non-whitespace before first tag."

My WSDL is valid, but this error (in title) occurs on soap.createClient. The WSDL is hosted on the server. After inspecting the node-soap source, it looks like if I can disable the "strict" flag in the WSDL class this error will not occur, but I can't seem to figure out how to disable this. I tried passing options to the createClient method like so:
soap.createClient(wsdl, { strict: false }, callback);
But that does not seem to resolve this issue. Unfortunately I can't share the WSDL, but you can be sure that it passes validation, and there is no "non-whitespace" before the opening tag. I'm fairly certain that if I can somehow disable the strict option in the wsdl class that would resolve the issue. Has anyone had this occur before?
The short answer is no, it doesn't appear to be possible given the current code base. I would suggest opening a pull request to add the functionality you need.
The code you've referenced above, soap.createClient ends up using the wsdl.js file which, when it parses the wsdl, ends up in a function _parse. This function creates the sax parser but hard codes passing in true for the strict mode (link to code):
p = sax.parser(true),
The soap module depends on the sax module, which takes in a boolean to determine if strict mode should be enabled (link to code):
sax.parser = function (strict, opt) { return new SAXParser(strict, opt) }
So the options you pass to the createClient are not used in the creation of the sax parser, and instead it's set to strict mode. However, like I said above, a pull request could fix this since it looks like the options are passed all the way to the creation of the WSDL object, so it'd just be a matter of creating the sax parser with that option passed, instead of true.
(Keep in mind the code additionally creates a sax parser within another function, xmlToObject (link to source), but here again hard codes the strict mode)

How to avoid page-object deprecated for checkbox

I use cucumber since one year, and I am adding page-object-gem into it since few weeks.
When I execute the test, I get message :
DEPRECATION WARNING
You are calling a method named checkbox at commentPage.rb:23:in `block in delete_comment'.
This method does not exist in page-object so it is being passed to the driver.
This feature will be removed in the near future.
Please change your code to call the correct page-object method.
(I have got the same for other cases, but this "trivial" example should be easier to explain)
I search a way to avoid that, but it seems complicated.
For the test, I am checking a page, on which there is a table. Each row show a line, and I need to check the checkbox of a particular line.
My code in the pageObject:
table(:comment_list, :class => 'comments')
button(:delete, :text => "Delete")
def delete_comment (text)
self.comment_list_element.each do |row|
if row.text.include? "#{text}"
row.checkbox.set
self.delete
return true
end
end
false
end
Did I need a pretreatment of my table to use it during the test ?
You are getting the warning because you are calling a method that is on Watir and not page-object (checkbox method on a table row). If you want to access the Checkbox you can simply call the method that will return the nested element. This would change that portion of the call to row.checkbox_element. But you next call will also get the same issue. First of all the set method does not exist on CheckBox. In page-object the methods are check and uncheck. The full call should be:
row.checkbox_element.check
The reason you are getting the deprecation error is because I plan to remove the forwarding of calls to the underlying driver in the future. This ability really causes a lot of problems in complex situations.
In your code, row is a PageObject::Elements::TableRow, which does not have a checkbox method defined. I have not come across any examples where page-object elements were chained.
As a workaround, you could convert the PageObject::Elements::TableRow to a regular Watir::TableRow by doing:
row.element
So your code will work if you do:
row.element.checkbox.set

LuaLanes Unable to pass global variables between functions (in a single lane)

hope you're having a good day.
I have been programming a IRC chatbot in Lua the past few days, and finally I want to start implementing multiple server support into it.
So far, I have created the irc "object" to manage each server, and all that happy stuff - Now, I am having problems with threading.
Lua, as you probably know, doesn't have thread support built-in. LuaLanes and LuaThreads seemed like the closest to what I wanted to use, in terms of libraries. What made me choose LuaLanes is because LuaThreads requires a modified lua core. Plus the "lindas" feature of LuaLanes caught my eye (for later use in plugins)
Anyway, the issue that I'm having is when you generate a lane using function middleman (for example), which then calls another function sqr (for example). if you generate the function like lanes.gen({globals = _G}, middleman), middleman will have access to everything in your current global scope, which is exactly what I want. The problem is, if middleman calls sqr, and sqr uses something from the global scope, it throws an error, almost as if _G suddenly became empty.
Here's some example code I managed to throw together, using my example above:
require 'lanes'
function sqr()
print(5*5)
end
function middleman()
sqr()
end
gen = lanes.gen({globals = _G}, middleman)
print(gen()[1])
Produces an error saying:
tc#box:~$ lua lanestrouble.lua
lua: lanestrouble.lua:4: attempt to call global 'print' (a nil value)
stack traceback:
[C]: in function 'error'
./lanes.lua:190: in function <./lanes.lua:136>
lanestrouble.lua:13: in main chunk
[C]: ?
threading.c 399: pthread_cond_destroy(ref) failed, 16 EBUSY
Aborted
tc#box:~$
(By the way, I'm using linux)
However, if you change line 11 from gen = lanes.gen({globals = _G}, middleman) to gen = lanes.gen({globals = _G}, sqr), it works fine.
I've checked, and the same thing happens if you pass "*" (or any other option for the "libs_str" parameter) to load the default libraries.
I really wish there was something like Java's threading library for Lua, that's how I originally learned to use threads. (I know, not the most ideal environment I suppose)
Thanks, I appreciate help a lot. Especially since this has completely halted my IRC bot development! :(
Making sqr local does the trick. Since it becomes an upvalue of middleman, it is copied to the new lane.
require 'lanes'
local function sqr()
print(5*5)
end
function middleman()
sqr()
end
gen = lanes.gen({globals = _G}, middleman)
print(gen()[1])
But definitely something strange is going on. I mean, even when passing explictly "sqr" and "print" to the new lane, it won't see "print" (when called by "sqr"). It seems to me that something is not working right when serializing functions between lanes. You should contact its maintainer.

Resources