MarkUs Blog

MarkUs Developers Blog About Their Project

Learnings from my first changelist

without comments

Weird Behaviour of Mocha

In the markus code, there are a lot of places where we use markus_config_<something> instead of MarkusConfigurator.markus_config_<something>. We should start using the latter. He’s why:

ensure_config_helper.rb


def self.check_config()
puts "Checking #{markus_config_logging_logfile}"
puts "Checking #{markus_config_logging_errorlogfile}"
puts "Checking #{markus_config_repository_storage}"
puts "Checking #{markus_config_validate_file}"
puts "Checking #{MarkusConfigurator.markus_config_logging_logfile}"
puts "Checking #{MarkusConfigurator.markus_config_logging_errorlogfile}"
puts "Checking #{MarkusConfigurator.markus_config_repository_storage}"
puts "Checking #{MarkusConfigurator.markus_config_validate_file}"
check_in_writable_dir(markus_config_logging_logfile, "MARKUS_LOGGING_LOGFILE")
check_in_writable_dir(markus_config_logging_errorlogfile, "MARKUS_LOGGING_ERRORLOGFILE")
check_writable(markus_config_repository_storage, "REPOSITORY_STORAGE")
check_readable(markus_config_repository_storage, "REPOSITORY_STORAGE")
if ! RUBY_PLATFORM =~ /(:?mswin|mingw)/ # should match for Windows only
check_executable(markus_config_validate_file, "VALIDATE_FILE")
end
end

Output from running rake test:units When loading everything up:


Checking log/info_development.log
Checking log/error_development.log
Checking /home/jmate/everything/workspaces/repos
Checking /home/jmate/everything/workspaces/markus/config/dummy_validate.sh
Checking log/info_development.log
Checking log/error_development.log
Checking /home/jmate/everything/workspaces/repos
Checking /home/jmate/everything/workspaces/markus/config/dummy_validate.sh

At this point, <blah> == MarkusConfigurator.<blah>

When running the test cases:


/tmp/ensure_config_helper_test_777699315/log/log_info_file.log
Checking log/info_test.log
Checking log/error_test.log
Checking /home/jmate/everything/workspaces/repos
Checking /home/jmate/everything/workspaces/markus/config/dummy_validate.sh
Checking /tmp/ensure_config_helper_test_777699315/log/log_info_file.log
Checking /tmp/ensure_config_helper_test_777699315/log/log_error_file.log
Checking /tmp/ensure_config_helper_test_777699315/source_repo_dir
Checking /tmp/ensure_config_helper_test_777699315/validate_script.sh
/tmp/ensure_config_helper_test_595310852/log/log_info_file.log
...
...
...
Checking log/info_test.log
Checking log/error_test.log
Checking /home/jmate/everything/workspaces/repos
Checking /home/jmate/everything/workspaces/markus/config/dummy_validate.sh
Checking /tmp/ensure_config_helper_test_473533902/log/log_info_file.log
Checking /tmp/ensure_config_helper_test_473533902/log/log_error_file.log
Checking /tmp/ensure_config_helper_test_473533902/source_repo_dir
Checking /tmp/ensure_config_helper_test_473533902/validate_script.sh

Now you can see that <blah> != MarkusConfigurator.<blah> . So the namespace for the method you are trying to call cannot be ambiguous. In the source code above you must use MarkusConfigurator.<blah>.

Mocking Modules with Mocha

I could not find any examples on mocking modules with mocha. It’s probably because it’s so easy! It’s just like mocking an instance of a class.

the_module.rb :


module TheModule
def the_module_function
return "the real value"
end
end

test.rb :


require "test/unit"
require "mocha"
require "the_module"
include TheModule

class TheModuleTest < Test::Unit::TestCase
# replace 'the real value' with 'the mocked value'"
def test_it
assert TheModule.the_module_function == "the real value"

TheModule.stubs(:the_module_function).returns("the mocked value")

assert TheModule.the_module_function == "the mocked value"
end
end

Running the tests:


jmate@CalculatorJozef:~/everything/workspaces$ ruby test.rb
Loaded suite test
Started
.
Finished in 0.00096 seconds.

1 tests, 2 assertions, 0 failures, 0 errors

Nested Contexts

I learned a new trick with shoulda. Credit goes to: http://www.viget.com/extend/reusing-contexts-in-shoulda-with-context-macros/

You can nest contexts inorder to resuse them.

Here is a quick example I prepared:


context "we have a temp dir" do
setup do
@temp_dir = "/tmp/temp_#{rand(1073741824)}"</pre>
@log_dir = "#{@temp_dir}/log"
@file = "#{@log_dir}/file"
FileUtils.mkdir( @temp_dir )
end
teardown do
FileUtils.rm_r( @temp_dir )
end
should "be able to test with the temp dir" do
end

context "we have a log dir" do
setup do
FileUtils.mkdir( @log_dir )
end
should "be able to test with the temp and log dir" do
end

context "we have a file inside the log dir inside the temp dir" do
setup do
FileUtils.touch( [@file] )
end
should "be able to test with temp, log and file" do
end
end
end
end

Permissions, Directories and Ruby

I recently learned that if you remove the execute bit on a directory and try to rm -r the parent directory then you will be unable to remove the executable directory. However, this works in a terminal.

Example in ruby:


#!/usr/bin/env ruby
require 'fileutils'
include FileUtils

@parent_dir = "/tmp/parent_#{rand(1073741824)}"
@test_dir = "#{@parent_dir}/test"
@file = "#{@test_dir}/file"

FileUtils.mkdir( @parent_dir )
FileUtils.mkdir( @test_dir )
FileUtils.touch([ @file ])
FileUtils.chmod( 0600, [ @test_dir ])
FileUtils.rm_r( @parent_dir )

Output from script:


jmate@CalculatorJozef:~/everything$ ./test.rb
/usr/lib/ruby/1.8/fileutils.rb:1297:in `unlink': Permission denied - /tmp/parent_674314876/test/file (Errno::EACCES)
from /usr/lib/ruby/1.8/fileutils.rb:1297:in `remove_file'
from /usr/lib/ruby/1.8/fileutils.rb:1302:in `platform_support'
from /usr/lib/ruby/1.8/fileutils.rb:1296:in `remove_file'
from /usr/lib/ruby/1.8/fileutils.rb:1285:in `remove'
from /usr/lib/ruby/1.8/fileutils.rb:756:in `remove_entry'
from /usr/lib/ruby/1.8/fileutils.rb:1335:in `postorder_traverse'
from /usr/lib/ruby/1.8/fileutils.rb:1335:in `postorder_traverse'
from /usr/lib/ruby/1.8/fileutils.rb:1339:in `postorder_traverse'
from /usr/lib/ruby/1.8/fileutils.rb:1334:in `postorder_traverse'
from /usr/lib/ruby/1.8/fileutils.rb:1333:in `each'
from /usr/lib/ruby/1.8/fileutils.rb:1333:in `postorder_traverse'
from /usr/lib/ruby/1.8/fileutils.rb:1334:in `postorder_traverse'
from /usr/lib/ruby/1.8/fileutils.rb:1333:in `each'
from /usr/lib/ruby/1.8/fileutils.rb:1333:in `postorder_traverse'
from /usr/lib/ruby/1.8/fileutils.rb:754:in `remove_entry'
from /usr/lib/ruby/1.8/fileutils.rb:612:in `rm_r'
from /usr/lib/ruby/1.8/fileutils.rb:608:in `each'
from /usr/lib/ruby/1.8/fileutils.rb:608:in `rm_r'
from ./test.rb:14

Example in terminal:


jmate@CalculatorJozef:/tmp$ mkdir parent
jmate@CalculatorJozef:/tmp$ mkdir parent/test
jmate@CalculatorJozef:/tmp$ touch parent/test/file
jmate@CalculatorJozef:/tmp$ rm -r parent

As you can see from the output above. I had no trouble doing this in the terminal.

It might have something to do with not being able to cd into a directory that does not have the execute bit set.

I hope the knowledge I pass on helps you guys:

Ruby Permissions and Directories

Nested Contexts

Mocking Modules with Mocha

Weird Behaviour With Mocha

Cheers,
Joseph

Written by jmate

January 30th, 2010 at 11:14 pm

Posted in Getting Started

Leave a Reply