Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 103 additions & 12 deletions .github/workflows/rspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,121 @@ on:

jobs:
test:
name: "Ruby ${{ matrix.ruby-version }}${{ matrix.rails-version && format(' / Rails {0}', matrix.rails-version) || '' }} / ${{ matrix.adapter-name }}${{ matrix.adapter-version && format(' {0}', matrix.adapter-version) || '' }}"
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
ruby-version: ["3.2", "3.3", "3.4", "4.0"]

services:
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
include:
- ruby-version: "3.2"
adapter: redis
adapter-name: Redis
- ruby-version: "3.2"
adapter: solid/sqlite3
adapter-name: SQLite
- ruby-version: "3.3"
adapter: redis
adapter-name: Redis
- ruby-version: "3.3"
adapter: solid/sqlite3
adapter-name: SQLite
- ruby-version: "3.4"
adapter: redis
adapter-name: Redis
- ruby-version: "3.4"
adapter: solid/sqlite3
adapter-name: SQLite

# Run tests against all adapters and 2 latest rails majors for latest Ruby version
- ruby-version: "4.0"
adapter: redis
adapter-name: Redis
- ruby-version: "4.0"
adapter: redis
adapter-name: Redis
rails-version: "7"
- ruby-version: "4.0"
adapter: solid/sqlite3
adapter-name: SQLite
- ruby-version: "4.0"
adapter: solid/sqlite3
adapter-name: SQLite
adapter-version: "1.7"
rails-version: "7"
- ruby-version: "4.0"
adapter: solid/postgresql
adapter-name: PostgreSQL
- ruby-version: "4.0"
adapter: solid/postgresql
adapter-name: PostgreSQL
rails-version: "7"
- ruby-version: "4.0"
adapter: solid/mysql2
adapter-name: MySQL (mysql2)
- ruby-version: "4.0"
adapter: solid/mysql2
adapter-name: MySQL (mysql2)
rails-version: "7"
- ruby-version: "4.0"
adapter: solid/trilogy
adapter-name: "MySQL (trilogy)"
- ruby-version: "4.0"
adapter: solid/trilogy
adapter-name: "MySQL (trilogy)"
rails-version: "7"

env:
FINO_TEST_ADAPTER: ${{ matrix.adapter }}
FINO_TEST_REDIS_HOST: localhost
FINO_TEST_POSTGRES_HOST: localhost
FINO_TEST_POSTGRES_USER: postgres
FINO_TEST_POSTGRES_PASSWORD: postgres
FINO_TEST_POSTGRES_DB: fino_test
FINO_TEST_MYSQL_HOST: 127.0.0.1
FINO_TEST_MYSQL_USER: root
FINO_TEST_MYSQL_PASSWORD: root
FINO_TEST_MYSQL_DB: fino_test

steps:
- uses: actions/checkout@v4

- name: Set adapter version override
if: matrix.adapter-version
run: |
GEM_NAME="${FINO_TEST_ADAPTER#solid/}"
ENV_NAME="$(echo "${GEM_NAME}" | tr '[:lower:]' '[:upper:]')_VERSION"
echo "${ENV_NAME}=${{ matrix.adapter-version }}" >> $GITHUB_ENV

- name: Set Rails version override
if: matrix.rails-version
run: echo "RAILS_VERSION=${{ matrix.rails-version }}" >> $GITHUB_ENV

- name: Start Redis
if: matrix.adapter == 'redis'
run: |
docker run -d --name redis -p 6379:6379 redis:7
timeout 30 bash -c 'until docker exec redis redis-cli ping 2>/dev/null; do sleep 1; done'

- name: Start PostgreSQL
if: matrix.adapter == 'solid/postgresql'
run: |
docker run -d --name postgres -p 5432:5432 \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=fino_test \
postgres:17
timeout 30 bash -c 'until docker exec postgres pg_isready 2>/dev/null; do sleep 1; done'

- name: Start MySQL
if: matrix.adapter == 'solid/mysql2' || matrix.adapter == 'solid/trilogy'
run: |
docker run -d --name mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=fino_test \
mysql:8.4
timeout 60 bash -c 'until docker exec mysql mysqladmin ping -h 127.0.0.1 --silent 2>/dev/null; do sleep 1; done'

- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
Expand Down
9 changes: 7 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ gem "guard-livereload"
gem "rack-livereload"

gem "puma"
gem "rails", "~> #{ENV['RAILS_VERSION'] || '8.0'}"
gem "sqlite3", "~> #{ENV['SQLITE_VERSION'] || '2.7'}"
gem "rails", "~> #{ENV.fetch('RAILS_VERSION', '8.0')}"

# Database adapters
gem "mysql2", "~> #{ENV.fetch('MYSQL2_VERSION', '0')}"
gem "pg", "~> #{ENV.fetch('POSTGRESQL_VERSION', '1')}"
gem "sqlite3", "~> #{ENV.fetch('SQLITE3_VERSION', '2')}"
gem "trilogy", "~> #{ENV.fetch('TRILOGY_VERSION', '2')}"

gem "rspec", "~> 3.0"
gem "rubocop", "~> 1.80.1", require: false
Expand Down
2 changes: 1 addition & 1 deletion fino-rails.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
]

spec.add_dependency "fino", "~> #{Fino::VERSION}"
spec.add_dependency "rails", "~> 8.0"
spec.add_dependency "rails", ">= 7.0"
end
4 changes: 0 additions & 4 deletions fino-solid.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,4 @@ Gem::Specification.new do |spec|

spec.add_dependency "activerecord", ">= 6.1"
spec.add_dependency "fino", "~> #{Fino::VERSION}"

spec.add_development_dependency "mysql2", ">= 0.5"
spec.add_development_dependency "pg", ">= 1.0"
spec.add_development_dependency "sqlite3", ">= 1.4"
end
20 changes: 16 additions & 4 deletions lib/fino/solid/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ def write(setting_definition, value, overrides, variants)

Fino::Solid::Setting.upsert(
{ key: setting_definition.key, data: data },
unique_by: :key
**unique_by_option(:key)
)
end

def read_persisted_setting_keys
Fino::Solid::Setting.pluck(:key)
end

def clear(setting_key)
Fino::Solid::Setting.where(key: setting_key).delete_all > 0
def clear(setting_key) # rubocop:disable Naming/PredicateMethod
Fino::Solid::Setting.where(key: setting_key).delete_all.positive?
end

def fetch_value_from(raw_adapter_data)
Expand All @@ -70,7 +70,7 @@ def record_ab_testing_conversion(setting_definition, variant, scope, time)
scope: scope.to_s,
converted_at: time
},
unique_by: :idx_fino_conversions_unique
**unique_by_option(:idx_fino_conversions_unique)
)
end

Expand Down Expand Up @@ -101,6 +101,18 @@ def fetch_raw_variants_from(raw_adapter_data)
memo << { percentage: percentage.to_f, value: value }
end
end

private

def unique_by_option(constraint)
return {} if mysql_adapter?

{ unique_by: constraint }
end

def mysql_adapter?
Fino::Solid::Record.connection.adapter_name.match?(/Mysql2|Trilogy/i)
end
end
end
end
2 changes: 2 additions & 0 deletions spec/dummy/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@

/storage/*
!/storage/.keep

Gemfile.lock
2 changes: 2 additions & 0 deletions spec/integration/adapters/redis_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

RSpec.describe "Redis adapter integration", type: :integration do
before(:all) do
skip "Redis adapter not under test" unless TestHelpers.redis_adapter?

Fino.reconfigure do
adapter { TestHelpers.adapter }
cache { TestHelpers.cache }
Expand Down
11 changes: 3 additions & 8 deletions spec/integration/adapters/solid_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

RSpec.describe "Solid adapter integration", type: :integration do
before(:all) do
SolidTestHelpers.setup_database(:sqlite3)
skip "Solid adapter not under test" unless TestHelpers.solid_adapter?

Fino.reconfigure do
adapter { SolidTestHelpers.solid_adapter }
adapter { Fino::Solid::Adapter.new }
cache { TestHelpers.cache }

settings do
Expand Down Expand Up @@ -38,16 +38,11 @@
end
end

before do
TestHelpers.cache.clear
SolidTestHelpers.clear_database
end

it_behaves_like "fino adapter integration"

describe "#supports_ab_testing_analysis?" do
it "returns true" do
expect(SolidTestHelpers.solid_adapter.supports_ab_testing_analysis?).to eq(true)
expect(Fino::Solid::Adapter.new.supports_ab_testing_analysis?).to eq(true)
end
end
end
14 changes: 13 additions & 1 deletion spec/support/from_scratch.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
# frozen_string_literal: true

RSpec.configure do |config|
config.before(:suite) do
next unless TestHelpers.solid_adapter?

db_adapter = TestHelpers.adapter_env.delete_prefix("solid/").to_sym
SolidTestHelpers.setup_database(db_adapter)
end

config.before do
TestHelpers.cache.clear
TestHelpers.redis.flushdb

if TestHelpers.solid_adapter?
SolidTestHelpers.clear_database
else
TestHelpers.redis.flushdb
end
end
end
8 changes: 8 additions & 0 deletions spec/support/solid_test_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ def database_config(adapter_name)
username: ENV.fetch("FINO_TEST_POSTGRES_USER", "postgres"),
password: ENV.fetch("FINO_TEST_POSTGRES_PASSWORD", "")
}
when :trilogy
{
adapter: "trilogy",
host: ENV.fetch("FINO_TEST_MYSQL_HOST", "mysql.fino.orb.local"),
database: ENV.fetch("FINO_TEST_MYSQL_DB", "fino_test"),
username: ENV.fetch("FINO_TEST_MYSQL_USER", "root"),
password: ENV.fetch("FINO_TEST_MYSQL_PASSWORD", "")
}
when :mysql2
{
adapter: "mysql2",
Expand Down
25 changes: 24 additions & 1 deletion spec/support/test_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
# frozen_string_literal: true

module TestHelpers
VALID_ADAPTERS = %w[redis solid/sqlite3 solid/postgresql solid/mysql2 solid/trilogy].freeze
DEFAULT_ADAPTER = "redis"

module_function

def adapter_env
@adapter_env ||= ENV.fetch("FINO_TEST_ADAPTER", DEFAULT_ADAPTER).tap do |value|
unless VALID_ADAPTERS.include?(value)
raise "Unknown test adapter: #{value}. Valid: #{VALID_ADAPTERS.join(', ')}"
end
end
end

def redis_adapter?
adapter_env == "redis"
end

def solid_adapter?
adapter_env.start_with?("solid/")
end

def cache
@cache ||= Fino::Cache::Memory.new(expires_in: 10)
end
Expand All @@ -15,6 +34,10 @@ def redis
end

def adapter
@adapter ||= Fino::Redis::Adapter.new(redis, namespace: "fino_test")
@adapter ||= if redis_adapter?
Fino::Redis::Adapter.new(redis, namespace: "fino_test")
elsif solid_adapter?
Fino::Solid::Adapter.new
end
end
end
Loading