|
5 | 5 | Bundler.require
|
6 | 6 |
|
7 | 7 | ENV["RAILS_ENV"] = "development"
|
| 8 | +ENV["DATABASE_URL"] = "sqlite3:tmp/rails_mini_development.sqlite3" |
8 | 9 |
|
9 |
| -require "action_controller" |
| 10 | +require "action_controller/railtie" |
| 11 | +require "active_record/railtie" |
| 12 | +require "active_job/railtie" |
10 | 13 |
|
11 | 14 | class RailsMiniApp < Rails::Application
|
12 | 15 | config.hosts = nil
|
@@ -39,10 +42,71 @@ def debug_log_path
|
39 | 42 | config.transport.transport_class = Sentry::DebugTransport
|
40 | 43 | config.sdk_debug_transport_log_file = debug_log_path.join("sentry_debug_events.log")
|
41 | 44 | config.background_worker_threads = 0
|
| 45 | + |
| 46 | + config.enable_logs = true |
| 47 | + config.structured_logger_class = Sentry::DebugStructuredLogger |
| 48 | + config.sdk_debug_structured_logger_log_file = debug_log_path.join("sentry_e2e_tests.log") |
| 49 | + |
| 50 | + config.rails.structured_logging.enabled = true |
| 51 | + config.rails.structured_logging.attach_to = [:active_record, :action_controller, :active_job] |
42 | 52 | end
|
43 | 53 | end
|
44 | 54 | end
|
45 | 55 |
|
| 56 | +class Post < ActiveRecord::Base |
| 57 | +end |
| 58 | + |
| 59 | +class User < ActiveRecord::Base |
| 60 | +end |
| 61 | + |
| 62 | +class ApplicationJob < ActiveJob::Base |
| 63 | + retry_on ActiveRecord::Deadlocked |
| 64 | + |
| 65 | + discard_on ActiveJob::DeserializationError |
| 66 | +end |
| 67 | + |
| 68 | +class SampleJob < ApplicationJob |
| 69 | + queue_as :default |
| 70 | + |
| 71 | + def perform(message = "Hello from ActiveJob!") |
| 72 | + Rails.logger.info("SampleJob executed with message: #{message}") |
| 73 | + |
| 74 | + Post.count |
| 75 | + User.count |
| 76 | + |
| 77 | + message |
| 78 | + end |
| 79 | +end |
| 80 | + |
| 81 | +class DatabaseJob < ApplicationJob |
| 82 | + queue_as :default |
| 83 | + |
| 84 | + def perform(post_title = "Test Post") |
| 85 | + Rails.logger.info("DatabaseJob creating post: #{post_title}") |
| 86 | + |
| 87 | + post = Post.create!(title: post_title, content: "Content for #{post_title}") |
| 88 | + found_post = Post.find(post.id) |
| 89 | + |
| 90 | + Rails.logger.info("DatabaseJob found post: #{found_post.title}") |
| 91 | + |
| 92 | + found_post |
| 93 | + end |
| 94 | +end |
| 95 | + |
| 96 | +class FailingJob < ApplicationJob |
| 97 | + queue_as :default |
| 98 | + |
| 99 | + def perform(should_fail = true) |
| 100 | + Rails.logger.info("FailingJob started") |
| 101 | + |
| 102 | + if should_fail |
| 103 | + raise StandardError, "Intentional job failure for testing" |
| 104 | + end |
| 105 | + |
| 106 | + "Job completed successfully" |
| 107 | + end |
| 108 | +end |
| 109 | + |
46 | 110 | class ErrorController < ActionController::Base
|
47 | 111 | before_action :set_cors_headers
|
48 | 112 |
|
@@ -97,12 +161,134 @@ def set_cors_headers
|
97 | 161 | end
|
98 | 162 | end
|
99 | 163 |
|
| 164 | +class PostsController < ActionController::Base |
| 165 | + before_action :set_cors_headers |
| 166 | + def index |
| 167 | + posts = Post.all.to_a |
| 168 | + |
| 169 | + Sentry.logger.info("Posts index accessed", posts_count: posts.length) |
| 170 | + |
| 171 | + render json: { |
| 172 | + posts: posts.map { |p| { id: p.id, title: p.title, content: p.content } } |
| 173 | + } |
| 174 | + end |
| 175 | + |
| 176 | + def create |
| 177 | + post = Post.create!(post_params) |
| 178 | + |
| 179 | + Sentry.logger.info("Post created", post_id: post.id, title: post.title) |
| 180 | + |
| 181 | + render json: { post: { id: post.id, title: post.title, content: post.content } }, status: :created |
| 182 | + rescue ActiveRecord::RecordInvalid => e |
| 183 | + render json: { error: e.message }, status: :unprocessable_entity |
| 184 | + end |
| 185 | + |
| 186 | + def show |
| 187 | + post = Post.find(params[:id]) |
| 188 | + render json: { post: { id: post.id, title: post.title, content: post.content } } |
| 189 | + rescue ActiveRecord::RecordNotFound |
| 190 | + render json: { error: "Post not found" }, status: :not_found |
| 191 | + end |
| 192 | + |
| 193 | + private |
| 194 | + |
| 195 | + def post_params |
| 196 | + params.require(:post).permit(:title, :content) |
| 197 | + end |
| 198 | + |
| 199 | + def set_cors_headers |
| 200 | + response.headers['Access-Control-Allow-Origin'] = '*' |
| 201 | + response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS' |
| 202 | + response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, sentry-trace, baggage' |
| 203 | + end |
| 204 | +end |
| 205 | + |
| 206 | +class JobsController < ActionController::Base |
| 207 | + before_action :set_cors_headers |
| 208 | + |
| 209 | + def sample_job |
| 210 | + job = SampleJob.perform_later("Hello from Rails mini app!") |
| 211 | + |
| 212 | + Sentry.logger.info("SampleJob enqueued", job_id: job.job_id) |
| 213 | + |
| 214 | + render json: { |
| 215 | + message: "SampleJob enqueued successfully", |
| 216 | + job_id: job.job_id, |
| 217 | + job_class: job.class.name |
| 218 | + } |
| 219 | + end |
| 220 | + |
| 221 | + def database_job |
| 222 | + title = params[:title] || "Test Post from Job" |
| 223 | + job = DatabaseJob.perform_later(title) |
| 224 | + |
| 225 | + Sentry.logger.info("DatabaseJob enqueued", job_id: job.job_id, post_title: title) |
| 226 | + |
| 227 | + render json: { |
| 228 | + message: "DatabaseJob enqueued successfully", |
| 229 | + job_id: job.job_id, |
| 230 | + job_class: job.class.name, |
| 231 | + post_title: title |
| 232 | + } |
| 233 | + end |
| 234 | + |
| 235 | + def failing_job |
| 236 | + should_fail = params[:should_fail] != "false" |
| 237 | + job = FailingJob.perform_later(should_fail) |
| 238 | + |
| 239 | + Sentry.logger.info("FailingJob enqueued", job_id: job.job_id, should_fail: should_fail) |
| 240 | + |
| 241 | + render json: { |
| 242 | + message: "FailingJob enqueued successfully", |
| 243 | + job_id: job.job_id, |
| 244 | + job_class: job.class.name, |
| 245 | + should_fail: should_fail |
| 246 | + } |
| 247 | + end |
| 248 | + |
| 249 | + private |
| 250 | + |
| 251 | + def set_cors_headers |
| 252 | + response.headers['Access-Control-Allow-Origin'] = '*' |
| 253 | + response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS' |
| 254 | + response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, sentry-trace, baggage' |
| 255 | + end |
| 256 | +end |
| 257 | + |
100 | 258 | RailsMiniApp.initialize!
|
101 | 259 |
|
| 260 | +ActiveRecord::Schema.define do |
| 261 | + create_table :posts, force: true do |t| |
| 262 | + t.string :title, null: false |
| 263 | + t.text :content |
| 264 | + t.timestamps |
| 265 | + end |
| 266 | + |
| 267 | + create_table :users, force: true do |t| |
| 268 | + t.string :name, null: false |
| 269 | + t.string :email |
| 270 | + t.timestamps |
| 271 | + end |
| 272 | +end |
| 273 | + |
| 274 | +Post.create!(title: "Welcome Post", content: "Welcome to the Rails mini app!") |
| 275 | +Post.create!(title: "Sample Post", content: "This is a sample post for testing.") |
| 276 | +User.create!(name: "Test User", email: "test@example.com") |
| 277 | + |
102 | 278 | RailsMiniApp.routes.draw do
|
103 | 279 | get '/health', to: 'events#health'
|
104 | 280 | get '/error', to: 'error#error'
|
105 | 281 | get '/trace_headers', to: 'events#trace_headers'
|
| 282 | + get '/logged_events', to: 'events#logged_events' |
| 283 | + post '/clear_logged_events', to: 'events#clear_logged_events' |
| 284 | + |
| 285 | + get '/posts', to: 'posts#index' |
| 286 | + post '/posts', to: 'posts#create' |
| 287 | + get '/posts/:id', to: 'posts#show' |
| 288 | + |
| 289 | + post '/jobs/sample', to: 'jobs#sample_job' |
| 290 | + post '/jobs/database', to: 'jobs#database_job' |
| 291 | + post '/jobs/failing', to: 'jobs#failing_job' |
106 | 292 |
|
107 | 293 | match '*path', to: proc { |env|
|
108 | 294 | [200, {
|
|
0 commit comments