Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test Environment #92

Open
LauraKirby opened this issue Jun 27, 2018 · 3 comments
Open

Test Environment #92

LauraKirby opened this issue Jun 27, 2018 · 3 comments

Comments

@LauraKirby
Copy link

LauraKirby commented Jun 27, 2018

I am not sure if this is a feature request, bug or user error.
issue:

issue: CassandraMigrations::Cassandra.create_keyspace!('test') does not create keyspace. Therefore, the test keyspace must be manually created with RAILS_ENV=test rake cassandra:drop cassandra:create cassandra:migrate. After manual creation, I can successfully run bundle exec rspec, which includes writing and reading from CassandraMigrations::Cassandra.

ideal solution: ability to run something like what cassandra:drop cassandra:create cassandra:migrate offers; however, within ./spec/rails_helper. This might be built but I don't think it is working properly, see setup below.


Using Rspec, I would like to create the keyspace, run migrations and drop the keyspace before and after the suite is run. After each test, I would like to clear out the data in all the tables. Below is my attempt at doing this:

./config/cassandra.yml

common: &common
  port: 9042
  replication:
    class: 'SimpleStrategy'
    replication_factor: 1

test:
  <<: *common
  keyspace: analytics_test
  hosts:
    - cassandra

./spec/rails_helper

require 'spec_helper'
require 'rspec/rails'
require 'shoulda/matchers'
require 'active_support/all'
require 'cql'
require 'cassandra_migrations'

RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = false

  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-rails/docs
  config.infer_spec_type_from_file_location!

  config.before(:suite) do
    # create keyspace
    CassandraMigrations::Cassandra.create_keyspace!('test')
    # run migrations
    # ...
  end

  config.around(:each) do |example|
    # clear data from tables
    # ...
  end

  config.after(:suite) do
    # remove keyspace and all corresponding test data
    CassandraMigrations::Cassandra.drop_keyspace!('test')
  end
end

run: bundle exec rspec

Keyspace 'analytics_test' does not exist : Keyspace 'analytics_test' does not exist

An error occurred while loading ./spec/models/transfer_spec.rb.
Failure/Error: require File.expand_path('../../config/environment', __FILE__)

CassandraMigrations::Errors::UnexistingKeyspaceError:
  Keyspace analytics_test does not exist. Run rake cassandra:create.
# /usr/local/bundle/gems/cassandra_migrations-1.0.0/lib/cassandra_migrations/cassandra.rb:63:in `rescue in use'
# /usr/local/bundle/gems/cassandra_migrations-1.0.0/lib/cassandra_migrations/cassandra.rb:59:in `use'
# /usr/local/bundle/gems/cassandra_migrations-1.0.0/lib/cassandra_migrations/cassandra.rb:20:in `start!'
# /usr/local/bundle/gems/cassandra_migrations-1.0.0/lib/cassandra_migrations/railtie/initializer.rb:14:in `<module:CassandraMigrations>'
# /usr/local/bundle/gems/cassandra_migrations-1.0.0/lib/cassandra_migrations/railtie/initializer.rb:12:in `<top (required)>'
# /usr/local/bundle/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `require'
# /usr/local/bundle/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `block in require'
# /usr/local/bundle/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:258:in `load_dependency'
# /usr/local/bundle/gems/activesupport-5.1.6/lib/active_support/dependencies.rb:292:in `require'
# /usr/local/bundle/gems/cassandra_migrations-1.0.0/lib/cassandra_migrations/railtie.rb:6:in `block in <class:Railtie>'
# /usr/local/bundle/gems/railties-5.1.6/lib/rails/initializable.rb:30:in `instance_exec'
# /usr/local/bundle/gems/railties-5.1.6/lib/rails/initializable.rb:30:in `run'
# /usr/local/bundle/gems/railties-5.1.6/lib/rails/initializable.rb:59:in `block in run_initializers'
# /usr/local/bundle/gems/railties-5.1.6/lib/rails/initializable.rb:58:in `run_initializers'
# /usr/local/bundle/gems/railties-5.1.6/lib/rails/application.rb:353:in `initialize!'
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:5:in `require'
# ./spec/rails_helper.rb:5:in `<top (required)>'
# ./spec/models/transfer_spec.rb:1:in `require'
# ./spec/models/transfer_spec.rb:1:in `<top (required)>'
# ------------------
# --- Caused by: ---
# Cassandra::Errors::InvalidError:
#   Keyspace 'analytics_test' does not exist
#   /usr/local/bundle/gems/cassandra-driver-3.2.2/lib/cassandra/future.rb:637:in `get'
No examples found.
@bsbodden
Copy link
Collaborator

@LauraKirby Looking at https://github.com/hsgubert/cassandra_migrations/blob/master/lib/cassandra_migrations/railtie/tasks.rake it's using create_keyspace as such:

    begin
      CassandraMigrations::Cassandra.start!
      puts "Keyspace #{CassandraMigrations::Config.keyspace} already exists!"
    rescue CassandraMigrations::Errors::UnexistingKeyspaceError
      CassandraMigrations::Cassandra.create_keyspace!(Rails.env)
      puts "Created keyspace #{CassandraMigrations::Config.keyspace}"
    end

This might be by design but it looks like the call to CassandraMigrations::Cassandra.start! which in turn calls use(Config.keyspace) and the first thing it does is connect_to_server so you might want to try:

  config.before(:suite) do
    # connect to c*
   CassandraMigrations::Cassandra.connect_to_server
    # create keyspace
    CassandraMigrations::Cassandra.create_keyspace!('test')
    # run migrations
    # ...
  end

That assumes that there is config for that env. Let me know if that works.

@LauraKirby
Copy link
Author

LauraKirby commented Jul 3, 2018

@bsbodden, thank you for noting the rake file. I am able to successfully read and write to the database. The test specs contain things like CassandraMigrations::Cassandra.write!(table, transfer_attrs, ttl: 400). The issue appears to be specifically with the create.

After more testing, CassandraMigrations::Cassandra.drop_keyspace!(Rails.env) is working perfectly fine in my config.before(:suite) do block; however, CassandraMigrations::Cassandra.create_keyspace!(Rails.env) returns CassandraMigrations::Errors::UnexistingKeyspaceError: Keyspace analytics_test does not exist. Run rake cassandra:create

config.before(:suite) do
    CassandraMigrations::Cassandra.drop_keyspace!(Rails.env)
    CassandraMigrations::Cassandra.create_keyspace!(Rails.env)
    CassandraMigrations::Cassandra.start!
    CassandraMigrations::Migrator.up_to_latest!

    puts "Created keyspace #{CassandraMigrations::Config.keyspace}"

    migrations_up_count = CassandraMigrations::Migrator.up_to_latest!

    if migrations_up_count == 0
      puts "Already up-to-date"
    else
      puts "Migrated #{migrations_up_count} version(s) up."
    end

  end

If i run RAILS_ENV=test then rake cassandra:drop cassandra:create cassandra:migrate. I can then successfully run the above block with bundle exec rspec.

@LauraKirby
Copy link
Author

LauraKirby commented Jul 3, 2018

Here is my complete and working rails_helper

# This file is copied to spec/ when you run 'rails generate rspec:install'

require 'spec_helper'
require 'active_support/all'
ENV['RAILS_ENV'] = 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'cassandra_migrations'

# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'rspec/rails'
require 'shoulda/matchers'
require 'mock_redis'
require 'webmock/rspec'

# Add additional requires below this line. Rails is not loaded until this point!

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec

    with.library :rails
  end
end

RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = false

  config.before(:suite) do
    CassandraMigrations::Cassandra.drop_keyspace!(Rails.env)
    CassandraMigrations::Cassandra.create_keyspace!(Rails.env)
    CassandraMigrations::Cassandra.start!
    CassandraMigrations::Migrator.up_to_latest!

    migrations_up_count = CassandraMigrations::Migrator.up_to_latest!
  end

# here is an example on how to delete a table in the database:
  config.before(:each) do
      CassandraMigrations::Cassandra.delete!('transfers', 'organization_id = 4')
  end

  # RSpec Rails can automatically mix in different behaviours to your tests
  # based on their file location, for example enabling you to call `get` and
  # `post` in specs under `spec/controllers`.
  #
  # You can disable this behaviour by removing the line below, and instead
  # explicitly tag your specs with their type, e.g.:
  #
  #     RSpec.describe UsersController, :type => :controller do
  #       # ...
  #     end
  #
  # The different available types are documented in the features, such as in
  # https://relishapp.com/rspec/rspec-rails/docs
  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")

  config.after(:suite) do
    CassandraMigrations::Cassandra.drop_keyspace!(Rails.env)
    CassandraMigrations::Cassandra.create_keyspace!(Rails.env)
  end
end

To run tests:

one time only do:
RAILS_ENV=test then rake cassandra:drop cassandra:create cassandra:migrate
(aka not after each time you run bundle exec rspec)

These methods seem to work when placed right after each
other.
CassandraMigrations::Cassandra.drop_keyspace!(Rails.env)
CassandraMigrations::Cassandra.create_keyspace!(Rails.env)

When CassandraMigrations::Cassandra.create_keyspace!(Rails.env) is placed first and the keyspace has not been created, an exception is raised.

I have included an example of deleting data from a table before each spec is run (see: config.before(:each) do above). It would be nice to be able to select without inserting a specific id however; * fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants