Using Pickle with spork? - cucumber

Pickle doesn't seem to be loading for me when I'm using spork...
If I run my cucumber normally, the step works as expected:
➜ bundle exec cucumber
And a product exists with name: "Windex", category: "Household Cleaners", description: "nasty bluish stuff" # features/step_definitions/pickle_steps.rb:4
But if I run it through spork, I get an undefined step:
You can implement step definitions for undefined steps with these snippets:
Given /^a product exists with name: "([^"]*)", category: "([^"]*)", description: "([^"]*)"$/ do |arg1, arg2, arg3|
pending # express the regexp above with the code you wish you had
end
What gives?

So it turns out there is an extra config line necessary for features/support/env.rb when using spork in order to have Pickle be able to pickup on AR models, a la this gist:
In features/support/env.rb
Spork.prefork do
ENV["RAILS_ENV"] ||= "test"
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
# So that Pickle's AR adapter properly picks up the application's models.
Dir["#{Rails.root}/app/models/*.rb"].each { |f| load f }
# ...
end
Adding in this line fixes my problem. This is more of a spork issue than guard, per se. I'll update my question...

Related

Codeception doesn't override parameter in Gitlab

I have this issue
*********** codeception.yml ***************
paths:
tests: tests
output: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
actor_suffix: Tester
#amount customer per product
amountPerProduct: 1
wishCountry: 1
wishProduct: 0
I am using the param like this:
$countryIndex = Configuration::config()['wishCountry'];
but on the console I calling the test like this:
codecept run tests/acceptance/ChangeCest.php --env chrome --xml --html -o "wishProduct:55"
I get this error:
enter image description here
QUESTION: how can I override this config in Gitlab?
Thank you
Not entirely sure if this solves your problem but for Codeception v5 (also my current local version v4.2.1) the option is exploded with : , i.e. with an appended space. I notice in your screenshot the exception does show the key/value without the space in between, but you didn't specify which version of Codeception you're using.
From Config.php:
foreach ($configOptions as $option) {
$keys = explode(': ', $option);
// ^ notice the space here
if (count($keys) < 2) {
throw new \InvalidArgumentException('--override should have config passed as "key: value"');
}
https://github.com/Codeception/Codeception/blob/5.0/src/Codeception/Command/Shared/ConfigTrait.php
i find the answer to my problem.
I store the parameters in a new file params.yml
params.yml
parameters:
WISH_PRODUCT: 55
codeception.yml
params:
- params.yml
acceptance.suite.yml
config:
custom_params:
wishProduct: %WISH_PRODUCT%
AcceptanceTester.php
so in AcceptanceTester I can read the values like this
$custom_params = Configuration::suiteSettings('acceptance', Configuration::config())['modules']['custom_params'];

Can callbacks be used to configure remotes?

I was reading the Origen documentation on remotes and had a question. When do the remote files get retrieved relative to the Origen callbacks? The reason i ask is that the files we want to retrieve would be used to construct our DUT model and there are some order dependencies.
I have tried all of the existing callbacks, in an attempt to configure the remotes, with no success.
def pre_initialize
Origen.app.config.remotes = [
{
dir: 'product',
vault: 'ssh://git#stash.com/myproduct/origen.git',
version: '0.1.0'
}
]
end
If I add the remotes config to the application file it works:
config.remotes = [
{
dir: 'product',
vault: 'ssh://git#stash.com/myproduct/origen.git',
version: '0.1.0'
}
]
The problem with using the config/application.rb file is that we can't keep product specific information anywhere in our application space. We use symbolic links to map to source files that are stored in test program stash repositories. I think we may need a new callback, please advise.
thx
** EDIT **
So I defined the remotes in another file and call the method to actually do it in the boot.rb file. Then I placed the remote manager require method in the on_create callback but got no remotes fetched.
284: def on_create
285: binding.pry
=> 286: Origen.remote_manager.require!
287: end
[1] pry(#<PPEKit::Product>)> Origen.config.remotes
=> [{:dir=>"remote_checkout", :rc_url=>"ssh://git#stash.us.com:7999/osdk/us-calendar.git", :version=>"v0.1.0"}]
[2] pry(#<PPEKit::Product>)>
origen(main):001:0>
It seems like the Origen.remote_manager.require! is not working. So I checked the remotes manager file and don't see how the require! method could ever work with a callback because it seems to be checking the remotes are dirty, which can never happen for a remote definition that was set after the application.rb file was loaded. So I created a resolve_remotes! method that seems to work:
def resolve_remotes!
resolve_remotes
remotes.each do |_name, remote|
dir = workspace_of(remote)
rc_url = remote[:rc_url] || remote[:vault]
tag = Origen::VersionString.new(remote[:version])
version_file = dir.to_s + '/.current_version'
begin
if File.exist?("#{dir}/.initial_populate_successful")
FileUtils.rm_f(version_file) if File.exist?(version_file)
rc = RevisionControl.new remote: rc_url, local: dir
rc.checkout version: prefix_tag(tag), force: true
File.open(version_file, 'w') do |f|
f.write tag
end
else
rc = RevisionControl.new remote: rc_url, local: dir
rc.checkout version: prefix_tag(tag), force: true
FileUtils.touch "#{dir}/.initial_populate_successful"
File.open(version_file, 'w') do |f|
f.write tag
end
end
rescue Origen::GitError, Origen::DesignSyncError => e
# If Git failed in the remote, its usually easy to see what the problem is, but now *where* it is.
# This will prepend the failing remote along with the error from the revision control system,
# then rethrow the error
e.message.prepend "When updating remotes for #{remote[:importer].name}: "
raise e
end
end
end
The resolve_remotes! method just forces all known remotes to be fetched. Would a PR be accepted for this solution?
thx
Remotes are currently required at application load time, which means it occurs before any of the application call back points.
The content of config.remotes can still be made dynamic by assigning it in a block:
config.remotes do
r = [{
dir: 'product',
vault: 'ssh://git#stash.com/myproduct/origen.git',
version: '0.1.0'
}]
if some_condition
r << { dir: ... }
end
r
end
The config.remotes attribute will be evaluated before the target is loaded however, so you won't be able to reference dut for example, though maybe that is good enough.
Alternatively, you could implement a post target require of the remotes within your application pretty easily.
Make the remotes return en empty array if the dut is not available yet, that will make it work ok when it is called by Origen during application load:
config.remotes do
if dut
# As above example
else
[]
end
end
Then within the callback handler of your choice:
Origen.remote_manager.require!
That should cause it to re-evaluate config.remotes and fetch any remotes that are missing.

Cannot create web documentation from on_flow_end callback

I'm trying to setup origen to automatically generate web documentation after generating a flow with the origen p command, so I added the following callback:
def on_flow_end(options)
OrigenDocHelpers.generate_flow_docs layout: "#{Origen.root}/templates/web/layouts/_basic.html.erb", tab: :flows do |d|
d.page flow: "#{options[:test_module]}_flow".to_sym,
name: "#{options[:test_module].to_s.upcase} Flow",
target: "#{Origen.target.name}.rb"
end
end
This causes an error when building the flow page:
[INFO] 14.641[0.005] || Building flow page: /users/chorton/osdk/ppekit/web/content/flows/pcie_flow.md
COMPLETE CALL STACK
-------------------
Can't find: partials/_navbar.html
/home/chorton/.origen/gems/ruby/2.3.0/bundler/gems/origen-7bf48a874995/lib/origen/file_handler.rb:137:in `clean_path_to'
/home/chorton/.origen/gems/ruby/2.3.0/bundler/gems/origen-7bf48a874995/lib/origen/file_handler.rb:226:in `rescue in clean_path_to_sub_template'
/home/chorton/.origen/gems/ruby/2.3.0/bundler/gems/origen-7bf48a874995/lib/origen/file_handler.rb:213:in `clean_path_to_sub_template'
/home/chorton/.origen/gems/ruby/2.3.0/bundler/gems/origen-7bf48a874995/lib/origen/generator/renderer.rb:8:in `render'
(erb):4:in `_get_binding'
There is no error if I separately call origen p (without the added callback) and then run:
origen web compile --remote --api
Is it possible to combine the two into one command with a callback like I'm trying to do or is it necessary for origen web compile to be called after origen p?
Thanks.
This does seem like a bug, please open a ticket for it here if you cannot get it resolved - https://github.com/Origen-SDK/origen/issues
I would say that the convention normally used to do this is to hook into the after_web_site_compile callback in your config/application.rb.
Here is an example:
# config/application.rb
def after_web_site_compile(options)
# Build the test flow docs
Origen.environment.temporary = 'v93k.rb'
# Generate the program for the target(s) you want to document
%w(device_a device_b).each do |target|
Origen.target.temporary = "#{target}.rb"
Origen.app.runner.launch action: :program,
files: 'program/full.list' # Or whatever file arg you pass to 'origen p'
OrigenDocHelpers.generate_flow_docs layout: "#{Origen.root}/templates/web/layouts/_basic.html.erb", tab: :flows do |d|
d.page flow: "#{options[:test_module]}_flow".to_sym,
name: "#{options[:test_module].to_s.upcase} Flow",
target: "#{target}.rb"
end
end
end

post test execution callbacks available?

I am looking to apply a callback post test execution that will check for an alarm flag. I don't see any listed here so I then checked the test interface and only see what looks like a flow level callback:
# This will be called at the end of every flow or sub-flow (at the end of every
# Flow.create block).
# Any options passed to Flow.create will be passed in here.
# The options will contain top_level: true, whenever this is called at the end of a
# top-level flow file.
def shutdown(options = {})
end
We need the ability to check the alarm flags after every test but still apply a common group ID to a list of tests like this:
group "func tests", id: :func do
[:minvdd, :maxvdd].each do |cond|
func :bin1_1200, ip: :cpu, testmode: :speed, cond: cond
end
end
Here is an example of the V93K alarm flow flag:
thx!
It is common when writing interfaces to funnel all test generation methods through a common single method to add them to the flow:
def func(name, options = {})
t = test_suites.add(name)
t.test_method = test_methods.origen.functional_test(options)
add_to_flow(t, options)
end
def para(name, options = {})
t = test_suites.add(name)
t.test_method = test_methods.origen.parametric_test(options)
add_to_flow(t, options)
end
def add_to_flow(test_obj, options = {})
# Here you can do anything you want before adding each test to the flow
flow.test(test_obj, options)
# Here you can do anything you want after adding each test to the flow
end
So while there is no per-test callback, you can generally achieve whatever you wanted to do with one via the above interface architecture.
EDIT:
With reference to the alarm flag flow structure you want to create, you would code it like this:
func :some_func_test, id: :sft1
if_failed :sft1 do
bin 10, if_flag: "Alarm"
bin 11, unless_flag: "Alarm"
end
Or, if you prefer, this is equivalent:
func :some_func_test, id: :sft1
bin 10, if_flag: "Alarm", if_failed: :sft1
bin 11, unless_flag: "Alarm", if_failed: :sft1
At the time of writing, that will generate something logically correct but with a sub-optimal branch structure.
In the next release that will be fixed, see the test case that has been added here and the output it generates here.
You can call all of the flow control methods from the interface the same way you can from within the flow, so you can inject such conditions in the add_to_flow method if you want.
Note also that in the test case both if_flag and if_enable are used. if_enable should generally be used if the flag is something that would be set at the start of the flow (e.g. by the operator) and would not change. if_flag should be used if it is a flag that is subject to modification by the flow at runtime.

Groovy CliBuilder: only last LongOpt is taken in account

I'm trying to use the groovy CliBuilder to parse command line options. I'm trying to use multiple long options without a short option.
I have the following processor:
def cli = new CliBuilder(usage: 'Generate.groovy [options]')
cli.with {
h longOpt: "help", "Usage information"
r longOpt: "root", args: 1, type: GString, "Root directory for code generation"
x args: 1, type: GString, "Type of processor (all, schema, beans, docs)"
_ longOpt: "dir-beans", args: 1, argName: "directory", type: GString, "Custom location for grails bean classes"
_ longOpt: "dir-orm", args: 1, argName: "directory", type: GString, "Custom location for grails domain classes"
}
options = cli.parse(args)
println "BEANS=${options.'dir-beans'}"
println "ORM=${options.'dir-orm'}"
if (options.h || options == null) {
cli.usage()
System.exit(0)
}
According to the groovy documentation I should be able to use multiple "_" values for an option when I want it to ignore the short option name and use a long option name only. According to the groovy documentation:
Another example showing long options (partial emulation of arg
processing for 'curl' command line):
def cli = new CliBuilder(usage:'curl [options] <url>')
cli._(longOpt:'basic', 'Use HTTP Basic Authentication')
cli.d(longOpt:'data', args:1, argName:'data', 'HTTP POST data')
cli.G(longOpt:'get', 'Send the -d data with a HTTP GET')
cli.q('If used as the first parameter disables .curlrc')
cli._(longOpt:'url', args:1, argName:'URL', 'Set URL to work with')
Which has the following usage message:
usage: curl [options] <url>
--basic Use HTTP Basic Authentication
-d,--data <data> HTTP POST data
-G,--get Send the -d data with a HTTP GET
-q If used as the first parameter disables .curlrc
--url <URL> Set URL to work with
This example shows a common convention. When mixing short and long
names, the short names are often one
character in size. One character
options with arguments don't require a
space between the option and the
argument, e.g. -Ddebug=true. The
example also shows the use of '_' when
no short option is applicable.
Also note that '_' was used multiple times. This is supported but
if any other shortOpt or any longOpt is repeated, then the behavior is undefined.
http://groovy.codehaus.org/gapi/groovy/util/CliBuilder.html
When I use the "_" it only accepts the last one in the list (last one encountered). Am I doing something wrong or is there a way around this issue?
Thanks.
not sure what you mean it only accepts the last one. but this should work...
def cli = new CliBuilder().with {
x 'something', args:1
_ 'something', args:1, longOpt:'dir-beans'
_ 'something', args:1, longOpt:'dir-orm'
parse "-x param --dir-beans beans --dir-orm orm".split(' ')
}
assert cli.x == 'param'
assert cli.'dir-beans' == 'beans'
assert cli.'dir-orm' == 'orm'
I learned that my original code works correctly. What is not working is the function that takes all of the options built in the with enclosure and prints a detailed usage. The function call built into CliBuilder that prints the usage is:
cli.usage()
The original code above prints the following usage line:
usage: Generate.groovy [options]
--dir-orm <directory> Custom location for grails domain classes
-h,--help Usage information
-r,--root Root directory for code generation
-x Type of processor (all, schema, beans, docs)
This usage line makes it look like I'm missing options. I made the mistake of not printing each individual item separate from this usage function call. That's what made this look like it only cared about the last _ item in the with enclosure. I added this code to prove that it was passing values:
println "BEANS=${options.'dir-beans'}"
println "ORM=${options.'dir-orm'}"
I also discovered that you must use = between a long option and it's value or it will not parse the command line options correctly (--long-option=some_value)

Resources