drbqs 0.0.15 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/.document +3 -0
  2. data/README.md +137 -128
  3. data/VERSION +1 -1
  4. data/docs/FormatExecute.md +119 -0
  5. data/docs/GettingStarted.md +242 -0
  6. data/drbqs.gemspec +36 -13
  7. data/example/command/server_def.rb +4 -5
  8. data/example/execute/execute.rb +41 -0
  9. data/example/execute/server.rb +14 -0
  10. data/example/execute/task.rb +0 -0
  11. data/example/mandelbrot/README.md +15 -0
  12. data/example/mandelbrot/execute.rb +10 -0
  13. data/example/mandelbrot/mandelbrot.rb +56 -0
  14. data/example/mandelbrot/server.rb +49 -0
  15. data/example/server/server.rb +3 -6
  16. data/example/simple/README.md +18 -0
  17. data/example/simple/execute.rb +11 -0
  18. data/example/simple/server.rb +8 -0
  19. data/example/simple/task.rb +11 -0
  20. data/example/sum/server_def.rb +1 -1
  21. data/example/sum2/execute_def.rb +21 -8
  22. data/example/sum2/server_def.rb +8 -7
  23. data/example/transfer/file.rb +42 -8
  24. data/example/transfer/server_def.rb +43 -9
  25. data/lib/drbqs.rb +1 -1
  26. data/lib/drbqs/command_line/command_execute.rb +3 -3
  27. data/lib/drbqs/command_line/command_line.rb +1 -1
  28. data/lib/drbqs/execute/execute_node.rb +50 -0
  29. data/lib/drbqs/execute/process_define.rb +102 -54
  30. data/lib/drbqs/execute/register.rb +241 -87
  31. data/lib/drbqs/execute/server_define.rb +69 -58
  32. data/lib/drbqs/ext/task.rb +2 -0
  33. data/lib/drbqs/ext/task/command_task.rb +43 -0
  34. data/lib/drbqs/manage/manage.rb +5 -4
  35. data/lib/drbqs/manage/ssh_shell.rb +2 -8
  36. data/lib/drbqs/node/connection.rb +1 -1
  37. data/lib/drbqs/node/node.rb +8 -14
  38. data/lib/drbqs/node/task_client.rb +1 -1
  39. data/lib/drbqs/server/history.rb +5 -1
  40. data/lib/drbqs/server/message.rb +7 -34
  41. data/lib/drbqs/server/queue.rb +14 -2
  42. data/lib/drbqs/server/server.rb +86 -43
  43. data/lib/drbqs/server/server_hook.rb +3 -0
  44. data/lib/drbqs/server/test/node.rb +1 -1
  45. data/lib/drbqs/server/test/prof.rb +50 -0
  46. data/lib/drbqs/server/test/server.rb +2 -2
  47. data/lib/drbqs/server/transfer_setting.rb +23 -11
  48. data/lib/drbqs/setting/base.rb +15 -0
  49. data/lib/drbqs/setting/data_container.rb +1 -1
  50. data/lib/drbqs/setting/execute.rb +3 -3
  51. data/lib/drbqs/setting/node.rb +1 -1
  52. data/lib/drbqs/setting/server.rb +2 -2
  53. data/lib/drbqs/task/registrar.rb +39 -0
  54. data/lib/drbqs/task/task.rb +139 -59
  55. data/lib/drbqs/task/task_generator.rb +93 -116
  56. data/lib/drbqs/utility/misc.rb +15 -10
  57. data/lib/drbqs/utility/temporary.rb +7 -2
  58. data/lib/drbqs/utility/transfer/transfer.rb +81 -0
  59. data/lib/drbqs/utility/transfer/transfer_client.rb +68 -69
  60. data/lib/drbqs/utility/transfer/transfer_client_connect.rb +83 -0
  61. data/lib/drbqs/utility/transfer/transfer_file_list.rb +40 -0
  62. data/spec/execute/def/execute1.rb +4 -4
  63. data/spec/execute/def/execute2.rb +24 -0
  64. data/spec/execute/process_define_spec.rb +43 -6
  65. data/spec/execute/register_spec.rb +403 -9
  66. data/spec/execute/server_define_spec.rb +1 -1
  67. data/spec/ext/task/command_task_spec.rb +16 -0
  68. data/spec/integration_test/01_basic_usage_spec.rb +1 -1
  69. data/spec/integration_test/02_use_generator_spec.rb +2 -2
  70. data/spec/integration_test/04_use_unix_domain_spec.rb +1 -1
  71. data/spec/integration_test/05_server_exit_signal_spec.rb +1 -1
  72. data/spec/integration_test/06_node_exit_after_task_spec.rb +4 -4
  73. data/spec/integration_test/08_shutdown_unused_nodes_spec.rb +2 -2
  74. data/spec/integration_test/09_server_process_data_spec.rb +1 -1
  75. data/spec/integration_test/definition/server01.rb +4 -5
  76. data/spec/integration_test/definition/server02.rb +2 -4
  77. data/spec/node/node_spec.rb +34 -0
  78. data/spec/server/message_spec.rb +1 -1
  79. data/spec/server/queue_spec.rb +34 -7
  80. data/spec/server/server_spec.rb +21 -9
  81. data/spec/server/transfer_setting_spec.rb +59 -24
  82. data/spec/setting/base_spec.rb +11 -0
  83. data/spec/setting/data_container_spec.rb +8 -0
  84. data/spec/spec_helper.rb +1 -7
  85. data/spec/task/registrar_spec.rb +34 -0
  86. data/spec/task/task_generator_spec.rb +15 -15
  87. data/spec/task/task_spec.rb +132 -23
  88. data/spec/utility/misc_spec.rb +2 -2
  89. data/spec/utility/transfer/transfer_client_connect_spec.rb +90 -0
  90. data/spec/utility/transfer/transfer_file_list_spec.rb +27 -0
  91. data/spec/{task/file_transfer_spec.rb → utility/transfer/transfer_spec.rb} +24 -24
  92. metadata +66 -45
  93. data/lib/drbqs/manage/execute_node.rb +0 -50
  94. data/lib/drbqs/server/prof.rb +0 -48
  95. data/lib/drbqs/task/command_task.rb +0 -43
  96. data/lib/drbqs/utility/transfer/file_transfer.rb +0 -73
data/spec/spec_helper.rb CHANGED
@@ -61,7 +61,7 @@ def drbqs_fork_server(uri_arg, opts = {}, &block)
61
61
  task_args = [task_args]
62
62
  end
63
63
  task_args.each do |arg|
64
- if DRbQS::TaskGenerator === arg
64
+ if DRbQS::Task::Generator === arg
65
65
  server.add_task_generator(arg)
66
66
  else
67
67
  server.queue.add(arg)
@@ -69,12 +69,6 @@ def drbqs_fork_server(uri_arg, opts = {}, &block)
69
69
  end
70
70
  end
71
71
 
72
- unless opts[:continue]
73
- server.add_hook(:finish) do |serv|
74
- serv.exit
75
- end
76
- end
77
-
78
72
  server.set_signal_trap
79
73
  server.start
80
74
  server.wait
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require 'drbqs/task/task'
4
+
5
+ describe DRbQS::Task::Registrar do
6
+ subject do
7
+ DRbQS::Task::Registrar.new({})
8
+ end
9
+
10
+ it "should raise error for invalid argumuents." do
11
+ lambda do
12
+ subject.add("neither DRbQS::Task nor Array")
13
+ end.should raise_error ArgumentError
14
+ end
15
+
16
+ it "should call Fiber.yield." do
17
+ task = DRbQS::Task.new([1, 2, 3], :size, note: "calculate size of an array")
18
+ Fiber.should_receive(:yield).with(task)
19
+ subject.add(task)
20
+ end
21
+
22
+ it "should call Fiber.yield for each task." do
23
+ task_ary = 5.times.map do |i|
24
+ DRbQS::Task.new(i, :to_s, note: "convert to string")
25
+ end
26
+ Fiber.should_receive(:yield).exactly(task_ary.size).times
27
+ subject.add(task_ary)
28
+ end
29
+
30
+ it "should call Fiber.yield with :wait." do
31
+ Fiber.should_receive(:yield).with(:wait)
32
+ subject.wait
33
+ end
34
+ end
@@ -2,24 +2,24 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  require 'drbqs/task/task'
4
4
 
5
- describe DRbQS::TaskGenerator do
5
+ describe DRbQS::Task::Generator do
6
6
  def check_task_ary(tasks, num, cl = DRbQS::Task)
7
7
  tasks.should have(num).items
8
8
  tasks.all? { |t| cl === t }.should be_true
9
9
  end
10
10
 
11
- subject { DRbQS::TaskGenerator.new(:abc => 'ABC', :def => 123, :data => [1, 2, 3]) }
11
+ subject { DRbQS::Task::Generator.new(:abc => 'ABC', :def => 123, :data => [1, 2, 3]) }
12
12
 
13
13
  it "should initialize instance varibles" do
14
- source = subject.instance_variable_get('@source')
15
- source.instance_variable_get('@abc').should == 'ABC'
16
- source.instance_variable_get('@def').should == 123
14
+ registrar = subject.instance_variable_get('@registrar')
15
+ registrar.instance_variable_get('@abc').should == 'ABC'
16
+ registrar.instance_variable_get('@def').should == 123
17
17
  end
18
18
 
19
19
  it "should create new tasks" do
20
- subject.set(:generate => 2) do
20
+ subject.set(:generate => 2) do |reg|
21
21
  @data.each do |i|
22
- create_add_task(i, :to_s)
22
+ reg.create_add(i, :to_s)
23
23
  end
24
24
  end
25
25
  subject.init
@@ -29,22 +29,22 @@ describe DRbQS::TaskGenerator do
29
29
  end
30
30
 
31
31
  it "should should create task sets" do
32
- subject.set(:generate => 2, :collect => 10) do
32
+ subject.set(:generate => 2, :collect => 10) do |reg|
33
33
  100.times do |i|
34
- create_add_task(i, :to_s)
34
+ reg.create_add(i, :to_s)
35
35
  end
36
36
  end
37
37
  subject.init
38
38
  5.times do |i|
39
- check_task_ary(subject.new_tasks, 2, DRbQS::TaskSet)
39
+ check_task_ary(subject.new_tasks, 2, DRbQS::Task::TaskSet)
40
40
  end
41
41
  subject.new_tasks.should be_nil
42
42
  end
43
43
 
44
44
  it "should debug generator" do
45
- subject.set(:generate => 2) do
45
+ subject.set(:generate => 2) do |reg|
46
46
  @data.each do |i|
47
- create_add_task(i, :to_s)
47
+ reg.create_add(i, :to_s)
48
48
  end
49
49
  end
50
50
  subject.init
@@ -54,12 +54,12 @@ describe DRbQS::TaskGenerator do
54
54
  end
55
55
 
56
56
  it "should wait" do
57
- subject.set(:generate => 2) do
57
+ subject.set(:generate => 2) do |reg|
58
58
  @data.each do |i|
59
59
  if i == 2
60
- wait_all_tasks
60
+ reg.wait
61
61
  end
62
- create_add_task(i, :to_s)
62
+ create_add(i, :to_s)
63
63
  end
64
64
  end
65
65
  subject.init
@@ -2,46 +2,126 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  require 'drbqs/task/task'
4
4
 
5
+ class TestTask
6
+ def initialize(result)
7
+ @result = result
8
+ end
9
+
10
+ def calc
11
+ end
12
+
13
+ def test_hook(srv, result)
14
+ @result.should == result
15
+ end
16
+ end
17
+
5
18
  describe DRbQS::Task do
6
- it "should not set hook" do
19
+ it "should not set hook." do
7
20
  task = DRbQS::Task.new([1, 2, 3], :size)
8
21
  task.hook.should be_nil
9
22
  end
10
23
 
11
- it "should set hook" do
24
+ it "should set hook of block." do
12
25
  task = DRbQS::Task.new([1, 2, 3], :size) do |server, ret|
13
26
  p ret
14
27
  end
15
28
  task.hook.should be_an_instance_of Proc
16
29
  end
17
30
 
18
- it "should have same targets" do
19
- task1 = DRbQS::Task.new([1, 2, 3], :concat, [3, 4, 5])
20
- task2 = DRbQS::Task.new([1, 2, 3], :concat, [3, 4, 5])
21
- task1.same_target?(task2).should be_true
31
+ it "should set hook of symbol." do
32
+ task = DRbQS::Task.new([1, 2, 3], :size, hook: :to_s)
33
+ task.hook.should == :to_s
34
+ end
35
+
36
+ it "should return nil for nonexistent hook." do
37
+ task = DRbQS::Task.new([1, 2, 3], :size)
38
+ task.exec_hook(nil, nil).should be_nil
39
+ end
40
+
41
+ it "should execute hook of block." do
42
+ mock = mock('for task')
43
+ task = DRbQS::Task.new(mock, :calc) do |server, result|
44
+ mock.hook_method(server, result)
45
+ end
46
+ mock.should_receive(:hook_method).with(:server, :result)
47
+ task.exec_hook(:server, :result)
48
+ end
49
+
50
+ it "should execute hook of symbol." do
51
+ mock = mock('for task')
52
+ task = DRbQS::Task.new(mock, :calc, hook: :hook_method)
53
+ mock.should_receive(:hook_method).with(:server, :result)
54
+ task.exec_hook(:server, :result)
55
+ end
56
+
57
+ it "should set note." do
58
+ note_string = "Return size"
59
+ task = DRbQS::Task.new([1, 2, 3], :size, note: note_string)
60
+ task.note.should == note_string
61
+ end
62
+
63
+ it "should not have note." do
64
+ note_string = "Return size"
65
+ task = DRbQS::Task.new([1, 2, 3], :size)
66
+ task.note.should be_nil
67
+ end
68
+
69
+ it "should have empty argument array." do
70
+ task = DRbQS::Task.new([1, 2, 3], :size)
71
+ task.args.should == []
72
+ end
73
+
74
+ it "should set arguments." do
75
+ ary = [3, 4, 5]
76
+ task = DRbQS::Task.new([1, 2, 3], :concat, args: ary)
77
+ task.args.should == ary
78
+ end
79
+
80
+ it "should marshalize." do
81
+ task = DRbQS::Task.new(TestTask.new(100), :calc, hook: :test_hook)
82
+ lambda do
83
+ Marshal.dump(task)
84
+ end.should_not raise_error
85
+ end
86
+
87
+ it "should not marshalize." do
88
+ task = DRbQS::Task.new(TestTask.new(100), :calc) do |srv, res|
89
+ p res
90
+ end
91
+ lambda do
92
+ Marshal.dump(task)
93
+ end.should raise_error
22
94
  end
23
95
  end
24
96
 
25
- describe DRbQS::CommandExecute do
26
- it "should execute command" do
27
- cmd_exec = DRbQS::CommandExecute.new('ls > /dev/null')
28
- cmd_exec.exec.should == 0
97
+ describe DRbQS::Task::TaskSet::ContainerTask do
98
+ it "should dump and load" do
99
+ obj = [[1], [1, 2], [1, 2, 3]]
100
+ tasks = obj.map do |ary|
101
+ DRbQS::Task.new(ary, :size)
102
+ end
103
+ container = DRbQS::Task::TaskSet::ContainerTask.new(tasks)
104
+ dump = Marshal.dump(container)
105
+ Marshal.load(dump).should == container
29
106
  end
30
107
 
31
- it "should enqueue files" do
32
- DRbQS::FileTransfer.should_receive(:enqueue).exactly(2)
33
- cmd_exec = DRbQS::CommandExecute.new('ls > /dev/null', :transfer => ['hello', 'world'])
34
- cmd_exec.exec
108
+ it "should execute each task" do
109
+ obj = [[1, 3, 4], [2], [1, 2, 3]]
110
+ tasks = obj.map do |ary|
111
+ DRbQS::Task.new(ary, :size)
112
+ end
113
+ container = DRbQS::Task::TaskSet::ContainerTask.new(tasks)
114
+ container.exec.should == [3, 1, 3]
35
115
  end
36
116
  end
37
117
 
38
- describe DRbQS::TaskContainer do
118
+ describe DRbQS::Task::TaskSet::ContainerWithoutHook do
39
119
  it "should dump and load" do
40
120
  obj = [[1], [1, 2], [1, 2, 3]]
41
121
  tasks = obj.map do |ary|
42
122
  DRbQS::Task.new(ary, :size)
43
123
  end
44
- container = DRbQS::TaskContainer.new(tasks)
124
+ container = DRbQS::Task::TaskSet::ContainerWithoutHook.new(tasks)
45
125
  dump = Marshal.dump(container)
46
126
  Marshal.load(dump).should == container
47
127
  end
@@ -51,15 +131,33 @@ describe DRbQS::TaskContainer do
51
131
  tasks = obj.map do |ary|
52
132
  DRbQS::Task.new(ary, :size)
53
133
  end
54
- container = DRbQS::TaskContainer.new(tasks)
134
+ container = DRbQS::Task::TaskSet::ContainerWithoutHook.new(tasks)
55
135
  container.exec.should == [3, 1, 3]
56
136
  end
57
137
  end
58
138
 
59
- describe DRbQS::TaskSet do
60
- it "should execute hooks" do
61
- server = double('server')
62
- methods_for_hook = double('hook')
139
+ describe DRbQS::Task::TaskSet do
140
+ it "should use DRbQS::Task::TaskSet::ContainerTask." do
141
+ tasks = [DRbQS::Task.new([1, 2], :to_s), DRbQS::Task.new([1, 2], :size, hook: :to_s)]
142
+ task_set = DRbQS::Task::TaskSet.new(tasks)
143
+ task_set.obj.should be_an_instance_of DRbQS::Task::TaskSet::ContainerTask
144
+ end
145
+
146
+ it "should use DRbQS::Task::TaskSet::ContainerWithoutHook." do
147
+ tasks = []
148
+ tasks << DRbQS::Task.new([1, 2], :to_s) do |srv, result|
149
+ p result
150
+ end
151
+ tasks << DRbQS::Task.new([1, 2], :size) do |srv, result|
152
+ p result
153
+ end
154
+ task_set = DRbQS::Task::TaskSet.new(tasks)
155
+ task_set.obj.should be_an_instance_of DRbQS::Task::TaskSet::ContainerWithoutHook
156
+ end
157
+
158
+ it "should execute hooks of blocks." do
159
+ server = mock('server')
160
+ methods_for_hook = mock('hook')
63
161
  methods_for_hook.should_receive(:m0).exactly(1)
64
162
  methods_for_hook.should_receive(:m1).exactly(1)
65
163
  methods_for_hook.should_receive(:m2).exactly(1)
@@ -68,7 +166,18 @@ describe DRbQS::TaskSet do
68
166
  tasks << DRbQS::Task.new(obj[0], :size, &methods_for_hook.method(:m0))
69
167
  tasks << DRbQS::Task.new(obj[1], :size, &methods_for_hook.method(:m1))
70
168
  tasks << DRbQS::Task.new(obj[2], :size, &methods_for_hook.method(:m2))
71
- task_set = DRbQS::TaskSet.new(tasks)
72
- task_set.hook.call(server, [1, 2, 3])
169
+ task_set = DRbQS::Task::TaskSet.new(tasks)
170
+ task_set.exec_hook(server, [1, 2, 3])
171
+ end
172
+
173
+ it "should execute hooks of symbols." do
174
+ server = mock('server')
175
+ obj = [TestTask.new(100), TestTask.new(200), TestTask.new(300)]
176
+ tasks = []
177
+ tasks << DRbQS::Task.new(obj[0], :some_method, hook: :test_hook)
178
+ tasks << DRbQS::Task.new(obj[1], :some_method, hook: :test_hook)
179
+ tasks << DRbQS::Task.new(obj[2], :some_method, hook: :test_hook)
180
+ task_set = DRbQS::Task::TaskSet.new(tasks)
181
+ task_set.exec_hook(server, [100, 200, 300])
73
182
  end
74
183
  end
@@ -2,9 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  require 'drbqs/utility/temporary'
4
4
 
5
- describe DRbQS::LoggerDummy do
5
+ describe DRbQS::Misc::LoggerDummy do
6
6
  subject do
7
- DRbQS::LoggerDummy.new
7
+ DRbQS::Misc::LoggerDummy.new
8
8
  end
9
9
 
10
10
  it "should respond to info." do
@@ -0,0 +1,90 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ require 'drbqs/utility/temporary'
4
+ require 'drbqs/utility/transfer/transfer'
5
+ require 'drbqs/utility/transfer/transfer_client'
6
+
7
+ def create_sample_transfer_files(n = nil)
8
+ tmp_dir = DRbQS::Temporary.directory
9
+ files = []
10
+ (n || 3).times do |i|
11
+ path = File.join(tmp_dir, "test%d.txt" % i)
12
+ files << path
13
+ open(path, 'w') do |f|
14
+ f.puts (i * i).to_s
15
+ end
16
+ end
17
+ [tmp_dir, files]
18
+ end
19
+
20
+ describe DRbQS::Transfer::Client::Local do
21
+ before(:all) do
22
+ @dir = DRbQS::Temporary.directory
23
+ @client = DRbQS::Transfer::Client::Local.new(@dir)
24
+ end
25
+
26
+ it "should move files." do
27
+ tmp_dir, files = create_sample_transfer_files
28
+ @client.transfer(files)
29
+ files.all? do |path|
30
+ !File.exist?(path)
31
+ end.should be_true
32
+ files.all? do |path|
33
+ File.exist?(File.join(@dir, File.basename(path)))
34
+ end.should be_true
35
+ end
36
+
37
+ it "should copy files." do
38
+ tmp_dir, files = create_sample_transfer_files
39
+ @client.download(files)
40
+ files.all? do |path|
41
+ File.exist?(path)
42
+ end.should be_true
43
+ files.all? do |path|
44
+ File.exist?(File.join(@dir, File.basename(path)))
45
+ end.should be_true
46
+ end
47
+
48
+ after(:all) do
49
+ DRbQS::Temporary.delete_all
50
+ end
51
+ end
52
+
53
+ describe DRbQS::Transfer::Client::SFTP do
54
+ module Net::SFTP
55
+ def self.set_mock(m)
56
+ @mock = m
57
+ end
58
+
59
+ def self.start(user, host, &block)
60
+ yield(@mock)
61
+ end
62
+ end
63
+
64
+ before(:all) do
65
+ @dir = DRbQS::Temporary.directory
66
+ @client = DRbQS::Transfer::Client::SFTP.new('user_name', 'example.com', @dir)
67
+ end
68
+
69
+ it "should transfer files." do
70
+ tmp_dir, files = create_sample_transfer_files(1)
71
+ source_path = files[0]
72
+ sftp = mock('sftp')
73
+ sftp.should_receive(:upload).with(source_path, File.join(@dir, File.basename(source_path)))
74
+ FileUtils.should_receive(:rm_r).with(source_path)
75
+ Net::SFTP.set_mock(sftp)
76
+ @client.transfer(files)
77
+ end
78
+
79
+ it "should download files. (incomplete)" do
80
+ tmp_dir, files = create_sample_transfer_files(1)
81
+ sftp = mock('sftp')
82
+ sftp.should_receive(:download)
83
+ Net::SFTP.set_mock(sftp)
84
+ @client.download(files)
85
+ end
86
+
87
+ after(:all) do
88
+ DRbQS::Temporary.delete_all
89
+ end
90
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ require 'drbqs/utility/transfer/transfer'
4
+ require 'drbqs/utility/transfer/transfer_client'
5
+ require 'drbqs/utility/transfer/transfer_file_list'
6
+
7
+ describe DRbQS::Transfer::FileList do
8
+ before(:all) do
9
+ @files = Dir.glob("#{File.dirname(__FILE__)}/*.rb")
10
+ end
11
+
12
+ it "should download files." do
13
+ client = mock('transfer client')
14
+ DRbQS::Transfer::Client.stub(:get).and_return(client)
15
+ client.should_receive(:download).with(@files, nil)
16
+ file_list = DRbQS::Transfer::FileList.new(*@files)
17
+ file_list.path
18
+ end
19
+
20
+ it "should download files with readonly." do
21
+ client = mock('transfer client')
22
+ DRbQS::Transfer::Client.stub(:get).and_return(client)
23
+ client.should_receive(:download).with(@files, true)
24
+ file_list = DRbQS::Transfer::FileList.new(*@files, :readonly => true)
25
+ file_list.path
26
+ end
27
+ end