fix: Increase the parallelism config to fix flaky tests, revert bad commits (#13410)
The specs break only in Circle CI, we have to figure out the root cause for the same. At the moment, I have increased the parallelism to fix this.
This commit is contained in:
@@ -144,7 +144,7 @@ jobs:
|
|||||||
# Backend tests with parallelization
|
# Backend tests with parallelization
|
||||||
backend-tests:
|
backend-tests:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
parallelism: 16
|
parallelism: 20
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- node/install:
|
- node/install:
|
||||||
|
|||||||
@@ -16,28 +16,27 @@ class V2::Reports::FirstResponseTimeDistributionBuilder
|
|||||||
|
|
||||||
def build_distribution
|
def build_distribution
|
||||||
results = fetch_aggregated_counts
|
results = fetch_aggregated_counts
|
||||||
format_results(results)
|
map_to_channel_types(results)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_aggregated_counts
|
def fetch_aggregated_counts
|
||||||
ReportingEvent
|
ReportingEvent
|
||||||
.joins('INNER JOIN inboxes ON reporting_events.inbox_id = inboxes.id')
|
|
||||||
.where(account_id: account.id, name: 'first_response')
|
.where(account_id: account.id, name: 'first_response')
|
||||||
.where(range_condition)
|
.where(range_condition)
|
||||||
.group('inboxes.channel_type')
|
.group(:inbox_id)
|
||||||
.select(
|
.select(
|
||||||
'inboxes.channel_type',
|
:inbox_id,
|
||||||
bucket_case_statements
|
bucket_case_statements
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def bucket_case_statements
|
def bucket_case_statements
|
||||||
<<~SQL.squish
|
<<~SQL.squish
|
||||||
COUNT(CASE WHEN reporting_events.value < 3600 THEN 1 END) AS bucket_0_1h,
|
COUNT(CASE WHEN value < 3600 THEN 1 END) AS bucket_0_1h,
|
||||||
COUNT(CASE WHEN reporting_events.value >= 3600 AND reporting_events.value < 14400 THEN 1 END) AS bucket_1_4h,
|
COUNT(CASE WHEN value >= 3600 AND value < 14400 THEN 1 END) AS bucket_1_4h,
|
||||||
COUNT(CASE WHEN reporting_events.value >= 14400 AND reporting_events.value < 28800 THEN 1 END) AS bucket_4_8h,
|
COUNT(CASE WHEN value >= 14400 AND value < 28800 THEN 1 END) AS bucket_4_8h,
|
||||||
COUNT(CASE WHEN reporting_events.value >= 28800 AND reporting_events.value < 86400 THEN 1 END) AS bucket_8_24h,
|
COUNT(CASE WHEN value >= 28800 AND value < 86400 THEN 1 END) AS bucket_8_24h,
|
||||||
COUNT(CASE WHEN reporting_events.value >= 86400 THEN 1 END) AS bucket_24h_plus
|
COUNT(CASE WHEN value >= 86400 THEN 1 END) AS bucket_24h_plus
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -45,15 +44,25 @@ class V2::Reports::FirstResponseTimeDistributionBuilder
|
|||||||
range.present? ? { created_at: range } : {}
|
range.present? ? { created_at: range } : {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_results(results)
|
def inbox_channel_types
|
||||||
|
@inbox_channel_types ||= account.inboxes.pluck(:id, :channel_type).to_h
|
||||||
|
end
|
||||||
|
|
||||||
|
def map_to_channel_types(results)
|
||||||
results.each_with_object({}) do |row, hash|
|
results.each_with_object({}) do |row, hash|
|
||||||
hash[row.channel_type] = {
|
channel_type = inbox_channel_types[row.inbox_id]
|
||||||
'0-1h' => row.bucket_0_1h,
|
next unless channel_type
|
||||||
'1-4h' => row.bucket_1_4h,
|
|
||||||
'4-8h' => row.bucket_4_8h,
|
hash[channel_type] ||= empty_buckets
|
||||||
'8-24h' => row.bucket_8_24h,
|
hash[channel_type]['0-1h'] += row.bucket_0_1h
|
||||||
'24h+' => row.bucket_24h_plus
|
hash[channel_type]['1-4h'] += row.bucket_1_4h
|
||||||
}
|
hash[channel_type]['4-8h'] += row.bucket_4_8h
|
||||||
|
hash[channel_type]['8-24h'] += row.bucket_8_24h
|
||||||
|
hash[channel_type]['24h+'] += row.bucket_24h_plus
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def empty_buckets
|
||||||
|
{ '0-1h' => 0, '1-4h' => 0, '4-8h' => 0, '8-24h' => 0, '24h+' => 0 }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class AddIndexToReportingEventsForResponseDistribution < ActiveRecord::Migration[7.1]
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_index :reporting_events,
|
||||||
|
[:account_id, :name, :inbox_id, :created_at],
|
||||||
|
name: 'index_reporting_events_for_response_distribution',
|
||||||
|
algorithm: :concurrently,
|
||||||
|
if_not_exists: true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2026_01_20_121402) do
|
ActiveRecord::Schema[7.1].define(version: 2026_01_30_061021) do
|
||||||
# These extensions should be enabled to support this database
|
# These extensions should be enabled to support this database
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
enable_extension "pg_trgm"
|
enable_extension "pg_trgm"
|
||||||
@@ -1115,6 +1115,7 @@ ActiveRecord::Schema[7.1].define(version: 2026_01_20_121402) do
|
|||||||
t.datetime "event_start_time", precision: nil
|
t.datetime "event_start_time", precision: nil
|
||||||
t.datetime "event_end_time", precision: nil
|
t.datetime "event_end_time", precision: nil
|
||||||
t.index ["account_id", "name", "created_at"], name: "reporting_events__account_id__name__created_at"
|
t.index ["account_id", "name", "created_at"], name: "reporting_events__account_id__name__created_at"
|
||||||
|
t.index ["account_id", "name", "inbox_id", "created_at"], name: "index_reporting_events_for_response_distribution"
|
||||||
t.index ["account_id"], name: "index_reporting_events_on_account_id"
|
t.index ["account_id"], name: "index_reporting_events_on_account_id"
|
||||||
t.index ["conversation_id"], name: "index_reporting_events_on_conversation_id"
|
t.index ["conversation_id"], name: "index_reporting_events_on_conversation_id"
|
||||||
t.index ["created_at"], name: "index_reporting_events_on_created_at"
|
t.index ["created_at"], name: "index_reporting_events_on_created_at"
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ describe Enterprise::Billing::TopupCheckoutService do
|
|||||||
it 'raises error for invalid credits' do
|
it 'raises error for invalid credits' do
|
||||||
expect do
|
expect do
|
||||||
service.create_checkout_session(credits: 500)
|
service.create_checkout_session(credits: 500)
|
||||||
end.to(raise_error { |error| expect(error.class.name).to eq('Enterprise::Billing::TopupCheckoutService::Error') })
|
end.to raise_error(Enterprise::Billing::TopupCheckoutService::Error)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises error when account is on free plan' do
|
it 'raises error when account is on free plan' do
|
||||||
@@ -54,7 +54,7 @@ describe Enterprise::Billing::TopupCheckoutService do
|
|||||||
|
|
||||||
expect do
|
expect do
|
||||||
service.create_checkout_session(credits: 1000)
|
service.create_checkout_session(credits: 1000)
|
||||||
end.to(raise_error { |error| expect(error.class.name).to eq('Enterprise::Billing::TopupCheckoutService::Error') })
|
end.to raise_error(Enterprise::Billing::TopupCheckoutService::Error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ RSpec.describe SendReplyJob do
|
|||||||
twitter_channel = create(:channel_twitter_profile)
|
twitter_channel = create(:channel_twitter_profile)
|
||||||
twitter_inbox = create(:inbox, channel: twitter_channel)
|
twitter_inbox = create(:inbox, channel: twitter_channel)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: twitter_inbox))
|
message = create(:message, conversation: create(:conversation, inbox: twitter_inbox))
|
||||||
allow(Twitter::SendOnTwitterService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Twitter::SendOnTwitterService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Twitter::SendOnTwitterService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Twitter::SendOnTwitterService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -42,8 +42,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Twilio::SendOnTwilioService when its twilio message' do
|
it 'calls ::Twilio::SendOnTwilioService when its twilio message' do
|
||||||
twilio_channel = create(:channel_twilio_sms)
|
twilio_channel = create(:channel_twilio_sms)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: twilio_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: twilio_channel.inbox))
|
||||||
allow(Twilio::SendOnTwilioService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Twilio::SendOnTwilioService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Twilio::SendOnTwilioService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Twilio::SendOnTwilioService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -51,8 +51,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Telegram::SendOnTelegramService when its telegram message' do
|
it 'calls ::Telegram::SendOnTelegramService when its telegram message' do
|
||||||
telegram_channel = create(:channel_telegram)
|
telegram_channel = create(:channel_telegram)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: telegram_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: telegram_channel.inbox))
|
||||||
allow(Telegram::SendOnTelegramService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Telegram::SendOnTelegramService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Telegram::SendOnTelegramService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Telegram::SendOnTelegramService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -60,8 +60,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Line:SendOnLineService when its line message' do
|
it 'calls ::Line:SendOnLineService when its line message' do
|
||||||
line_channel = create(:channel_line)
|
line_channel = create(:channel_line)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: line_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: line_channel.inbox))
|
||||||
allow(Line::SendOnLineService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Line::SendOnLineService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Line::SendOnLineService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Line::SendOnLineService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -70,8 +70,8 @@ RSpec.describe SendReplyJob do
|
|||||||
stub_request(:post, 'https://waba.360dialog.io/v1/configs/webhook')
|
stub_request(:post, 'https://waba.360dialog.io/v1/configs/webhook')
|
||||||
whatsapp_channel = create(:channel_whatsapp, sync_templates: false)
|
whatsapp_channel = create(:channel_whatsapp, sync_templates: false)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: whatsapp_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: whatsapp_channel.inbox))
|
||||||
allow(Whatsapp::SendOnWhatsappService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Whatsapp::SendOnWhatsappService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Whatsapp::SendOnWhatsappService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Whatsapp::SendOnWhatsappService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -79,8 +79,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Sms::SendOnSmsService when its sms message' do
|
it 'calls ::Sms::SendOnSmsService when its sms message' do
|
||||||
sms_channel = create(:channel_sms)
|
sms_channel = create(:channel_sms)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: sms_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: sms_channel.inbox))
|
||||||
allow(Sms::SendOnSmsService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Sms::SendOnSmsService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Sms::SendOnSmsService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Sms::SendOnSmsService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -88,8 +88,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Instagram::Direct::SendOnInstagramService when its instagram message' do
|
it 'calls ::Instagram::Direct::SendOnInstagramService when its instagram message' do
|
||||||
instagram_channel = create(:channel_instagram)
|
instagram_channel = create(:channel_instagram)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: instagram_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: instagram_channel.inbox))
|
||||||
allow(Instagram::SendOnInstagramService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Instagram::SendOnInstagramService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Instagram::SendOnInstagramService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Instagram::SendOnInstagramService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -112,8 +112,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Email::SendOnEmailService when its email message' do
|
it 'calls ::Email::SendOnEmailService when its email message' do
|
||||||
email_channel = create(:channel_email)
|
email_channel = create(:channel_email)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: email_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: email_channel.inbox))
|
||||||
allow(Email::SendOnEmailService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Email::SendOnEmailService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Email::SendOnEmailService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Email::SendOnEmailService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -121,8 +121,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Messages::SendEmailNotificationService when its webwidget message' do
|
it 'calls ::Messages::SendEmailNotificationService when its webwidget message' do
|
||||||
webwidget_channel = create(:channel_widget)
|
webwidget_channel = create(:channel_widget)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: webwidget_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: webwidget_channel.inbox))
|
||||||
allow(Messages::SendEmailNotificationService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Messages::SendEmailNotificationService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Messages::SendEmailNotificationService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Messages::SendEmailNotificationService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -130,8 +130,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Messages::SendEmailNotificationService when its api channel message' do
|
it 'calls ::Messages::SendEmailNotificationService when its api channel message' do
|
||||||
api_channel = create(:channel_api)
|
api_channel = create(:channel_api)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: api_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: api_channel.inbox))
|
||||||
allow(Messages::SendEmailNotificationService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Messages::SendEmailNotificationService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Messages::SendEmailNotificationService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Messages::SendEmailNotificationService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
@@ -139,8 +139,8 @@ RSpec.describe SendReplyJob do
|
|||||||
it 'calls ::Tiktok::SendOnTiktokService when its tiktok message' do
|
it 'calls ::Tiktok::SendOnTiktokService when its tiktok message' do
|
||||||
tiktok_channel = create(:channel_tiktok)
|
tiktok_channel = create(:channel_tiktok)
|
||||||
message = create(:message, conversation: create(:conversation, inbox: tiktok_channel.inbox))
|
message = create(:message, conversation: create(:conversation, inbox: tiktok_channel.inbox))
|
||||||
allow(Tiktok::SendOnTiktokService).to receive(:new).with(message: having_attributes(id: message.id)).and_return(process_service)
|
allow(Tiktok::SendOnTiktokService).to receive(:new).with(message: message).and_return(process_service)
|
||||||
expect(Tiktok::SendOnTiktokService).to receive(:new).with(message: having_attributes(id: message.id))
|
expect(Tiktok::SendOnTiktokService).to receive(:new).with(message: message)
|
||||||
expect(process_service).to receive(:perform)
|
expect(process_service).to receive(:perform)
|
||||||
described_class.perform_now(message.id)
|
described_class.perform_now(message.id)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user