Chefspec unit-testing - unit-testing

I'm no developer and a newbie with Chef.
I created a simple recipe and tested it on a test Kitchen and it works well but when I upload it to Jenkins it won't pass.
Can you help me point out what I'm missing?
Recipe:
# Recipe:: default
# Download VerneMQ
remote_file "#{Chef::Config[:file_cache_path]}/vernemq_1.4.0-1_amd64.deb" do
source 'https://bintray.com/artifact/download/erlio/vernemq/deb/trusty/vernemq_1.4.0-1_amd64.deb'
end
# Install
dpkg_package 'vernemq_1.4.0-1_amd64.deb' do
source "#{Chef::Config[:file_cache_path]}/vernemq_1.4.0-1_amd64.deb"
action :install
end
# Service Start
service 'vernemq' do
action [:enable, :start]
end
# Configurations
template '/etc/vernemq/vernemq.conf' do
source 'vernemq.conf.erb'
owner 'root'
group 'root'
mode '0644'
end
template '/etc/vernemq/vmq.passwd' do
source 'vmq.passwd.erb'
end
This is my unit test.
Unit Test:
require 'spec_helper'
require 'chefspec'
describe 'vernemq::default' do
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04').converge(described_recipe) }
it 'downloads the remote_file' do
expect(chef_run).to create_remote_file('#{Chef::Config[:file_cache_path]}/vernemq_1.4.0-1_amd64.deb')
end
it 'installs a dpkg_package' do
expect(chef_run).to install_dpkg_package('vernemq')
end
it 'executes both actions' do
expect(chef_run).to enable_service('vernemq')
expect(chef_run).to start_service('vernemq')
end
it 'creates a file' do
expect(chef_run).to create_directory('/etc/vernemq/vernemq.conf')
end
it 'creates a file' do
expect(chef_run).to create_directory('/etc/vernemq/vmq.passwd')
end
end
errors from Jenkins
01:06:57 tm_vernemq::default
01:06:58 [2018-07-19T01:06:58-07:00] WARN: Chef::Provider::AptRepository already exists! Cannot create deprecation class for LWRP provider apt_repository from cookbook apt
01:06:58 [2018-07-19T01:06:58-07:00] WARN: Property sensitive of resource apt_repository overwrites an existing method. Please use a different property name. This will raise an exception in Chef 13. (CHEF-11)/tmp/d20180719-10648-933ma2/cookbooks/apt/resources/repository.rb:54:in class_from_file'.
01:06:58 Please see https://docs.chef.io/deprecations_property_name_collision.html for further details and information on how to correct this problem. at /opt/chefdk/embedded/lib/ruby/gems/2.3.0/gems/chef-12.19.36/lib/chef/event_dispatch/dispatcher.rb:43:incall'
01:06:58 [2018-07-19T01:06:58-07:00] WARN: AptRepository already exists! Deprecation class overwrites Custom resource apt_repository from cookbook apt
01:06:58 executes both actions
01:06:58 installs a dpkg_package (FAILED - 1)
01:06:58 creates a file (FAILED - 2)
01:06:58 creates a file (FAILED - 3)
01:06:58 downloads the remote_file (FAILED - 4)
01:06:58
01:06:58 Failures:
01:06:58
01:06:58 1) vernemq::default installs a dpkg_package
01:06:58 Failure/Error: expect(chef_run).to install_dpkg_package('vernemq')
01:06:58
01:06:58 expected "dpkg_package[vernemq]" with action :install to be in Chef run. Other dpkg_package resources:
01:06:58
01:06:58 dpkg_package[vernemq_1.4.0-1_amd64.deb]
01:06:58
01:06:58 # ./test/unit/recipes/default_spec.rb:18:in `block (2 levels) in <top (required)>'
01:06:58
01:06:58 2) tm_vernemq::default creates a file
01:06:58 Failure/Error: expect(chef_run).to create_directory('/etc/vernemq/vmq.passwd')
01:06:58
01:06:58 expected "directory[/etc/vernemq/vmq.passwd]" with action :create to be in Chef run. Other directory resources:
01:06:58

You didn't include the full error message so this is mostly a guess but you have dpkg_package 'vernemq_1.4.0-1_amd64.deb' do vs install_dpkg_package('vernemq'). Those need to have the same name in them.

Related

Require rest-client to module in Chef

I need to include res-client into my module in order to use RestClient::Resource.
I use the method in the module in a Chef recipe (ruby_block resource).
When my ruby_block resource tries to run the method in the module it output this error:
ERROR: cannot load such file -- rest-client
The following is my module residing in libraries folder:
module SecretServer
def fetch_token
payload = { :username => "***", :password => "***", :grant_type => "****"}
uri = ***
request = RestClient::Resource.new(uri, :verify_ssl => false)
post_request = request.post payload, :content_type => 'application/x-www-form-urlencoded'
token = JSON.parse(post_request)["access_token"]
return token
end
end
require 'rest-client'
Chef::Recipe.include(SecretServer)
Chef::Resource.include(SecretServer)
The following is the resource that calls the function in module:
ruby_block 'parse data' do
block do
res = fetch_token
puts res
end
end
This is just one of the several recipes in my cookbook. This recipe runs after the target node is almost ready and 'bundle install' has been run on the target node.
I also install rest-client in the target node. I tried each of following resource before my ruby_block resource:
chef_gem 'rest-client' do
action :install
end
gem_package 'rest-client' do
action :install
end
My question is how to include 'rest-client' and utilize it in Chef recipes?
Long ago, the HTTP clients lived together in harmony. Then everything changed when the JSON gem attacked. Only the Chef::HTTP was still to be included with Chef as all the other clients were under too much flux to include.
We don't include that gem anymore, so to use it, you would have to install it yourself either via a cookbook gem dependency or a chef_gem resource. But for simple stuff you can just use our Chef::HTTP::SimpleJSON client instead:
Chef::HTTP::SimpleJson.new(uri).post("", args)["access_token"]
Or something like that (specifics depend on if you must use form encoding or if the server also speaks JSON).

undefined method define_enum_for for RSpec::ExampleGroups

I am getting undefined define_enum_for method error after upgrading rails to 4.2.0 from 4.1.
Is there any fix for this?
Rails : 4.2.0
Ruby : ruby 2.1.5p273 (2014-11-13 revision 48405) [i686-linux]
1) Recording
Failure/Error:
should define_enum_for(:state).
with({
initial: 'initial',
running: 'running',
stopped: 'stopped'
})
NoMethodError:
undefined method `define_enum_for' for #<RSpec::ExampleGroups::Recording:0x99a0ea8>
shoulda-matchers#define_enum_for
specifying the test_framework :rspec for shoulda-matchers#configuration solved this problem.
shoulda-matchers#configuration
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :active_record
with.library :active_model
with.library :action_controller
end
end
Configuration Required
spec_helper.rb/rails_helper.rb configure block
type: metadata
spec_helper.rb/rails_helper.rb
I required the Shoulda::Matchers configuration in the spec_helper.rb (the application had not been migrated to rails_helper.rb - but rails_helper.rb is the place I would have put it if available):
# spec/spec_helper.rb
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails # same as :active_record + :active_model + :active_controller
end
end
Metadata
But, it also required the type: metadata before it worked:
This==============\/
describe User, type: :model do
it { should define_enum_for(:status) }
end

Capistrano 3.4 Deployment Problems

I have inherited a Rails project and I am unable to deploy it using the supplied instructions using Capistrano. I am not familiar with capistrano at all.
Whatever I try I always get the following error message
(Backtrace restricted to imported tasks)
cap aborted!
ArgumentError: wrong number of arguments (1 for 2)
Tasks: TOP => production
(See full trace by running task with --trace)
This includes
$ bundle exec cap -T
$ bundle exec cap production deploy
I am following the guide here https://github.com/capistrano/capistrano
I have starred out important info but here is the a copy of the config/deploy/staging.rb
role :app, %w{deploy#**.**.**.**:****}
role :web, %w{deploy#**.**.**.**:****}
role :db, %w{deploy#**.**.**.**:****}
set :branch, 'develop'
set :deploy_to, '/var/www/soreen.staged.ws'
set :ssh_options, {
keepalive: true,
keepalive_interval: 60 #seconds
}
and here is Capfile
# Load DSL and Setup Up Stages
require 'capistrano/setup'
# Includes default deployment tasks
require 'capistrano/deploy'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/migrations'
require 'capistrano/rails/assets'
require 'capistrano/rails/collection'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
and here is config/deploy.rb
# config valid only for current version of Capistrano
lock '3.4.0'
set :application, 'Soreen'
set :repo_url => "****************"
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.1.2'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=# {fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :rbenv_roles, :all # default value
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
execute :mkdir, '-p', "#{ release_path }/tmp"
execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
end
end
end
Please help !
You can get a backtrace for the error using the following:
bundle exec cap --backtrace -T
That will give you more information. Likely this is a syntax error in your configuration.

Rails 4, capistrano 3, delayed_job - can't find bin/delayed_job on one of the servers

When i deploy to pre server everything's woking fine. But if i try to deploy to staging server i get this error:
bundler: command not found: bin/delayed_job
file - config/deploy/staging.rb
set :rails_env, 'staging'
set :eager_load, :true
set :unicorn_rack_env, 'staging'
role :app, %w{deploy#x.x.x.x}
role :web, %w{deploy#x.x.x.x}
role :db, %w{deploy#x.x.x.x}
set :rvm_type, :auto # Defaults to: :auto
set :rvm_ruby_version, '2.1.2'
set :rails_env, 'staging'
set :eager_load, :true
role :app, %w{deploy#x.x.x.}
role :web, %w{deploy#x.x.x.}
role :db, %w{deploy#x.x.x.}
set :rvm_type, :auto # Defaults to: :auto
set :rvm_ruby_version, '2.1.2'
set :deploy_to, '/var/www/app'
server 'x.x.x', user: 'deploy', roles: %w{web app} , port: 222
set :unicorn_pid, ->{ "#{deploy_to}/shared/tmp/pids/unicorn.pid" }
set :scm, :git
set :ssh_options, { user: 'superman' }
set :keep_releases, 5
restart of delayed jobs -
namespace :delayed_job do
def args
fetch(:delayed_job_args, "")
end
def delayed_job_roles
fetch(:delayed_job_server_role, :app)
end
desc 'Stop the delayed_job process'
task :stop do
on roles(delayed_job_roles) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :'bin/delayed_job', :stop
end
end
end
end
desc 'Start the delayed_job process'
task :start do
on roles(delayed_job_roles) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :'bin/delayed_job', args, :start
end
end
end
end
desc 'Restart the delayed_job process'
task :restart do
on roles(delayed_job_roles) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :'bin/delayed_job', args, :restart
end
end
end
end
end
Could you please give me a hand in this issue ? Thanks in advance!
UPDATE 1
More info on this error :
lib/capistrano/tasks/delayed_job.rake:33 which is execute :bundle, :exec, :'bin/delayed_job', args, :restart
You should run once on destination server:
bundle exec rails generate delayed_job
This will generate delayed_job executable script in shared/bin
Check if you can see delayed_job on your staging server in #{deploy_to}/shared/bin/
If it's not there, copy it there from your project's bin folder.
In addition to operations in answer by Rider. Following will perform 'bundle exec rails generate delayed_job' on remote if bin/delayed_job is missing there. Put it in config/deploy.rb file.
namespace :delayed_job do
desc "Install Deployed Job executable if needed"
task :install do
on roles(delayed_job_roles) do |host|
within release_path do
# Only install if not already present
unless test("[ -f #{release_path}/#{delayed_job_bin} ]")
with rails_env: fetch(:rails_env) do
execute :bundle, :exec, :rails, :generate, :delayed_job
end
end
end
end
end
before :start, :install
before :restart, :install
end
This is happening because the delayed_job executable is missing on the server. It should exist in the bin directory. To fix this you should generate the executable on your development machine and check it in to source control.
This command will generate the executable for you:
bundle exec rails generate delayed_job
Its better to use Capistrano::DelayedJob Gem
Delayed Job support for Capistrano 3.x
Add this line to your application's Gemfile:
gem 'capistrano3-delayed-job', '~> 1.0'
Require in Capfile to use the default task:
require 'capistrano/delayed-job'
Add this to your deploy.rb file
after 'deploy:published', 'restart' do
invoke 'delayed_job:restart'
end
For more configurable options https://github.com/platanus/capistrano3-delayed-job
Please check if you setup your rails_env system variable correctly.

Chef, cannot find template

I am trying to use chef with aws opsworks.
however it doesn't seem to be loading my template.
Here is the part of the recipe concerned which is in /api/recipes/configure.rb
# write out our applications site configurations
template "/etc/httpd/sites-available/#{application}.conf" do
source 'site-config.erb'
owner 'root'
group 'root'
mode 0644
variables(
:docroot => "#{deploy[:deploy_to]}/public"
)
end
Here is the stack trace
[2014-04-15T05:08:03+00:00] INFO: Processing template[/etc/httpd/sites-available/testing_app.conf] action create (api::configure line 33)
================================================================================
Error executing action `create` on resource 'template[/etc/httpd/sites-available/testing_app.conf]'
================================================================================
Chef::Exceptions::FileNotFound
------------------------------
Cookbook 'api' (0.1.0) does not contain a file at any of these locations:
templates/amazon-2013.09/site-config.erb
templates/amazon/site-config.erb
templates/default/site-config.erb
Resource Declaration:
---------------------
# In /var/lib/aws/opsworks/cache/cookbooks/api/recipes/configure.rb
33: template "/etc/httpd/sites-available/#{application}.conf" do
34: source 'site-config.erb'
35: owner 'root'
36: group 'root'
37: mode 0644
38: variables(
39: :docroot => "#{deploy[:deploy_to]}/public"
40: )
41: end
42:
Compiled Resource:
------------------
# Declared in /var/lib/aws/opsworks/cache/cookbooks/api/recipes/configure.rb:33:in `block in from_file'
template("/etc/httpd/sites-available/testing_app.conf") do
provider Chef::Provider::Template
action "create"
retries 0
retry_delay 2
path "/etc/httpd/sites-available/testing_app.conf"
backup 5
atomic_update true
source "site-config.erb"
variables {:docroot=>"/srv/www/testing_app/public"}
cookbook_name "api"
recipe_name "configure"
owner "root"
group "root"
mode 420
end
[2014-04-15T05:08:03+00:00] INFO: Running queued delayed notifications before re-raising exception
[2014-04-15T05:08:03+00:00] ERROR: Running exception handlers
[2014-04-15T05:08:03+00:00] ERROR: Exception handlers complete
[2014-04-15T05:08:03+00:00] FATAL: Stacktrace dumped to /var/lib/aws/opsworks/cache/chef-stacktrace.out
[2014-04-15T05:08:03+00:00] ERROR: template[/etc/httpd/sites-available/testing_app.conf] (api::configure line 33) had an error: Chef::Exceptions::FileNotFound: Cookbook 'api' (0.1.0) does not contain a file at any of these locations:
templates/amazon-2013.09/site-config.erb
templates/amazon/site-config.erb
templates/default/site-config.erb
[2014-04-15T05:08:04+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
And here is my directory structure
You will need to put the template into one of the following directories api/templates/default api/templates/amazon or api/templates/amazon-2013.09. If you want the same template files to work on any platform, then put the templates in the api/templates/default directory.
Check out http://docs.chef.io/templates.html#file-specificity for more details on where you might want to place your templates.