polytrix 0.0.1 → 0.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/.rspec +1 -6
- data/.rubocop-todo.yml +19 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +11 -0
- data/Gemfile +0 -16
- data/README.md +119 -28
- data/Rakefile +18 -123
- data/bin/polytrix +5 -0
- data/doc-src/_markdown.md +5 -0
- data/doc-src/default_bootstrap.md +13 -0
- data/docs/influences.md +28 -0
- data/docs/samples/code2doc/java/HelloWorld.md +13 -0
- data/docs/samples/code2doc/java/Quine.md +33 -0
- data/docs/samples/code2doc/python/hello_world.md +3 -0
- data/docs/samples/code2doc/python/quine.md +4 -0
- data/docs/samples/code2doc/ruby/hello_world.md +7 -0
- data/features/execution.feature +67 -0
- data/features/fixtures/configs/empty.yml +12 -0
- data/features/fixtures/configs/hello_world.yml +10 -0
- data/features/fixtures/spec/polytrix_merge.rb +5 -0
- data/features/fixtures/spec/polytrix_spec.rb +10 -0
- data/features/reporting.feature +140 -0
- data/features/step_definitions/sdk_steps.rb +12 -0
- data/features/support/env.rb +8 -0
- data/lib/polytrix/challenge.rb +20 -7
- data/lib/polytrix/challenge_runner.rb +9 -44
- data/lib/polytrix/cli/add.rb +67 -0
- data/lib/polytrix/cli/report.rb +88 -0
- data/lib/polytrix/cli/reports/hash_reporter.rb +30 -0
- data/lib/polytrix/cli/reports/json_reporter.rb +14 -0
- data/lib/polytrix/cli/reports/markdown_reporter.rb +23 -0
- data/lib/polytrix/cli/reports/yaml_reporter.rb +14 -0
- data/lib/polytrix/cli.rb +158 -0
- data/lib/polytrix/configuration.rb +65 -4
- data/lib/polytrix/core/file_system_helper.rb +75 -0
- data/lib/polytrix/core/implementor.rb +31 -3
- data/lib/polytrix/documentation/code_segmenter.rb +168 -0
- data/lib/polytrix/documentation/comment_styles.rb +87 -0
- data/lib/polytrix/documentation/helpers/code_helper.rb +85 -0
- data/lib/polytrix/documentation/view_helper.rb +21 -0
- data/lib/polytrix/documentation_generator.rb +59 -10
- data/lib/polytrix/executor.rb +89 -0
- data/lib/polytrix/logger.rb +17 -0
- data/lib/polytrix/manifest.rb +64 -7
- data/lib/polytrix/result.rb +16 -2
- data/lib/polytrix/rspec/documentation_formatter.rb +41 -16
- data/lib/polytrix/rspec/yaml_report.rb +51 -0
- data/lib/polytrix/rspec.rb +32 -53
- data/lib/polytrix/runners/middleware/feature_executor.rb +4 -3
- data/lib/polytrix/runners/middleware/setup_env_vars.rb +6 -4
- data/lib/polytrix/validation.rb +20 -0
- data/lib/polytrix/validations.rb +23 -0
- data/lib/polytrix/validator.rb +20 -0
- data/lib/polytrix/validator_registry.rb +34 -0
- data/lib/polytrix/version.rb +1 -1
- data/lib/polytrix.rb +125 -22
- data/polytrix.gemspec +7 -2
- data/polytrix.rb +6 -0
- data/polytrix_tests.yml +20 -0
- data/resources/code_sample.tt +2 -0
- data/samples/.gitignore +2 -0
- data/samples/_markdown.md +5 -0
- data/samples/default_bootstrap.rb +14 -0
- data/samples/polytrix.rb +28 -0
- data/samples/polytrix_cli.sh +7 -0
- data/samples/polytrix_tests.yml +10 -0
- data/{sdks/fog → samples}/scripts/bootstrap +0 -2
- data/samples/scripts/wrapper +7 -0
- data/samples/sdks/custom/polytrix.yml +2 -0
- data/samples/sdks/java/.gitignore +2 -0
- data/samples/sdks/java/build.gradle +14 -0
- data/samples/sdks/java/challenges/HelloWorld.java +10 -0
- data/samples/sdks/java/challenges/Quine.java +31 -0
- data/samples/sdks/java/code_sample.tt +11 -0
- data/samples/sdks/java/scripts/bootstrap +2 -0
- data/samples/sdks/java/scripts/wrapper +8 -0
- data/samples/sdks/python/challenges/hello_world.py +2 -0
- data/samples/sdks/python/challenges/quine.py +2 -0
- data/{sdks/pkgcloud → samples/sdks/python}/scripts/wrapper +1 -1
- data/samples/sdks/ruby/challenges/hello_world.rb +4 -0
- data/scripts/bootstrap +1 -9
- data/scripts/wrapper +7 -0
- data/spec/fabricators/challenge_fabricator.rb +17 -0
- data/spec/fabricators/manifest_fabricator.rb +50 -0
- data/spec/fabricators/validator_fabricator.rb +12 -0
- data/spec/fixtures/{polytrix.yml → polytrix_tests.yml} +0 -0
- data/spec/fixtures/src-doc/_scenario.md.erb +1 -0
- data/spec/polytrix/challenge_runner_spec.rb +3 -3
- data/spec/polytrix/challenge_spec.rb +3 -4
- data/spec/polytrix/cli_spec.rb +39 -0
- data/spec/polytrix/configuration_spec.rb +45 -1
- data/spec/polytrix/documentation/helpers/code_helper_spec.rb +120 -0
- data/spec/polytrix/documentation_generator_spec.rb +41 -20
- data/spec/polytrix/file_finder_spec.rb +4 -3
- data/spec/polytrix/implementor_spec.rb +33 -0
- data/spec/polytrix/manifest_spec.rb +32 -14
- data/spec/polytrix/middleware/feature_executor_spec.rb +1 -1
- data/spec/polytrix/result_spec.rb +49 -0
- data/spec/polytrix/validations_spec.rb +16 -0
- data/spec/polytrix/validator_registry_spec.rb +39 -0
- data/spec/polytrix/validator_spec.rb +63 -0
- data/spec/polytrix_spec.rb +33 -7
- data/spec/spec_helper.rb +14 -1
- data/spec/thor_spy.rb +64 -0
- metadata +177 -160
- data/.rspec_parallel +0 -10
- data/Vagrantfile +0 -41
- data/features/0_identity_spec.rb +0 -40
- data/features/1_cloud_files_spec.rb +0 -48
- data/features/2_servers_spec.rb +0 -19
- data/features/features_helper.rb +0 -46
- data/features/helpers/cloudfiles_helper.rb +0 -31
- data/features/helpers/pacto_helper.rb +0 -33
- data/features/helpers/teardown_helper.rb +0 -49
- data/features/pacto/extensions/loaders/api_blueprint_loader.rb +0 -63
- data/features/pacto/extensions/loaders/simple_loader.rb +0 -55
- data/features/pacto/extensions/loaders/yaml_or_json_loader.rb +0 -17
- data/features/pacto/extensions/matchers.rb +0 -38
- data/features/phase2/feature_coverage_report.rb +0 -109
- data/features/phase2/run_all_features.rb +0 -14
- data/features/static_site/fixtures/index.html +0 -6
- data/lib/polytrix/challenge_builder.rb +0 -16
- data/lib/polytrix/core/file_finder.rb +0 -43
- data/lib/polytrix/core/result_tracker.rb +0 -25
- data/lib/polytrix/runners/middleware/pacto.rb +0 -59
- data/packer/.gitignore +0 -3
- data/packer/Berksfile +0 -15
- data/packer/Gemfile +0 -5
- data/packer/Vagrantfile +0 -128
- data/packer/cookbooks/drg/metadata.rb +0 -27
- data/packer/cookbooks/drg/recipes/admins.rb +0 -22
- data/packer/cookbooks/drg/recipes/default.rb +0 -9
- data/packer/cookbooks/drg/recipes/dotnet.rb +0 -4
- data/packer/cookbooks/drg/recipes/golang.rb +0 -4
- data/packer/cookbooks/drg/recipes/java.rb +0 -5
- data/packer/cookbooks/drg/recipes/php.rb +0 -10
- data/packer/cookbooks/drg/recipes/ruby.rb +0 -29
- data/packer/cookbooks/drg/recipes/system.rb +0 -13
- data/packer/create_box.sh +0 -10
- data/packer/http/preseed.cfg +0 -87
- data/packer/packer.json +0 -91
- data/packer/scripts/root_setup.sh +0 -37
- data/packer/scripts/setup.sh +0 -32
- data/pacto/config/pacto_server.rb +0 -40
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/extensions.json +0 -64
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/flavors/id.json +0 -100
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/images/id.json +0 -176
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/servers/id.json +0 -189
- data/pacto/contracts/dfw.servers.api.rackspacecloud.com/v2/account_id/servers.json +0 -63
- data/pacto/contracts/dns.api.rackspacecloud.com/v1.0/_tenant_id/domains.json +0 -62
- data/pacto/contracts/identity.api.rackspacecloud.com/v2.0/tokens.json +0 -192
- data/pacto/contracts/monitoring.api.rackspacecloud.com/v1.0/_tenant_id/account.json +0 -39
- data/pacto/contracts/ord.autoscale.api.rackspacecloud.com/v1.0/_tenant_id/groups.json +0 -38
- data/pacto/contracts/ord.blockstorage.api.rackspacecloud.com/v1/_tenant_id/volumes.json +0 -30
- data/pacto/contracts/ord.databases.api.rackspacecloud.com/v1.0/_tenant_id/instances.json +0 -30
- data/pacto/contracts/ord.loadbalancers.api.rackspacecloud.com/v1.0/_tenant_id/loadbalancers.json +0 -114
- data/pacto/contracts/ord.queues.api.rackspacecloud.com/v1/_tenant_id/queues.json +0 -13
- data/pacto/contracts/ord.servers.api.rackspacecloud.com/v2/_tenant_id/os-networksv2.json +0 -46
- data/pacto/contracts/ord.servers.api.rackspacecloud.com/v2/_tenant_id/servers/detail.json +0 -230
- data/pacto/contracts/storage101.dfw1.clouddrive.com/v1/mosso_account/container/object.json +0 -15
- data/pacto/contracts/storage101.dfw1.clouddrive.com/v1/mosso_account.json +0 -43
- data/pacto/contracts/storage101.ord1.clouddrive.com/v1/_mosso_id.json +0 -44
- data/pacto/pacto_server.rb +0 -100
- data/pacto/rackspace_uri_map.yaml +0 -229
- data/scripts/cibuild +0 -4
- data/sdks/fog/.gitignore +0 -1
- data/sdks/fog/Gemfile +0 -5
- data/sdks/fog/challenges/all_connections.rb +0 -45
- data/sdks/fog/challenges/authenticate_token.rb +0 -15
- data/sdks/fog/challenges/cdn_enable_container.rb +0 -20
- data/sdks/fog/challenges/create_a_container.rb +0 -17
- data/sdks/fog/challenges/create_server.rb +0 -36
- data/sdks/fog/challenges/get_object_metadata.rb +0 -13
- data/sdks/fog/challenges/list_containers.rb +0 -10
- data/sdks/fog/challenges/provision_scalable_webapp.rb +0 -30
- data/sdks/fog/challenges/upload_folder.rb +0 -25
- data/sdks/fog/scripts/bootstrap.ps1 +0 -1
- data/sdks/fog/scripts/wrapper +0 -2
- data/sdks/fog/scripts/wrapper.ps1 +0 -1
- data/sdks/gophercloud/.gitignore +0 -2
- data/sdks/gophercloud/challenges/authenticate_token.go +0 -23
- data/sdks/gophercloud/scripts/bootstrap +0 -6
- data/sdks/gophercloud/scripts/wrapper +0 -10
- data/sdks/jclouds/.gitignore +0 -1
- data/sdks/jclouds/challenges/AuthenticateToken.java +0 -115
- data/sdks/jclouds/pom.xml +0 -34
- data/sdks/jclouds/scripts/bootstrap +0 -3
- data/sdks/jclouds/scripts/wrapper +0 -7
- data/sdks/openstack.net/.gitignore +0 -4
- data/sdks/openstack.net/.nuget/Microsoft.Build.dll +0 -0
- data/sdks/openstack.net/.nuget/NuGet.Config +0 -6
- data/sdks/openstack.net/.nuget/NuGet.exe +0 -0
- data/sdks/openstack.net/.nuget/NuGet.targets +0 -136
- data/sdks/openstack.net/Challenge.cs +0 -10
- data/sdks/openstack.net/RunChallenge.cs +0 -19
- data/sdks/openstack.net/challenges/AuthenticateToken.cs +0 -24
- data/sdks/openstack.net/challenges/Weird.cs +0 -133
- data/sdks/openstack.net/openstack.net.csproj +0 -58
- data/sdks/openstack.net/openstack.net.sln +0 -27
- data/sdks/openstack.net/openstack.net.userprefs +0 -8
- data/sdks/openstack.net/packages.config +0 -6
- data/sdks/openstack.net/scripts/bootstrap +0 -2
- data/sdks/openstack.net/scripts/bootstrap.ps1 +0 -2
- data/sdks/openstack.net/scripts/wrapper +0 -7
- data/sdks/openstack.net/scripts/wrapper.ps1 +0 -1
- data/sdks/php-opencloud/.gitignore +0 -4
- data/sdks/php-opencloud/challenges/all_connections.php +0 -64
- data/sdks/php-opencloud/challenges/authenticate_token.php +0 -14
- data/sdks/php-opencloud/challenges/create_server.php +0 -39
- data/sdks/php-opencloud/challenges/get_object_metadata.php +0 -19
- data/sdks/php-opencloud/composer.json +0 -5
- data/sdks/php-opencloud/scripts/bootstrap +0 -4
- data/sdks/php-opencloud/scripts/bootstrap.ps1 +0 -2
- data/sdks/php-opencloud/scripts/wrapper +0 -2
- data/sdks/php-opencloud/scripts/wrapper.ps1 +0 -1
- data/sdks/pkgcloud/.gitignore +0 -1
- data/sdks/pkgcloud/challenges/authenticate_token.js +0 -17
- data/sdks/pkgcloud/challenges/get_object_metadata.js +0 -18
- data/sdks/pkgcloud/scripts/bootstrap +0 -2
- data/sdks/pkgcloud/scripts/bootstrap.ps1 +0 -1
- data/sdks/pkgcloud/scripts/wrapper.ps1 +0 -1
- data/sdks/pyrax/.gitignore +0 -2
- data/sdks/pyrax/challenges/all_connections.py +0 -61
- data/sdks/pyrax/challenges/authenticate_token.py +0 -17
- data/sdks/pyrax/challenges/cdn_enable_container.py +0 -22
- data/sdks/pyrax/challenges/create_a_container.py +0 -21
- data/sdks/pyrax/challenges/create_server.py +0 -35
- data/sdks/pyrax/challenges/get_object_metadata.py +0 -17
- data/sdks/pyrax/challenges/upload_folder.py +0 -32
- data/sdks/pyrax/requirements.txt +0 -21
- data/sdks/pyrax/scripts/bootstrap +0 -9
- data/sdks/pyrax/scripts/bootstrap.ps1 +0 -7
- data/sdks/pyrax/scripts/wrapper +0 -3
- data/sdks/pyrax/scripts/wrapper.ps1 +0 -2
- data/spec/polytrix/challenge_builder_spec.rb +0 -16
- data/spec/rspec_spec.rb +0 -17
data/Vagrantfile
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
# -*- mode: ruby -*-
|
2
|
-
# vi: set ft=ruby :
|
3
|
-
|
4
|
-
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
5
|
-
VAGRANTFILE_API_VERSION = "2"
|
6
|
-
|
7
|
-
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
8
|
-
config.vm.box = "drg"
|
9
|
-
|
10
|
-
# Original box used to build pre-packaged DRG box
|
11
|
-
# config.vm.box = "ubuntu1310"
|
12
|
-
# config.vm.box_url = "https://dl.dropboxusercontent.com/s/ng79gg5bg24r38p/ubuntu1310.box?token_hash=AAGKH9rJTMozemrLMLw8n8Htvg8-gGhb7xo8cwh0TaYCaw&dl=1"
|
13
|
-
|
14
|
-
config.cache.auto_detect = true
|
15
|
-
|
16
|
-
config.vm.provision :shell, :inline => "curl -L https://opscode.com/chef/install.sh | bash"
|
17
|
-
|
18
|
-
config.vm.define :polytrix do |vm|
|
19
|
-
end
|
20
|
-
|
21
|
-
config.vm.provider :rackspace do |rs, override|
|
22
|
-
override.vm.box = "dummy"
|
23
|
-
override.ssh.private_key_path = '~/.ssh/id_rsa'
|
24
|
-
rs.public_key_path = '~/.ssh/id_rsa.pub'
|
25
|
-
rs.username = ENV['RAX_USERNAME']
|
26
|
-
rs.api_key = ENV['RAX_API_KEY']
|
27
|
-
rs.flavor = /2 GB Performance/
|
28
|
-
rs.image = "DRG" # image created by packer. See ./packer/
|
29
|
-
rs.rackspace_region = :ord
|
30
|
-
end
|
31
|
-
|
32
|
-
config.vm.provision :chef_solo do |chef|
|
33
|
-
chef.cookbooks_path = ["packer/cookbooks", "packer/vendor/cookbooks"]
|
34
|
-
chef.add_recipe "drg"
|
35
|
-
# chef.log_level = :debug
|
36
|
-
chef.json = {
|
37
|
-
:instance_role => "vagrant"
|
38
|
-
}
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
data/features/0_identity_spec.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
describe 'Getting Started', :markdown =>
|
2
|
-
"""
|
3
|
-
Welcome to the SDK guide!
|
4
|
-
|
5
|
-
In this section, you will learn how to connect to OpenStack by authenticating against the [Identity service](http://docs.openstack.org/api/openstack-identity-service/2.0/content/).
|
6
|
-
|
7
|
-
By the end of the section, you will know:
|
8
|
-
- You have valid, working credentials
|
9
|
-
- You are able to load use the SDK of your choice
|
10
|
-
|
11
|
-
In the sections that follow, we will build the cloud infrastructure for a sample application using the OpenStack services.
|
12
|
-
""" do
|
13
|
-
code_sample 'authenticate token', """
|
14
|
-
Please use the SDK to [authenticate](http://docs.rackspace.com/auth/api/v2.0/auth-client-devguide/content/POST_authenticate_v2.0_tokens_Token_Calls.html) using a username and API key.
|
15
|
-
""", standard_env_vars, [:Authenticate] do
|
16
|
-
# Assertions
|
17
|
-
expect(Pacto).to have_validated_service('Identity', 'Authenticate')
|
18
|
-
expect(Pacto).to_not have_failed_validations
|
19
|
-
expect(Pacto).to_not have_unmatched_requests
|
20
|
-
end
|
21
|
-
|
22
|
-
code_sample 'all connections', """
|
23
|
-
Let's make a connection to each of the available OpenStack products
|
24
|
-
""", standard_env_vars, [] do
|
25
|
-
expect(Pacto).to have_validated_service('Identity', 'Authenticate')
|
26
|
-
expect(Pacto).to have_validated_service('Cloud Servers', 'List Servers')
|
27
|
-
expect(Pacto).to have_validated_service('Cloud Networks', 'List Networks')
|
28
|
-
expect(Pacto).to have_validated_service('Cloud Files', 'List Containers')
|
29
|
-
expect(Pacto).to have_validated_service('Cloud Load Balancers', 'List Load Balancers')
|
30
|
-
expect(Pacto).to have_validated_service('Cloud Databases', 'List Instances')
|
31
|
-
expect(Pacto).to have_validated_service('DNS', 'List Domains')
|
32
|
-
# Only a few SDKs have implemented monitoring
|
33
|
-
# expect(Pacto).to have_validated_service('Cloud Monitoring', 'Get Account')
|
34
|
-
expect(Pacto).to have_validated_service('Cloud Block Storage', 'List Volumes')
|
35
|
-
expect(Pacto).to have_validated_service('Autoscale', 'List Groups')
|
36
|
-
expect(Pacto).to have_validated_service('Cloud Queues', 'List Queues')
|
37
|
-
expect(Pacto).to_not have_failed_validations
|
38
|
-
# expect(Pacto).to_not have_unmatched_requests
|
39
|
-
end
|
40
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
describe 'Cloud Files', :markdown =>
|
2
|
-
"""
|
3
|
-
In this section we'll cover Cloud Files. We'll start with a few simple services. In the final example for this section, we will upload static assets to a CDN-enabled Cloud Files container that will be used by our sample application.
|
4
|
-
""" do
|
5
|
-
env = standard_env_vars
|
6
|
-
file = build :file, env
|
7
|
-
env.merge!(
|
8
|
-
'TEST_DIRECTORY' => file.directory.key,
|
9
|
-
'TEST_FILE' => file.key
|
10
|
-
)
|
11
|
-
|
12
|
-
vars = standard_env_vars
|
13
|
-
code_sample "List Containers", """
|
14
|
-
Use the SDK to list your existing cloud Cloud Files containers.
|
15
|
-
""", vars, [] do |success|
|
16
|
-
# Assertions
|
17
|
-
expect(Pacto).to have_validated_service('Cloud Files', 'List Containers')
|
18
|
-
expect(Pacto).to_not have_failed_validations
|
19
|
-
expect(Pacto).to_not have_unmatched_requests
|
20
|
-
end
|
21
|
-
|
22
|
-
code_sample "Get object metadata", """
|
23
|
-
Now, use the SDK to retrieve a file from Cloud Files.
|
24
|
-
""", env, [] do
|
25
|
-
expect(Pacto).to have_validated_service('Cloud Files', 'Get Object Metadata')
|
26
|
-
# Not that we're validated it did *not* get the data
|
27
|
-
expect(Pacto).to_not have_validated('Cloud Files', 'Get Object Data')
|
28
|
-
end
|
29
|
-
|
30
|
-
code_sample "Upload a single file", """
|
31
|
-
Now, let's upload logo.png to Cloud Files so we can start building a website.
|
32
|
-
""", env, [] do
|
33
|
-
pending
|
34
|
-
end
|
35
|
-
|
36
|
-
code_sample "Upload static assets", """
|
37
|
-
Finally, let's upload static assets (javascript, css, images, fonts) for a website.
|
38
|
-
""", env, [] do
|
39
|
-
pending
|
40
|
-
end
|
41
|
-
|
42
|
-
code_sample "Upload static assets", """
|
43
|
-
Let's enable the CDN for our assets.
|
44
|
-
""", env, [] do
|
45
|
-
pending
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
data/features/2_servers_spec.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
describe 'Cloud Servers', :markdown =>
|
2
|
-
"""
|
3
|
-
|
4
|
-
Scenarios using [Next Generation Cloud Servers API V2](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_preface.html).
|
5
|
-
""" do
|
6
|
-
code_sample "Create Server", """
|
7
|
-
[Create a Server](http://docs.rackspace.com/servers/api/v2/cs-devguide/content/CreateServers.html)
|
8
|
-
using the image and flavor, and region specified in the environment.
|
9
|
-
""", standard_env_vars.merge({
|
10
|
-
'RAX_REGION' => 'DFW',
|
11
|
-
'SERVER1_IMAGE' => 'f70ed7c7-b42e-4d77-83d8-40fa29825b85',
|
12
|
-
'SERVER1_FLAVOR' => 'performance1-1'
|
13
|
-
}), [] do |success|
|
14
|
-
# Assertions
|
15
|
-
expect(Pacto).to have_validated_service('Cloud Servers', 'Create Server')
|
16
|
-
expect(Pacto).to_not have_failed_validations
|
17
|
-
expect(Pacto).to_not have_unmatched_requests
|
18
|
-
end
|
19
|
-
end
|
data/features/features_helper.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
$:.unshift File.expand_path('../pacto', File.dirname(__FILE__))
|
2
|
-
require 'polytrix/rspec'
|
3
|
-
require 'webmock/rspec'
|
4
|
-
require 'matrix_formatter'
|
5
|
-
require 'helpers/pacto_helper'
|
6
|
-
require 'pacto/extensions/matchers'
|
7
|
-
require 'pacto/extensions/loaders/simple_loader'
|
8
|
-
require 'pacto/extensions/loaders/api_blueprint_loader'
|
9
|
-
require 'helpers/teardown_helper'
|
10
|
-
require 'helpers/cloudfiles_helper'
|
11
|
-
|
12
|
-
SDKs = Dir['sdks/*'].map{|sdk| File.basename sdk}
|
13
|
-
|
14
|
-
Polytrix.implementors = SDKs.map{ |sdk|
|
15
|
-
Polytrix::Implementor.new :name => sdk #, :language => lang
|
16
|
-
}
|
17
|
-
|
18
|
-
require 'polytrix/runners/middleware/pacto'
|
19
|
-
Polytrix.configure do |c|
|
20
|
-
c.middleware.insert 0, Polytrix::Runners::Middleware::Pacto, {}
|
21
|
-
end
|
22
|
-
|
23
|
-
RSpec.configure do |c|
|
24
|
-
c.matrix_implementors = SDKs
|
25
|
-
c.treat_symbols_as_metadata_keys_with_true_values = true
|
26
|
-
c.include Polytrix::RSpec::Helper
|
27
|
-
end
|
28
|
-
|
29
|
-
def standard_env_vars
|
30
|
-
@standard_env_vars ||= {
|
31
|
-
'RAX_USERNAME' => ENV['RAX_USERNAME'],
|
32
|
-
'RAX_API_KEY' => ENV['RAX_API_KEY'],
|
33
|
-
'RAX_REGION' => 'ORD', # FIXME: stubbing multiple hosts
|
34
|
-
# 'RAX_REGION' => ENV['RAX_REGION'] || %w{DFW ORD IAD SYD HKG}.sample, # omitted LON since it requires UK account
|
35
|
-
'RAX_AUTH_URL' => PACTO_SERVER || 'https://identity.api.rackspacecloud.com'
|
36
|
-
}
|
37
|
-
end
|
38
|
-
|
39
|
-
def redact(data)
|
40
|
-
Hash[data.map do |k,v|
|
41
|
-
if k =~ /password|api_key/i
|
42
|
-
v = '******'
|
43
|
-
end
|
44
|
-
[k, v]
|
45
|
-
end]
|
46
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'fog'
|
2
|
-
|
3
|
-
def build type, env = {}
|
4
|
-
case type
|
5
|
-
when :file
|
6
|
-
build_file env
|
7
|
-
else
|
8
|
-
raise ArgumentError.new "Don't know how to be a #{type}"
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def build_file env
|
13
|
-
without_webmock do
|
14
|
-
service = Fog::Storage.new({
|
15
|
-
:provider => 'rackspace',
|
16
|
-
:rackspace_username => env['RAX_USERNAME'],
|
17
|
-
:rackspace_api_key => env['RAX_API_KEY'],
|
18
|
-
:rackspace_region => env['RAX_REGION']
|
19
|
-
})
|
20
|
-
|
21
|
-
directory = service.directories.create :key => 'asdf'
|
22
|
-
file = directory.files.create :key => 'asdf', :body => 'efgh'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def without_webmock
|
27
|
-
WebMock.disable!
|
28
|
-
ret_val = yield
|
29
|
-
WebMock.enable!
|
30
|
-
ret_val
|
31
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'pacto'
|
2
|
-
require 'pacto/rspec'
|
3
|
-
require 'pacto_server'
|
4
|
-
require 'goliath/test_helper'
|
5
|
-
|
6
|
-
def test_env_number
|
7
|
-
ENV['TEST_ENV_NUMBER'].to_i
|
8
|
-
end
|
9
|
-
|
10
|
-
def pacto_port
|
11
|
-
@pacto_port ||= 9900 + test_env_number
|
12
|
-
end
|
13
|
-
|
14
|
-
COVERAGE_FILE = "reports/api_coverage#{test_env_number}.yaml"
|
15
|
-
PACTO_SERVER = "http://identity.api.rackspacecloud.dev:#{pacto_port}" unless ENV['NO_PACTO']
|
16
|
-
|
17
|
-
RSpec.configure do |c|
|
18
|
-
c.include Goliath::TestHelper
|
19
|
-
c.before(:each) { Pacto.clear! }
|
20
|
-
c.after(:each) { save_coverage }
|
21
|
-
end
|
22
|
-
|
23
|
-
def generate?
|
24
|
-
ENV['PACTO_GENERATE'] == 'true'
|
25
|
-
end
|
26
|
-
|
27
|
-
def save_coverage
|
28
|
-
data = YAML::load(File.read(COVERAGE_FILE)) if File.exists?(COVERAGE_FILE)
|
29
|
-
data ||= {}
|
30
|
-
validations = Pacto::ValidationRegistry.instance.validations
|
31
|
-
data[example.full_description] = validations.reject{|v| v.contract.nil?}.map{|v| v.contract.name }
|
32
|
-
File.open(COVERAGE_FILE, 'w') {|f| f.write data.to_yaml }
|
33
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
RSpec.configure do |c|
|
2
|
-
c.after(:each) { auto_teardown }
|
3
|
-
end
|
4
|
-
|
5
|
-
def auth_token
|
6
|
-
@auth_token ||= Pacto::ValidationRegistry.instance.validations.map do | val |
|
7
|
-
token = val.request.headers['X-Auth-Token']
|
8
|
-
end.compact.reject(&:empty?).first
|
9
|
-
end
|
10
|
-
|
11
|
-
def auto_teardown
|
12
|
-
# HACK: This should be simplified and moved to Pacto
|
13
|
-
|
14
|
-
created_resources = auto_find_prg
|
15
|
-
auto_delete created_resources, auth_token
|
16
|
-
end
|
17
|
-
|
18
|
-
REDIRECTS = [201, 202, (300...400).to_a.flatten]
|
19
|
-
|
20
|
-
def auto_find_prg
|
21
|
-
# Find URLs that were the "Get" part of a Post-Redirect-Get pattern
|
22
|
-
created_uris = Pacto::ValidationRegistry.instance.validations.map {|validation|
|
23
|
-
validation.response.headers['Location'] if validation.request.method == :post and REDIRECTS.include? validation.response.status
|
24
|
-
}.compact
|
25
|
-
|
26
|
-
created_uris.map do | created_uri |
|
27
|
-
Addressable::URI.parse created_uri
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def auto_delete uris, auth_token
|
32
|
-
uris.group_by(&:site).each do | site, uris |
|
33
|
-
connection = Excon.new(site)
|
34
|
-
uris.each do | uri |
|
35
|
-
puts "Removing #{uri}"
|
36
|
-
connection.delete(:path => uri.path,
|
37
|
-
:debug_request => true,
|
38
|
-
:debug_response => true,
|
39
|
-
:expects => [204],
|
40
|
-
:headers => {
|
41
|
-
"User-Agent" => "fog/1.18.0",
|
42
|
-
"Content-Type" => "application/json",
|
43
|
-
"Accept" => "application/json",
|
44
|
-
"X-Auth-Token" => auth_token
|
45
|
-
}
|
46
|
-
)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
require 'yaml'
|
3
|
-
require 'jsonpath'
|
4
|
-
require 'pacto'
|
5
|
-
|
6
|
-
module Pacto
|
7
|
-
module Extensions
|
8
|
-
module Loaders
|
9
|
-
class APIBlueprintLoader < YamlOrJsonLoader
|
10
|
-
def self.load(file)
|
11
|
-
data = super
|
12
|
-
contracts = []
|
13
|
-
resources = JsonPath.on(data, '$..resources[(@.uriTemplate)]')
|
14
|
-
resources.each do |resource|
|
15
|
-
resource['actions'].each do |action|
|
16
|
-
contract = load_action(action, resource, file)
|
17
|
-
Pacto.contract_registry.register(contract)
|
18
|
-
contracts << contract
|
19
|
-
end
|
20
|
-
end
|
21
|
-
Pacto::ContractList.new contracts
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def self.load_action(action, resource, file)
|
27
|
-
# contract_definition = File.read(contract_path)
|
28
|
-
# definition = JSON.parse(contract_definition)
|
29
|
-
# schema.validate definition
|
30
|
-
# request = RequestClause.new(host, definition['request'])
|
31
|
-
# response = ResponseClause.new(definition['response'])
|
32
|
-
# Contract.new(request, response, contract_path, definition['name'])
|
33
|
-
|
34
|
-
# FIXME: Host info not available in blueprint.
|
35
|
-
host = 'http://localhost'
|
36
|
-
request_clause = RequestClause.new(host, {
|
37
|
-
'method' => action['method'],
|
38
|
-
'headers' => [], #not supporting this yet, probably needs conversion
|
39
|
-
'path' => resource['uriTemplate']
|
40
|
-
})
|
41
|
-
response = action['examples'].first['responses'].first
|
42
|
-
response_clause = ResponseClause.new({
|
43
|
-
'status' => response['name'],
|
44
|
-
'headers' => [], #not supporting this yet, probably needs conversion
|
45
|
-
'body' => schema_from(response)
|
46
|
-
})
|
47
|
-
Contract.new(request_clause, response_clause, file, resource['name'])
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.schema_from(response)
|
51
|
-
schema = response['schema']
|
52
|
-
if schema.nil? or schema.empty?
|
53
|
-
{}
|
54
|
-
else
|
55
|
-
MultiJson.load schema
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# contracts = Pacto::Extensions::Loaders::APIBlueprintLoader.load('pacto/blueprints/otter.json')
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
require 'yaml'
|
3
|
-
require 'pacto'
|
4
|
-
require_relative 'yaml_or_json_loader'
|
5
|
-
|
6
|
-
class Pacto::Extensions::Loaders::URIMapLoader < Pacto::Extensions::Loaders::YamlOrJsonLoader
|
7
|
-
class << self
|
8
|
-
include Pacto::Logger
|
9
|
-
|
10
|
-
def load(file)
|
11
|
-
data = super
|
12
|
-
contracts = []
|
13
|
-
data['services'].each do | group_name, service_group |
|
14
|
-
service_group['servers'].each do | server |
|
15
|
-
if service_group['services']
|
16
|
-
service_group['services'].each_pair do | service_name, service_definition|
|
17
|
-
contract = build_simple_contract service_definition, group_name, service_name, server, file
|
18
|
-
Pacto.contract_registry.register(contract)
|
19
|
-
contracts << contract
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
Pacto::ContractList.new contracts
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
def build_simple_contract service_definition, group_name, service_name, server, file
|
29
|
-
service_signature = "#{service_definition['method'].upcase} #{service_definition['uriTemplate']}"
|
30
|
-
logger.debug "Building contract for '#{service_signature}' as '#{group_name} - #{service_name}' on #{server}"
|
31
|
-
# FIXME: What about scheme?
|
32
|
-
host = "https://#{server}"
|
33
|
-
request_clause = Pacto::RequestClause.new(host, {
|
34
|
-
'method' => service_definition['method'],
|
35
|
-
'headers' => [], #not supporting this yet, probably needs conversion
|
36
|
-
'path' => convert_template(service_definition['uriTemplate']),
|
37
|
-
'body' => service_definition['requestSchema'] || {}
|
38
|
-
})
|
39
|
-
response_clause = Pacto::ResponseClause.new({
|
40
|
-
'status' => service_definition['responseStatusCode'] || 200,
|
41
|
-
'headers' => [], #not supporting this yet, probably needs conversion
|
42
|
-
'body' => service_definition['responseSchema'] || {}
|
43
|
-
})
|
44
|
-
Pacto::Contract.new(request_clause, response_clause, file, service_name)
|
45
|
-
end
|
46
|
-
|
47
|
-
def convert_template path
|
48
|
-
Addressable::Template.new(path) if path
|
49
|
-
# path.gsub(/{(\w+)}/, ':\1') if path
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Pacto.configuration.strict_matchers = false
|
55
|
-
# contracts = Pacto::Extensions::Loaders::URIMapLoader.load('pacto/rackspace_uri_map.yaml')
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Pacto
|
2
|
-
module Extensions
|
3
|
-
module Loaders
|
4
|
-
class YamlOrJsonLoader
|
5
|
-
YAML_EXTENSIONS = %w{.yml .yaml}
|
6
|
-
def self.load(file)
|
7
|
-
raw_data = File.read file
|
8
|
-
if YAML_EXTENSIONS.include? File.extname(file)
|
9
|
-
YAML::load(raw_data)
|
10
|
-
else
|
11
|
-
MultiJson.load(raw_data)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
RSpec::Matchers.define :have_validated_service do |group_name, service_name|
|
2
|
-
@requested_name = service_name
|
3
|
-
@contract = Pacto.contract_registry.find{ |c| c.name == @requested_name }
|
4
|
-
match do
|
5
|
-
unless @contract.nil?
|
6
|
-
@validations = Pacto::ValidationRegistry.instance.validations.select {|v|
|
7
|
-
# FIXME: Same contract on multiple servers is currently problematic
|
8
|
-
v.contract && v.contract.name == @contract.name
|
9
|
-
}
|
10
|
-
!(@validations.empty? || @validations.map(&:successful?).include?(false))
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
failure_message_for_should do
|
15
|
-
buffer = StringIO.new
|
16
|
-
buffer.puts "expected Pacto to have validated #{@requested_name}"
|
17
|
-
if @contract.nil?
|
18
|
-
buffer.puts ' but no known contract matches that name'
|
19
|
-
elsif @validations.empty?
|
20
|
-
buffer.puts ' but no request matched the pattern'
|
21
|
-
buffer.puts " pattern: #{@contract.request_pattern}"
|
22
|
-
buffer.puts ' received:'
|
23
|
-
buffer.puts "#{WebMock::RequestRegistry.instance}"
|
24
|
-
elsif @validations.map(&:successful?).include?(false)
|
25
|
-
buffer.puts ' but validation errors were found:'
|
26
|
-
buffer.print ' '
|
27
|
-
validation_results = @validations.map(&:results).flatten.compact
|
28
|
-
buffer.puts validation_results.join "\n "
|
29
|
-
validation_results.each do |validation_result|
|
30
|
-
buffer.puts " #{validation_result}"
|
31
|
-
end
|
32
|
-
else
|
33
|
-
# FIXME: ensure this is unreachable?
|
34
|
-
buffer.puts ' but an unknown problem occurred'
|
35
|
-
end
|
36
|
-
buffer.string
|
37
|
-
end
|
38
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'yaml'
|
3
|
-
require 'csv'
|
4
|
-
|
5
|
-
class CSVFeatureMatrix
|
6
|
-
def initialize(matrix_csv)
|
7
|
-
@feature_matrix = []
|
8
|
-
|
9
|
-
CSV.foreach(matrix_csv, :headers => :first_row) do |row|
|
10
|
-
|
11
|
-
# Carry the product
|
12
|
-
@product = row['Product'] if row['Product']
|
13
|
-
row['Product'] ||= @product
|
14
|
-
|
15
|
-
next if row['Feature'].nil? or row['Feature'].empty?
|
16
|
-
|
17
|
-
# Normalize status
|
18
|
-
SDKs.each do |sdk|
|
19
|
-
row[sdk] = '' unless row[sdk] == 'Done'
|
20
|
-
end
|
21
|
-
|
22
|
-
@feature_matrix << row.to_hash
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def products
|
27
|
-
@feature_matrix.map{|f| f['Product']}.uniq.compact
|
28
|
-
end
|
29
|
-
|
30
|
-
def features(product)
|
31
|
-
@feature_matrix.select{|f| f['Product'] == product}.map{|f| f['Feature']}.compact
|
32
|
-
end
|
33
|
-
|
34
|
-
def implementers product, service_name
|
35
|
-
code_sample = @feature_matrix.find{|f| f['Feature'] == service_name}
|
36
|
-
feature.keys.select{|k| feature[k] == 'Done'}
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class CoveredFeatures
|
41
|
-
def initialize(coverage_files)
|
42
|
-
@coverage = {}
|
43
|
-
@covered_features = {}
|
44
|
-
[*coverage_files].each do |file|
|
45
|
-
@coverage.merge! YAML::load(File.read(file))
|
46
|
-
end
|
47
|
-
@coverage.values.flatten.uniq do |covered_feature|
|
48
|
-
@covered_features[covered_feature] = SDKs.select{|sdk|
|
49
|
-
@coverage.select{|k,v| k =~ /#{sdk}$/}.values.flatten.include? covered_feature
|
50
|
-
}
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def coverers(product, feature)
|
55
|
-
@covered_features[feature] || []
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
sdk_coverage = CoveredFeatures.new(Dir['reports/api_coverage*.yaml'])
|
60
|
-
original_feature_matrix = CSVFeatureMatrix.new 'original_feature_matrix.csv'
|
61
|
-
|
62
|
-
original_feature_matrix.products.each do |product|
|
63
|
-
describe product do
|
64
|
-
original_feature_matrix.features(product).each do |feature|
|
65
|
-
describe feature do
|
66
|
-
coverers = sdk_coverage.coverers(product, feature)
|
67
|
-
implementers = original_feature_matrix.implementers(product,feature)
|
68
|
-
SDKs.each do |sdk|
|
69
|
-
it sdk, sdk.to_sym do
|
70
|
-
if coverers.include? sdk
|
71
|
-
# pass
|
72
|
-
else
|
73
|
-
if implementers.include? sdk
|
74
|
-
pending
|
75
|
-
else
|
76
|
-
fail
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# data = YAML::load(File.read('pacto/rackspace_uri_map.yaml'))
|
87
|
-
# data['services'].each do |service_group_name, service_group|
|
88
|
-
# describe service_group_name do
|
89
|
-
# services = service_group['services'] || []
|
90
|
-
# services.each do |service_name, service|
|
91
|
-
# describe service_name do
|
92
|
-
# SDKs.each do |sdk|
|
93
|
-
# it sdk, sdk.to_sym do
|
94
|
-
# sdk_coverage = coverage.select{|k,v| k =~ /#{sdk}$/ }
|
95
|
-
# if sdk_coverage.values.flatten.include? service_name
|
96
|
-
# # pass
|
97
|
-
# else
|
98
|
-
# if original_feature_matrix.implemented? service_name, sdk
|
99
|
-
# pending
|
100
|
-
# else
|
101
|
-
# fail
|
102
|
-
# end
|
103
|
-
# end
|
104
|
-
# end
|
105
|
-
# end
|
106
|
-
# end
|
107
|
-
# end
|
108
|
-
# end
|
109
|
-
# end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
data = YAML::load(File.read('pacto/rackspace_uri_map.yaml'))
|
5
|
-
data['services'].each do |service_group_name, service_group|
|
6
|
-
describe service_group_name do
|
7
|
-
services = service_group['services'] || []
|
8
|
-
services.each do |service_name, service|
|
9
|
-
code_sample service_name, '', standard_env_vars, [] do
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Polytrix
|
2
|
-
class ChallengeBuilder
|
3
|
-
include Polytrix::Core::FileFinder
|
4
|
-
|
5
|
-
def initialize(implementor)
|
6
|
-
@implementor = implementor
|
7
|
-
end
|
8
|
-
|
9
|
-
def build(challenge_data)
|
10
|
-
challenge_data[:source_file] ||= find_file @implementor.basedir, challenge_data[:name]
|
11
|
-
challenge_data[:basedir] ||= @implementor.basedir
|
12
|
-
challenge_data[:implementor] ||= @implementor.name
|
13
|
-
Challenge.new challenge_data
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|