Last active
April 28, 2026 21:20
-
-
Save pavanshekar/f181a2846fe1be38bdc7909d38cd42c6 to your computer and use it in GitHub Desktop.
performance_test_errata_migration.rake
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Performance test for errata applications migration | |
| # Run with: bundle exec rake katello:dev:performance_test_migration | |
| namespace :katello do | |
| namespace :dev do | |
| desc "Performance test for errata applications migration" | |
| task :performance_test_migration => :environment do | |
| require 'benchmark' | |
| puts "=" * 80 | |
| puts "Errata Applications Migration Performance Test" | |
| puts "Started at: #{Time.current}" | |
| puts "=" * 80 | |
| # Set user context | |
| User.current = User.anonymous_api_admin | |
| # Count existing data before migration | |
| puts "\nPre-migration state:" | |
| existing_applications = Katello::ErrataApplication.count | |
| puts " Existing ErrataApplication records: #{existing_applications}" | |
| # Count tasks that will be processed | |
| puts "\nCounting tasks to be processed..." | |
| count_time = Benchmark.realtime do | |
| @task_count = ForemanTasks::Task | |
| .joins(template_invocation: { template: :remote_execution_features }) | |
| .where(label: 'Actions::RemoteExecution::RunHostJob') | |
| .where('remote_execution_features.label': ['katello_errata_install', 'katello_errata_install_by_search']) | |
| .where.not(started_at: nil) | |
| .distinct | |
| .count | |
| end | |
| puts " Tasks to process: #{@task_count}" | |
| puts " Count query took: #{count_time.round(2)} seconds" | |
| if @task_count.zero? | |
| puts "\nNo tasks found to migrate. Run the seed script first:" | |
| puts " bundle exec rake katello:dev:seed_errata_tasks[50000,100]" | |
| exit 0 | |
| end | |
| # Run the migration and time it | |
| puts "\n" + "=" * 80 | |
| puts "Running migration..." | |
| puts "=" * 80 | |
| migration_time = Benchmark.realtime do | |
| system("bundle exec rake katello:upgrades:4.21:populate_errata_applications") | |
| unless $?.success? | |
| puts "\nERROR: Migration failed with exit code #{$?.exitstatus}" | |
| exit 1 | |
| end | |
| end | |
| puts "\n" + "=" * 80 | |
| puts "Migration completed in: #{migration_time.round(2)} seconds (#{(migration_time / 60).round(2)} minutes)" | |
| puts "=" * 80 | |
| # Verify results | |
| puts "\nPost-migration state:" | |
| new_applications = Katello::ErrataApplication.count | |
| created_count = new_applications - existing_applications | |
| puts " Total ErrataApplication records: #{new_applications}" | |
| puts " New records created: #{created_count}" | |
| if created_count > 0 | |
| puts " Average time per record: #{(migration_time / created_count * 1000).round(2)} ms" | |
| puts " Records per second: #{(created_count / migration_time).round(2)}" | |
| elsif @task_count > 0 | |
| puts " WARNING: No records created despite #{@task_count} tasks found" | |
| end | |
| # Sample some records | |
| puts "\nSample records created:" | |
| Katello::ErrataApplication.order(created_at: :desc).limit(3).each do |app| | |
| puts " - Host: #{app.host.name}, Errata: #{app.errata_ids.count}, Status: #{app.status}, Date: #{app.applied_at}" | |
| end | |
| # Test report generation if we have data | |
| if new_applications > 100 | |
| puts "\n" + "=" * 80 | |
| puts "Testing report generation..." | |
| puts "=" * 80 | |
| # Create a test scope object | |
| test_scope_class = Class.new do | |
| include Katello::Concerns::BaseTemplateScopeExtensions | |
| end | |
| test_scope = test_scope_class.new | |
| # Test 1: Simple report (last 7 days) | |
| puts "\nTest 1: Report for last 7 days" | |
| report_time_1 = Benchmark.realtime do | |
| @results_1 = test_scope.load_errata_applications_from_db( | |
| filter_errata_type: 'all', | |
| include_last_reboot: 'no', | |
| since: 7.days.ago.to_s, | |
| up_to: Time.current.to_s, | |
| status: 'all', | |
| host_filter: nil | |
| ) | |
| end | |
| puts " Results: #{@results_1.count} rows" | |
| puts " Time: #{report_time_1.round(2)} seconds" | |
| # Test 2: Report with host filter (single host) | |
| if @results_1.any? | |
| sample_host = @results_1.first[:hostname] | |
| puts "\nTest 2: Report for single host (#{sample_host})" | |
| report_time_2 = Benchmark.realtime do | |
| @results_2 = test_scope.load_errata_applications_from_db( | |
| filter_errata_type: 'all', | |
| include_last_reboot: 'no', | |
| status: 'all', | |
| host_filter: "name = #{sample_host}" | |
| ) | |
| end | |
| puts " Results: #{@results_2.count} rows" | |
| puts " Time: #{report_time_2.round(2)} seconds" | |
| end | |
| # Test 3: Large report (all data with last_reboot) | |
| puts "\nTest 3: Full report with last_reboot data" | |
| report_time_3 = Benchmark.realtime do | |
| @results_3 = test_scope.load_errata_applications_from_db( | |
| filter_errata_type: 'all', | |
| include_last_reboot: 'yes', | |
| status: 'all', | |
| host_filter: nil | |
| ) | |
| end | |
| puts " Results: #{@results_3.count} rows" | |
| puts " Time: #{report_time_3.round(2)} seconds" | |
| # Show query efficiency metrics | |
| if defined?(report_time_3) && @results_3&.count&.positive? | |
| puts "\nReport generation metrics:" | |
| puts " Average time per result row: #{(report_time_3 / @results_3.count * 1000).round(2)} ms" | |
| puts " Rows per second: #{(@results_3.count / report_time_3).round(2)}" | |
| end | |
| # Sample report data | |
| if @results_3.any? | |
| puts "\nSample report rows:" | |
| @results_3.take(3).each do |row| | |
| puts " - #{row[:hostname]}: #{row[:erratum_id]} (#{row[:erratum_type]}) - #{row[:status]}, still_applicable: #{row[:still_applicable]}" | |
| end | |
| end | |
| else | |
| puts "\nSkipping report generation test (insufficient data)" | |
| end | |
| # Database statistics | |
| puts "\n" + "=" * 80 | |
| puts "Database Statistics" | |
| puts "=" * 80 | |
| # Table size | |
| result = ActiveRecord::Base.connection.execute( | |
| "SELECT pg_size_pretty(pg_total_relation_size('katello_errata_applications')) as size" | |
| ) | |
| puts " Table size: #{result.first['size']}" | |
| # Index usage | |
| index_stats = ActiveRecord::Base.connection.execute(<<-SQL) | |
| SELECT | |
| indexrelname as index_name, | |
| idx_scan as times_used, | |
| pg_size_pretty(pg_relation_size(indexrelid)) as index_size | |
| FROM pg_stat_user_indexes | |
| WHERE schemaname = 'public' | |
| AND relname = 'katello_errata_applications' | |
| ORDER BY idx_scan DESC | |
| SQL | |
| if index_stats.any? | |
| puts "\n Index statistics:" | |
| index_stats.each do |stat| | |
| puts " #{stat['index_name']}: used #{stat['times_used']} times, size: #{stat['index_size']}" | |
| end | |
| end | |
| # Summary | |
| puts "\n" + "=" * 80 | |
| puts "SUMMARY" | |
| puts "=" * 80 | |
| puts " Tasks processed: #{@task_count}" | |
| puts " Records created: #{created_count}" | |
| puts " Migration time: #{migration_time.round(2)} seconds (#{(migration_time / 60).round(2)} minutes)" | |
| if created_count > 0 | |
| puts " Throughput: #{(created_count / migration_time).round(2)} records/second" | |
| end | |
| if defined?(report_time_3) && defined?(@results_3) | |
| puts "\n Report generation (full dataset):" | |
| puts " Rows: #{@results_3.count}" | |
| puts " Time: #{report_time_3.round(2)} seconds" | |
| if @results_3.count > 0 | |
| puts " Throughput: #{(@results_3.count / report_time_3).round(2)} rows/second" | |
| end | |
| end | |
| puts "\nCompleted at: #{Time.current}" | |
| puts "=" * 80 | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment