Julia #everywhere importall confusing behaviour - parallel-processing

I'm trying to make some imported function available on all processes.
module EverywhereTest
#everywhere importall SubTest
function output()
test_print()
end
end
module SubTest
export test_print
function test_print()
print("hello")
end
end
On one process, this works without the #everywhere
using EverywhereTest
EverywhereTest.output()
hello
But with #everywhere I get UndefVarError: test_print not defined. Same behaviour with using instead of importall.
Does anyone know why this happens?

Related

Parallel processing: #everywhere, distributions and types

I have recently started studying parallel processing in Julia and I am having an issue which I don't really understand how to fix.
After having executed Julia with julia -p 4 I want to load the Distributions module in all the processes and I would like to define a Type which depends on Distributions.
The following apparently works correctly when I include it:
#everywhere using Distributions
type TypeDistrib{T <: Float64}
d::Distributions.Normal{T}
end
If I write exactly the same code as a module, then it doesn't:
module test
#everywhere using Distributions
type TypeDistrib{T <: Float64}
d::Distributions.Normal{T}
end
export TypeDistrib
end
The above gives the following error message:
ERROR: LoadError: UndefVarError: Distributions not defined
in include_from_node1(::String) at ./loading.jl:488
in include_from_node1(::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
while loading /***/test.jl, in expression starting on line 4
Would you please clarify what I am not doing correctly here?
Note: I replaced the full path in the error message with *** since it was confusing.
#everywhere something evaluates something in the Main module across all processes. And in this case, not in test module, and therefore the error in the second case and not in the first.
Perhaps
#everywhere module test
using Distributions
type TypeDistrib{T <: Float64}
d::Distributions.Normal{T}
end
export TypeDistrib
end
does what is meant.

How to handle running Cucumber features within Ruby method?

I am using a AfterConfiguration hook to run some setup config before my tests start, however the issue that I am faced with is that when I run my methods one of them will run a set of feature files using backticks in a Ruby method, which in turn seems to re-initialize cucumber and repeat the process, so I am stuck in a loop
AfterConfiguration do
EnvironmentSetup::TestUsers.create_test_users
end
module EnvironmentSetup
class TestUsers
def self.create_test_users
# other logic here
`cucumber "#{path_to_feature}"` # Use backticks to run cucumber scripts in a subshell
end
end
end
So when this is executed it goes back to the beginning and runs it all my other logic again
Is there a way to only run this once, or ignore the AfterConfiguration on the second loop? declare a global variable?
I have also tried
AfterConfiguration do
if defined? $a == nil
EnvironmentSetup::RedisUsers.check_redis_users
EnvironmentSetup::TestUsers.create_test_users
end
end
module EnvironmentSetup
class TestUsers
def self.create_test_users
# other logic here
$a = true
`cucumber "#{path_to_feature}"` # Use backticks to run cucumber scripts in a subshell
end
end
end
but I'm guessing that the variable set is not being carried across when re-initializing?
Try setting Environment variable:
AfterConfiguration do
return if ENV['CUCUMBER_CONFIGURED'] == 'yes'
EnvironmentSetup::TestUsers.create_test_users
ENV['CUCUMBER_CONFIGURED'] = 'yes'
end
And run cucumber something like this:
CUCUMBER_CONFIGURED='no'; cucumber ...

Load a Ruby TestCase Without Running It

I'm trying to write a custom tool that runs ruby unit tests with my customizations.
What I need it to do is to load a certain TestCase from given file(through require or whatever), and then run it after doing some calculations and initializations.
Problem is, the moment I require "test/unit" and a test case, it runs immediately.
What can I do with this?
Thanks.
Since you're running 1.9 and test/unit in 1.9 is merely a wrapper for MiniTest, the following approach should work:
implement your own custom Runner
set MiniTest's runner to your custom runner
Something like (shameless plug from EndOfLine Custom Test Runner, adjusted to Ruby 1.9):
fastfailrunner.rb:
require 'test/unit'
class FastFailRunner19 < MiniTest::Unit
def _run args = []
puts "fast fail runner"
end
end
~
example_test.rb:
require 'test/unit'
class ExampleTest < Test::Unit::TestCase
def test_assert_equal
assert_equal 1, 1
end
def test_lies
assert false
end
def test_exceptions
raise Exception, 'Beware the Jubjub bird, and shun the frumious Bandersnatch!'
end
def test_truth
assert true
end
end
run.rb:
require_relative 'fast_fail_runner'
require_relative 'example_test'
MiniTest::Unit.runner= FastFailRunner19.new
If you run this with
ruby run.rb
the custom FastFailRunner19 will be used, which does nothing.
What about reading file content as a regular text file and doing eval on its content after you initialize/calculate things you say? It may not be sufficient for your needs and may require manual setup and execution of testing framework.
Like that (I put heredoc instead of reading file). Basically content is just a string containing your test case code.
content = <<TEST_CASE
class YourTestCase
def hello
puts 'Hello from eval'
end
end
YourTestCase.new.hello
TEST_CASE
eval content
Note: Altough I'd rather not use eval if there is another way. One should be extra careful when evaling code from string manually in any language.
You could collect the test cases you want to deferred its executions and store them in an array. Afterwards you would create a block execution code. For instance:
test_files = ['test/unit/first_test.rb'] #=> Testcases you want to run
test_block = Proc.new {spec_files.each {|f|load f} } #=> block storing the actual execution of those tests.
Once you're ready to call those testcases you just do test_block.call.
To generalize a bit, when thinking about deferring or delaying code executions, closures are a very elegant and flexible alternative.

Ruby not selecting correct overloaded method

Ive got a simple Nunit runner for a rake script i have:
module NUnitRunner
#NUnitPath = "#{RootDir}/tools/nunit/nunit-console.exe";
def self.RunTests(testFile)
system("\"#{#NUnitPath}\" ? \"#{testFile}\"")
end
def self.RunTests(testFile, runArgs)
system("\"#{#NUnitPath}\" ? \"#{testFile}\" #{runArgs}")
end
end
When im calling this module from within my task:
# Run Unit Tests
task :run_unit_tests do
puts "Running Unit Tests"
unitTestFile = "#{RootDir}/src/tests/unittests.dll"
NUnitRunner.RunTests(unitTestFile)
end
It just keeps telling me "wrong number of arguments (1 for 2)", and if i remove the overloaded method which takes 2 arguments it works fine, so is there some quirk with ruby that i dont know about in this instance?
Ruby doesn't support method overloading.

Including the same module file within itself in Ruby?

I am learning ruby and about modules and mixins..
I tried the following code. The name of the ruby file test.rb.
module Mod1
def Mod1.sayHello()
puts "Hello Mod1"
end
end
module Mod2
def Mod2.sayHello()
puts "Hello Mod2"
end
end
class TestMod
require 'file'
Mod1.sayHello
end
t = TestMod.new
I am suprised to the output:
Hello Mod1
Hello Mod1 (twice)
I am don't have an explanation for this, can somebody help?
You did not define your initialize method for your class (the constructor). You are simply executing Mod1.sayHello inside the class definition (it is even executed before creating the instance). Try to comment out your t = TestMod.new statement. The output will still stay visible.
Since you include the exact same file, this ends up being executed twice (the file does not get included another time afterwards; ruby prevents this). The class should look like this:
class TestMod
def initialize
Mod1.sayHello
end
end
Why did you include the file anyway? This does not make sense to me.
EDIT: Removed a mistake.
I would recommend to replace the Mod1 and Mod2 inside your module definitions with self. This way you wont have to change the name everywhere if it changes some time.

Resources