proxy_tester 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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