-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnet_test.rb
More file actions
182 lines (136 loc) · 5.1 KB
/
net_test.rb
File metadata and controls
182 lines (136 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
require 'optparse'
require 'yaml'
require 'socket'
require_relative 'result_recorder'
# 1. get parameters
# set endpoint name (e.g. "Portland" or "SanDiego")
# get remote address
# get frequency of test from parameters (default = 15 minutes)
# get duration of test (default = 2 hours)
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: net_test.rb [options]"
opts.on('-n NAME', '--name NAME', 'Name of endpoint, e.g. "Portland"') { |v| options[:local_name] = v }
opts.on('-r HOST', '--remote HOST', 'Remote hostname or IP address') { |v| options[:host] = v }
opts.on('-i INTERVAL', '--interval INTERVAL', 'Interval in minutes to run test') { |v| options[:interval] = v.to_f }
opts.on('-d DURATION', '--duration DURATION', 'How long in hours to run test') { |v| options[:duration] = v.to_f }
opts.on('-p PACKETS', '--packets PACKETS', 'How long in hours to run test') { |v| options[:packets] = v.to_i }
opts.on("-h", "--help", "Prints this help") do
puts opts
exit
end
end.parse!
puts "Missing required -n NAME argument. See --help" unless options[:local_name]
puts "Missing required -r HOST argument. See --help" unless options[:host]
options[:interval]=15 unless options[:interval]
options[:duration]=2 unless options[:duration]
options[:packets]=1000 unless options[:packets]
options[:file]="earth_test_file.png"
puts "Settings:"
puts options.to_yaml
puts "\n"
launch_time = Time.now
keep_running_until = launch_time + (options[:duration]*60*60)
puts "This test will keep running until #{keep_running_until}"
# m4. ping test
def ping(s)
start_time = Time.now
s.puts 'PING'
s.gets
(Time.now - start_time) * 1000
end
def latency(s)
results = []
3.times do
results << ping(s)
end
results.max
end
def send_packets(options)
u = UDPSocket.new
u.connect(options[:host], 6364)
start_time = Time.now
options[:packets].times do |i|
u.send "p#{i}", 0
end
elapsed_time = Time.now - start_time
u.close
puts " sent #{options[:packets]} packets in #{(elapsed_time*1000).round(2)} ms"
end
SIZE = 1024 * 1024 * 5
def throughput_test(s, filename, host)
s.puts "THROUGHPUTUP"
sleep 3
bytes_written=0
# Use a maximum 5 mb file
TCPSocket.open(host, 6364) do |socket|
File.open(filename, 'rb') do |file|
while chunk = file.read(SIZE)
bytes_written+=chunk.size
socket.write(chunk)
end
end
end
elapsed_time = s.gets.to_f
mb=bytes_written/(1024.0*1024.0)
[mb/elapsed_time, 0.0]
end
def packet_drop_test(options, s)
puts " Starting packet test with #{options[:packets]} packets"
s.puts "PACKETDROPUP"
s.puts options[:packets]
sleep 1
send_packets(options)
sleep 1
reply = s.gets
puts " reply: #{reply}"
puts " finished packet drop test"
received = reply.split(':')[0].to_i
[options[:packets]-received, options[:packets]]
end
def run_suite(options, run_number)
test_run={time: Time.now}
puts "\n\nStarting run #{run_number}!"
s = TCPSocket.new options[:host], 6363
# m1.5. get remote name
s.puts 'NAME'
test_run[:remote_name] = s.gets
puts " #{options[:local_name]} --> #{test_run[:remote_name]}"
# m3. latency test: do ping test 3 times, take slowest score.
test_run[:latency] = latency(s)
puts " Latency test result (worst of 3): #{test_run[:latency].round(3)} ms"
test_run[:throughput_up], test_run[:throughput_down] = throughput_test(s, options[:file], options[:host])
puts " Throughput test (sending of 3.2mb file):"
puts " Up datarate: #{test_run[:throughput_up].round(3)} MBytes/Sec (#{(test_run[:throughput_up]*8).round(3)} mbps)"
puts " Down datarate: #{test_run[:throughput_down].round(3)} MBytes/Sec"
test_run[:transmitted_dropped], test_run[:received_dropped] = packet_drop_test(options, s)
puts " Packet Drop Test (ratio of 1000 packets transmitted):"
puts " Up dropped: #{test_run[:transmitted_dropped]}"
puts " Down dropped: #{test_run[:received_dropped]}"
ResultRecorder.record(options, test_run)
# m7. log data
# if logfile doesn't exist, create it and header
# write remote name, time, latency, throughput, packet drop
# close log file
# m8. sleep until next interval
# interval start time + interval time = next run time
# if next_interval after end_time, clean up.
s.puts "FINISHED"
s.close # close socket when done
test_run
end
run_number=0
until Time.now > keep_running_until
results = run_suite(options, run_number+=1)
time_until_next_run = (results[:time] + (options[:interval]*60)) - Time.now
puts "\nNext run is in #{time_until_next_run.round(2)} seconds, or #{(time_until_next_run/60.0).round(2)} minutes"
test_time_left = keep_running_until - Time.now
puts "Test will keep running for #{(test_time_left/60.0).round(2)} minutes, or #{(test_time_left/3600.0).round(2)} hours"
GC.start
puts "current memory usage: #{`ps -o rss -p #{$$}`.strip.split.last.to_i} KB"
puts "NETWORK TESTING IN PROGRESS. DO NOT STOP.\nSleeping..."
sleep time_until_next_run
end
# m9. clean up
# send "EXIT" to remove end
# email log file to interested parties