Rails Rspec tests failing on Github Action - ruby-on-rails

I have the following Github Action to run my tests for my Rails app (Rails 6.1.4, Ruby 3.1.3):
name: Ruby CI 💣
on:
push:
branches: [ develop, staging, master ]
pull_request:
branches: [ develop, staging, master ]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports: ['5432:5432']
options:
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout#v3
- name: Setup Ruby
uses: ruby/setup-ruby#v1
with:
bundler-cache: true
- name: Build and run test
env:
DATABASE_URL: postgres://postgres:#localhost:5432/test
RAILS_ENV: test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
PIPE_ENV: development
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
run: |
sudo apt-get -yqq install libpq-dev
gem install bundler:1.17.3
bundle install --jobs 4 --retry 3
bundle exec rails db:drop RAILS_ENV=test
bundle exec rails db:create RAILS_ENV=test
bundle exec rails db:migrate RAILS_ENV=test
bundle exec rake RAILS_ENV=test
The action seems to be working fine. The thing is that all my tests pass locally but some of them break on Github:
1) CashFlow cash_flow#index returns 200
Failure/Error: raise ParamsValidationError, errors.full_messages
ParamsValidationError:
missing_params
# ./app/forms/transactions/sale_create_form.rb:52:in `save'
# ./spec/requests/v1/cash_flow_spec.rb:42:in `block (3 levels) in <main>'
All of my tests that have an inclusion validation fails. But if I print the received value vs the expected value right inside the class, they match! No typos, no mistakes, nothing on my side.
module Transactions
class SaleCreateForm
include ActiveModel::Model
attr_accessor :organization,
:transaction,
:contact_id,
:products,
:amount,
:discount,
:concept,
:payment_type,
:payment_method,
:transaction_status,
:transaction_origin,
:transaction_category_id,
:pay_at,
:created_at
validates :payment_type, :payment_method, presence: true
validates :payment_type, inclusion: {
in: PaymentType.pluck(:slug),
message: :payment_type_error
}
validates :payment_method, inclusion: {
in: PaymentMethod.pluck(:slug),
message: :payment_method_error
}
...
This is what I got inside the method that executes the validation:
if invalid?
p PaymentType.pluck(:slug)
-> ["in-cash", "credit"]
p PaymentMethod.pluck(:slug)
-> ["cash", "on-credit", "card", "other", "bank"]
p #payment_type
-> "in-cash"
p #payment_method
-> "cash"
p errors.full_messages
-> ["Payment type in-cash is not a valid payment type", "Payment method cash is not a
valid payment method"]
end
All the values I pass on the test are the expected ones, and they pass locally on my machine. I also get errors for my webmock stubs that I don't get locally:
expected no Exception, got #<WebMock::NetConnectNotAllowedError: Real HTTP connections are disabled. Unregistered request: POST ...-7032-4fc2-b924-be77e5056b65", nil]]
Any hint on what I can do to solve this is appreciated.

Related

Why are my rails test all passing on my computer, but some aren't passing in my Github action?

I have been trying to create a Github Action where it runs my rails test as I push to my main branch. I run rails test on my terminal, and all of the tests passed, but when I try to run the tests in my main.yml file in my workflow on github, it fails only 2 tests, both relating to deleting an object with a relationship with another object (with a foreign key).
When I run my rails test through my terminal, this is my output
Running 74 tests in parallel using 2 processes
DEBUGGER: Attaching after process 42736 fork to child process 42753
DEBUGGER[bin/rails#42754]: Attaching after process 42736 fork to child process 42754
Started with run options --seed 10960
74/74: [=================================] 100% Time: 00:00:04, Time: 00:00:04
Finished in 5.09323s
74 tests, 135 assertions, 0 failures, 0 errors, 0 skips
When I push to my main branch on Github, this is my output for the tests
Running 74 tests in parallel using 2 processes
DEBUGGER: Attaching after process 3336 fork to child process 3357
DEBUGGER[bin/rails#3359]: Attaching after process 3336 fork to child process 3359
Started with run options --seed 27863
Progress: |=========ERROR ReviewsControllerTest#test_should_destroy_review (3.88s)
Minitest::UnexpectedError: DRb::DRbRemoteError: PG::ForeignKeyViolation: ERROR: update or delete on table "reviews" violates foreign key constraint "fk_rails_7314ea0830" on table "restaurants"
DETAIL: Key (id)=(1) is still referenced from table "restaurants".
(ActiveRecord::InvalidForeignKey)
app/controllers/reviews_controller.rb:52:in `destroy'
test/controllers/reviews_controller_test.rb:43:in `block (2 levels) in <class:ReviewsControllerTest>'
test/controllers/reviews_controller_test.rb:42:in `block in <class:ReviewsControllerTest>'
=========ERROR HalalItemsControllerTest#test_should_destroy_halal_item (4.09s)
Minitest::UnexpectedError: DRb::DRbRemoteError: PG::ForeignKeyViolation: ERROR: update or delete on table "halal_items" violates foreign key constraint "fk_rails_0fa9986d41" on table "restaurants"
DETAIL: Key (id)=(1) is still referenced from table "restaurants".
(ActiveRecord::InvalidForeignKey)
app/controllers/halal_items_controller.rb:52:in `destroy'
test/controllers/halal_items_controller_test.rb:43:in `block (2 levels) in <class:HalalItemsControllerTest>'
test/controllers/halal_items_controller_test.rb:42:in `block in <class:HalalItemsControllerTest>'
==================================================|
Finished in 5.04433s
74 tests, 131 assertions, 0 failures, 2 errors, 0 skips
Here is what my main.yml looks like
name: Ruby
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:12
ports: ['5432:5432']
env:
POSTGRES_DB: **redacted**
POSTGRES_PASSWORD: **redacted**
POSTGRES_USER: **redacted**
steps:
- name: Checkout repo
uses: actions/checkout#main
- name: Setup Ruby
uses: ruby/setup-ruby#v1
- name: Install dependencies
run: |
sudo apt-get -yqq install libpq-dev
gem install bundler
- name: Install gems
run: |
bundle install --jobs 4 --retry 3
- name: Setup database
env:
DATABASE_URL: **redacted**
RAILS_ENV: test
DISABLE_SPRING: 1
run: bundle exec rails db:prepare
- name: Run tests
env:
DATABASE_URL: **redacted**
RAILS_ENV: test
DISABLE_SPRING: 1
run: bundle exec rails test
Here are the models for the reviews, halal items, and restaurants (some of the relations are not relevant for this question)
app/models/review.rb
class Review < ApplicationRecord
belongs_to :restaurant
belongs_to :user
belongs_to :halal_item
end
app/models/halal_items.rb
class HalalItem < ApplicationRecord
belongs_to :restaurant
has_many :reviews, dependent: :nullify
end
app/models/restaurants.rb
class Restaurant < ApplicationRecord
has_many :reviews, dependent: :nullify
has_many :halal_items, dependent: :nullify
end
Here are the tests that are failing in my Github action, but not locally (with the associated controller)
/test/controllers/halal_items_controller_test.rb
test "should destroy halal_item" do
assert_difference("HalalItem.count", -1) do
delete halal_item_url(#halal_item)
end
assert_redirected_to halal_items_url
end
/app/controllers/halal_items_controller.rb
def destroy
#halal_item.destroy # this was line that the test was failing on
respond_to do |format|
format.html { redirect_to halal_items_url, notice: "Halal item was successfully destroyed." }
format.json { head :no_content }
end
end
/test/controllers/reviews_controller_test.rb
test "should destroy review" do
assert_difference("Review.count", -1) do
delete review_url(#review)
end
assert_redirected_to reviews_url
end
/app/controllers/reviews_controller.rb
def destroy
#review.destroy # this was line that the test was failing on
respond_to do |format|
format.html { redirect_to reviews_url, notice: "Review was successfully destroyed." }
format.json { head :no_content }
end
end

PG: Operation timed out Is the server running on that host and accepting TCP/IP connections?

I have a rails app with docker setup. I have two containers and i have verified they are on the same network but still i am getting error
PG::ConnectionBad: connection to server at "192.168.160.2", port 5432 failed: Operation timed out Is the server running on that host and accepting TCP/IP connections?
I have changed network too, also removed all images and volumes but still no luck.
Everything was working fine until I composed down the containers and when i tried to run again make setup command i started facing the issue.
Here is my docker-compose.yml
x-toolbox-environment: &toolbox-environment
- PROJECT=frameworq
- APPLICATION=portal
- AWS_REGION
- AWS_DEFAULT_REGION
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN
- AWS_SECURITY_TOKEN
- AWS_SESSION_EXPIRATION
x-web-volumes: &web-volumes
- .:/app:cached
- bundle_cache:/usr/local/bundle
- rails_cache:/app/tmp/cache:cached
- public_cache:/app/public:cached
x-web-environment: &web-environment
- RAILS_PORT=4000
- MAILER_FROM=noreply#frameworq.com
- APP_DOMAIN=lvh.me
services:
web:
build: .
volumes: *web-volumes
ports:
- '4000:4000'
- '3035:3035'
environment: *web-environment
command: bash -c "bundle exec foreman s"
links:
- db
db:
image: postgres:12
ports:
- 5432:5432
volumes:
- postgres:/var/lib/postgresql:cached
environment:
POSTGRES_HOST_AUTH_METHOD: trust
toolbox:
image: partos/ecs_toolbox:latest
environment: *toolbox-environment
volumes:
- .:/app:cached
- /var/run/docker.sock:/var/run/docker.sock
- .aws:/root/.aws
remote:
build: ./docker/remote
environment: *toolbox-environment
entrypoint: ""
volumes:
- ./docker/remote:/app:cached
- .aws:/root/.aws
volumes:
bundle_cache:
rails_cache:
postgres:
public_cache:
localstack_data:
driver: local
database.yml
# # SQL Server (2012 or higher required)
# #
# # Install the adapters and driver
# # gem install tiny_tds
# # gem install activerecord-sqlserver-adapter
# #
# # Ensure the activerecord adapter and db driver gems are defined in your Gemfile
# # gem 'tiny_tds'
# # gem 'activerecord-sqlserver-adapter'
# #
# default: &default
# adapter: sqlserver
# encoding: utf8
# azure: false
# mode: dblib
# host: localhost
# username: sa
# password: this-is-the-kms-test-database-p2ssw0rd
# azure: &azure
# adapter: sqlserver
# encoding: utf8
# azure: true
# mode: dblib
# host: <%= Rails.application.credentials.database_host %>
# username: <%= Rails.application.credentials.database_user %>
# password: <%= Rails.application.credentials.database_password %>
# #----------
# development:
# <<: *default
# database: kmsDev
# legacy:
# <<: *azure
# database: kmsprod
# # Warning: The database defined as "test" will be erased and
# # re-generated from your development database when you run "rake".
# # Do not set this db to the same as development or production.
# test:
# <<: *default
# database: kmsTest
# production:
# <<: *azure
# database: <%= ENV['DATABASE_NAME'] %>
default: &default
adapter: postgresql
encoding: unicode
host: <%= ENV["DB_HOST"] %>
database: <%= ENV["DB_NAME"] %>
username: <%= ENV["DB_USERNAME"] %>
password: <%= ENV["DB_PASSWORD"] %>
port: <%= ENV["DB_PORT"] %>
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
host: <%= ENV.fetch("PGHOST") { 'db' } %>
database: <%= ENV.fetch("POSTGRES_DB") { 'frameworq_development' } %>
username: <%= ENV.fetch("POSTGRES_USER") { 'postgres' } %>
password: <%= ENV.fetch("POSTGRES_PASSWORD") { '' } %>
port: <%= ENV.fetch("PGPORT") { 5432 } %>
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: frameworq_test
host: <%= ENV.fetch("PGHOST") { 'db' } %>
database: <%= ENV.fetch("POSTGRES_DB") { 'frameworq_test' } %>
username: <%= ENV.fetch("POSTGRES_USER") { 'postgres' } %>
password: <%= ENV.fetch("POSTGRES_PASSWORD") { '' } %>
port: <%= ENV.fetch("PGPORT") { 5432 } %>
qa:
<<: *default
staging:
<<: *default
production:
<<: *default
Dockerfile
FROM ruby:3.0.4-alpine
RUN apk --update add --no-cache build-base bash git vim curl postgresql-dev openssl-dev nodejs npm yarn tzdata less \
imagemagick postgresql-client gcompat chromium chromium-chromedriver
RUN mkdir /app
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle update --bundler
RUN bundle install --jobs 5
ADD . /app
RUN yarn install
RUN RAILS_SECRET_KEY_BASE=secret_key_base RAILS_ENV=production bundle exec rails assets:precompile apipie:cache
EXPOSE 5000
VOLUME ["/app/public", "/usr/local/bundle"]
CMD bash -c "bundle exec puma -C config/puma.rb"
Makefile
# DEVELOPMENT TARGETS
setup: destroy_shell build_shell prepare_shell up
destroy_shell:
docker-compose down -v
build_shell:
docker-compose build
prepare_shell:
docker-compose run --rm web bash -c "make prepare"
up:
docker-compose run --rm --service-ports --use-aliases web
shell:
docker-compose run --rm web bash
toolbox:
docker-compose run --rm toolbox bash
prepare_bundle:
bundle -j 4
yarn
prepare_db_first_time:
bundle exec rails db:create db:schema:load
prepare_db:
bundle exec rails db:migrate:with_data
prepare_test_db:
bundle exec rails db:create db:schema:load
prepare: prepare_bundle prepare_db_first_time
check: test_web fix_lint_web lint_front
lint_web:
bundle exec rubocop
fix_lint_web:
bundle exec rubocop -A
test_web:
RAILS_ENV=test bundle exec rails assets:precompile && bundle exec rails test
test_compiled_web:
RAILS_ENV=test bundle exec rails test
prepare_test_assets:
# We're not using webpacker now, importmaps instead
# cp -R public/packs public/packs-test
RAILS_ENV=test bundle exec rails assets:precompile
test_web_with_db: prepare_test_assets prepare_test_db test_compiled_web
lint_front:
# We're using importmaps, not yarn now
# yarn install && yarn run eslint --fix app/javascript/
generate_ts_routes:
docker-compose run --rm web bash -c 'bundle exec rails ts:routes'
db-reset:
bundle exec rails db:drop
bundle exec rails db:create
bundle exec rails db:schema:load
bundle exec rails db:migrate
bundle exec rails db:seed
eslint:
# We're using importmaps, not yarn now
# NODE_ENV=development yarn install
# yarn eslint --ext .js --ext .jsx /app/app/javascript/
tailwind:
docker-compose run --rm web bash -c 'bin/rails tailwindcss:watch'
guard:
docker-compose run --rm web bash -c 'bundle exec guard'
console:
docker-compose run --rm web bash -c 'rails c'
taildev:
docker-compose run --rm web bash -c 'tail -f log/development.log'
tailstaging:
docker-compose run --rm web bash -c 'tail -f log/staging.log'

EC2 backend docker run issues after ssh into instance

Im attempting to bring up the backend on this Ruby on Rails app using docker but am getting the following error after I try to run the following commands on my ssh'd ec2 instance.
[ec2-user#ip-10-10-3-155 ~]$ docker run --rm \
>-it --name *****-db-setup \
>839014*****.dkr.ecr.us-east-1.amazonaws.com/*****-backend:dev-latest \
>bundle exec rake db:drop db:create db:migrate
rake aborted!
PG::ConnectionBad: could not translate host name "db"
to address: Name or service not known
/usr/local/bundle/gems/pg-0.21.0/lib/pg.rb:56:in `initialize'
/usr/local/bundle/gems/pg-0.21.0/lib/pg.rb:56:in `new'
/usr/local/bundle/gems/pg-0.21.0/lib/pg.rb:56:in `connect'
/usr/local/bundle/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:695:in
`connect'
/usr/local/bundle/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:220:in
`initialize'
/usr/local/bundle/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:38:in `new'
/usr/local/bundle/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:38:in `postgresql_connection' /myapp/app/models/admin.rb:7:in `include'
/myapp/app/models/admin.rb:7:in `<class:Admin>'
/myapp/app/models/admin.rb:3:in `<top (required)>'
/usr/local/bundle/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:476:in
`load' .......Tasks: TOP => db:drop =>
db:check_protected_environments => environment
this is my env file I created
$ export AWS_ACCESS_KEY_ID=***********
$ export AWS_SECRET_ACCESS_KEY=***************************
$ export AWS_DEFAULT_REGION=us-east-1
$ export DB_USER=*****
$ export DB_PASS=****test1
$ export DB_NAME=*****_backend
$ export DB_HOST=tf-*****-backend-2021051***********.c8o12l*****.us-east-1.rds.amazonaws.com
$ export DB_PORT=5432
Docker-compose.yml
version: '3'
services:
db:
image: postgres
backend:
build: backend
# https://stackoverflow.com/a/38732187/42559
entrypoint: /myapp/entrypoint.sh
command: bundle exec unicorn -p 3001
volumes:
- ./backend/:/myapp
ports:
- "3001:3001"
depends_on:
- db
env_file:
- ./.env
frontend:
build: frontend
command: yarn server
volumes:
- ./frontend/:/app
- /app/node_modules
ports:
- "3000:3000"
depends_on:
- backend
This is the Database.yml
default: &default
adapter: postgresql
encoding: unicode
host: <%= ENV.fetch("DB_HOST") { "db" } %>
username: <%= ENV.fetch("DB_USER") { "postgres" } %>
port: <%= ENV["DB_PORT"] %>
password: <%= ENV["DB_PASS"] %>
# For details on connection pooling, see Rails configuration guide
# http://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: backend_development
test:
<<: *default
database: backend_test
production:
<<: *default
database: <%= ENV["DB_NAME"] %>
From my observations and attempts I believe it due to how the Docker-compose.yml and env file are interacting or something with my ruby server. I already have the backend image in the EC2 instance repository, now im trying to convert it to a container and bring up the backend. Thanks for any insight provided in advance !

Codeship doesn't work with Rails multiverse gem

locally all tests are passing but I cannot get rspec to run on Codeship:
Script:
bundle exec rake db:drop db:create db:migrate
DB=catalog bundle exec rake db:drop db:create db:migrate
DB=catalog bundle exec rails db:test:prepare
bundle exec rspec
Codeship error:
Failure/Error: establish_connection :"catalog_#{Rails.env}"
ActiveRecord::AdapterNotSpecified:
'catalog_test' database is not configured. Available: ["development", "test"]
ActiveRecord::ConnectionNotEstablished:
No connection pool with 'CatalogRecord' found.
database.yml:
.
.
.
catalog_development:
<<: *default
database: catalog_development
catalog_test:
<<: *default
database: catalog_test
CatalogRecord
class CatalogRecord < ActiveRecord::Base
self.abstract_class = true
establish_connection :"catalog_#{Rails.env}"
end
Rails projects on CodeShip Basic will have their database.yml file overwritten in order to connect to default databases. I would check out the linked documentation on re-asserting your own database.yml variant.

Configuration Issue with rails gem nkallen-cache-money (0.2.5): Get RecordNotFound exception on find method

I installed nkallen's cache-money gem per the github readme. I run into RecordNotFound exceptions during my tests. If I comment out the contents of config/initializers/cache-money.rb, the tests run fine. My cache-money.rb file is identical to that on the github instructions.
Here is the contents of my config/memcached.yml:
development:
ttl: 604800
namespace: cache-#{RAILS_ENV}
sessions: false
debug: true
servers: localhost:11211
test:
ttl: 604800
namespace: cache-#{RAILS_ENV}
sessions: false
debug: true
servers: localhost:11211
production:
ttl: 604800
namespace: cache-#{RAILS_ENV}
sessions: false
debug: false
servers: localhost:11211
I can't find any other documentation on how to configuration or install cache-money. I'd appreciate any insight or help to debugging this. Thanks in advance!
I put my cache-money config into /config/initializers/cache_money.rb:
if RAILS_ENV != 'development'
require 'cache_money'
config = YAML.load(IO.read(File.join(RAILS_ROOT, "config", "memcached.yml")))[RAILS_ENV]
$memcache = MemCache.new(config)
$memcache.servers = config['servers']
$local = Cash::Local.new($memcache)
$lock = Cash::Lock.new($memcache)
$cache = Cash::Transactional.new($local, $lock)
class ActiveRecord::Base
is_cached :repository => $cache
end
else
# If we're in development mode, we don't want to
# deal with cacheing oddities, so let's overrite
# cache-money's #index method to do nothing...
class ActiveRecord::Base
def self.index(*args)
end
end
end
No other setup was necessary. This works great for me.

Resources