This one has me baffled a bit.
Brand new Rails 6.1.3, Ruby 2.7.0 application with Rspec and database_cleaner
After setting up the application and Rspec, I just created a quick unit test for the User model and then one quick request test to check the default root page.
The first issue I ran into was my request test failing. Instead of displaying the root page which simply has an h1 tag with Home inside of it, the request was returning an error message about www.example.com being a blocked host and to add example.com as into config.hosts
This is the very first time I encountered that and I have another application I created not so long ago with Rails 6.1 and Ruby 2.6.4 and essentially the same configuration but never had this blocked host issue show up.
So I went and added example.com to config.hosts in my test.rb environment. Same issue. I went and added it into development.rb environment file and it passed. This should have been my first red flag.
After toying with my application in development mode and testing the user sign up, adding, deleting users. I ran my test suite again and then found out all the data I had toyed with in development was gone. So I realzed that Rspec was actually running in development environment and running on my development database. Even though my rails_helper.rb file does have the ENV['RAILS_ENV'] ||= 'test' line.
The only way I can get this to run properly is to explicitely run my rspec like so: RAILS_ENV="test" bundle exec rspec spec/requests/pages_spec.rb
But I've never had to do this. Not even in the application I recently created. So it this something new out of Rails 6.1.3? Or perhaps a newer version or Rspec?
Has anyone encountered anything like that? What puzzles me is that both Rails applications were created perhaps a few months apart and other than the Ruby version and the Rails version being different, the other gems are pretty much the same.
Here are the details of the particular files
Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.0'
gem 'rails', '~> 6.1.3'
gem 'pg', '~> 1.1'
gem 'puma', '~> 5.0'
gem 'sass-rails', '>= 6'
gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'
gem 'bootsnap', '>= 1.4.4', require: false
gem 'devise', '~> 4.7', '>= 4.7.3'
gem 'interactor', '~> 3.0'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
gem 'faker'
group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'factory_bot_rails', '6.1.0'
gem 'rspec-rails', '4.0.2'
gem 'spring-commands-rspec'
end
group :development do
gem 'web-console', '>= 4.1.0'
gem 'rack-mini-profiler', '~> 2.0'
gem 'listen', '~> 3.3'
gem 'spring'
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
group :test do
gem 'capybara', '3.35.0'
gem 'selenium-webdriver', '3.142.6'
gem 'database_cleaner'
gem 'geckodriver-helper'
gem 'webdrivers', '4.1.2'
end
rails_helper.rb
require 'spec_helper'
require 'factory_bot_rails'
require 'devise'
require 'database_cleaner'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.include FactoryBot::Syntax::Methods
config.include ControllerMacros, type: :request
config.include Features::SessionHelpers, type: :feature
config.include Devise::Test::IntegrationHelpers, type: :request
config.include Devise::Test::IntegrationHelpers, type: :view
config.include Devise::Test::IntegrationHelpers, type: :feature
config.include Warden::Test::Helpers
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
config.after(:each) do
Warden.test_reset!
end
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
Capybara.javascript_driver = :selenium_chrome
FactoryBot::SyntaxRunner.class_eval do
include ActionDispatch::TestProcess
include ActiveSupport::Testing::FileFixtures
end
end
database.yml
# PostgreSQL. Versions 9.3 and up are supported.
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: trunfo_development
host: localhost
pool: 5
username: <%= ENV.fetch("DB_USER") %>
password: <%= ENV.fetch("DB_PASSWORD") %>
test:
<<: *default
database: trunfo_test
host: localhost
pool: 5
username: <%= ENV.fetch("DB_USER") %>
password: <%= ENV.fetch("DB_PASSWORD") %>
try setting ENV['RAILS_ENV'] ||= 'test' in project_name/test/test_helper.rb
Perhaps somewhere RAILS_ENV is already being set to something other than "test".
Have you tried to print out the env to see?
Does writing ENV['RAILS_ENV'] = 'test' in your helper file make a difference?
Related
I'm trying to deploy a CRA + Craco React application via Azure Devops. This is my YML file:
# Node.js React Web App to Linux on Azure
# Build a Node.js React app and deploy it to Azure as a Linux web app.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://learn.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
variables:
# Azure Resource Manager connection created during pipeline creation
azureSubscription: '{REDACTED FOR SO}'
# Web app name
webAppName: 'frontend'
# Environment name
environmentName: 'public'
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: ArchiveFiles#2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
artifact: drop
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: $(environmentName)
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
- task: AzureRmWebAppDeployment#4
displayName: 'Azure App Service Deploy: '
inputs:
ConnectionType: 'AzureRM'
azureSubscription: 'My Subscription'
appType: 'webAppLinux'
WebAppName: 'frontend'
packageForLinux: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
RuntimeStack: 'NODE|10.10'
StartupCommand: 'npm run start'
ScriptType: 'Inline Script'
InlineScript: |
npm install
npm run build --if-present
The build tasks succeeds. However, the deployment fails after running for ~20 minutes, with the following error:
Starting: Azure App Service Deploy:
==============================================================================
Task : Azure App Service deploy
Description : Deploy to Azure App Service a web, mobile, or API app using Docker, Java, .NET, .NET Core, Node.js, PHP, Python, or Ruby
Version : 4.198.0
Author : Microsoft Corporation
Help : https://aka.ms/azureappservicetroubleshooting
==============================================================================
Got service connection details for Azure App Service:'frontend'
Package deployment using ZIP Deploy initiated.
Deploy logs can be viewed at https://{MYAPPSERVICENAME}.scm.azurewebsites.net/api/deployments/62cf55c3f1434309b71a8334b2696fc9/log
Successfully deployed web package to App Service.
Trying to update App Service Application settings. Data: {"SCM_COMMAND_IDLE_TIMEOUT":"1800"}
App Service Application settings are already present.
Executing given script on Kudu service.
##[error]Error: Unable to run the script on Kudu Service. Error: Error: Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.
Successfully updated deployment History at https://{MYAPPSERVICENAME}.scm.azurewebsites.net/api/deployments/3641645137779498
App Service Application URL: http://{MYAPPSERVICENAME}.azurewebsites.net
Finishing: Azure App Service Deploy:
This YML solved my issues, along with upgrading Azure app service node version to 14.*
What I did is, I have moved the npm install and npm run build to build stage, and removed it from the deployment inline script stage.
So the package is ready before the deployment, after the successful unzip it will start the app using pm2 serve /home/site/wwwroot/build --no-daemon --spa as its running in a linux app service. (it works if your build directory is within wwwroot), if not please update the path accordingly
# Node.js React Web App to Linux on Azure
# Build a Node.js React app and deploy it to Azure as a Linux web app.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- develop
variables:
# Azure Resource Manager connection created during pipeline creation
azureSubscription: 'YOUR-SUBSCRIPTION'
# Web app name
webAppName: 'AZURE_APP_NAME'
# Environment name
environmentName: 'APP_ENV_NAME'
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: NodeTool#0
inputs:
versionSpec: '14.x'
displayName: 'Install Node.js'
- script: |
npm install
displayName: 'npm install'
- script: |
npm run build
displayName: 'npm build'
- task: ArchiveFiles#2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
artifact: drop
- stage: Deploy
displayName: Deploy stage
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: $(environmentName)
pool:
vmImage: $(vmImageName)
strategy:
runOnce:
deploy:
steps:
- task: AzureRmWebAppDeployment#4
displayName: 'Azure App Service Deploy: poultry-web-test'
inputs:
azureSubscription: $(azureSubscription)
appType: webAppLinux
WebAppName: $(webAppName)
packageForLinux: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
RuntimeStack: 'NODE|14-lts'
StartupCommand: 'pm2 serve /home/site/wwwroot/build --no-daemon --spa'
I am new to gitlab CI and I need help to configure gitlab-ci to run feature tests with Firefox (Ruby 2.7 / Rails 6 / Rspec / Capybara).
All is ok except feature tests.
I think I have to configure something with Firefox, or maybe install something.
Thanks for your help !
Error message when running tests :
Failure/Error: visit "/meth/methodologies/#{#meth.id}/edit"
Selenium::WebDriver::Error::WebDriverError:
Could not find Firefox binary (os=linux). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path=
File .gitlab-ci.yml
stages:
- build
- test
- deploy
image: ruby:2.7.1
cache: &global_cache
key: ${CI_COMMIT_REF_SLUG}
paths:
- apt-cache/
- vendor/ruby
- node_modules
- .yarn-cache
policy: pull-push
.base:
cache:
# inherit all global cache settings
<<: *global_cache
before_script:
- gem install bundler --no-document
- bundle install --jobs $(nproc) "${FLAGS[#]}" --path=vendor
.base_db:
# extends: .base
services:
- name: mysql:8.0.21
command: ['--default-authentication-plugin=mysql_native_password']
- name: selenium/standalone-firefox
alias: selenium
variables:
MYSQL_ROOT_PASSWORD: xxxx
DB_USERNAME: xxxx
DB_PASSWORD: xxxx
DB_HOST: mysql
RAILS_ENV: test
DISABLE_SPRING: 1
BUNDLE_PATH: vendor/bundle
cache:
# inherit all global cache settings
<<: *global_cache
before_script:
# install yarn & dependencies
- export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR
- wget -q -O - https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
- echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
- apt-get update -qq && apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -y yarn
- yarn config set cache-folder .yarn-cache
- yarn install
- gem install bundler --no-document
- bundle install --jobs $(nproc) "${FLAGS[#]}" --path=vendor/ruby
# Setup test database
- cp config/database.ci.yml config/database.yml
- RAILS_ENV=test bundle exec rails db:create db:migrate
rubocop:
extends: .base
stage: build
# cache:
# policy: pull-push
script:
- bundle exec rubocop app --fail-level W
rspec:
extends: .base_db
stage: test
script:
- bundle exec rspec -t ~type:feature
artifacts:
paths:
- coverage/
features:
extends: .base_db
stage: test
script:
- bundle exec rspec
# services:
# - name: selenium/standalone-firefox
# alias: selenium
# artifacts:
# paths:
# - coverage/
pages:
stage: deploy
dependencies:
- rspec
script:
- mv coverage/ public/
artifacts:
paths:
- public
expire_in: 30 days
# only:
# - master
EDIT :
I added the installation of firefox.
Tests that use js still don't work. The error is now as follows :
Failure/Error: visit "/meth/methodologies/#{#meth.id}/edit"
Selenium::WebDriver::Error::UnknownError:
Process unexpectedly closed with status 1
You have to use your browser with headless option
rails_helper.rb
Capybara.register_driver :headless_firefox do |app|
browser_options = Selenium::WebDriver::Firefox::Options.new()
browser_options.args << '--headless'
Capybara::Selenium::Driver.new(
app,
browser: :firefox,
options: browser_options
)
end
Capybara.javascript_driver = :headless_firefox
Capybara.configure do |config|
config.default_max_wait_time = 10 # seconds
config.default_driver = :headless_firefox
end
WARNING: [pool app] child 29 said into stderr: "php-fpm: pool app: symbol lookup error: /opt/php73/lib/x86_64-linux-gnu/extensions/no-debug-non-zts-20180731/opencensus.so: undefined symbol: ZVAL_DESTRUCTOR"
I using GAE env flex. today GAE use php7.3-fpm and i got that error. I check other website in GAE using php7.2-fpm working normally.
How can i fix problem.
Inside your app.yaml you should set the runtime:
env: flex
runtime: php
On your composer.json file you should specify the version that you want to use, for example if you want to use php 7.2 instead of 7.3:
{
"require": {
"php": "7.2.*"
}
}
It's important to specify said version otherwise the runtime might upgrade inadvertently into a new version as mentioned in the official documentation
By default, the PHP runtime uses PHP 7.2, but you should explicitly
declare your PHP version in the composer.json file to prevent your
application from being automatically upgraded when a new version of
PHP becomes available.
env: flex
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 1
disk_size_gb: 10
runtime_config:
document_root: public
# Ensure we skip ".env", which is only for local development
skip_files:
- .env
- .git
- /vendor/
- /node_modules/
env_variables:
# Put production environment variables here.
APP_LOG: errorlog
APP_KEY: **App_Key**
APP_NAME: Application
APP_ENV: production
APP_DEBUG: true ```
I'm fairly new to working with live projects.
My project runs perfectly on localhost, I deploy the exact same copy to google app engine using the command gcloud beta app deploy.
My welcome page works perfectly:
As Well as my auth pages:
straight after the auth process i get the following response:
To verify that the account has been authenticated my route url is redirecting to the dashboard:
example.com/admin/users
my app.yaml file is as follows:
runtime: php
env: flex
runtime_config:
document_root: public
# Ensure we skip ".env", which is only for local development
skip_files:
- .env
env_variables:
# Put production environment variables here.
APP_LOG: errorlog
APP_KEY: App-key
STORAGE_DIR: /tmp
CACHE_DRIVER: file
SESSION_DRIVER: file
## Set these environment variables according to your CloudSQL configuration.
DB_HOST: localhost
DB_DATABASE: lara
DB_USERNAME: root
DB_PASSWORD: password
DB_SOCKET: /cloudsql/connection-name
MAIL_MAILER: smtp
MAIL_HOST: smtp.mailtrap.io
MAIL_PORT: 2525
MAIL_USERNAME:username
MAIL_PASSWORD: password
MAIL_FROM_ADDRESS: from#example.com
MAIL_FROM_NAME: {App-Name}
#we need this for the flex environment
beta_settings:
# for Cloud SQL, set this value to the Cloud SQL connection name,
cloud_sql_instances: connection-name
Here is my log?
This is the view it is looking for:
My routes:
It's funny how small things create the biggest issues, took me over 3 weeks to resolve this issue.
As I was conducting research I discovered that Google App engine is case sensitive and so here are steps I used to resolve this issue:
1st I checked my routes using php artisan route:list and my route is route: admin.users.index and my file structure was --path: views/Admin/Users/index.blade.php and so i change all my folders to lower-case to match the route.
Then I ran the following commands:
php artisan cache:clear
php artisan route:clear
php artisan view:clear
Lastly I added the following script under scripts on my composer.json file:
"post-install-cmd": [
"chmod -R 755 bootstrap\/cache",
"php artisan cache:clear"
]
Deployed using gcloud app deploy
Worked like a charm.
Followed the steps described here to connect my grails 3.2.9 app to google cloud-sql instance on google-app-engine flexible env
http://guides.grails.org/grails-google-cloud/guide/index.html#deployingTheApp
My grails version is as follows
==> grails -version
| Grails Version: 3.2.9
| Groovy Version: 2.4.10
| JVM Version: 1.8.0_131
My application.yml looks as follows
# tag::dataSourceConfiguration[]
dataSource:
pooled: true
jmxExport: true
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
environments:
development:
dataSource:
dbCreate: create-drop
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
test:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
production:
dataSource:
driverClassName: com.mysql.jdbc.Driver
dbCreate: create-drop
url: jdbc:cloudsql://google/{DATABASE_NAME}?cloudSqlInstance={INSTANCE_NAME}&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user={USERNAME}&password={PASSWORD}&useSSL=false
properties:
When I run locally using
grails run-app
the app runs correctly
I run
./gradlew appengineDeploy to deploy and it deploys correctly
But when I try to open the scaffolded pages in the browser, I see the following error in the logs
==> gcloud app logs tail -s default
ERROR --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper
: Driver:com.mysql.jdbc.Driver#75b3ef1a returned null for
URL:jdbc:cloudsql://google/{DATABASE_NAME}?cloudSqlInstance=
{INSTANCE_NAME}&socketFactory=com.google.cloud.sql.mysql.SocketFactory&us
er={USERNAME}&password={PASSWORD}&useSSL=false
In addition the following error is also seen in the logs
ERROR --- [ Thread-16] .SchemaDropperImpl$DelayedDropActionImpl :
HHH000478: Unsuccessful: alter table property drop foreign key
FKgcduyfiunk1ewg7920pw4l3o9
Does the HH indicate that it is using the h2 database in production env?
Please help debug.
It seems the issue linked to hibernate. The same error for grails discussed here:
https://hibernate.atlassian.net/browse/HHH-11470
You are using MySQL because as you can see the error code say
Driver:com.mysql.jdbc.Driver#75b3ef1a returned null for
Your problem is that you need to configure the URL with your particular details changing {DATABASE_NAME} with the name of your database
you can see how to replace in the example at http://guides.grails.org/grails-google-cloud/guide/index.html#dataSourceGoogleCloudSQL