proxy_tester 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. data/Gemfile +2 -0
  2. data/Gemfile.lock +18 -1
  3. data/README.md +88 -4
  4. data/bin/proxy_tester +11 -0
  5. data/config.yaml +0 -0
  6. data/features/.keep +0 -0
  7. data/features/add_test_case.feature +41 -0
  8. data/features/step_definitions.rb +30 -0
  9. data/features/support/debugging.rb +3 -0
  10. data/features/support/env.rb +12 -0
  11. data/features/support/environment.rb +22 -0
  12. data/features/support/filesystem.rb +19 -0
  13. data/lib/proxy_tester.rb +11 -1
  14. data/lib/proxy_tester/actions/add_test_case.rb +40 -0
  15. data/lib/proxy_tester/actions/clear_environment.rb +21 -0
  16. data/lib/proxy_tester/actions/fetch_urls.rb +94 -0
  17. data/lib/proxy_tester/actions/handle_error.rb +10 -6
  18. data/lib/proxy_tester/capybara_proxy.rb +1 -1
  19. data/lib/proxy_tester/cli/main.rb +10 -3
  20. data/lib/proxy_tester/cli/test.rb +79 -0
  21. data/lib/proxy_tester/config.rb +1 -1
  22. data/lib/proxy_tester/error_handler.rb +16 -7
  23. data/lib/proxy_tester/error_messages.rb +45 -3
  24. data/lib/proxy_tester/exceptions.rb +31 -2
  25. data/lib/proxy_tester/git_repository.rb +6 -7
  26. data/lib/proxy_tester/http_proxy.rb +48 -0
  27. data/lib/proxy_tester/locales/en.yml +18 -0
  28. data/lib/proxy_tester/main.rb +1 -1
  29. data/lib/proxy_tester/models/user.rb +2 -2
  30. data/lib/proxy_tester/remote_repository.rb +55 -0
  31. data/lib/proxy_tester/reporters/fetch_urls.rb +34 -0
  32. data/lib/proxy_tester/version.rb +2 -1
  33. data/proxy_tester.gemspec +2 -0
  34. data/script/ci +4 -0
  35. data/script/test_web +5 -2
  36. data/spec/actions/add_test_case_spec.rb +81 -0
  37. data/spec/actions/fetch_urls_spec.rb +52 -0
  38. data/spec/actions/handle_error_spec.rb +1 -1
  39. data/spec/capybara_proxy_spec.rb +1 -1
  40. data/spec/git_repository_spec.rb +22 -0
  41. data/spec/http_proxy_spec.rb +47 -0
  42. data/spec/remote_repository_spec.rb +103 -0
  43. data/spec/reporters/fetch_urls_spec.rb +58 -0
  44. data/spec/support/filesystem.rb +2 -0
  45. data/spec/support/reporting.rb +6 -0
  46. data/spec/user_spec.rb +10 -2
  47. metadata +66 -5
  48. data/lib/proxy_tester/actions/clone_repository.rb +0 -39
  49. data/spec/actions/clone_repository_spec.rb +0 -83
@@ -29,13 +29,6 @@ module ProxyTester
29
29
  def self.clone(source, destination, options = {})
30
30
  bare = options.fetch(:bare, false)
31
31
 
32
- source = Addressable::URI.heuristic_parse(::File.expand_path(source))
33
- if source.scheme.blank?
34
- source.scheme = 'file'
35
- source.authority = ''
36
- end
37
- source = source.to_s
38
-
39
32
  destination = ::File.expand_path(destination)
40
33
 
41
34
  if bare
@@ -45,6 +38,12 @@ module ProxyTester
45
38
  end
46
39
 
47
40
  new(destination)
41
+ rescue Rugged::NetworkError
42
+ raise Exceptions::RepositoryDoesNotExist, JSON.dump(repository: source)
43
+ rescue Rugged::OSError
44
+ raise Exceptions::RepositoryDoesNotExist, JSON.dump(repository: source)
45
+ rescue Rugged::RepositoryError
46
+ raise Exceptions::RepositoryInvalid, JSON.dump(repository: source)
48
47
  end
49
48
 
50
49
  def add_content(path, content = '', mode = 0100644, commit_info = default_commit_info)
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ module ProxyTester
3
+ class HttpProxy
4
+
5
+ private
6
+
7
+ attr_reader :user
8
+
9
+ public
10
+
11
+ attr_reader :host, :port
12
+
13
+ def initialize(connection_string)
14
+ match = connection_string_pattern.match(connection_string) || {}
15
+
16
+ raise Exceptions::ProxyConnectionStringInvalid, JSON.dump(connection_string: connection_string) if match[:host].blank?
17
+ raise Exceptions::ProxyConnectionStringInvalid, JSON.dump(connection_string: connection_string) if match[:port].blank?
18
+
19
+ @host = match[:host]
20
+ @port = match[:port]
21
+ end
22
+
23
+ def use_user(user)
24
+ @user = user
25
+ end
26
+
27
+ def to_string(options = {})
28
+ result = []
29
+ result << 'http://'
30
+
31
+ if user and options[:cleartext] == true
32
+ result << "#{user.name}:#{user.password}@"
33
+ elsif user
34
+ result << "#{user.name}:#{'*' * 4}@" if user
35
+ end
36
+
37
+ result << "#{host}:#{port}"
38
+
39
+ result.join
40
+ end
41
+
42
+ private
43
+
44
+ def connection_string_pattern
45
+ /(?<host>[[:alnum:]._-]+):(?<port>\d+{1,5})/
46
+ end
47
+ end
48
+ end
@@ -37,6 +37,24 @@ en:
37
37
  invalid_proxy_type:
38
38
  summary: Invalid proxy type...
39
39
  details: 'Sorry, but I cannot fullfill your request. You provided an invalid proxy type "%{type}". Allowed values are ":none", ":http" or ":socks5".'
40
+ invalid_proxy_connection_string:
41
+ summary: Invalid Proxy Connection String...
42
+ details: 'Sorry, but I cannot fullfill your request. You provided an invalid proxy connection string "%{string}". It needs to be something like "proxy:port".'
43
+ unreachable_proxy:
44
+ summary: Unreachable Proxy...
45
+ details: 'Sorry, but I cannot fullfill your request. I was not able to contact the given proxy "%{host}" on port "%{port}". Maybe it is an invalid hostname?'
46
+ unexisting_repository:
47
+ summary: Repository Does Not Exist...
48
+ details: 'Sorry, but I cannot fullfill your request. The path "%{repository}" you provided does not exist.'
49
+ invalid_repository:
50
+ summary: Invalid Repository...
51
+ details: 'Sorry, but I cannot fullfill your request. The path "%{repository}" you provided is not a repository of a supported type (git).'
52
+ sigint:
53
+ summary: Program Execution Interrupted...
54
+ details: You've chosen to interrupt the program execution.
55
+ sigterm:
56
+ summary: Program Execution Aborted...
57
+ details: I received a SIGTERM. Aborting program execution.
40
58
  views:
41
59
  application:
42
60
  title: Proxy Tester
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- module ProxyTester;
2
+ module ProxyTester
3
3
  @environment = ProxyTester::Environment.new
4
4
  @config = ProxyTester::Config.new
5
5
  @ui_logger = ProxyTester::UiLogger.new
@@ -10,8 +10,8 @@ module ProxyTester
10
10
  source.create_users(self)
11
11
  end
12
12
 
13
- def to_string
14
- sprintf '%s:%s', name, password
13
+ def to_string(options = {})
14
+ sprintf '%s:%s', name, options.key?(:cleartext) ? password : '*' * 4
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ module ProxyTester
3
+ class RemoteRepository
4
+
5
+ private
6
+
7
+ attr_reader :repository
8
+
9
+ public
10
+
11
+ # Create Remote Repository
12
+ def initialize(repository)
13
+ @repository = parse(repository)
14
+ end
15
+
16
+ # source path of repository
17
+ #
18
+ # @return [String]
19
+ # base path to repository
20
+ #
21
+ # @example
22
+ # http://githost/repo.git => repo
23
+ # user@host:/githost/repo.git => repo
24
+ def base
25
+ ::File.basename(repository.path, '.*')
26
+ end
27
+
28
+ # source path of repository
29
+ #
30
+ # @return [String]
31
+ # path to repository
32
+ def source
33
+ repository.to_s
34
+ end
35
+
36
+ private
37
+
38
+ def parse(repo_string)
39
+ repo_string = ::File.expand_path(repo_string) if repo_string =~ %r{^(?:[^/@]+/)*[^/]+$}
40
+
41
+ repo = Addressable::URI.heuristic_parse(repo_string)
42
+
43
+ if repo.scheme.blank?
44
+ repo.scheme = 'file'
45
+ repo.authority = ''
46
+ repo.path = repo_string
47
+ elsif repo.scheme == 'ssh'
48
+ repo.host = repo.host + ':'
49
+ end
50
+
51
+ repo
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module ProxyTester
3
+ module Reporters
4
+ class FetchUrls
5
+
6
+ private
7
+
8
+ attr_reader :output
9
+
10
+ public
11
+
12
+ def initialize(output = $stdout)
13
+ @output = output
14
+ end
15
+
16
+ def header
17
+ puts 'Results of run'
18
+ end
19
+
20
+ def data(d)
21
+ output.printf "%-10s: %s\n", 'proxy', d[:proxy]
22
+ output.printf "%-10s: %s\n", 'url', d[:url]
23
+ output.printf "%-10s: %s\n", 'status', d[:status]
24
+
25
+ output.printf "%-10s:\n", 'headers'
26
+
27
+ d[:headers].each do |h,v|
28
+ output.printf " %-20s: %s\n", h, v
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ end
@@ -1,3 +1,4 @@
1
+ #main ProxyTester
1
2
  module ProxyTester
2
- VERSION = "0.0.1"
3
+ VERSION = '0.0.2'
3
4
  end
@@ -31,4 +31,6 @@ Gem::Specification.new do |spec|
31
31
  spec.add_runtime_dependency 'poltergeist'
32
32
  spec.add_runtime_dependency 'proxy_pac_rb', '~>0.2.5'
33
33
  spec.add_runtime_dependency 'therubyracer'
34
+ spec.add_runtime_dependency 'excon'
35
+ spec.add_runtime_dependency 'highline'
34
36
  end
data/script/ci CHANGED
@@ -1,3 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
+ script/test_web &
4
+
3
5
  bundle exec rake test:coveralls
6
+
7
+ pkill -P $$
@@ -17,6 +17,9 @@ class Webserver < Sinatra::Base
17
17
  end
18
18
  end
19
19
  end
20
- end
21
20
 
22
- Webserver.start!
21
+ get '/rspec/:test' do
22
+ params[:test]
23
+ end
24
+
25
+ end
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Actions::AddTestCase do
5
+ let(:remote_repository_path) { File.join(working_directory, 'git_repo.git') }
6
+
7
+ context '#initialize' do
8
+ it 'requires a source and a destination' do
9
+ repo = GitRepository.create(remote_repository_path)
10
+ repo.add_content('file.txt', 'asdf1')
11
+
12
+ remote_repository = double('RemoteRepository')
13
+ allow(remote_repository).to receive(:source).and_return("file://#{remote_repository_path}")
14
+
15
+ expect {
16
+ Actions::AddTestCase.new(remote_repository, working_directory)
17
+ }.not_to raise_error
18
+ end
19
+ end
20
+
21
+ context '#run' do
22
+ it 'runs the action' do
23
+ repo = GitRepository.create(remote_repository_path)
24
+ repo.add_content('file.txt', 'asdf1')
25
+
26
+ remote_repository = double('RemoteRepository')
27
+ allow(remote_repository).to receive(:to_string).and_return("file://#{remote_repository_path}")
28
+ allow(remote_repository).to receive(:source).and_return("file://#{remote_repository_path}")
29
+ allow(remote_repository).to receive(:base).and_return(::File.basename(remote_repository_path, '.git'))
30
+
31
+ action = Actions::AddTestCase.new(remote_repository, working_directory)
32
+ silence(:stderr) do
33
+ action.run
34
+ end
35
+
36
+ expect(path_exists?('git_repo')).to be_true
37
+ end
38
+
39
+ it 'respects existing path' do
40
+ repo = GitRepository.create(remote_repository_path)
41
+ repo.add_content('file.txt', 'asdf1')
42
+
43
+ remote_repository = double('RemoteRepository')
44
+ allow(remote_repository).to receive(:to_string).and_return("file://#{remote_repository_path}")
45
+ allow(remote_repository).to receive(:source).and_return("file://#{remote_repository_path}")
46
+ allow(remote_repository).to receive(:base).and_return(::File.basename(remote_repository_path, '.git'))
47
+
48
+ create_directory(::File.join(::File.basename(remote_repository_path, '.git'), '.git'))
49
+
50
+ action = Actions::AddTestCase.new(remote_repository, working_directory)
51
+
52
+ result = capture(:stderr) do
53
+ ProxyTester.ui_logger.level = :info
54
+ action.run
55
+ end
56
+
57
+ expect(result).to include('already')
58
+ end
59
+
60
+ it 'does remove existing path if forced to' do
61
+ repo = GitRepository.create(remote_repository_path)
62
+ repo.add_content('file.txt', 'asdf1')
63
+
64
+ remote_repository = double('RemoteRepository')
65
+ allow(remote_repository).to receive(:to_string).and_return("file://#{remote_repository_path}")
66
+ allow(remote_repository).to receive(:source).and_return("file://#{remote_repository_path}")
67
+ allow(remote_repository).to receive(:base).and_return(::File.basename(remote_repository_path, '.git'))
68
+
69
+ create_directory(::File.join(::File.basename(remote_repository_path, '.git'), '.git'))
70
+
71
+ action = Actions::AddTestCase.new(remote_repository, working_directory, force: true)
72
+
73
+ result = capture(:stderr) do
74
+ ProxyTester.ui_logger.level = :info
75
+ action.run
76
+ end
77
+
78
+ expect(result).to include('Add')
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Actions::FetchUrls do
5
+ context '#initialize' do
6
+ it 'requires a set of options' do
7
+ proxy = double('HttpProxy')
8
+ reporter = double('reporter')
9
+ allow(reporter).to receive(:header)
10
+
11
+ options = {
12
+ proxy: proxy,
13
+ urls: ['http://localhost:4567/rspec/url_fetcher'],
14
+ timeout: 2,
15
+ count: 1,
16
+ concurrent: false,
17
+ output: StringIO.new,
18
+ reporter: reporter,
19
+ }
20
+
21
+ expect {
22
+ Actions::FetchUrls.new(options)
23
+ }.not_to raise_error
24
+ end
25
+ end
26
+
27
+ context '#run' do
28
+ it 'fetchs urls' do
29
+ proxy = double('HttpProxy')
30
+ allow(proxy).to receive(:to_string).and_return('http://localhost:3128')
31
+
32
+ reporter = double('reporter')
33
+ allow(reporter).to receive(:data)
34
+ allow(reporter).to receive(:header)
35
+
36
+ options = {
37
+ proxy: proxy,
38
+ urls: ['http://example.org'],
39
+ timeout: 2,
40
+ count: 2,
41
+ output: StringIO.new,
42
+ concurrent: false,
43
+ reporter: reporter,
44
+ }
45
+
46
+ fetcher = Actions::FetchUrls.new(options)
47
+ silence :stderr do
48
+ fetcher.run
49
+ end
50
+ end
51
+ end
52
+ end
@@ -5,7 +5,7 @@ describe Actions::HandleError do
5
5
  context '#initialize' do
6
6
  it 'requires an exception' do
7
7
  expect {
8
- Actions::HandleError.new(StandardError.new)
8
+ Actions::HandleError.new(Exceptions::DefaultError.new('message'))
9
9
  }.not_to raise_error
10
10
  end
11
11
  end
@@ -61,7 +61,7 @@ describe CapybaraProxy do
61
61
  proxy.port = 3128
62
62
 
63
63
  proxy.user = double('user')
64
- allow(proxy.user).to receive(:to_string).and_return('user:password')
64
+ allow(proxy.user).to receive(:to_string).with(cleartext: true).and_return('user:password')
65
65
 
66
66
  expect(proxy.as_phantomjs_arguments).to eq(
67
67
  [
@@ -107,5 +107,27 @@ describe GitRepository do
107
107
 
108
108
  expect(Rugged::Repository.new(clone_path).bare?).to be true
109
109
  end
110
+
111
+ it 'raises error if repository does not exist' do
112
+ expect {
113
+ GitRepository.clone('asdf', 'asdf1')
114
+ }.to raise_error Exceptions::RepositoryDoesNotExist
115
+ end
116
+
117
+ it 'raises error if repository does not exist' do
118
+ expect {
119
+ GitRepository.clone('asdf.git', 'asdf1')
120
+ }.to raise_error Exceptions::RepositoryDoesNotExist
121
+ end
122
+
123
+ it 'raises error if repository is not a supported vcs repository' do
124
+ create_directory('invalid_repo')
125
+
126
+ expect {
127
+ in_working_directory do
128
+ GitRepository.clone('invalid_repo', 'asdf1')
129
+ end
130
+ }.to raise_error Exceptions::RepositoryInvalid
131
+ end
110
132
  end
111
133
  end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe HttpProxy do
5
+ context '#initialize' do
6
+ it 'requires a connection string' do
7
+ expect {
8
+ HttpProxy.new('localhost:8080')
9
+ }.not_to raise_error
10
+ end
11
+
12
+ it 'fails on invalid connection string' do
13
+ expect {
14
+ HttpProxy.new('gargabe:asdf')
15
+ }.to raise_error Exceptions::ProxyConnectionStringInvalid
16
+ end
17
+ end
18
+
19
+ context '#to_string' do
20
+ it 'generates a string' do
21
+ proxy = HttpProxy.new('localhost:8080')
22
+ expect(proxy.to_string).to eq('http://localhost:8080')
23
+ end
24
+
25
+ it 'uses a user and output no password' do
26
+ user = double('ProxyUser')
27
+ allow(user).to receive(:name).and_return('user')
28
+ expect(user).not_to receive(:password)
29
+
30
+ proxy = HttpProxy.new('localhost:8080')
31
+ proxy.use_user user
32
+
33
+ expect(proxy.to_string).to eq('http://user:****@localhost:8080')
34
+ end
35
+
36
+ it 'uses a user and output password on request' do
37
+ user = double('ProxyUser')
38
+ allow(user).to receive(:name).and_return('user')
39
+ allow(user).to receive(:password).and_return('password')
40
+
41
+ proxy = HttpProxy.new('localhost:8080')
42
+ proxy.use_user user
43
+
44
+ expect(proxy.to_string(cleartext: true)).to eq('http://user:password@localhost:8080')
45
+ end
46
+ end
47
+ end