Forum: Ruby Vaguely humorous Test::Unit problem (long)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
1701d4632405d53639a1faedcb78d829?d=identicon&s=25 unknown (Guest)
on 2007-06-26 08:40
(Received via mailing list)
Hi everybody,

I have a problem I can't figure out.  I've created a test class using
Test::Unit::TestCase.  One of the test cases is failing, but if I
comment out the passing one, the failing one passes.  Moreover, if I
rename the failing test to something preceeding the passing one in
alphabetical order, it passes.

The issue is a bit complicated, however.  I'll post some code, then
explain it.

require 'drb'
require 'test/unit'
require '../lib/classes/Config.rb'
require '../lib/classes/Service.rb'

class TestService < Test::Unit::TestCase

  def test_statistics # fails, unless named e.g. test_astatistics
    message = {:data => [1,1,1], :mixin => :statistics}.to_config
    config = {:url => 'druby://localhost:9001',}.to_config

    remote_service = Service.new(config)
    DRb.start_service()
    service = DRbObject.new(nil, config.url)
    assert_equal([:statistics, 1, 0], service.process(message))
  end

  def test_service_drb  # Always passes.
    message = {:data => 1, :mixin => :trivial}.to_config
    config = {:url => 'druby://localhost:9000',}.to_config

    remote_service = Service.new(config)
    DRb.start_service()
    service = DRbObject.new(nil, config.url)
    assert_equal(service.process(message),1)
  end
end

EOC

Note that outside of the message and config objects, and parameters to
assert_equal, the code is identical.

The Hash.to_config method turns hash keys into attr_reader's and hash
values into the reader's return value.  The new object's class is
Config.

Oh, right, I should explain what a Service object is.  First off,
Service.new(config) takes in a Config object.  It also starts a DRb
server with the line:

DRb.start_service(@config.url, self)

service.process is harder to explain.  Essentially, Service objects
are servers that dynamically change how they process data depending on
the type of data they recieve.  I implemented this idea using mixins
and a stable public API.  So for each call of
service.process(message), the Service object checks the value of
config.mixin, compares it to the currently loaded module, and requires
and includes it if they differ.  Then it calls the run(message.data)
method, which is implemented by the mixed in module.  The Service
class:

class Service

  def initialize(config)
    @mixin = ""
    @config = config
    DRb.start_service(@config.url, self)
  end

  def process(message)
    new_mixin = message.mixin
    unless @mixin == new_mixin
      require "../lib/services/#{new_mixin.to_s.capitalize}.rb"
      self.class.class_eval("include #{new_mixin.to_s.capitalize}" )
      @mixin = new_mixin
    end
    self.run(message.data)
  end
end

EOC

Little help?
Thanks,
Alex
934180817a3765d132193a5428f99051?d=identicon&s=25 Sylvain Joyeux (Guest)
on 2007-06-26 09:58
(Received via mailing list)
You're calling DRb.start_service a lot. In my experience, this can lead
to
problems. Try adding DRb.stop_service in #teardown.
1701d4632405d53639a1faedcb78d829?d=identicon&s=25 unknown (Guest)
on 2007-06-26 22:16
(Received via mailing list)
On Jun 26, 12:57 am, Sylvain Joyeux <sylvain.joy...@polytechnique.org>
wrote:
> You're calling DRb.start_service a lot. In my experience, this can lead to
> problems. Try adding DRb.stop_service in #teardown.
> --
> Sylvain Joyeux

Well, I refactored the tests so that Drb.start_service is only called
once.  I still get the name dependent failure.

require 'drb'
require 'test/unit'
require '../lib/classes/Config.rb'
require '../lib/classes/Service.rb'

class TestService < Test::Unit::TestCase

  @@config = {:url => 'druby://localhost:9001',}.to_config
  @@remote_service = Service.new(@@config) # calls DRb.service_start

  def test_service_stat # fails
    message = {:data => [1,1,1], :mixin => :statistics}.to_config
    service = DRbObject.new(nil, @@config.url)
    assert_equal([:statistics, 1, 0], service.process(message))
  end

  def test_service_trivial
    message = {:data => 1, :mixin => :trivial}.to_config
    service = DRbObject.new(nil, @@config.url)
    assert_equal(service.process(message),1)
  end
end

EOC

One thing I forgot to mention is that test_service_statistics fails
with:

<[:statistics, 1, 0]> expected but was
<[1, 1, 1]>

which means that it was actually using Trivial::run(data) instead of
Statistics::run(data).  Is DRb threaded?  Could this be a race
condition in DRb and not my code?  (I can't see how it would by a bug
in my code)

Thanks,
Alex
1701d4632405d53639a1faedcb78d829?d=identicon&s=25 unknown (Guest)
on 2007-06-26 22:26
(Received via mailing list)
On Jun 26, 1:13 pm, poopdevi...@gmail.com wrote:
>
>   def test_service_stat # fails
> end
> Statistics::run(data).  Is DRb threaded?  Could this be a race
> condition in DRb and not my code?  (I can't see how it would by a bug
> in my code)

My mistake.  DRb is obviously threaded.  I meant to ask if Test::Unit
is threaded, and if there might be a race condition there.

Alex
This topic is locked and can not be replied to.