expect-behaviors 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c8e49f4c01b13e382732ef998726de1eff8b6c4f
4
+ data.tar.gz: b3c03d88f5651851aebe59a9b9a0ce67726494d3
5
+ SHA512:
6
+ metadata.gz: 4583cb4d126badafc6070e5f78d556503d559a4e53d5b6fc3803f32d1d3f9bb8e66903aebee4210abf502a90f006730413d4502b967e72a3990d040f892c97a8
7
+ data.tar.gz: d86ad237e6d44d7424da9d191d503e57e652970623561e4d236770478923faca0a37e32c8a6a96e6e579b5009ff40715774c1e43021e3b1c4ab158cedca7b373
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
@@ -0,0 +1 @@
1
+ ruby-2.2.1
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
4
+ - 2.0.0
5
+ install:
6
+ - bundle install
7
+ script:
8
+ - uname -s
9
+ - rake test
10
+ addons:
11
+ code_climate:
12
+ repo_token: da682865771c5c7d9c6f59c442013c80989a6f19a25a960cecf46aca0f8d0f0d
13
+ deploy:
14
+ provider: rubygems
15
+ api_key:
16
+ secure: YZdbnjpyIZXeoQVizdAWU1MI5zLKsDmHjIMFuAa/sKptsZxqBA6amFGF7uUdmvHvRXlCxN/b3WliXuUJhvsRdzMU28a2/GEfjiCuEfXJm5vmoGH122UxgTBVYw8j9FsxteD09xTZE0eg+XP08CAfBKcgbbAfuhdfVPtW+pvnBx8=
17
+ gem: expect-behaviors
18
+ on:
19
+ tags: true
20
+ repo: francisluong/expect-behaviors
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+
7
+ gem 'net-ssh', '~> 2.9', '>= 2.9.2'
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "codeclimate-test-reporter", '~> 0', group: :test, require: nil
13
+ gem "mocha", '~> 1.1', '>= 1.1.0'
14
+ gem "pry", "~>0.10.1"
15
+ gem "shoulda", '~> 3.5', '>= 3.5.0'
16
+ gem "shoulda-context", '~> 1.2', '>= 1.2.1'
17
+ gem "rdoc", "~> 3.12"
18
+ gem "bundler", "~> 1.0"
19
+ gem "jeweler", '~> 2.0', '>= 2.0.0'
20
+ gem 'test-unit', '~> 2.5', '>= 2.5.5'
21
+ end
@@ -0,0 +1,99 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (4.2.0)
5
+ i18n (~> 0.7)
6
+ json (~> 1.7, >= 1.7.7)
7
+ minitest (~> 5.1)
8
+ thread_safe (~> 0.3, >= 0.3.4)
9
+ tzinfo (~> 1.1)
10
+ addressable (2.3.6)
11
+ builder (3.2.2)
12
+ codeclimate-test-reporter (0.4.7)
13
+ simplecov (>= 0.7.1, < 1.0.0)
14
+ coderay (1.1.0)
15
+ descendants_tracker (0.0.4)
16
+ thread_safe (~> 0.3, >= 0.3.1)
17
+ docile (1.1.5)
18
+ faraday (0.9.1)
19
+ multipart-post (>= 1.2, < 3)
20
+ git (1.2.9.1)
21
+ github_api (0.12.2)
22
+ addressable (~> 2.3)
23
+ descendants_tracker (~> 0.0.4)
24
+ faraday (~> 0.8, < 0.10)
25
+ hashie (>= 3.3)
26
+ multi_json (>= 1.7.5, < 2.0)
27
+ nokogiri (~> 1.6.3)
28
+ oauth2
29
+ hashie (3.3.2)
30
+ highline (1.6.21)
31
+ i18n (0.7.0)
32
+ jeweler (2.0.1)
33
+ builder
34
+ bundler (>= 1.0)
35
+ git (>= 1.2.5)
36
+ github_api
37
+ highline (>= 1.6.15)
38
+ nokogiri (>= 1.5.10)
39
+ rake
40
+ rdoc
41
+ json (1.8.2)
42
+ jwt (1.2.0)
43
+ metaclass (0.0.4)
44
+ method_source (0.8.2)
45
+ mini_portile (0.6.2)
46
+ minitest (5.5.1)
47
+ mocha (1.1.0)
48
+ metaclass (~> 0.0.1)
49
+ multi_json (1.10.1)
50
+ multi_xml (0.5.5)
51
+ multipart-post (2.0.0)
52
+ net-ssh (2.9.2)
53
+ nokogiri (1.6.5)
54
+ mini_portile (~> 0.6.0)
55
+ oauth2 (1.0.0)
56
+ faraday (>= 0.8, < 0.10)
57
+ jwt (~> 1.0)
58
+ multi_json (~> 1.3)
59
+ multi_xml (~> 0.5)
60
+ rack (~> 1.2)
61
+ pry (0.10.1)
62
+ coderay (~> 1.1.0)
63
+ method_source (~> 0.8.1)
64
+ slop (~> 3.4)
65
+ rack (1.6.0)
66
+ rake (10.4.2)
67
+ rdoc (3.12.2)
68
+ json (~> 1.4)
69
+ shoulda (3.5.0)
70
+ shoulda-context (~> 1.0, >= 1.0.1)
71
+ shoulda-matchers (>= 1.4.1, < 3.0)
72
+ shoulda-context (1.2.1)
73
+ shoulda-matchers (2.7.0)
74
+ activesupport (>= 3.0.0)
75
+ simplecov (0.9.2)
76
+ docile (~> 1.1.0)
77
+ multi_json (~> 1.0)
78
+ simplecov-html (~> 0.9.0)
79
+ simplecov-html (0.9.0)
80
+ slop (3.6.0)
81
+ test-unit (2.5.5)
82
+ thread_safe (0.3.4)
83
+ tzinfo (1.2.2)
84
+ thread_safe (~> 0.1)
85
+
86
+ PLATFORMS
87
+ ruby
88
+
89
+ DEPENDENCIES
90
+ bundler (~> 1.0)
91
+ codeclimate-test-reporter (~> 0)
92
+ jeweler (~> 2.0, >= 2.0.0)
93
+ mocha (~> 1.1, >= 1.1.0)
94
+ net-ssh (~> 2.9, >= 2.9.2)
95
+ pry (~> 0.10.1)
96
+ rdoc (~> 3.12)
97
+ shoulda (~> 3.5, >= 3.5.0)
98
+ shoulda-context (~> 1.2, >= 1.2.1)
99
+ test-unit (~> 2.5, >= 2.5.5)
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Francis Luong (Franco)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,16 @@
1
+ # expect-behaviors
2
+ Ruby Mixin to add Expect Behaviors to SSH/Serial/Telnet controllers
3
+
4
+ [![Build Status](https://travis-ci.org/francisluong/expect-behaviors.svg?branch=master)](https://travis-ci.org/francisluong/expect-behaviors)
5
+ [![Code Climate](https://codeclimate.com/github/francisluong/expect-behaviors/badges/gpa.svg)](https://codeclimate.com/github/francisluong/expect-behaviors)
6
+ [![Test Coverage](https://codeclimate.com/github/francisluong/expect-behaviors/badges/coverage.svg)](https://codeclimate.com/github/francisluong/expect-behaviors)
7
+
8
+ # Contributing to expect-behaviors
9
+
10
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
11
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
12
+ * Fork the project.
13
+ * Start a feature/bugfix branch.
14
+ * Commit and push until you are happy with your contribution.
15
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
16
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ require 'rake'
6
+
7
+ begin
8
+ Bundler.setup(:default, :development)
9
+ rescue Bundler::BundlerError => e
10
+ $stderr.puts e.message
11
+ $stderr.puts "Run `bundle install` to install missing gems"
12
+ exit e.status_code
13
+ end
14
+
15
+ task :default => :test
16
+
17
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |raketask| load raketask }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,36 @@
1
+ require 'expect/ssh'
2
+
3
+ hostname = 'localhost'
4
+ @ssh = Expect::SSH.new(hostname, ENV['USER'], ignore_known_hosts: true)
5
+ @ssh.start
6
+ prompt = /.*\$/
7
+ @ssh.expect { when_matching(prompt) { @exp_match } } # first prompt
8
+
9
+ def strip_command_and_prompt(expect_match)
10
+ expect_match.buffer.lines[1..-2].join.strip
11
+ end
12
+
13
+ @ssh.send_data('date')
14
+ result = @ssh.expect do
15
+ when_matching(prompt) {@exp_match}
16
+ end
17
+ date = strip_command_and_prompt(result)
18
+
19
+ @ssh.send_data('uname -a')
20
+ result = @ssh.expect do
21
+ when_matching(prompt) {@exp_match}
22
+ end
23
+ uname = strip_command_and_prompt(result)
24
+
25
+ puts "[date=#{date}]"
26
+ puts "[uname=#{uname}]"
27
+
28
+ print "[TEST timeout action: "
29
+ @ssh.send_data('sleep 3')
30
+ result = @ssh.expect do
31
+ when_matching(prompt) {"FAILED - got prompt"}
32
+ when_timeout(1) {"PASSED"}
33
+ end
34
+ puts result + ']'
35
+
36
+ @ssh.stop
@@ -0,0 +1,95 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: expect-behaviors 0.1.1 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "expect-behaviors"
9
+ s.version = "0.1.1"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Francis Luong (Franco)"]
14
+ s.date = "2016-03-14"
15
+ s.description = "Ruby Mixin to add Expect Behaviors to SSH/Serial/Telnet controllers"
16
+ s.email = "me@francisluong.com"
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".ruby-version",
24
+ ".travis.yml",
25
+ "Gemfile",
26
+ "Gemfile.lock",
27
+ "LICENSE",
28
+ "README.md",
29
+ "Rakefile",
30
+ "VERSION",
31
+ "examples/example_ssh_localhost.rb",
32
+ "expect-behaviors.gemspec",
33
+ "lib/expect/behavior.rb",
34
+ "lib/expect/match.rb",
35
+ "lib/expect/ssh.rb",
36
+ "lib/expect/timeout_error.rb",
37
+ "tasks/doc.rake",
38
+ "tasks/jeweler.rake",
39
+ "tasks/test.rake",
40
+ "test/acceptance/sshd/erb/ssh_config.erb",
41
+ "test/acceptance/sshd/erb/sshd_config.erb",
42
+ "test/acceptance/test_expect_behaviors_slow_tests.rb",
43
+ "test/acceptance/test_expect_ssh.rb",
44
+ "test/class_including_expect_behavior.rb",
45
+ "test/helper.rb",
46
+ "test/sshd.rb",
47
+ "test/unit/expect/test_expect_behaviors.rb",
48
+ "test/unit/expect/test_expect_match.rb",
49
+ "test/unit/expect/test_includer_class.rb"
50
+ ]
51
+ s.homepage = "http://github.com/francisluong/expect-behaviors"
52
+ s.licenses = ["MIT"]
53
+ s.rubygems_version = "2.4.6"
54
+ s.summary = "Ruby Mixin to add Expect Behaviors"
55
+
56
+ if s.respond_to? :specification_version then
57
+ s.specification_version = 4
58
+
59
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
60
+ s.add_runtime_dependency(%q<net-ssh>, [">= 2.9.2", "~> 2.9"])
61
+ s.add_development_dependency(%q<codeclimate-test-reporter>, ["~> 0"])
62
+ s.add_development_dependency(%q<mocha>, [">= 1.1.0", "~> 1.1"])
63
+ s.add_development_dependency(%q<pry>, ["~> 0.10.1"])
64
+ s.add_development_dependency(%q<shoulda>, [">= 3.5.0", "~> 3.5"])
65
+ s.add_development_dependency(%q<shoulda-context>, [">= 1.2.1", "~> 1.2"])
66
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
67
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
68
+ s.add_development_dependency(%q<jeweler>, [">= 2.0.0", "~> 2.0"])
69
+ s.add_development_dependency(%q<test-unit>, [">= 2.5.5", "~> 2.5"])
70
+ else
71
+ s.add_dependency(%q<net-ssh>, [">= 2.9.2", "~> 2.9"])
72
+ s.add_dependency(%q<codeclimate-test-reporter>, ["~> 0"])
73
+ s.add_dependency(%q<mocha>, [">= 1.1.0", "~> 1.1"])
74
+ s.add_dependency(%q<pry>, ["~> 0.10.1"])
75
+ s.add_dependency(%q<shoulda>, [">= 3.5.0", "~> 3.5"])
76
+ s.add_dependency(%q<shoulda-context>, [">= 1.2.1", "~> 1.2"])
77
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
78
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
79
+ s.add_dependency(%q<jeweler>, [">= 2.0.0", "~> 2.0"])
80
+ s.add_dependency(%q<test-unit>, [">= 2.5.5", "~> 2.5"])
81
+ end
82
+ else
83
+ s.add_dependency(%q<net-ssh>, [">= 2.9.2", "~> 2.9"])
84
+ s.add_dependency(%q<codeclimate-test-reporter>, ["~> 0"])
85
+ s.add_dependency(%q<mocha>, [">= 1.1.0", "~> 1.1"])
86
+ s.add_dependency(%q<pry>, ["~> 0.10.1"])
87
+ s.add_dependency(%q<shoulda>, [">= 3.5.0", "~> 3.5"])
88
+ s.add_dependency(%q<shoulda-context>, [">= 1.2.1", "~> 1.2"])
89
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
90
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
91
+ s.add_dependency(%q<jeweler>, [">= 2.0.0", "~> 2.0"])
92
+ s.add_dependency(%q<test-unit>, [">= 2.5.5", "~> 2.5"])
93
+ end
94
+ end
95
+
@@ -0,0 +1,134 @@
1
+ require 'expect/match'
2
+ require 'expect/timeout_error'
3
+
4
+ module Expect
5
+
6
+ ##
7
+ # Add Expect behaviors to Accessor classes that have an input buffer: e.g. telnet/ssh
8
+ # :Required methods to be created by the class mixing Expect::Behaviors :
9
+ # #exp_process - should do one iteration of handle input and append buffer
10
+ # #exp_buffer - provide the current buffer contents and empty it
11
+ module Behavior
12
+
13
+ attr_reader :exp_match
14
+ attr_accessor :exp_timeout_sec
15
+ attr_accessor :exp_sleep_interval_sec
16
+
17
+ EXP_TIMEOUT_SEC_DEFAULT = 10
18
+ EXP_SLEEP_INTERVAL_SEC_DEFAULT = 0.1
19
+
20
+ def expect(&block)
21
+ #pre-action
22
+ initialize_expect if @__exp_buffer.nil?
23
+ @exp_match_registry = {}
24
+ #register callbacks
25
+ instance_eval(&block)
26
+ #action
27
+ result = execute_expect_loop
28
+ #post-action
29
+ @exp_timeout_sec_ephemeral = @exp_timeout_sec
30
+ result
31
+ end
32
+
33
+
34
+ ##################
35
+ private
36
+ ##################
37
+
38
+ def clear_expect_buffer
39
+ @__exp_buffer = ''
40
+ end
41
+
42
+ def current_time
43
+ Time.now.to_f
44
+ end
45
+
46
+ def exp_registered_matches
47
+ match_object = nil
48
+ unless @__exp_buffer.nil?
49
+ @exp_match_registry.each_pair do |expr, block|
50
+ expr = expr.to_s unless expr.is_a?(Regexp)
51
+ if @__exp_buffer.match(expr)
52
+ result = block.call
53
+ match_object = result.eql?('exp_continue') ? nil : Expect::Match.new(expr, @__exp_full_buffer)
54
+ break # don't try to match more than one
55
+ end
56
+ end
57
+ end
58
+ @exp_match = match_object
59
+ @exp_match
60
+ end
61
+
62
+ ##
63
+ # reset timeout and continue expect loop
64
+ def expect_continue
65
+ init_timeout
66
+ @__exp_buffer = '' # avoid matching the same text twice
67
+ "exp_continue"
68
+ end
69
+ alias_method :exp_continue, :expect_continue
70
+ alias_method :reset_timeout, :expect_continue
71
+
72
+ def execute_expect_loop
73
+ init_timeout
74
+ @exp_match = nil
75
+ result = nil
76
+ @__exp_buffer = ''
77
+ @__exp_full_buffer = ''
78
+ while result.nil?
79
+ if timeout?
80
+ result = @exp_timeout_block.nil? ? timeout_action_default : @exp_timeout_block.call
81
+ else
82
+ raise unless respond_to?(:exp_buffer)
83
+ raise unless respond_to?(:exp_process)
84
+ # call process/buffer and then check for match
85
+ exp_process
86
+ newbuffertext = exp_buffer.to_s
87
+ @__exp_buffer << newbuffertext
88
+ @__exp_full_buffer << newbuffertext
89
+ if exp_registered_matches
90
+ result = @exp_match
91
+ else
92
+ sleep(@exp_sleep_interval_sec)
93
+ end
94
+ end
95
+ end
96
+ result
97
+ end
98
+
99
+ def initialize_expect
100
+ @exp_match_registry ||= {}
101
+ @exp_match = nil
102
+ @exp_sleep_interval_sec ||= EXP_SLEEP_INTERVAL_SEC_DEFAULT
103
+ @exp_timeout_sec ||= EXP_TIMEOUT_SEC_DEFAULT
104
+ @exp_timeout_sec_ephemeral = @exp_timeout_sec
105
+ @exp_timeout_block ||= nil
106
+ @__exp_buffer ||= ''
107
+ @__exp_full_buffer ||= ''
108
+ end
109
+
110
+ def init_timeout
111
+ @start_time = current_time
112
+ end
113
+
114
+ def timeout?
115
+ (current_time - @start_time) > @exp_timeout_sec_ephemeral
116
+ end
117
+
118
+ def timeout_action_default
119
+ raise(TimeoutError, "Expect Timeout [start_time=#{@start_time}] [time=#{current_time}]")
120
+ end
121
+
122
+ def when_matching(expression, &block)
123
+ @exp_match_registry[expression] = block
124
+ end
125
+ alias_method :when_match, :when_matching
126
+
127
+ def when_timeout(timeout_sec = nil, &block)
128
+ @exp_timeout_sec_ephemeral = timeout_sec unless timeout_sec.nil?
129
+ @exp_timeout_block = block
130
+ end
131
+
132
+
133
+ end
134
+ end