diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml new file mode 100644 index 0000000..f44c877 --- /dev/null +++ b/.github/workflows/integration_test.yml @@ -0,0 +1,69 @@ +name: Integration Test + +on: + push: + branches: + - master + pull_request: + branches: + - master + +env: + RUBY_VERSION: 3.3 + +jobs: + mysql: + continue-on-error: true + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./integration_test + env: + BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile + MYSQL_HOST: 127.0.0.1 + strategy: + matrix: + gemfile: + - ar_6.1 + - ar_7.0 + - ar_7.1 + steps: + - uses: actions/checkout@v4 + - name: Start DB + run: docker compose up -d mysql + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ env.RUBY_VERSION }} + - name: Run bundle install + run: bundle install + - name: Run integration test + run: bundle exec rspec spec/mysql2_spec.rb + + postgresql: + continue-on-error: true + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./integration_test + env: + BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile + POSTGRES_HOST: 127.0.0.1 + strategy: + matrix: + gemfile: + - ar_6.1 + - ar_7.0 + - ar_7.1 + steps: + - uses: actions/checkout@v4 + - name: Start DB + run: docker compose up -d postgres + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ env.RUBY_VERSION }} + - name: Run bundle install + run: bundle install + - name: Run integration test + run: bundle exec rspec spec/postgresql_spec.rb diff --git a/.gitignore b/.gitignore index e786654..df4805e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *.swp *.gem Gemfile.lock -gemfiles/*.lock +*.gemfile.lock .bundle/ diff --git a/integration_test/Appraisals b/integration_test/Appraisals new file mode 120000 index 0000000..526794e --- /dev/null +++ b/integration_test/Appraisals @@ -0,0 +1 @@ +../Appraisals \ No newline at end of file diff --git a/integration_test/Gemfile b/integration_test/Gemfile new file mode 100644 index 0000000..7577434 --- /dev/null +++ b/integration_test/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'arproxy', path: '..' +gem 'rspec' +gem 'appraisal' +gem 'mysql2' +gem 'pg' diff --git a/integration_test/docker-compose.yml b/integration_test/docker-compose.yml new file mode 100644 index 0000000..18ccaeb --- /dev/null +++ b/integration_test/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3' + +services: + mysql: + image: mysql:9.0 + restart: always + environment: + MYSQL_ROOT_PASSWORD: rootpassword + MYSQL_DATABASE: arproxy_test + MYSQL_USER: arproxy + MYSQL_PASSWORD: password + ports: + - "23306:3306" + + postgres: + image: postgres:16 + restart: always + environment: + POSTGRES_DB: arproxy_test + POSTGRES_USER: arproxy + POSTGRES_PASSWORD: password + ports: + - "25432:5432" diff --git a/integration_test/gemfiles/ar_6.1.gemfile b/integration_test/gemfiles/ar_6.1.gemfile new file mode 100644 index 0000000..24d1563 --- /dev/null +++ b/integration_test/gemfiles/ar_6.1.gemfile @@ -0,0 +1,10 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "arproxy", path: "../.." +gem "rspec" +gem "appraisal" +gem "mysql2" +gem "pg" +gem "activerecord", "~> 6.1.0" diff --git a/integration_test/gemfiles/ar_7.0.gemfile b/integration_test/gemfiles/ar_7.0.gemfile new file mode 100644 index 0000000..72e4b83 --- /dev/null +++ b/integration_test/gemfiles/ar_7.0.gemfile @@ -0,0 +1,10 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "arproxy", path: "../.." +gem "rspec" +gem "appraisal" +gem "mysql2" +gem "pg" +gem "activerecord", "~> 7.0.0" diff --git a/integration_test/gemfiles/ar_7.1.gemfile b/integration_test/gemfiles/ar_7.1.gemfile new file mode 100644 index 0000000..5273122 --- /dev/null +++ b/integration_test/gemfiles/ar_7.1.gemfile @@ -0,0 +1,10 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "arproxy", path: "../.." +gem "rspec" +gem "appraisal" +gem "mysql2" +gem "pg" +gem "activerecord", "~> 7.1.0" diff --git a/integration_test/spec/mysql2_spec.rb b/integration_test/spec/mysql2_spec.rb new file mode 100644 index 0000000..d5dca8a --- /dev/null +++ b/integration_test/spec/mysql2_spec.rb @@ -0,0 +1,52 @@ +require_relative 'spec_helper' +require 'mysql2' + +context 'MySQL' do + before(:all) do + ActiveRecord::Base.establish_connection( + adapter: 'mysql2', + host: ENV.fetch('MYSQL_HOST', '127.0.0.1'), + port: ENV.fetch('MYSQL_PORT', '23306').to_i, + database: 'arproxy_test', + username: 'arproxy', + password: 'password' + ) + + Arproxy.configure do |config| + config.adapter = 'mysql2' + config.use HelloProxy + config.use QueryLogger + end + Arproxy.enable! + + ActiveRecord::Base.connection.create_table :products, force: true do |t| + t.string :name + t.integer :price + end + + Product.create(name: 'apple', price: 100) + Product.create(name: 'banana', price: 200) + Product.create(name: 'orange', price: 300) + end + + after(:all) do + ActiveRecord::Base.connection.drop_table :products + ActiveRecord::Base.connection.close + Arproxy.disable! + end + + before(:each) do + QueryLogger.reset! + end + + it do + expect(QueryLogger.log.size).to eq(0) + + expect(Product.count).to eq(3) + expect(Product.first.name).to eq('apple') + + expect(QueryLogger.log.size).to eq(2) + expect(QueryLogger.log[0]).to eq('SELECT COUNT(*) FROM `products` -- Hello Arproxy!') + expect(QueryLogger.log[1]).to eq('SELECT `products`.* FROM `products` ORDER BY `products`.`id` ASC LIMIT 1 -- Hello Arproxy!') + end +end diff --git a/integration_test/spec/postgresql_spec.rb b/integration_test/spec/postgresql_spec.rb new file mode 100644 index 0000000..737fe39 --- /dev/null +++ b/integration_test/spec/postgresql_spec.rb @@ -0,0 +1,52 @@ +require_relative 'spec_helper' +require 'pg' + +context 'PostgreSQL' do + before(:all) do + ActiveRecord::Base.establish_connection( + adapter: 'postgresql', + host: ENV.fetch('POSTGRES_HOST', '127.0.0.1'), + port: ENV.fetch('POSTGRES_PORT', '25432').to_i, + database: 'arproxy_test', + username: 'arproxy', + password: 'password' + ) + + Arproxy.configure do |config| + config.adapter = 'postgresql' + config.use HelloProxy + config.use QueryLogger + end + Arproxy.enable! + + ActiveRecord::Base.connection.create_table :products, force: true do |t| + t.string :name + t.integer :price + end + + Product.create(name: 'apple', price: 100) + Product.create(name: 'banana', price: 200) + Product.create(name: 'orange', price: 300) + end + + after(:all) do + ActiveRecord::Base.connection.drop_table :products + ActiveRecord::Base.connection.close + Arproxy.disable! + end + + before(:each) do + QueryLogger.reset! + end + + it do + expect(QueryLogger.log.size).to eq(0) + + expect(Product.count).to eq(3) + expect(Product.first.name).to eq('apple') + + expect(QueryLogger.log.size).to eq(2) + expect(QueryLogger.log[0]).to eq('SELECT COUNT(*) FROM `products` -- Hello Arproxy!') + expect(QueryLogger.log[1]).to eq('SELECT `products`.* FROM `products` ORDER BY `products`.`id` ASC LIMIT 1 -- Hello Arproxy!') + end +end diff --git a/integration_test/spec/spec_helper.rb b/integration_test/spec/spec_helper.rb new file mode 100644 index 0000000..869dec6 --- /dev/null +++ b/integration_test/spec/spec_helper.rb @@ -0,0 +1,28 @@ +require 'arproxy' +require 'active_record' + +class Product < ActiveRecord::Base +end + +class QueryLogger < Arproxy::Base + def execute(sql, name = nil) + @@log ||= [] + @@log << sql + puts "QueryLogger: #{sql}" + super + end + + def self.log + @@log + end + + def self.reset! + @@log = [] + end +end + +class HelloProxy < Arproxy::Base + def execute(sql, name = nil) + super("#{sql} -- Hello Arproxy!", name) + end +end