pants 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ require 'pants/readers/file_reader'
3
+
4
+
5
+ describe Pants::Readers::FileReader do
6
+ let(:core_stopper_callback) do
7
+ double "EventMachine.Callback", call: true
8
+ end
9
+
10
+ let(:tick_loop) do
11
+ tl = double "EventMachine::TickLoop"
12
+ tl.stub(:on_stop)
13
+
14
+ tl
15
+ end
16
+
17
+ before do
18
+ EventMachine.stub(:tick_loop).and_return(tick_loop)
19
+ EventMachine::Iterator.stub_chain(:new, :each)
20
+ end
21
+
22
+ subject do
23
+ Pants::Readers::FileReader.new('some file', core_stopper_callback)
24
+ end
25
+
26
+ describe "#start" do
27
+ let(:file) { double "File" }
28
+ let(:starter) { double "EventMachine::Callback starter" }
29
+ let(:stopper) { double "EventMachine::Callback stopper" }
30
+
31
+ before do
32
+ File.should_receive(:open).and_return(file)
33
+ subject.should_receive(:starter).and_return(starter)
34
+ subject.should_receive(:stopper).and_return(stopper)
35
+ end
36
+
37
+ it "defines an EventMachine Callback" do
38
+ EventMachine.should_receive(:Callback).times.and_yield.and_call_original
39
+
40
+ EventMachine.should_receive(:attach) do |arg1, arg2, arg3, arg4, arg5|
41
+ arg1.should == file
42
+ arg2.should == Pants::Readers::FileReaderConnection
43
+ arg3.should be_a EventMachine::Channel
44
+ arg4.should == starter
45
+ arg5.should == stopper
46
+ end
47
+
48
+ subject.start
49
+ end
50
+ end
51
+ end
52
+
53
+ describe Pants::Readers::FileReaderConnection do
54
+ let(:channel) { double "EventMachine::Channel" }
55
+ let(:starter) { double "EventMachine::Callback starter" }
56
+ let(:stopper) { double "EventMachine::Callback stopper" }
57
+
58
+ subject do
59
+ Pants::Readers::FileReaderConnection.new(1, channel, starter, stopper)
60
+ end
61
+
62
+ describe "#post_init" do
63
+ let(:starter) { double "EventMachine::Callback" }
64
+
65
+ it "tells the starter that it's started" do
66
+ starter.should_receive(:call)
67
+ subject
68
+ end
69
+ end
70
+
71
+ describe "#receive_data" do
72
+ let(:data) { "some data" }
73
+
74
+ before do
75
+ Pants::Readers::FileReaderConnection.any_instance.stub(:post_init)
76
+ end
77
+
78
+ it "directly writes it to the channel" do
79
+ channel.should_receive(:<<).with(data)
80
+ subject.receive_data(data)
81
+ end
82
+ end
83
+
84
+ describe "#unbind" do
85
+ before do
86
+ Pants::Readers::FileReaderConnection.any_instance.stub(:post_init)
87
+ end
88
+
89
+ it "tells the stopper that it's stopped" do
90
+ stopper.should_receive(:call)
91
+ subject.unbind
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+ require 'pants/version'
3
+
4
+
5
+ describe Pants do
6
+ specify { Pants::VERSION.should == '0.1.0' }
7
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'pants/writers/base_writer'
3
+
4
+
5
+ describe Pants::Writers::BaseWriter do
6
+ let(:channel) { double "EventMachine::Channel" }
7
+
8
+ subject do
9
+ Pants::Writers::BaseWriter.new(channel)
10
+ end
11
+
12
+ describe "#starter" do
13
+ context "@starter not yet defined" do
14
+ it "creates a new deferrable that sets @running to true" do
15
+ subject.should_not be_running
16
+ subject.starter.call
17
+ subject.should be_running
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "#stopper" do
23
+ context "@stopper not yet defined and @running is true" do
24
+ before do
25
+ subject.instance_variable_set(:@running, true)
26
+ end
27
+
28
+ it "creates a new deferrable that sets @running to false" do
29
+ subject.should be_running
30
+ subject.stopper.call
31
+ subject.should_not be_running
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'pants/writers/file_writer'
3
+
4
+
5
+ describe Pants::Writers::FileWriter do
6
+ let(:channel) { EventMachine::Channel.new }
7
+
8
+ subject do
9
+ Pants::Writers::FileWriter.new(file, channel)
10
+ end
11
+
12
+ describe "#stop" do
13
+ let(:file) do
14
+ c = double "File"
15
+ c.should_receive(:closed?).and_return(false)
16
+ c.should_receive(:close)
17
+
18
+ c
19
+ end
20
+
21
+ let(:stopper) do
22
+ s = double "EventMachine::Callback"
23
+ s.should_receive(:call)
24
+
25
+ s
26
+ end
27
+
28
+ before do
29
+ File.stub(:open)
30
+ subject.instance_variable_set(:@file, file)
31
+ end
32
+
33
+ it "closes the file and calls succeed on the stopper" do
34
+ subject.should_receive(:stopper).and_return(stopper)
35
+ subject.stop
36
+ end
37
+ end
38
+
39
+ describe "#start" do
40
+ let(:data) do
41
+ '0' * 100
42
+ end
43
+
44
+ let(:file) do
45
+ f = double "File"
46
+ f.should_receive(:write_nonblock).once.with(data).and_return(data.size)
47
+ f.should_receive(:closed?).and_return(true)
48
+
49
+ f
50
+ end
51
+
52
+ let(:tick_loop) do
53
+ t = double "EventMachine::TickLoop"
54
+ t.should_receive(:on_stop).and_yield
55
+
56
+ t
57
+ end
58
+
59
+ before do
60
+ File.should_receive(:open).and_return(file)
61
+ end
62
+
63
+ it "subscribes to the channel and writes data as it comes in" do
64
+ EM.should_receive(:defer).and_yield
65
+ channel.should_receive(:subscribe).and_yield(data).and_call_original
66
+ EventMachine.should_receive(:tick_loop).and_yield.and_return(tick_loop)
67
+
68
+ subject.start
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+ require 'pants/writers/udp_writer'
3
+
4
+
5
+ describe Pants::Writers::UDPWriter do
6
+ let(:channel) { double "EventMachine::Channel" }
7
+ let(:ip) { '127.0.0.1' }
8
+ let(:port) { 1234 }
9
+ before { subject.stub(:log) }
10
+
11
+ subject do
12
+ Pants::Writers::UDPWriter.new(ip, port, channel)
13
+ end
14
+
15
+ describe "#start" do
16
+ let(:starter) do
17
+ s = double "EventMachine::Callback"
18
+ s.should_receive(:call)
19
+
20
+ s
21
+ end
22
+
23
+ let(:tick_loop) do
24
+ t = double "EventMachine::TickLoop"
25
+ t.should_receive(:on_stop).and_yield
26
+
27
+ t
28
+ end
29
+
30
+ before do
31
+ subject.stub(:starter).and_return(starter)
32
+ end
33
+
34
+ it "opens a datagram socket on 0.0.0.0 then calls succeed on the starter" do
35
+ EventMachine.should_receive(:defer).and_yield
36
+ EventMachine.should_receive(:open_datagram_socket).with(
37
+ '0.0.0.0', 0, Pants::Writers::UDPWriterConnection, channel, ip, port
38
+ ).and_return(true)
39
+ EventMachine.should_receive(:tick_loop).and_yield.and_return(tick_loop)
40
+
41
+ subject.start
42
+ end
43
+ end
44
+
45
+ describe "#stop" do
46
+ let(:connection) do
47
+ c = double "EventMachine::Connection"
48
+ c.should_receive(:close_connection_after_writing)
49
+
50
+ c
51
+ end
52
+
53
+ let(:stopper) do
54
+ s = double "EventMachine::Callback"
55
+ s.should_receive(:call)
56
+
57
+ s
58
+ end
59
+
60
+ before do
61
+ subject.instance_variable_set(:@connection, connection)
62
+ subject.stub(:stopper).and_return(stopper)
63
+ end
64
+
65
+ it "closes the socket and calls succeed on the stopper" do
66
+ subject.stop
67
+ end
68
+ end
69
+ end
70
+
71
+ describe Pants::Writers::UDPWriterConnection do
72
+ let(:channel) { EventMachine::Channel.new }
73
+ let(:port) { 1234 }
74
+ let(:ip) { '127.0.0.1' }
75
+
76
+ subject do
77
+ Pants::Writers::UDPWriterConnection.new(1, channel, ip, port)
78
+ end
79
+
80
+ describe "#initialize" do
81
+ before do
82
+ Pants::Writers::UDPWriterConnection.any_instance.stub(:post_init)
83
+ end
84
+
85
+ context "multicast IP address" do
86
+ let(:ip) { '224.0.0.1' }
87
+
88
+ it "sets up the socket to do multicast" do
89
+ Pants::Writers::UDPWriterConnection.any_instance.
90
+ should_receive(:setup_multicast_socket).with(ip)
91
+
92
+ Pants::Writers::UDPWriterConnection.new(0, channel, ip, port)
93
+ end
94
+ end
95
+
96
+ context "unicast IP address" do
97
+ let(:ip) { '223.0.0.1' }
98
+
99
+ it "does not set up the socket to do multicast" do
100
+ Pants::Writers::UDPWriterConnection.any_instance.
101
+ should_not_receive(:setup_multicast_socket)
102
+
103
+ Pants::Writers::UDPWriterConnection.new(0, channel, ip, port)
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "#post_init" do
109
+ around(:each) do |example|
110
+ EM.run do
111
+ example.run
112
+ EM.stop
113
+ end
114
+ end
115
+
116
+ before do
117
+ channel.should_receive(:subscribe).and_yield(data).and_call_original
118
+ end
119
+
120
+ context "data is bigger than PACKET_SPLIT_THRESHOLD" do
121
+ let(:data) do
122
+ "0" * Pants::Writers::UDPWriterConnection::PACKET_SPLIT_THRESHOLD * split_count
123
+ end
124
+
125
+ let(:split_count) { 3 }
126
+
127
+ it "splits the data by PACKET_SPLIT_SIZE and sends each chunk" do
128
+ subject.should_receive(:send_datagram).exactly(split_count + 1).times
129
+ channel << data
130
+ subject
131
+ end
132
+ end
133
+
134
+ context "data is smaller than PACKET_SPLIT_THRESHOLD" do
135
+ let(:data) do
136
+ "0" * 100
137
+ end
138
+
139
+ it "sends the data as it is" do
140
+ subject.should_receive(:send_datagram).once.with(data, ip, port)
141
+ channel << data
142
+ subject
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require "pants"
3
+
4
+
5
+ describe Pants do
6
+ end
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'thor'
4
+ require 'benchmark'
5
+ require './lib/pants'
6
+ require 'bundler/setup'
7
+
8
+
9
+ class Pantsmark < Thor
10
+ desc "file_copy [FILE]", "Copies [FILE] --times number of times and benchmarks it"
11
+ method_option :times, type: :numeric, :default => 100
12
+ def file_copy(file_path)
13
+ Benchmark.bm do |x|
14
+ Pants.log = false
15
+
16
+ x.report("\tpants:") do
17
+ Pants.read(file_path) do |tee|
18
+ options[:times].times do |i|
19
+ tee.write_to("pants_test#{i}")
20
+ end
21
+ end
22
+ end
23
+
24
+ options[:times].times do |i|
25
+ result = %x[diff "#{file_path}" pants_test#{i}]
26
+ puts "Diff result: #{result}" unless result.empty?
27
+ end
28
+
29
+ x.report(" FileUtils.cp:") do
30
+ threads = []
31
+
32
+ options[:times].times do |i|
33
+ threads << Thread.new do
34
+ FileUtils.cp('pants_test1', "fu_cp_test#{i}")
35
+ end
36
+
37
+ threads.last.join
38
+ end
39
+ end
40
+
41
+ x.report(" cp:") do
42
+ threads = []
43
+
44
+ options[:times].times do |i|
45
+ threads << Thread.new do
46
+ `cp pants_test1 cp_test#{i}`
47
+ end
48
+
49
+ threads.last.join
50
+ end
51
+ end
52
+ end
53
+ rescue
54
+ FileUtils.rm_rf(Dir["./pants_test*"])
55
+ FileUtils.rm_rf(Dir["./fu_cp_test*"])
56
+ FileUtils.rm_rf(Dir["./cp_test*"])
57
+
58
+ raise
59
+ ensure
60
+ FileUtils.rm_rf(Dir["./pants_test*"])
61
+ FileUtils.rm_rf(Dir["./fu_cp_test*"])
62
+ FileUtils.rm_rf(Dir["./cp_test*"])
63
+ end
64
+ end
65
+
66
+ Pantsmark.start
@@ -0,0 +1,43 @@
1
+ require_relative './lib/pants'
2
+
3
+
4
+ Pants.log = true
5
+
6
+ #EM.threadpool_size = 200
7
+ #EM.kqueue
8
+ #EM.epoll
9
+
10
+ orig_file = 'spec/support/pants.wav'
11
+ dest_file = 'dest_test_file'
12
+ #Pants.read('udp://127.0.0.1:1234') do |reader|
13
+ Pants.read(orig_file) do |reader|
14
+ 10.times do |i|
15
+ reader.add_writer(dest_file)
16
+ reader.add_writer("udp://127.0.0.1:#{1235 + i}")
17
+ end
18
+ reader.add_writer('udp://10.221.222.90:9000')
19
+ end
20
+
21
+ if defined? orig_file
22
+ pants_file_size = File.stat(dest_file).size
23
+ orig_file_size = File.stat(orig_file).size
24
+ puts "Pants file size: #{pants_file_size}"
25
+ puts "Original file size: #{orig_file_size}"
26
+ puts "Difference: #{orig_file_size - pants_file_size}"
27
+ end
28
+
29
+ #==============
30
+ core = Pants::Core.new
31
+ udp_reader = core.read 'udp://127.0.0.1:1234'
32
+ udp_reader.write_to 'udp://127.0.0.1:1235'
33
+
34
+ udp_reader2 = core.add_reader(Pants::Readers::UDPReader, '127.0.0.1', 1234)
35
+ udp_reader2.add_writer(Pants::Writers::UDPWriter, '127.0.0.1', 1235)
36
+
37
+ udp_reader3 = Pants::Readers::UDPReader.new('127.0.0.1', 1234, core.callback)
38
+ udp_writer3 = Pants::Writers::UDPWriter.new('127.0.0.1', 1235, udp_reader3.write_to_channel)
39
+ core.add_reader(udp_reader3)
40
+ udp_reader3.add_writer(udp_writer3)
41
+
42
+ seam = udp_reader.add_seam(Pants::SimpleSeam)
43
+ seam.write_to 'my_file'