Is there a way to disable fakeredis once it's loaded? - ruby

I'm working with some code that uses the fakeredis gem for specs, but whenever I run those specs from a REPL, fakeredis stays around and commands like Redis.new will just give me fakeredis. I need to be able to disable it to be able to access the real redis store again.
Is there a way to disable/enable it in the REPL?

Two solutions, either remove the fakeredis memory class:
Redis::Connection.drivers.delete_if {|d| d == Redis::Connection::Memory }
or append the Ruby adapter again:
Redis::Connection.drivers << Redis::Connection::Ruby
Source: https://github.com/guilleiguaran/fakeredis/issues/63

Related

Setting path to custom .irbrc using IRB.conf

I want to invoke irb dynamically from my Ruby program, but have it not to load the default ~/.irbrc, but a file ./custom_irbrc instead. I can do it like this:
require 'irb'
ENV['IRBRC'] = './custom_irbrc'
IRB.setup(nil)
# My configurations follow here
IRB.conf[...]=...
IRB.start
I wonder whether I can set my custom irbrc also via .conf instead of polluting the environment. I didn't find a really comprehensive description of the possible conf-settings, but from what I found, I tried as educated guess:
IRB.conf[:IRB_RC] = './custom_irbrc'
IRB.conf[:RC] = './custom_irbrc'
but neither one seems to have any effect.
The desired effect can be achieved, although by using an undocumented feature, and there is no guarantee that it will be available in future Ruby versions too:
IRB.conf[:RC_NAME_GENERATOR] = proc { './custom_irbrc' }
This has to be done before IRB.setup is called.

Unknown response for all methods and commands in ruby-asterisk

Testing ruby-asterisk manager interface with ruby version 1.9.3p0 and gem 1.8.11, for all command and methods its printing the the same output.
Anyone faced similar problem.
Code:
#!/usr/bin/env ruby
require 'ruby-asterisk'
#ami = RubyAsterisk::AMI.new("192.168.1.5",5038)
#ami.login("admin","passs")
puts #ami.command("sip show peers")
Output:
#<RubyAsterisk::Response:0x000000016af710>
Project URL
Problem solved. Didn’t check the readme RESPONSE OBJECT section.
It's working.
var = #ami.command(""sip show peers)
puts var.data
You are putting the Instance of the RubyAsterix. I think after haveing a brief look at the project that most/all of the instance methods returns the instance it self. The reason for doing it that way is that it makes it very easy to chain multiplie actions which makes for a nice syntax/usage.
I think you should remove the puts and allow the gem to display what it wants to display.

Is it better idea to save elements in yml file?

I'm writing automated tests using Selenium WebDriver with Ruby. So, I'm thinking to keep elements in another file and actual code in another file. And for Ruby, I found yaml gem which allows to store data and access it. Hence I stored elements in lib.yml and test code in test.rb as following:
lib/lib.yml
homepage:
frame: 'mainPage'
email: 'loginPage-email'
password: 'loginPage-password'
login_button: 'btnLogin'
tests/test.rb
require 'selenium-webdriver'
require 'yaml'
driver = Selenium::WebDriver.for :firefox
driver.get 'http://www.abc.com'
config = YAML.load_file('./lib/lib.yml')
driver.switch_to.frame(config['homepage']['frame'])
email = driver.find_element(:id, config['homepage']['email'])
password = driver.find_element(:id, config['homepage']['password'])
email.clear
email.send_keys 'abc#gmail.com'
password.clear
password.send_keys 'password'
driver.find_element(:id, config['homepage']['login_button']).click
driver.quit
This way maintenance becomes easier. I just want to make sure if doing so is a good way or not. I'm asking because I'm trying this first time and don't know what difficulties I'll run into if I choose this for larger project.
I know, using Page object model, we can achieve same thing. But I don't know about Page object. So should I avoid using yml gem and directly go for page object gem?
Also, can someone explain how using yml will not be good idea(if it's not)?
Note:
In above code, config['homepage']['something'] is repetitive code. I'll write method to avoid repetition for that.
Yeah this definitely is useful... It keeps the changes to minimum when there is UI change in future.. You always have just one place to edit... Is there any data you have to pass to your code? How are storing the automation data passed to your test.. The only concern might be you might end up with too many yaml files which could be difficult to keep track...
In your specific case I don't see how this adds much value. Half of the settings (frame, login_button) won't change for your tests, so I suggest leaving them directly in the code where they are used. The html structure is not something that usually changes.
The other two values (email, password) seem like they might change when you want to try out different users (i.e. different cases). If you have one test with several example inputs then I suggest using a more readable solution as Cucumber.
(I'd suggest using capybara anyway for testing browser interaction, as it abstracts away many details of the underlying driver)
Apart from that, yaml is usually the ruby way for storing configuration.
I added one more step: Declared locator (id, name etc) in the yaml itself.
Ex:(yaml)
Declared env.rb which load the environment from yaml files
env.yml:
LOGIN:
UserName: {id: UserName}
Password: {id: Password}
RememberME: {id: RememberMe}
Submit: {xpath: "//input[#value='Log On']"}
Then added "pages\Login.rb"
#Loads all objects from yaml
def get_objects
username=#browser.find_element( $object_array['LOGIN']['UserName'])
password=#browser.find_element( $object_array['LOGIN']['Password'])
remember_me=#browser.find_element( $object_array['LOGIN']['RememberME'])
submit= #browser.find_element($object_array['LOGIN']['Submit'])
end
#Added methods in this class like
def loginas(uname,pass)
username.send_keys uname
password.send_keys pass
remember_me.click
submit.click
end #loginas_siteadmin
Created Tests file Login_tests.rb
lp=LoginPage::new(#browser)
lp.navigate
lp.loginas('SiteAdmin','password123')
This way your scripts and maintainable and most importantly you are free of any other external gem or dependency.

Passing options and parameters to Test/Unit via Rake::TestTask

So I've been trying to figure this out, and the best solution I can came up with his global variables - but that seems so dirty and 1974 - Am I missing a feature of Rake/ Test::Unit?
I have a Rake file in which I'm running tests:
Rake::TestTask.new(:test) do |t|
t.test_files = FileList['test_*.rb']
end
and test_1.rb has something like this:
require "test/unit"
class TestStuff < Test::Unit::TestCase
def setup
#thingy = Thing.New(parameter1, parameter2)
end
def test_this_thing
#thing.do()
end
end
My problem is, Thing.new() requires arguments, and those arguments are specific to my environment. In reality, I'm running Selenium-WebDriver, and I want to pass in a browser type, and a url, etc... sometimes I want ff, othertimes I want chrome... sometimes this URL, sometimes that... depending on the day, etc.
The simplest thing seems to do something like:
#all that rake stuff
$parameter1 = x
$parameter2 = y
and then make Thing.new() look up my global vars:
#thingy = Thing.New($parameter1, $parameter2)
This seems sloppy.. and it just doesn't feel right to me. I'm still trying to get this 'test harness' up and running, and want to do it right the first time. That's why I chose Rake, based on a lot of other feedback.
Keep in mind, I'll probably have 100's of tests, ultimately, and they'll all need to do get this information... I thought Rake was good at making sure all of this was easy, but it doesn't seem to be.
Where did I go wrong?
I have used YAML files to store my configuration (browser config, environments including URLs, etc).
You can also use an environmental variable to define simple configurations. You can access environmental variables via ENV['foobar'] in Ruby.
So, for example, my browser call might look like this inside my setup method:
driver = Selenium::WebDriver.for (ENV['SWD_BROWSER'] || "firefox").to_sym
and in my Rake file (or in the shell console) define the environmental variable to use.

How to create a sandboxed RSpec environment?

Essentially, I want to create a program that will run some untrusted code that defines some method or class, and then run an untrusted rspec spec against it.
I've looked into sandboxing Ruby a bit, and this video from rubyconf was particularly helpful. After looking at several solutions, the two that appear to be the most helpful are rubycop, which essentially does static analysis on the code, and the jruby sandbox (both covered in above video). My instinct tells me that the jruby sandbox is probably safer, but I could well be wrong.
Here's a completely unsafe example of what I want to do:
code = <<-RUBY
class Person
def hey
"hey!"
end
end
RUBY
spec = <<-RUBY
describe Person do
let(:person) { Person.new }
it "says hey" do
person.hey.should == "hey!"
end
end
RUBY
# code and spec will be from user input (unsafe)
eval code
require 'rspec/autorun'
eval spec
Which all works fine, but the code obviously needs to be sandboxed. It will be a matter of minutes before some genius submits system("rm -rf /*"), fork while fork or something equally dangerous.
I made various attempts with the jruby sandbox...
sand = Sandbox::Safe.new
sand.eval("require 'rspec/autorun'")
sand.activate! # lock it down
sand.eval code
puts sand.eval spec
That code throws this exception:
Sandbox::SandboxException: NoMethodError: undefined method `require' for #<RSpec::Core::Configuration:0x7c3cfaab>
This is because RSpec tries to require some stuff after the sandbox has been locked down.
So, I tried to force RSpec to require stuff before the sandbox gets locked down by calling an empty describe:
sand = Sandbox::Safe.new
sand.eval("require 'rspec/autorun'")
sand.eval("describe("") { }")
sand.activate! # lock it down
sand.eval code
sand.eval spec
And I get this:
Sandbox::SandboxException: NameError: uninitialized constant RSpec
Which basically means that RSpec doesn't exist in the sandbox. Which is odd, considering sand.eval("require 'rspec/autorun'") returns true, and that the earlier example actually worked (RSpec's autoloader started to run).
It may be a problem with gems and this particular sandbox though. The sandbox object actually supports a method #require, which is essentially bound to Kernel.require, and therefore can't load gems.
It's starting to look like using this sandbox just might not really be possible with rspec. The main problem is trying to actually load it into the sandbox. I even tried something like this:
require 'rspec'
sand.ref(RSpec) # open access to local rspec
But it wasn't having any of it.
So, my question is two-fold:
Does anyone have any bright ideas on how to get this to work with the jruby sandbox?
If not, how secure is rubycop? Apparently codeschool use it, so it must be pretty well tested... it would be nice to be able to use ruby 1.9 instead of jruby as well.
It looks like the sand box environment isn't loading the bundle/gemset. RVM could be at fault here if you are using a gemset or something.
One might try loading the Bundle again once sand boxed.
I would look at ruby taint modes
$SAFE The security level
0 --> No checks are performed on externally supplied (tainted) data. (default)
1 --> Potentially dangerous operations using tainted data are forbidden.
2 --> Potentially dangerous operations on processes and files are forbidden.
3 --> All newly created objects are considered tainted.
4 --> Modification of global data is forbidden.
I have been trying to figure out a similar problem. I want to use some gems like json and rest-client inside my sandbox after activating it. I tried following.
require "sandbox"
s=Sandbox.safe
s.eval <<-RUBY
require 'bundler'
Bundler.require :sandbox
RUBY
s.activate!
Gemfile.rb
group :sandbox do
platforms :jruby do
gem 'json'
gem 'rest-client'
end
end
This way, I was able to require gems in my sandbox. But, then there were some gem specific issues with sandbox. For eg, I had to add a method initialize_dup to whitelist for safe.rb in jruby-sandbox. RestClient has some problem with Fake File Sytem ALT_SEPARATOR which I am trying to patch. You can try this approach for RSpec and see if everything goes through.

Resources