From 5d000837f4db9a72c8ce43b24714aa475f351c71 Mon Sep 17 00:00:00 2001 From: Igor Rzegocki Date: Sat, 9 Apr 2016 21:03:55 +0200 Subject: [PATCH] Initial version, with simple postgresql driver introduced --- .gitignore | 16 +++ .kitchen.yml | 21 +++ .lvimrc | 16 +++ Berksfile | 3 + README.md | 4 + chefignore | 102 ++++++++++++++ libraries/all.rb | 3 + libraries/core_ext.rb | 43 ++++++ libraries/drivers/base.rb | 25 ++++ libraries/drivers/db/base.rb | 75 ++++++++++ libraries/drivers/db/factory.rb | 16 +++ libraries/drivers/db/postgresql.rb | 8 ++ libraries/drivers/dsl/base.rb | 21 +++ libraries/drivers/dsl/packages.rb | 35 +++++ metadata.rb | 10 ++ recipes/configure.rb | 4 + recipes/default.rb | 1 + recipes/deploy.rb | 0 spec/fixtures/aws_opsworks_app.rb | 40 ++++++ spec/fixtures/aws_opsworks_rds_db_instance.rb | 15 ++ spec/fixtures/node.rb | 18 +++ spec/spec_helper.rb | 10 ++ spec/unit/libraries/core_ext_spec.rb | 37 +++++ .../unit/libraries/drivers/db/factory_spec.rb | 20 +++ .../libraries/drivers/db/postgresql_spec.rb | 129 ++++++++++++++++++ .../libraries/drivers/dsl/packages_spec.rb | 39 ++++++ spec/unit/recipes/default_spec.rb | 20 +++ .../default/serverspec/default_spec.rb | 9 ++ .../helpers/serverspec/spec_helper.rb | 8 ++ 29 files changed, 748 insertions(+) create mode 100644 .gitignore create mode 100644 .kitchen.yml create mode 100644 .lvimrc create mode 100644 Berksfile create mode 100644 README.md create mode 100644 chefignore create mode 100644 libraries/all.rb create mode 100644 libraries/core_ext.rb create mode 100644 libraries/drivers/base.rb create mode 100644 libraries/drivers/db/base.rb create mode 100644 libraries/drivers/db/factory.rb create mode 100644 libraries/drivers/db/postgresql.rb create mode 100644 libraries/drivers/dsl/base.rb create mode 100644 libraries/drivers/dsl/packages.rb create mode 100644 metadata.rb create mode 100644 recipes/configure.rb create mode 100644 recipes/default.rb create mode 100644 recipes/deploy.rb create mode 100644 spec/fixtures/aws_opsworks_app.rb create mode 100644 spec/fixtures/aws_opsworks_rds_db_instance.rb create mode 100644 spec/fixtures/node.rb create mode 100644 spec/spec_helper.rb create mode 100644 spec/unit/libraries/core_ext_spec.rb create mode 100644 spec/unit/libraries/drivers/db/factory_spec.rb create mode 100644 spec/unit/libraries/drivers/db/postgresql_spec.rb create mode 100644 spec/unit/libraries/drivers/dsl/packages_spec.rb create mode 100644 spec/unit/recipes/default_spec.rb create mode 100644 test/integration/default/serverspec/default_spec.rb create mode 100644 test/integration/helpers/serverspec/spec_helper.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ec2a890b --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +.vagrant +Berksfile.lock +*~ +*# +.#* +\#*# +.*.sw[a-z] +*.un~ + +# Bundler +Gemfile.lock +bin/* +.bundle/* + +.kitchen/ +.kitchen.local.yml diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 00000000..6a64d398 --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,21 @@ +--- +driver: + name: vagrant + +provisioner: + name: chef_zero + +# Uncomment the following verifier to leverage Inspec instead of Busser (the +# default verifier) +# verifier: +# name: inspec + +platforms: + - name: ubuntu-14.04 + - name: centos-7.1 + +suites: + - name: default + run_list: + - recipe[opsworks_ruby::default] + attributes: diff --git a/.lvimrc b/.lvimrc new file mode 100644 index 00000000..a53befbd --- /dev/null +++ b/.lvimrc @@ -0,0 +1,16 @@ +let test#ruby#rspec#options = { + \ 'nearest': '--format documentation --color', + \ 'file': '--format documentation --color', + \ 'suite': '--format documentation --color', +\} +let test#ruby#rspec#executable = 'chef exec rspec' +let test#ruby#bundle_exec = 0 + +let g:projectionist_heuristics = { + \ "*.rb": { + \ "libraries/*.rb": { "alternate": "spec/unit/libraries/{}_spec.rb", "type": "source" }, + \ "recipes/*.rb": { "alternate": "spec/unit/recipes/{}_spec.rb", "type": "source" }, + \ "spec/unit/libraries/*_spec.rb": { "alternate": "libraries/{}.rb", "type": "spec" }, + \ "spec/unit/recipes/*_spec.rb": { "alternate": "recipes/{}.rb", "type": "spec" } + \ } +\ } diff --git a/Berksfile b/Berksfile new file mode 100644 index 00000000..34fea216 --- /dev/null +++ b/Berksfile @@ -0,0 +1,3 @@ +source 'https://supermarket.chef.io' + +metadata diff --git a/README.md b/README.md new file mode 100644 index 00000000..0336781d --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# opsworks_ruby + +TODO: Enter the cookbook description here. + diff --git a/chefignore b/chefignore new file mode 100644 index 00000000..a9769175 --- /dev/null +++ b/chefignore @@ -0,0 +1,102 @@ +# Put files/directories that should be ignored in this file when uploading +# to a chef-server or supermarket. +# Lines that start with '# ' are comments. + +# OS generated files # +###################### +.DS_Store +Icon? +nohup.out +ehthumbs.db +Thumbs.db + +# SASS # +######## +.sass-cache + +# EDITORS # +########### +\#* +.#* +*~ +*.sw[a-z] +*.bak +REVISION +TAGS* +tmtags +*_flymake.* +*_flymake +*.tmproj +.project +.settings +mkmf.log + +## COMPILED ## +############## +a.out +*.o +*.pyc +*.so +*.com +*.class +*.dll +*.exe +*/rdoc/ + +# Testing # +########### +.watchr +.rspec +spec/* +spec/fixtures/* +test/* +features/* +examples/* +Guardfile +Procfile +.kitchen* +.rubocop.yml +spec/* +Rakefile +.travis.yml +.foodcritic +.codeclimate.yml + +# SCM # +####### +.git +*/.git +.gitignore +.gitmodules +.gitconfig +.gitattributes +.svn +*/.bzr/* +*/.hg/* +*/.svn/* + +# Berkshelf # +############# +Berksfile +Berksfile.lock +cookbooks/* +tmp + +# Cookbooks # +############# +CONTRIBUTING* +CHANGELOG* +TESTING* +MAINTAINERS.toml + +# Strainer # +############ +Colanderfile +Strainerfile +.colander +.strainer + +# Vagrant # +########### +.vagrant +Vagrantfile diff --git a/libraries/all.rb b/libraries/all.rb new file mode 100644 index 00000000..e1611f69 --- /dev/null +++ b/libraries/all.rb @@ -0,0 +1,3 @@ +libdir = File.expand_path('..', __FILE__) +require File.join(libdir, 'core_ext') +Dir[File.join(libdir, '*', '**', '*.rb')].each { |f| require f } diff --git a/libraries/core_ext.rb b/libraries/core_ext.rb new file mode 100644 index 00000000..63c909a4 --- /dev/null +++ b/libraries/core_ext.rb @@ -0,0 +1,43 @@ +class Object + def try(*a, &b) + try!(*a, &b) if a.empty? || respond_to?(a.first) + end + + def try!(*a, &b) + if a.empty? && block_given? + if b.arity == 0 + instance_eval(&b) + else + yield self + end + else + public_send(*a, &b) + end + end + + def blank? + respond_to?(:empty?) ? !!empty? : !self + end + + def present? + !blank? + end + + def self.descendants + ObjectSpace.each_object(Class).select { |klass| klass < self } + end +end + +class String + def constantize + split('::').inject(Object) {|o,c| o.const_get c} + end + + def classify + gsub(/(?:^.|_.)/) { |s| s[-1].upcase } + end + + def underscore + gsub(/[A-Z]/) { |s| "_#{s.downcase}" }.sub(/^_/, '') + end +end diff --git a/libraries/drivers/base.rb b/libraries/drivers/base.rb new file mode 100644 index 00000000..01f625f5 --- /dev/null +++ b/libraries/drivers/base.rb @@ -0,0 +1,25 @@ +module Drivers + class Base + def initialize(app, node, options = {}) + @app = app + @node = node + @options = options + end + + # Dummy methods for children to redefine + def setup + end + + def configure + end + + def deploy + end + + def undeploy + end + + def shutdown + end + end +end diff --git a/libraries/drivers/db/base.rb b/libraries/drivers/db/base.rb new file mode 100644 index 00000000..92548cbb --- /dev/null +++ b/libraries/drivers/db/base.rb @@ -0,0 +1,75 @@ +module Drivers + module Db + class Base < Drivers::Base + attr_reader :app, :node, :options + + def initialize(app, node, options = {}) + super + raise ArgumentError, ':rds option is not set.' unless options[:rds] + @connection_data_source = validate_engine + end + + def out + deploy_db_data = JSON.parse(node['deploy'][app['shortname']]['database'].to_json, symbolize_names: true) || {} + if @connection_data_source == :adapter + return deploy_db_data.merge(adapter: adapter).merge( + database: deploy_db_data[:database] || app['data_sources'].first['database_name'] + ) + end + + deploy_db_data.merge( + adapter: adapter, + username: options[:rds]['db_user'], + password: options[:rds]['db_password'], + host: options[:rds]['address'], + database: app['data_sources'].first['database_name'] + ) + end + + protected + + def self.allowed_engines(*engines) + @allowed_engines = engines.map(&:to_s) if engines.present? + @allowed_engines || [] + end + + def self.adapter(adapter = nil) + @adapter = adapter if adapter.present? + (@adapter || self.class.name.underscore).to_s + end + + def allowed_engines + self.class.allowed_engines + end + + def adapter + self.class.adapter + end + + def validate_engine + rds_engine = options[:rds]['engine'] + + return validate_adapter if rds_engine.blank? + + unless allowed_engines.include?(rds_engine) + raise ArgumentError, "Incorrect :rds engine, expected #{allowed_engines.inspect}, got '#{rds_engine}'." + end + + :rds + end + + def validate_adapter + connection_data = node['deploy'][app['shortname']]['database'] + adapter_engine = connection_data.try(:[], 'adapter') + + raise ArgumentError, "Missing :rds engine, expected #{allowed_engines.inspect}." if adapter_engine.blank? + unless allowed_engines.include?(adapter_engine) + raise ArgumentError, + "Incorrect engine provided by adapter, expected #{allowed_engines.inspect}, got '#{adapter_engine}'." + end + + :adapter + end + end + end +end diff --git a/libraries/drivers/db/factory.rb b/libraries/drivers/db/factory.rb new file mode 100644 index 00000000..268fd838 --- /dev/null +++ b/libraries/drivers/db/factory.rb @@ -0,0 +1,16 @@ +module Drivers + module Db + class Factory + def self.build(app, node, options = {}) + raise ArgumentError, ':rds option is not set.' unless options[:rds] + engine = Drivers::Db::Base.descendants.detect do |db_driver| + db_driver.allowed_engines.include?( + options[:rds]['engine'] || node['deploy'][app['shortname']]['database']['adapter'] + ) + end + raise StandardError, 'There is no supported Db driver for given configuration.' if engine.blank? + engine.new(app, node, options) + end + end + end +end diff --git a/libraries/drivers/db/postgresql.rb b/libraries/drivers/db/postgresql.rb new file mode 100644 index 00000000..c546b445 --- /dev/null +++ b/libraries/drivers/db/postgresql.rb @@ -0,0 +1,8 @@ +module Drivers + module Db + class Postgresql < Base + adapter :postgresql + allowed_engines :postgres, :postgresql + end + end +end diff --git a/libraries/drivers/dsl/base.rb b/libraries/drivers/dsl/base.rb new file mode 100644 index 00000000..faae1021 --- /dev/null +++ b/libraries/drivers/dsl/base.rb @@ -0,0 +1,21 @@ +module Drivers + module Dsl + module Base + @@params = {} + + def self.included(klass) + klass.instance_eval do + def param(name, options = {}) + name = name.to_sym + @@params[name] = options[:default] + send(:define_method, name) do |*values| + @@params[name] = options[:default].is_a?(Array) ? values : values.first unless values.empty? + @@params[name] + end + end + end + end + end + end +end + diff --git a/libraries/drivers/dsl/packages.rb b/libraries/drivers/dsl/packages.rb new file mode 100644 index 00000000..39a8affd --- /dev/null +++ b/libraries/drivers/dsl/packages.rb @@ -0,0 +1,35 @@ +module Drivers + module Dsl + module Packages + include Drivers::Dsl::Base + + param :packages_default_action, default: 'install' + param :packages, default: [] + + def handle_packages + case packages + when Array + if multipackage_supported? + package packages do + action packages_default_action.to_sym + end + else + packages.each do |pkg| + package pkg do + action packages_default_action.to_sym + end + end + end + when Hash + packages.each do |pkg, act| + package pkg.to_s do + action act.to_sym + end + end + else + Chef::Log.warn('`packages` must be an Array or Hash.') + end + end + end + end +end diff --git a/metadata.rb b/metadata.rb new file mode 100644 index 00000000..95038eb7 --- /dev/null +++ b/metadata.rb @@ -0,0 +1,10 @@ +name 'opsworks_ruby' +maintainer 'The Authors' +maintainer_email 'you@example.com' +license 'MIT' +description 'Installs/Configures opsworks_ruby' +long_description 'Installs/Configures opsworks_ruby' +version '0.1.0' + +depends 'packages' + diff --git a/recipes/configure.rb b/recipes/configure.rb new file mode 100644 index 00000000..d99e9165 --- /dev/null +++ b/recipes/configure.rb @@ -0,0 +1,4 @@ +app = search(:aws_opsworks_app).first +rds = search(:aws_opsworks_rds_db_instance).first + +database = Drivers::Db::Factory.build(app, node, rds: rds) diff --git a/recipes/default.rb b/recipes/default.rb new file mode 100644 index 00000000..5a284604 --- /dev/null +++ b/recipes/default.rb @@ -0,0 +1 @@ +include_recipe 'opsworks_ruby::deploy' diff --git a/recipes/deploy.rb b/recipes/deploy.rb new file mode 100644 index 00000000..e69de29b diff --git a/spec/fixtures/aws_opsworks_app.rb b/spec/fixtures/aws_opsworks_app.rb new file mode 100644 index 00000000..bfa97eda --- /dev/null +++ b/spec/fixtures/aws_opsworks_app.rb @@ -0,0 +1,40 @@ +def aws_opsworks_app(override = {}) + item = { + app_id: '3aef37c1-7e2b-4255-bbf1-03e06f07701a', + app_source: { + password: '3aa161d358a167204502', + revision: 'master', + ssh_key: '--- SSH KEY ---', + type: 'git', + url: 'git@git.example.com:repo/project.git', + user: 'dummy' + }, + attributes: { + auto_bundle_on_deploy: true, + aws_flow_ruby_settings: {}, + document_root: 'dummy_project', + rails_env: nil + }, + data_sources: [ + { arn: 'arn:aws:rds:us-west-2:850906259207:db:dummy-project', type: 'RdsDbInstance', database_name: 'dummydb' } + ], + domains: [ 'dummy-project.example.com', 'dummy_project' ], + enable_ssl: true, + environment: { + 'ENV_VAR1' => 'test', + 'ENV_VAR2' => 'some data' + }, + name: 'Dummy app', + shortname: 'dummy_project', + ssl_configuration: { + certificate: '--- SSL CERTIFICATE ---', + private_key: '--- SSL PRICATE KEY ---', + chain: '--- SSL CERTIFICATE CHAIN ---', + }, + type: 'other', + deploy: true, + id: 'dummy_project' + }.merge(override) + + JSON.parse(item.to_json) +end diff --git a/spec/fixtures/aws_opsworks_rds_db_instance.rb b/spec/fixtures/aws_opsworks_rds_db_instance.rb new file mode 100644 index 00000000..2acd3811 --- /dev/null +++ b/spec/fixtures/aws_opsworks_rds_db_instance.rb @@ -0,0 +1,15 @@ +def aws_opsworks_rds_db_instance(override = {}) + item = { + rds_db_instance_arn: 'arn:aws:rds:us-west-2:850906259207:db:dummy-project', + db_instance_identifier: 'dummy-project', + db_user: 'dbuser', + db_password: '03c1bc98cdd5eb2f9c75', + region: 'us-west-2', + address: 'dummy-project.c298jfowejf.us-west-2.rds.amazon.com', + engine: 'postgres', + missing_on_rds: false, + id: 'arn_aws_rds_us-west-2_850906259207_db_dummy-project' + }.merge(override) + + JSON.parse(item.to_json) +end diff --git a/spec/fixtures/node.rb b/spec/fixtures/node.rb new file mode 100644 index 00000000..3c0e87ac --- /dev/null +++ b/spec/fixtures/node.rb @@ -0,0 +1,18 @@ +def node(override = {}) + item = { + deploy: { + dummy_project: { + database: { + adapter: 'postgresql', + username: 'dbuser', + password: '03c1bc98cdd5eb2f9c75', + host: 'dummy-project.c298jfowejf.us-west-2.rds.amazon.com', + database: 'dummydb', + reaping_frequency: 10 + } + } + } + }.merge(override) + + JSON.parse(item.to_json) +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..cee38476 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,10 @@ +require 'chefspec' +require 'chefspec/berkshelf' + +# Require all libraries +Dir['libraries/*.rb'].each { |f| require File.expand_path(f) } + +# Require all fixtures +Dir[File.expand_path('../fixtures/*.rb', __FILE__)].each { |f| require f } + +at_exit { ChefSpec::Coverage.report! } diff --git a/spec/unit/libraries/core_ext_spec.rb b/spec/unit/libraries/core_ext_spec.rb new file mode 100644 index 00000000..744d4c14 --- /dev/null +++ b/spec/unit/libraries/core_ext_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe 'Core extensions' do + context 'classify' do + it 'basic' do + expect('basic'.classify).to eq 'Basic' + end + + it 'basic_with_underscore' do + expect('basic_with_underscore'.classify).to eq 'BasicWithUnderscore' + end + + it 'Basic' do + expect('Basic'.classify).to eq 'Basic' + end + + it 'BasicWithCamelCase' do + expect('BasicWithCamelCase').to eq 'BasicWithCamelCase' + end + end + + context 'constantize' do + it 'String' do + expect('String'.constantize).to eq String + end + + it 'Drivers::Dsl::Basic' do + expect('Drivers::Dsl::Basic'.constantize).to eq Drivers::Dsl::Basic + end + end + + context 'underscore' do + it 'LoremIpsumDolorXSitAmet' do + expect('LoremIpsumDolorXSitAmet'.underscore).to eq 'lorem_ipsum_dolor_x_sit_amet' + end + end +end diff --git a/spec/unit/libraries/drivers/db/factory_spec.rb b/spec/unit/libraries/drivers/db/factory_spec.rb new file mode 100644 index 00000000..04775446 --- /dev/null +++ b/spec/unit/libraries/drivers/db/factory_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Drivers::Db::Factory do + it 'raises error when no rds is present' do + expect do + described_class.build(aws_opsworks_app, node, dummy_option: true) + end.to raise_error ArgumentError, ':rds option is not set.' + end + + it 'raises error when unknown engine is present' do + expect do + described_class.build(aws_opsworks_app, node, rds: { 'engine' => 'unknown' }) + end.to raise_error StandardError, 'There is no supported Db driver for given configuration.' + end + + it 'returns a Postgresql class' do + db = described_class.build(aws_opsworks_app, node, rds: aws_opsworks_rds_db_instance) + expect(db).to be_instance_of(Drivers::Db::Postgresql) + end +end diff --git a/spec/unit/libraries/drivers/db/postgresql_spec.rb b/spec/unit/libraries/drivers/db/postgresql_spec.rb new file mode 100644 index 00000000..5b7858d0 --- /dev/null +++ b/spec/unit/libraries/drivers/db/postgresql_spec.rb @@ -0,0 +1,129 @@ +require 'spec_helper' + +describe Drivers::Db::Postgresql do + it 'receives and exposes app, node and database bag' do + driver = described_class.new(aws_opsworks_app, node, rds: aws_opsworks_rds_db_instance) + + expect(driver.app).to eq aws_opsworks_app + expect(driver.node).to eq node + expect(driver.options[:rds]).to eq aws_opsworks_rds_db_instance + end + + it 'raises error when no rds is present' do + expect do + described_class.new(aws_opsworks_app, node, dummy_option: true) + end.to raise_error ArgumentError, ':rds option is not set.' + end + + context 'validate adapter and engine' do + it 'adapter = missing, engine = missing' do + expect do + described_class.new( + aws_opsworks_app, node(deploy: { dummy_project: {} }), rds: aws_opsworks_rds_db_instance(engine: nil) + ) + end.to raise_error ArgumentError, "Missing :rds engine, expected #{described_class.allowed_engines.inspect}." + end + + it 'adapter = missing, engine = wrong' do + expect do + described_class.new( + aws_opsworks_app, node(deploy: { dummy_project: {} }), rds: aws_opsworks_rds_db_instance(engine: 'mysql') + ) + end.to raise_error ArgumentError, + "Incorrect :rds engine, expected #{described_class.allowed_engines.inspect}, got 'mysql'." + end + + it 'adapter = missing, engine = correct' do + expect do + described_class.new( + aws_opsworks_app, node(deploy: { dummy_project: {} }), rds: aws_opsworks_rds_db_instance + ) + end.not_to raise_error + end + + it 'adapter = wrong, engine = missing' do + expect do + described_class.new( + aws_opsworks_app, + node(deploy: { dummy_project: { database: { adapter: 'mysql' } } }), + rds: aws_opsworks_rds_db_instance(engine: nil) + ) + end.to raise_error ArgumentError, + "Incorrect engine provided by adapter, expected #{described_class.allowed_engines.inspect}," \ + ' got \'mysql\'.' + end + + it 'adapter = wrong, engine = wrong' do + expect do + described_class.new( + aws_opsworks_app, + node(deploy: { dummy_project: { database: { adapter: 'mysql' } } }), + rds: aws_opsworks_rds_db_instance(engine: 'mysql') + ) + end.to raise_error ArgumentError, + "Incorrect :rds engine, expected #{described_class.allowed_engines.inspect}, got 'mysql'." + end + + it 'adapter = wrong, engine = correct' do + expect do + described_class.new( + aws_opsworks_app, + node(deploy: { dummy_project: { database: { adapter: 'mysql' } } }), + rds: aws_opsworks_rds_db_instance + ) + end.not_to raise_error + end + + it 'adapter = correct, engine = missing' do + expect do + described_class.new( + aws_opsworks_app, + node(deploy: { dummy_project: { database: { adapter: 'postgresql' } } }), + rds: aws_opsworks_rds_db_instance + ) + end.not_to raise_error + end + + it 'adapter = correct, engine = wrong' do + expect do + described_class.new( + aws_opsworks_app, + node(deploy: { dummy_project: { database: { adapter: 'postgresql' } } }), + rds: aws_opsworks_rds_db_instance(engine: 'mysql') + ) + end.to raise_error ArgumentError, + "Incorrect :rds engine, expected #{described_class.allowed_engines.inspect}, got 'mysql'." + end + + it 'adapter = correct, engine = correct' do + expect do + described_class.new( + aws_opsworks_app, + node(deploy: { dummy_project: { database: { adapter: 'postgresql' } } }), + rds: aws_opsworks_rds_db_instance + ) + end.not_to raise_error + end + end + + context 'connection data' do + after(:each) do + expect(@item.out).to eq( + adapter: 'postgresql', + username: 'dbuser', + password: '03c1bc98cdd5eb2f9c75', + host: 'dummy-project.c298jfowejf.us-west-2.rds.amazon.com', + database: 'dummydb', + reaping_frequency: 10 + ) + end + + it 'taken from engine' do + @item = described_class.new(aws_opsworks_app, node, rds: aws_opsworks_rds_db_instance) + end + + it 'taken from adapter' do + @item = described_class.new(aws_opsworks_app, node, rds: aws_opsworks_rds_db_instance(engine: nil)) + end + end +end diff --git a/spec/unit/libraries/drivers/dsl/packages_spec.rb b/spec/unit/libraries/drivers/dsl/packages_spec.rb new file mode 100644 index 00000000..c0379906 --- /dev/null +++ b/spec/unit/libraries/drivers/dsl/packages_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe Drivers::Dsl::Packages do + include described_class + + context 'parameters' do + it 'returns the default action' do + expect(packages_default_action).to eq 'install' + end + + it 'sets the default action' do + packages_default_action 'update' + + expect(packages_default_action).to eq 'update' + + packages_default_action 'install' + end + + it 'returns default packages' do + expect(packages).to eq [] + end + + it 'sets packages' do + packages 'ruby' + + expect(packages).to eq ['ruby'] + + packages [] + end + end + + context '#handle_packages' do + it 'install' do + packages 'wget', 'curl' + + handle_packages + end + end +end diff --git a/spec/unit/recipes/default_spec.rb b/spec/unit/recipes/default_spec.rb new file mode 100644 index 00000000..2610e0fe --- /dev/null +++ b/spec/unit/recipes/default_spec.rb @@ -0,0 +1,20 @@ +# +# Cookbook Name:: opsworks_ruby +# Spec:: default +# +# Copyright (c) 2016 The Authors, All Rights Reserved. + +require 'spec_helper' + +describe 'opsworks_ruby::default' do + context 'When all attributes are default, on an unspecified platform' do + let(:chef_run) do + runner = ChefSpec::ServerRunner.new + runner.converge(described_recipe) + end + + it 'converges successfully' do + expect { chef_run }.to_not raise_error + end + end +end diff --git a/test/integration/default/serverspec/default_spec.rb b/test/integration/default/serverspec/default_spec.rb new file mode 100644 index 00000000..08972e33 --- /dev/null +++ b/test/integration/default/serverspec/default_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe 'opsworks_ruby::default' do + # Serverspec examples can be found at + # http://serverspec.org/resource_types.html + it 'does something' do + skip 'Replace this with meaningful tests' + end +end diff --git a/test/integration/helpers/serverspec/spec_helper.rb b/test/integration/helpers/serverspec/spec_helper.rb new file mode 100644 index 00000000..c1fddf06 --- /dev/null +++ b/test/integration/helpers/serverspec/spec_helper.rb @@ -0,0 +1,8 @@ +require 'serverspec' + +if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil? + set :backend, :exec +else + set :backend, :cmd + set :os, family: 'windows' +end