Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Apr 28th, 2012  |  syntax: None  |  size: 8.36 KB  |  hits: 11  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. require File.dirname(__FILE__)+'/../spec_helper'
  2. describe RuoteMigrator, :type => :process do
  3.   before do
  4.     clear_workflow_storage!
  5.   end
  6.  
  7.   def define *args, &block
  8.     Processes.define *args, &block
  9.   end
  10.  
  11.   def launch
  12.     patient_wait_for_with_timeout :signal => "one" do
  13.       @wfid = Processes["test"].launch
  14.     end
  15.   end
  16.  
  17.   def status reload=false
  18.     return @status if @status and !reload
  19.     @status = Processes.status(@wfid)
  20.   end
  21.  
  22.   def migrator reload=false
  23.     return @migrator if @migrator and !reload
  24.     @migrator = RuoteMigrator.new(status(reload))
  25.   end
  26.  
  27.   def reply
  28.     patient_wait_for_with_timeout do
  29.       Workflow.workitems.reply(status.current_workitems.last)
  30.     end
  31.   end
  32.  
  33.   def current_task_names
  34.     status(true).current_tasks.map(&:process_task_name)
  35.   end
  36.  
  37.   def define_and_advance
  38.     #define("test"){one :task => 'a'; one :task => 'b'}
  39.     #launch
  40.     #reply
  41.     #dump_process_fixture @wfid, :test_a_b_at_b
  42.     @wfid = restore_process_fixture :test_a_b_at_b
  43.   end
  44.  
  45.   it "should be able to tell when a definition has changed from a running process" do
  46.     define("test"){one :task => 'a'; one :task => 'b'}
  47.     launch; reply
  48.     (migrator === Processes["test"]).should be_true
  49.     define("test"){one :task => 'c'; one :task => 'd'}
  50.     (migrator === Processes["test"]).should be_false
  51.   end
  52.  
  53.   it "should raise an error if the existing workitems can't automatically be remapped" do
  54.     define("test"){one :task => "a"}
  55.     launch
  56.     define("test"){one :task => "c"}
  57.     lambda do
  58.       patient_wait_for_with_timeout do
  59.         migrator.update_tree! Processes["test"]
  60.       end
  61.     end.should raise_error(RuoteMigrator::MigrationError)
  62.   end
  63.  
  64.   it "should be able to deal with a task redefinition by rewinding to the beginning" do
  65.     define_and_advance
  66.     define("test"){one :task => "c"; one :task => "d"; one :task => "e"}
  67.     patient_wait_for_with_timeout do
  68.       migrator.update_tree! Processes["test"], :rewind_silently => true
  69.     end
  70.     current_task_names.should == ["one_c"]
  71.     reply
  72.     current_task_names.should == ["one_d"]
  73.   end
  74.  
  75.   it "should raise an error if the existing workitems can't be remapped using a supplied mapping" do
  76.     define_and_advance
  77.     define("test"){one :task => "c"; one :task => "d"; one :task => "e"}
  78.     lambda do
  79.       patient_wait_for_with_timeout do
  80.         migrator.update_tree!(Processes["test"], {'task' => 'a'} => {'task' => 'd'})
  81.       end
  82.     end.should raise_error(RuoteMigrator::MigrationError)
  83.   end
  84.  
  85.   it "should not raise an error if the workitems can be remapped automatically but the mapping doesn't apply" do
  86.     define("test"){one :task => 'a'; one :task => 'b'}
  87.     launch
  88.     current_task_names.should == ["one_a"]
  89.     define("test"){one :task => "c"; one :task => "a"}
  90.     lambda do
  91.       patient_wait_for_with_timeout do
  92.         migrator.update_tree!(Processes["test"], {'task' => 'b'} => {'task' => 'c'})
  93.       end
  94.     end.should_not raise_error
  95.     current_task_names.should == ["one_a"]
  96.   end
  97.  
  98.   it "should prefer requested mappings over default mappings" do
  99.     define("test"){one :task => 'a'; one :task => 'b'}
  100.     launch
  101.     current_task_names.should == ["one_a"]
  102.     # this definition allows both the default and the supplied mapping to work
  103.     define("test"){one :task => "a"; one :task => "c"}
  104.     patient_wait_for_with_timeout do
  105.       # this mapping will be merged with the default:
  106.       #   {'task' => 'a', 'ref' => 'one'} => {'task' => 'a', 'ref' => 'one'},
  107.       # but this should take precedence
  108.       migrator.update_tree!(Processes["test"], {'task' => 'a'} => {'task' => 'c'})
  109.     end
  110.     current_task_names.should == ["one_c"]
  111.   end
  112.  
  113.   it "should be able to deal with a task redefinition by mapping task name changes" do
  114.     define_and_advance
  115.     define("test"){one :task => "c"; one :task => "d"; one :task => "e"}
  116.     patient_wait_for_with_timeout do
  117.       migrator.update_tree!(Processes["test"], {'task' => 'b'} => {'task' => 'd'})
  118.     end
  119.     current_task_names.should == ["one_d"]
  120.     reply
  121.     current_task_names.should == ["one_e"]
  122.   end
  123.  
  124.   it "should be able to map task name changes on a complex process" do
  125.     define("test") do
  126.       one :task => "a"
  127.       cursor do
  128.         one :task => "b"
  129.         one :task => "c"
  130.       end
  131.       one :task => "d"
  132.     end
  133.     launch
  134.     current_task_names.should == ["one_a"]
  135.     reply
  136.     current_task_names.should == ["one_b"]
  137.     define("test") do
  138.       cursor do
  139.         one :task => "f"
  140.         cursor do
  141.           one :task => "g"
  142.         end
  143.       end
  144.       one :task => "h"
  145.     end
  146.     patient_wait_for_with_timeout do
  147.       migrator.update_tree!(Processes["test"], {'task' => 'b'} => {'task' => 'g'})
  148.     end
  149.     current_task_names.should == ["one_g"]
  150.     reply
  151.     current_task_names.should == ["one_h"]
  152.   end
  153.  
  154.   it "should ignore task mappings that don't apply to this process instance, but still apply ones that do" do
  155.     define_and_advance
  156.     define("test"){one :task => "c"; one :task => "d"; one :task => "e"}
  157.     patient_wait_for_with_timeout do
  158.       migrator.update_tree!(Processes["test"], {'task' => 'a'} => {'task' => 'd'}, {'task' => 'b'} => {'task' => 'e'})
  159.     end
  160.     current_task_names.should == ["one_e"]
  161.   end
  162.  
  163.   it "should allow mapping tasks where two tasks have the same name, but different participants" do
  164.     define_and_advance
  165.     define("test"){one :task => "c"; two :task => "c"}
  166.     patient_wait_for_with_timeout do
  167.       migrator.update_tree!(Processes["test"], {'task' => 'b'} => {'task' => 'c', 'ref' => 'two'})
  168.     end
  169.     current_task_names.should == ["two_c"]
  170.   end
  171.  
  172.   it "should ensure the task remains the same, if possible" do
  173.     define_and_advance
  174.     define("test"){one :task => "c"; one :task => "b"; one :task => "d"}
  175.     patient_wait_for_with_timeout do
  176.       migrator.update_tree! Processes["test"]
  177.     end
  178.     current_task_names.should == ["one_b"]
  179.     reply
  180.     current_task_names.should == ["one_d"]
  181.   end
  182.  
  183.   it "should do the right thing when mapping a concurrent process" do
  184.     define("test") do
  185.       concurrence do
  186.         one :task => "a"
  187.         two :task => "b"
  188.       end
  189.       three :task => "c"
  190.     end
  191.     launch
  192.     current_task_names.should == ["one_a", "two_b"]
  193.     define("test") do
  194.       concurrence do
  195.         one :task => "d"
  196.         two :task => "e"
  197.         cursor do
  198.           one :task => "f"
  199.           one :task => "g"
  200.         end
  201.       end
  202.       three :task => "h"
  203.     end
  204.     patient_wait_for_with_timeout :signal => "one" do
  205.       migrator.update_tree!(Processes["test"], {'task' => 'a'} => {'task' => 'g'}, {'task' => 'b'} => {'task' => 'e'})
  206.     end
  207.     current_task_names.should == ["two_e", "one_g"]
  208.     wis = status.workitems
  209.     patient_wait_for_with_timeout :signal => "three" do
  210.       Workflow.workitems.reply(wis.find{|wi|wi.participant_name == "two"})
  211.       Workflow.workitems.reply(wis.find{|wi|wi.participant_name == "one"})
  212.     end
  213.     current_task_names.should == ["three_h"]
  214.   end
  215.  
  216.   it "should not destroy fields on the workitem" do
  217.     define("test"){set :field => 'my_field', :value => 'yes'; one :task => 'a'}
  218.     launch
  219.     status.workitems.first.fields.should include('my_field' => 'yes')
  220.     define("test"){one :task => 'b'}
  221.     patient_wait_for_with_timeout do
  222.       migrator.update_tree! Processes["test"], {'task' => 'a'} => {'task' => 'b'}
  223.     end
  224.     status(true).workitems.first.fields.should include('my_field' => 'yes')
  225.   end
  226.  
  227.   it "should be able to jump between subprocesses" do
  228.     define("test") do
  229.       define "sub_1" do
  230.         one :task => 'a'
  231.       end
  232.       define "sub_2" do
  233.         one :task => 'b'
  234.       end
  235.       cursor :tag => 'main' do
  236.         sub_1
  237.         sub_2
  238.       end
  239.     end
  240.     launch
  241.     current_task_names.should == ["one_a"]
  242.     patient_wait_for_with_timeout do
  243.       migrator.update_tree! Processes["test"], {'task' => 'a'} => {'ref' => 'sub_2'}
  244.     end
  245.     current_task_names.should == ["one_b"]
  246.   end
  247.  
  248.   it "should raise an error if you try to move to a subexpression of a subprocess" do
  249.     pending "There doesn't seem to be a way to detect that this is being done"
  250.     define("test") do
  251.       define "sub_1" do
  252.         one :task => 'a'
  253.       end
  254.       define "sub_2" do
  255.         one :task => 'b'
  256.         one :task => 'c'
  257.       end
  258.       cursor :tag => 'main' do
  259.         sub_1
  260.         sub_2
  261.       end
  262.     end
  263.     launch
  264.     current_task_names.should == ["one_a"]
  265.     lambda do
  266.       patient_wait_for_with_timeout do
  267.         migrator.update_tree! Processes["test"], {'task' => 'a'} => {'task' => 'c'}
  268.       end
  269.     end.should raise_error
  270.   end
  271. end