From 2fcc2bbb4cebb06edd541c134872e9b99889f049 Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Mon, 8 Dec 2014 14:57:45 +0900 Subject: [PATCH 01/11] Add .travis.yml. --- .travis.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d9e9706 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: ruby + +script: bundle exec rake travis + +rvm: + - 2.0.0 + - 2.1.0 + - ruby-head + +before_install: + - sudo apt-get update -qq + - sudo apt-get install libpcap-dev -qq + - gem update bundler + +matrix: + allow_failures: + - rvm: 2.1.0 + - rvm: ruby-head + fast_finish: true From 596b61258f6ba04c9009927f02de9f24786e51a3 Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Mon, 8 Dec 2014 15:11:01 +0900 Subject: [PATCH 02/11] Enables coveralls. --- .travis.yml | 10 +++++++--- spec/spec_helper.rb | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index d9e9706..ec55fdc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,16 @@ rvm: - ruby-head before_install: - - sudo apt-get update -qq - - sudo apt-get install libpcap-dev -qq - - gem update bundler + - sudo apt-get update -qq + - sudo apt-get install libpcap-dev -qq + - gem update bundler matrix: allow_failures: - rvm: 2.1.0 - rvm: ruby-head fast_finish: true + +env: + global: + secure: K8XOn6irNlcpwwXsTJYH5jA7Iu3JM329kl8lzKIeku+5ypVTOBoknVr7NHQJEJvC/RWUmXh9IxPSo2xUVfO6gVum9rjCRzG+m7dVvhvM7I4E0nnCn/ouTkY+ksSBcPJ34UDb7Z4NzyrrG04MtJKLwbBtD61hRseeo3hOO9uAH6Y= diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 275c352..42b551a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,14 @@ -# encoding: utf-8 +require 'simplecov' +require 'codeclimate-test-reporter' +require 'coveralls' + +formatters = [SimpleCov::Formatter::HTMLFormatter] +formatters << Coveralls::SimpleCov::Formatter if ENV['COVERALLS_REPO_TOKEN'] +if ENV['CODECLIMATE_REPO_TOKEN'] + formatters << CodeClimate::TestReporter::Formatter +end + +SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[*formatters] +SimpleCov.start { add_filter '/vendor/' } -require 'rspec' require 'rspec/given' From 0097f92701d551359feafc6917300d887882868d Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Mon, 8 Dec 2014 15:23:10 +0900 Subject: [PATCH 03/11] Enable codeclimate test coverage. --- .travis.yml | 3 ++- lib/patch_panel.rb | 2 +- spec/patch_panel_spec.rb | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 spec/patch_panel_spec.rb diff --git a/.travis.yml b/.travis.yml index ec55fdc..1cabfe6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,5 @@ matrix: env: global: - secure: K8XOn6irNlcpwwXsTJYH5jA7Iu3JM329kl8lzKIeku+5ypVTOBoknVr7NHQJEJvC/RWUmXh9IxPSo2xUVfO6gVum9rjCRzG+m7dVvhvM7I4E0nnCn/ouTkY+ksSBcPJ34UDb7Z4NzyrrG04MtJKLwbBtD61hRseeo3hOO9uAH6Y= + - secure: K8XOn6irNlcpwwXsTJYH5jA7Iu3JM329kl8lzKIeku+5ypVTOBoknVr7NHQJEJvC/RWUmXh9IxPSo2xUVfO6gVum9rjCRzG+m7dVvhvM7I4E0nnCn/ouTkY+ksSBcPJ34UDb7Z4NzyrrG04MtJKLwbBtD61hRseeo3hOO9uAH6Y= + - secure: lDefP7JDN2SBO/21Sm+TBIvXRYm6sTbyuJDaX76HXIX/ccf/oxYYuqfrxe32SgZuMXVHQcNKjl55kQMz0LtgSVLgKPhn2AaBn96j19F84FdcTV3wMJZURMGIrIgW7uKpc6KLGlQtAHnPcmKSm7/6Vhz2IbtlnZdEEC/jYagVOeY= diff --git a/lib/patch_panel.rb b/lib/patch_panel.rb index 520894f..0a26aaa 100644 --- a/lib/patch_panel.rb +++ b/lib/patch_panel.rb @@ -1,5 +1,5 @@ # Software patch-panel. -class PatchPanel < Controller +class PatchPanel < Trema::Controller def start @patch = [] File.open('./patch_panel.conf').each_line do |each| diff --git a/spec/patch_panel_spec.rb b/spec/patch_panel_spec.rb new file mode 100644 index 0000000..2a2c608 --- /dev/null +++ b/spec/patch_panel_spec.rb @@ -0,0 +1,5 @@ +require 'trema' +require 'patch_panel' + +describe PatchPanel do +end From 1f13f10bf8ad9fcf3842063f7656695e8fbb30f0 Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 08:29:13 +0900 Subject: [PATCH 04/11] Fix to run on trema/trema_ruby. --- .gitignore | 1 + .hound.yml | 3 + .rubocop.yml | 8 +-- .travis.yml | 8 ++- Gemfile | 3 +- Gemfile.lock | 39 +++++++------ features/patch_panel.feature | 55 ++++++++++++------- features/step_definitions/misc_steps.rb | 13 ----- .../step_definitions/send_packets_steps.rb | 10 ---- features/step_definitions/stats_steps.rb | 15 ----- features/support/env.rb | 7 --- features/support/hooks.rb | 21 ------- lib/patch_panel.rb | 8 ++- network.conf | 14 ----- spec/{ => lib}/patch_panel_spec.rb | 0 trema.conf | 14 +++++ 16 files changed, 87 insertions(+), 132 deletions(-) create mode 100644 .hound.yml delete mode 100644 features/step_definitions/misc_steps.rb delete mode 100644 features/step_definitions/send_packets_steps.rb delete mode 100644 features/step_definitions/stats_steps.rb delete mode 100644 network.conf rename spec/{ => lib}/patch_panel_spec.rb (100%) create mode 100644 trema.conf diff --git a/.gitignore b/.gitignore index f2c1360..df8f528 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /test/tmp/ /test/version_tmp/ /tmp/ +/vendor/ ## Specific to RubyMotion: .dat* diff --git a/.hound.yml b/.hound.yml new file mode 100644 index 0000000..b7945ab --- /dev/null +++ b/.hound.yml @@ -0,0 +1,3 @@ +ruby: + enabled: true + config_file: .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml index a6865b6..fa05aaa 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,2 @@ - AllCops: - Include: - - Gemfile - - Guardfile - - Rakefile - - tasks/*.rake +Style/StringLiterals: + EnforcedStyle: single_quotes diff --git a/.travis.yml b/.travis.yml index 1cabfe6..861ce99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ language: ruby +bundler_args: --without development + script: bundle exec rake travis rvm: - - 2.0.0 - - 2.1.0 + - 2.0 + - 2.1 + - 2.2 - ruby-head before_install: @@ -14,7 +17,6 @@ before_install: matrix: allow_failures: - - rvm: 2.1.0 - rvm: ruby-head fast_finish: true diff --git a/Gemfile b/Gemfile index e4d2684..009a363 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source 'https://rubygems.org' -gem 'trema', github: 'trema/trema', branch: 'develop' +gem 'phut', github: 'trema/phut', branch: 'develop' +gem 'trema', github: 'trema/trema_ruby', branch: 'develop' group :development, :test do gem 'aruba', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 06718e2..0d5a08b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,22 +1,27 @@ GIT - remote: git://github.com/trema/trema.git - revision: 40ecd9fb7f388743a03e09327eca2fd2a1e172d1 + remote: git://github.com/trema/phut.git + revision: 6d05e56b36f51ec4a147bfcd9cfbea88abb04c46 branch: develop specs: - trema (0.4.7) - gli (~> 2.11.0) - paper_house (~> 0.6.2) - pio (~> 0.8.1) + phut (0.1.0) + gli (~> 2.12.2) + pio (~> 0.11.1) + pry (~> 0.10.1) + +GIT + remote: git://github.com/trema/trema_ruby.git + revision: d84da85627961d77c6440f75024b35bac97ce8c7 + branch: develop + specs: + trema (0.1.0) + bundler (~> 1.7.12) + gli (~> 2.12.0) + pio (~> 0.11.1) rake - rdoc (~> 4.1.1) GEM remote: https://rubygems.org/ specs: - POpen4 (0.1.4) - Platform (>= 0.4.0) - open4 - Platform (0.4.0) abstract_type (0.0.7) adamantium (0.2.0) ice_nine (~> 0.11.0) @@ -64,7 +69,7 @@ GEM multi_json (~> 1.3) given_core (3.5.4) sorcerer (>= 0.3.7) - gli (2.11.0) + gli (2.12.2) guard (2.10.1) formatador (>= 0.2.4) listen (~> 2.7) @@ -89,7 +94,6 @@ GEM sparkr (>= 0.2.0) term-ansicolor yard (~> 0.8.7.5) - json (1.8.1) listen (2.8.3) celluloid (>= 0.15.2) rb-fsevent (>= 0.9.3) @@ -101,14 +105,10 @@ GEM mime-types (2.4.3) multi_json (1.10.1) multi_test (0.1.1) - open4 (1.3.4) - paper_house (0.6.2) - POpen4 (~> 0.1.4) - rake parser (2.2.0.pre.8) ast (>= 1.1, < 3.0) slop (~> 3.4, >= 3.4.5) - pio (0.8.1) + pio (0.11.1) bindata (~> 2.1.0) powerpack (0.0.9) procto (0.0.2) @@ -121,8 +121,6 @@ GEM rb-fsevent (0.9.4) rb-inotify (0.9.5) ffi (>= 0.5.0) - rdoc (4.1.2) - json (~> 1.4) reek (1.5.1) parser (~> 2.2.0.pre.7) rainbow (>= 1.99, < 3.0) @@ -192,6 +190,7 @@ DEPENDENCIES guard-rspec guard-rubocop inch + phut! rake reek rspec diff --git a/features/patch_panel.feature b/features/patch_panel.feature index 75e1a0f..133be8f 100644 --- a/features/patch_panel.feature +++ b/features/patch_panel.feature @@ -1,24 +1,39 @@ -Feature: "Patch Panel" sample application - @slow_process @ruby - Scenario: Run "Patch Panel" Ruby example +Feature: "Patch Panel" example + Background: + Given a file named ".trema/config" with: + """ + LOG_DIR: . + PID_DIR: . + SOCKET_DIR: . + """ + And I successfully run `sudo -v` + + Scenario: Run Given a file named "patch_panel.conf" with: - """ - 1 2 - """ - And a file named "network.conf" with: - """ - vswitch("patch") { datapath_id "0xabc" } + """ + 1 2 + """ + And a file named "trema.conf" with: + """ + vswitch('patch') { + datapath_id '0xabc' + } + + vhost ('host1') { + ip '192.168.0.1' + } - vhost("host1") { ip "192.168.0.1" } - vhost("host2") { ip "192.168.0.2" } + vhost ('host2') { + ip '192.168.0.2' + } - link "patch", "host1" - link "patch", "host2" - """ - And I run `trema run ../../lib/patch_panel.rb -c network.conf -d` - And wait until "PatchPanel" is up - When I send 1 packet from host1 to host2 - And I run `trema show_stats host1 --tx` - And I run `trema show_stats host2 --rx` + link 'patch', 'host1' + link 'patch', 'host2' + """ + And I successfully run `trema run ../../lib/patch_panel.rb -c trema.conf -d` + And I run `sleep 5` + When I successfully run `trema send_packets --source host1 --dest host2 --n_pkts 1` + And I run `trema show_stats host1 --tx` + And I run `trema show_stats host2 --rx` Then the output from "trema show_stats host1 --tx" should contain "192.168.0.2,1,192.168.0.1,1,1,50" - And the output from "trema show_stats host2 --rx" should contain "192.168.0.2,1,192.168.0.1,1,1,50" + And the output from "trema show_stats host2 --rx" should contain "192.168.0.2,1,192.168.0.1,1,1,50" diff --git a/features/step_definitions/misc_steps.rb b/features/step_definitions/misc_steps.rb deleted file mode 100644 index 285db6d..0000000 --- a/features/step_definitions/misc_steps.rb +++ /dev/null @@ -1,13 +0,0 @@ -# encoding: utf-8 - -When(/^wait until "([^"]*)" is up$/) do |process| - nloop = 0 - pid_file = File.join(Trema.pid, "#{process}.pid") - loop do - nloop += 1 - fail 'Timeout' if nloop > 100 # FIXME - break if FileTest.exists?(pid_file) && ps_entry_of(process) - sleep 0.1 - end - sleep 1 # FIXME -end diff --git a/features/step_definitions/send_packets_steps.rb b/features/step_definitions/send_packets_steps.rb deleted file mode 100644 index 7b08162..0000000 --- a/features/step_definitions/send_packets_steps.rb +++ /dev/null @@ -1,10 +0,0 @@ -# encoding: utf-8 - -When(/^I send (\d+) packets from (.+) to (.+)$/) do |n_packets, host_a, host_b| - step 'I run `trema send_packets '\ - "--source #{host_a} --dest #{host_b} --n_pkts #{n_packets}`" -end - -When(/^I send 1 packet from (.+) to (.+)$/) do |host_a, host_b| - step "I send 1 packets from #{host_a} to #{host_b}" -end diff --git a/features/step_definitions/stats_steps.rb b/features/step_definitions/stats_steps.rb deleted file mode 100644 index 258e6c7..0000000 --- a/features/step_definitions/stats_steps.rb +++ /dev/null @@ -1,15 +0,0 @@ -# encoding: utf-8 - -Then(/^the total number of tx packets should be:$/) do |table| - sleep 1 - table.hashes[0].each_pair do |host, n| - expect(count_packets(`trema show_stats #{host} --tx`)).to eq(n.to_i) - end -end - -Then(/^the total number of rx packets should be:$/) do |table| - sleep 1 - table.hashes[0].each_pair do |host, n| - expect(count_packets(`trema show_stats #{host} --rx`)).to eq(n.to_i) - end -end diff --git a/features/support/env.rb b/features/support/env.rb index 300d211..fb0a661 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -1,8 +1 @@ require 'aruba/cucumber' -require 'trema' - -ENV['TREMA_TMP'] = File.join(__dir__, '..', '..', 'tmp', 'aruba') - -def ps_entry_of(name) - `ps -ef | grep -w "#{name} " | grep -v grep` -end diff --git a/features/support/hooks.rb b/features/support/hooks.rb index e6f656c..9fa2c58 100644 --- a/features/support/hooks.rb +++ b/features/support/hooks.rb @@ -1,28 +1,7 @@ -require 'trema/path' - -def wait_until_all_pid_files_are_deleted(timeout = 12) - elapsed = 0 - loop do - fail 'Failed to clean up remaining processes.' if elapsed > timeout - break if Dir.glob(File.join(Trema.pid, '*.pid')).empty? - sleep 0.1 - elapsed += 0.1 - end - sleep 1 -end - Before do @aruba_timeout_seconds = 10 - run 'trema killall' - wait_until_all_pid_files_are_deleted -end - -Before('@slow_process') do - @aruba_io_wait_seconds = 1 end After do run 'trema killall' - wait_until_all_pid_files_are_deleted - processes.clear end diff --git a/lib/patch_panel.rb b/lib/patch_panel.rb index 0a26aaa..ddf89eb 100644 --- a/lib/patch_panel.rb +++ b/lib/patch_panel.rb @@ -1,8 +1,8 @@ # Software patch-panel. class PatchPanel < Trema::Controller - def start + def start(argv) @patch = [] - File.open('./patch_panel.conf').each_line do |each| + File.open(config_file(argv)).each_line do |each| if /^(\d+)\s+(\d+)$/ =~ each @patch << [Regexp.last_match[1].to_i, Regexp.last_match[2].to_i] end @@ -17,6 +17,10 @@ def switch_ready(datapath_id) private + def config_file(argv) + argv[1] ? argv[1] : './patch_panel.conf' + end + def make_patch(datapath_id, port_a, port_b) send_flow_mod_add( datapath_id, diff --git a/network.conf b/network.conf deleted file mode 100644 index ba907e6..0000000 --- a/network.conf +++ /dev/null @@ -1,14 +0,0 @@ -vswitch("patch") { - datapath_id "0xabc" -} - -vhost ("host1") { - ip "192.168.0.1" -} - -vhost ("host2") { - ip "192.168.0.2" -} - -link "patch", "host1" -link "patch", "host2" diff --git a/spec/patch_panel_spec.rb b/spec/lib/patch_panel_spec.rb similarity index 100% rename from spec/patch_panel_spec.rb rename to spec/lib/patch_panel_spec.rb diff --git a/trema.conf b/trema.conf new file mode 100644 index 0000000..d5fbf2a --- /dev/null +++ b/trema.conf @@ -0,0 +1,14 @@ +vswitch('patch') { + datapath_id '0xabc' +} + +vhost ('host1') { + ip '192.168.0.1' +} + +vhost ('host2') { + ip '192.168.0.2' +} + +link 'patch', 'host1' +link 'patch', 'host2' From 3c984c072c22f8ef40c97dfcea7be3dac64029b1 Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 10:38:00 +0900 Subject: [PATCH 05/11] Add RSpec tests. --- .rubocop.yml | 3 ++ Gemfile.lock | 95 ++++++++++++++++++++---------------- README.md | 2 +- spec/lib/patch_panel_spec.rb | 42 ++++++++++++++++ 4 files changed, 99 insertions(+), 43 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fa05aaa..d16f9ce 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,2 +1,5 @@ Style/StringLiterals: EnforcedStyle: single_quotes + +Style/DotPosition: + EnforcedStyle: trailing diff --git a/Gemfile.lock b/Gemfile.lock index 0d5a08b..175349b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,22 +1,22 @@ GIT remote: git://github.com/trema/phut.git - revision: 6d05e56b36f51ec4a147bfcd9cfbea88abb04c46 + revision: 64e63fb4384a262c740f2b5ae487a336a3d97895 branch: develop specs: phut (0.1.0) gli (~> 2.12.2) - pio (~> 0.11.1) + pio (~> 0.11.2) pry (~> 0.10.1) GIT remote: git://github.com/trema/trema_ruby.git - revision: d84da85627961d77c6440f75024b35bac97ce8c7 + revision: 40001eba07d657e583f97207f79875d2be5e3bf6 branch: develop specs: trema (0.1.0) bundler (~> 1.7.12) gli (~> 2.12.0) - pio (~> 0.11.1) + pio (~> 0.11.2) rake GEM @@ -26,7 +26,7 @@ GEM adamantium (0.2.0) ice_nine (~> 0.11.0) memoizable (~> 0.4.0) - aruba (0.6.1) + aruba (0.6.2) childprocess (>= 0.3.6) cucumber (>= 1.1.1) rspec-expectations (>= 2.7.0) @@ -39,19 +39,19 @@ GEM timers (~> 4.0.0) childprocess (0.5.5) ffi (~> 1.0, >= 1.0.11) - codeclimate-test-reporter (0.4.3) + codeclimate-test-reporter (0.4.6) simplecov (>= 0.7.1, < 1.0.0) coderay (1.1.0) concord (0.1.5) adamantium (~> 0.2.0) equalizer (~> 0.0.9) - coveralls (0.7.2) - multi_json (~> 1.3) - rest-client (= 1.6.7) - simplecov (>= 0.7) - term-ansicolor (= 1.2.2) - thor (= 0.18.1) - cucumber (1.3.17) + coveralls (0.7.3) + multi_json (~> 1.10) + rest-client (~> 1.7) + simplecov (~> 0.9.1) + term-ansicolor (~> 1.3) + thor (~> 0.19.1) + cucumber (1.3.18) builder (>= 2.1.2) diff-lcs (>= 1.1.3) gherkin (~> 2.12) @@ -61,40 +61,44 @@ GEM docile (1.1.5) equalizer (0.0.9) ffi (1.9.6) - flog (4.3.0) + flog (4.3.1) ruby_parser (~> 3.1, > 3.1.0) sexp_processor (~> 4.4) formatador (0.2.5) gherkin (2.12.2) multi_json (~> 1.3) - given_core (3.5.4) + given_core (3.6.0) sorcerer (>= 0.3.7) gli (2.12.2) - guard (2.10.1) + guard (2.11.1) formatador (>= 0.2.4) listen (~> 2.7) lumberjack (~> 1.0) + nenv (~> 0.1) + notiffany (~> 0.0) pry (>= 0.9.12) + shellany (~> 0.0) thor (>= 0.18.1) - guard-bundler (2.0.0) + guard-bundler (2.1.0) bundler (~> 1.0) guard (~> 2.2) - guard-compat (0.3.0) - guard-rspec (4.4.2) + guard-compat (~> 1.1) + guard-compat (1.2.1) + guard-rspec (4.5.0) guard (~> 2.1) - guard-compat (~> 0.1) + guard-compat (~> 1.1) rspec (>= 2.99.0, < 4.0) guard-rubocop (1.2.0) guard (~> 2.0) rubocop (~> 0.20) hitimes (1.2.2) ice_nine (0.11.1) - inch (0.5.7) + inch (0.5.10) pry sparkr (>= 0.2.0) term-ansicolor yard (~> 0.8.7.5) - listen (2.8.3) + listen (2.8.5) celluloid (>= 0.15.2) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) @@ -105,10 +109,14 @@ GEM mime-types (2.4.3) multi_json (1.10.1) multi_test (0.1.1) - parser (2.2.0.pre.8) + nenv (0.2.0) + netrc (0.10.2) + notiffany (0.0.3) + nenv (~> 0.1) + shellany (~> 0.0) + parser (2.2.0.2) ast (>= 1.1, < 3.0) - slop (~> 3.4, >= 3.4.5) - pio (0.11.1) + pio (0.11.2) bindata (~> 2.1.0) powerpack (0.0.9) procto (0.0.2) @@ -121,12 +129,13 @@ GEM rb-fsevent (0.9.4) rb-inotify (0.9.5) ffi (>= 0.5.0) - reek (1.5.1) + reek (1.6.4) parser (~> 2.2.0.pre.7) rainbow (>= 1.99, < 3.0) - unparser (~> 0.1.16) - rest-client (1.6.7) - mime-types (>= 1.16) + unparser (~> 0.2.2) + rest-client (1.7.2) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) rspec (3.1.0) rspec-core (~> 3.1.0) rspec-expectations (~> 3.1.0) @@ -136,22 +145,23 @@ GEM rspec-expectations (3.1.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.1.0) - rspec-given (3.5.4) - given_core (= 3.5.4) - rspec (>= 2.12) + rspec-given (3.6.0) + given_core (= 3.6.0) + rspec (>= 2.14.0) rspec-mocks (3.1.3) rspec-support (~> 3.1.0) rspec-support (3.1.2) - rubocop (0.27.1) + rubocop (0.28.0) astrolabe (~> 1.3) parser (>= 2.2.0.pre.7, < 3.0) powerpack (~> 0.0.6) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.4) - ruby-progressbar (1.7.0) - ruby_parser (3.6.3) + ruby-progressbar (1.7.1) + ruby_parser (3.6.4) sexp_processor (~> 4.1) - sexp_processor (4.4.4) + sexp_processor (4.4.5) + shellany (0.0.1) simplecov (0.9.1) docile (~> 1.1.0) multi_json (~> 1.0) @@ -160,19 +170,20 @@ GEM slop (3.6.0) sorcerer (1.0.2) sparkr (0.4.1) - term-ansicolor (1.2.2) - tins (~> 0.8) - thor (0.18.1) + term-ansicolor (1.3.0) + tins (~> 1.0) + thor (0.19.1) thread_safe (0.3.4) timers (4.0.1) hitimes - tins (0.13.2) - unparser (0.1.16) + tins (1.3.3) + unparser (0.2.2) abstract_type (~> 0.0.7) adamantium (~> 0.2.0) concord (~> 0.1.5) + diff-lcs (~> 1.2.5) equalizer (~> 0.0.9) - parser (~> 2.2.0.pre.7) + parser (~> 2.2.0.2) procto (~> 0.0.2) yard (0.8.7.6) diff --git a/README.md b/README.md index c44cd9d..02db94a 100644 --- a/README.md +++ b/README.md @@ -19,5 +19,5 @@ How to run ``` % bundle install -% bundle exec trema run lib/patch_panel.rb -c sample.conf +% bundle exec trema run lib/patch_panel.rb -c trema.conf ``` diff --git a/spec/lib/patch_panel_spec.rb b/spec/lib/patch_panel_spec.rb index 2a2c608..df992bb 100644 --- a/spec/lib/patch_panel_spec.rb +++ b/spec/lib/patch_panel_spec.rb @@ -2,4 +2,46 @@ require 'patch_panel' describe PatchPanel do + Given(:patch_panel) { PatchPanel.new } + + context 'when patch_panel.conf = "1 2\n3 4"' do + Given(:config) { "1 2\n3 4" } + Given { allow(File).to receive(:open).and_return(StringIO.new(config)) } + + describe '#start' do + When { patch_panel.start(argv) } + + context "with ['patch_panel.rb']" do + Given(:argv) { ['patch_panel.rb'] } + Then { patch_panel.instance_variable_get(:@patch) == [[1, 2], [3, 4]] } + + describe '#switch_ready' do + When { patch_panel.switch_ready(dpid) } + + context 'with 0xabc' do + Given(:dpid) { 0xabc } + Given { allow(patch_panel).to receive(:send_flow_mod_add) } + Then do + expect(patch_panel).to(have_received(:send_flow_mod_add). + with(0xabc, + match: Pio::Match.new(in_port: 1), + actions: Pio::SendOutPort.new(2))) + expect(patch_panel).to(have_received(:send_flow_mod_add). + with(0xabc, + match: Pio::Match.new(in_port: 2), + actions: Pio::SendOutPort.new(1))) + expect(patch_panel).to(have_received(:send_flow_mod_add). + with(0xabc, + match: Pio::Match.new(in_port: 3), + actions: Pio::SendOutPort.new(4))) + expect(patch_panel).to(have_received(:send_flow_mod_add). + with(0xabc, + match: Pio::Match.new(in_port: 4), + actions: Pio::SendOutPort.new(3))) + end + end + end + end + end + end end From d31e69e27546b48d025c3916f2e6711b56b8654f Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 11:01:39 +0900 Subject: [PATCH 06/11] Refactoring. --- lib/patch_panel.rb | 16 ++++++++-------- spec/lib/patch_panel_spec.rb | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/patch_panel.rb b/lib/patch_panel.rb index ddf89eb..b3ad8de 100644 --- a/lib/patch_panel.rb +++ b/lib/patch_panel.rb @@ -1,12 +1,9 @@ +require 'English' + # Software patch-panel. class PatchPanel < Trema::Controller def start(argv) - @patch = [] - File.open(config_file(argv)).each_line do |each| - if /^(\d+)\s+(\d+)$/ =~ each - @patch << [Regexp.last_match[1].to_i, Regexp.last_match[2].to_i] - end - end + @patch = parse(IO.read(argv[1] || './patch_panel.conf')) end def switch_ready(datapath_id) @@ -17,8 +14,11 @@ def switch_ready(datapath_id) private - def config_file(argv) - argv[1] ? argv[1] : './patch_panel.conf' + def parse(config) + config.split("\n").map do |each| + fail unless /^(\d+)\s+(\d+)$/=~ each + [$LAST_MATCH_INFO[1].to_i, $LAST_MATCH_INFO[2].to_i] + end end def make_patch(datapath_id, port_a, port_b) diff --git a/spec/lib/patch_panel_spec.rb b/spec/lib/patch_panel_spec.rb index df992bb..0d7a57e 100644 --- a/spec/lib/patch_panel_spec.rb +++ b/spec/lib/patch_panel_spec.rb @@ -6,7 +6,7 @@ context 'when patch_panel.conf = "1 2\n3 4"' do Given(:config) { "1 2\n3 4" } - Given { allow(File).to receive(:open).and_return(StringIO.new(config)) } + Given { allow(IO).to receive(:read).and_return(config) } describe '#start' do When { patch_panel.start(argv) } From 741c725cf3bce833f48ecd8c467dbce14e0c591d Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 11:06:19 +0900 Subject: [PATCH 07/11] Update README.md. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 02db94a..e6dc49b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ patch_panel [![Dependency Status](http://img.shields.io/gemnasium/trema/patch_panel.svg?style=flat)][gemnasium] [![Inline docs](http://inch-ci.org/github/trema/patch_panel.png?branch=develop)][inch] +OpenFlow controller that emulates a software patch panel. + [travis]: http://travis-ci.org/trema/patch_panel [coveralls]: https://coveralls.io/r/trema/patch_panel [codeclimate]: https://codeclimate.com/github/trema/patch_panel From 3be114f377eb37b249b8fa372410a5fe76f30301 Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 11:06:34 +0900 Subject: [PATCH 08/11] Add 0.1.0 entry. --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..08e6d25 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change log + +## develop (unreleased) + +## 0.1.0 (1/29/2015) + +### Misc + +* The initial release version of patch_panel that runs on [pure-Ruby Trema](https://github.com/trema/trema_ruby). From 938c6e0bd819c467337961d21251be61172e24c1 Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 11:06:55 +0900 Subject: [PATCH 09/11] Refactoring. --- lib/patch_panel.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/patch_panel.rb b/lib/patch_panel.rb index b3ad8de..3040791 100644 --- a/lib/patch_panel.rb +++ b/lib/patch_panel.rb @@ -16,7 +16,7 @@ def switch_ready(datapath_id) def parse(config) config.split("\n").map do |each| - fail unless /^(\d+)\s+(\d+)$/=~ each + fail "Invalid format: '#{each}'" unless /^(\d+)\s+(\d+)$/=~ each [$LAST_MATCH_INFO[1].to_i, $LAST_MATCH_INFO[2].to_i] end end From 4799bb7372f32ed0691fb2ee284f0e89b8803850 Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 15:18:15 +0900 Subject: [PATCH 10/11] Add configuration error handling tests. --- Gemfile.lock | 4 ++-- features/patch_panel.feature | 23 ++++++++++++++++------- features/support/hooks.rb | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 175349b..a8c4ea1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: git://github.com/trema/phut.git - revision: 64e63fb4384a262c740f2b5ae487a336a3d97895 + revision: ea3c98aa5fa8cfa815653273114458b759b91929 branch: develop specs: phut (0.1.0) @@ -10,7 +10,7 @@ GIT GIT remote: git://github.com/trema/trema_ruby.git - revision: 40001eba07d657e583f97207f79875d2be5e3bf6 + revision: 1fcbee5ddd7b491a6326f2d40b424bbd7f1c5702 branch: develop specs: trema (0.1.0) diff --git a/features/patch_panel.feature b/features/patch_panel.feature index 133be8f..58b7733 100644 --- a/features/patch_panel.feature +++ b/features/patch_panel.feature @@ -6,13 +6,6 @@ Feature: "Patch Panel" example PID_DIR: . SOCKET_DIR: . """ - And I successfully run `sudo -v` - - Scenario: Run - Given a file named "patch_panel.conf" with: - """ - 1 2 - """ And a file named "trema.conf" with: """ vswitch('patch') { @@ -30,6 +23,13 @@ Feature: "Patch Panel" example link 'patch', 'host1' link 'patch', 'host2' """ + And I successfully run `sudo -v` + + Scenario: Run + Given a file named "patch_panel.conf" with: + """ + 1 2 + """ And I successfully run `trema run ../../lib/patch_panel.rb -c trema.conf -d` And I run `sleep 5` When I successfully run `trema send_packets --source host1 --dest host2 --n_pkts 1` @@ -37,3 +37,12 @@ Feature: "Patch Panel" example And I run `trema show_stats host2 --rx` Then the output from "trema show_stats host1 --tx" should contain "192.168.0.2,1,192.168.0.1,1,1,50" And the output from "trema show_stats host2 --rx" should contain "192.168.0.2,1,192.168.0.1,1,1,50" + + Scenario: Invalid configuration file + Given a file named "patch_panel.conf" with: + """ + INVALID CONFIGURATION + """ + And I run `trema run "../../lib/patch_panel.rb patch_panel.conf" -c trema.conf` + Then the output should contain "error: Invalid format: 'INVALID CONFIGURATION'" + And the output should contain "RuntimeError" diff --git a/features/support/hooks.rb b/features/support/hooks.rb index 9fa2c58..63e7bc5 100644 --- a/features/support/hooks.rb +++ b/features/support/hooks.rb @@ -4,4 +4,5 @@ After do run 'trema killall' + sleep 5 end From 498b34ba0f47ecfc4215397966a2175e8e0cb84a Mon Sep 17 00:00:00 2001 From: Yasuhito Takamiya Date: Thu, 29 Jan 2015 16:00:14 +0900 Subject: [PATCH 11/11] Added configuration section. --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index e6dc49b..d3401ab 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,26 @@ How to run % bundle install % bundle exec trema run lib/patch_panel.rb -c trema.conf ``` + + +Configuration +------------- + +When `patch_panel.rb` starts up, it will search for its configuration +file named `patch_panel.conf` in the current working directory. If you +want to specify a path to a configuration file, pass it to +`patch_panel.rb` as its argument: + +``` +% bundle exec trema run "lib/patch_panel.rb foobar.conf" -c trema.conf +``` + +A configuration file contains patching information. Each line has a +pair of port numbers like so: + +``` +1 2 +3 4 +``` + +The first line means that switch port #1 is connected to port #2.