diff --git a/Jenkinsfile b/Jenkinsfile index 67b9ab2d1d..54dae3eb29 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,5 +1,6 @@ @Library('podTemplateLib') import net.santiment.utils.podTemplates +import java.util.UUID properties([ buildDiscarder( @@ -11,34 +12,136 @@ properties([ slaveTemplates = new podTemplates() +def numPartitions = 4 + slaveTemplates.dockerTemplate { label -> node(label) { - stage('Run Tests') { + stage('Build Test Image') { container('docker') { def scmVars = checkout scm def gitHead = scmVars.GIT_COMMIT.substring(0, 7) def sanitizedBranchName = env.BRANCH_NAME.replaceAll('/', '-') + def changeId = env.CHANGE_ID ?: 'none' + def imageTag = "sanbase-test:${scmVars.GIT_COMMIT}-${env.BUILD_ID}-${sanitizedBranchName}-${changeId}" sh "docker build \ - -t sanbase-test:${scmVars.GIT_COMMIT}-${env.BUILD_ID}-${sanitizedBranchName}-${env.CHANGE_ID} \ + -t ${imageTag} \ -f Dockerfile-test . \ --progress plain" - sh "docker run \ - --rm --name test-postgres-${scmVars.GIT_COMMIT}-${env.BUILD_ID}-${sanitizedBranchName}-${env.CHANGE_ID} \ - -e POSTGRES_PASSWORD=password \ - -d pgvector/pgvector:pg15" - - try { - sh "docker run --rm \ - --link test-postgres-${scmVars.GIT_COMMIT}-${env.BUILD_ID}-${sanitizedBranchName}-${env.CHANGE_ID}:test-db \ - --env DATABASE_URL=postgres://postgres:password@test-db:5432/postgres \ - -t sanbase-test:${scmVars.GIT_COMMIT}-${env.BUILD_ID}-${sanitizedBranchName}-${env.CHANGE_ID}" - } finally { - sh "docker kill test-postgres-${scmVars.GIT_COMMIT}-${env.BUILD_ID}-${sanitizedBranchName}-${env.CHANGE_ID}" + // Store variables for later stages + env.TEST_IMAGE_TAG = imageTag + env.GIT_HEAD = gitHead + env.GIT_COMMIT_FULL = scmVars.GIT_COMMIT + } + } + + stage('Run Tests') { + container('docker') { + catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { + def imageTag = env.TEST_IMAGE_TAG + def runToken = UUID.randomUUID().toString().substring(0, 8) + def buildSuffix = "${env.GIT_COMMIT_FULL}-${env.BUILD_ID}-${runToken}" + env.TEST_RUN_SUFFIX = buildSuffix + def failuresDir = "${pwd()}/test_failures_${buildSuffix}" + + sh "mkdir -p ${failuresDir}" + + // Start postgres containers for each partition + for (int i = 1; i <= numPartitions; i++) { + def postgresContainerName = "test-postgres-${buildSuffix}-p${i}" + sh "docker rm -f ${postgresContainerName} >/dev/null 2>&1 || true" + sh "docker run \ + --rm --name ${postgresContainerName} \ + -e POSTGRES_PASSWORD=password \ + --health-cmd 'pg_isready -U postgres' \ + --health-interval 2s \ + --health-timeout 5s \ + --health-retries 10 \ + -d pgvector/pgvector:pg15" + } + + // Wait for each Postgres container to be ready + sh """ + set -e + for i in \$(seq 1 ${numPartitions}); do + name="test-postgres-${buildSuffix}-p\$i" + echo "Waiting for \$name to be ready..." + for attempt in \$(seq 1 30); do + if docker exec "\$name" pg_isready -U postgres 2>/dev/null; then + echo "\$name is ready" + break + fi + if [ \$attempt -eq 30 ]; then + echo "ERROR: \$name did not become ready within 60 seconds" + docker logs "\$name" 2>&1 || true + exit 1 + fi + sleep 2 + done + done + """ + + try { + def partitions = [:] + + for (int i = 1; i <= numPartitions; i++) { + def partition = i + partitions["Partition ${partition}"] = { + sh "docker run --rm \ + --link test-postgres-${buildSuffix}-p${partition}:test-db \ + --env DATABASE_URL=postgres://postgres:password@test-db:5432/postgres \ + --env MIX_TEST_PARTITION=${partition} \ + -v ${failuresDir}:/app/_build/test/failures \ + -t ${imageTag} \ + mix test --partitions ${numPartitions} \ + --formatter Sanbase.FailedTestFormatter \ + --formatter ExUnit.CLIFormatter \ + --slowest 20" + } + } + + parallel partitions + } finally { + for (int i = 1; i <= numPartitions; i++) { + sh "docker kill test-postgres-${buildSuffix}-p${i} || true" + } + } } + } + } + + stage('Summarize Test Failures') { + container('docker') { + def buildSuffix = env.TEST_RUN_SUFFIX ?: "${env.GIT_COMMIT_FULL}-${env.BUILD_ID}" + def failuresDir = "${pwd()}/test_failures_${buildSuffix}" + + sh """ + set +x + echo '' + echo '========================================' + echo ' Combined results from all partitions' + echo '========================================' + + if ls ${failuresDir}/partition_*.txt 1>/dev/null 2>&1; then + echo 'Failing tests across all partitions:' + cut -f2 ${failuresDir}/partition_*.txt | sort + echo '' + echo 'Re-run with:' + echo " mix test \$(cut -f2 ${failuresDir}/partition_*.txt | tr '\\n' ' ')" + rm -rf ${failuresDir} + exit 1 + fi + + echo 'All partitions passed!' + rm -rf ${failuresDir} + """ + } + } - if (env.BRANCH_NAME == 'master') { + if (env.BRANCH_NAME == 'master') { + stage('Build & Push') { + container('docker') { withCredentials([ string( credentialsId: 'SECRET_KEY_BASE', @@ -57,15 +160,15 @@ slaveTemplates.dockerTemplate { label -> docker.withRegistry("https://${awsRegistry}", 'ecr:eu-central-1:ecr-credentials') { sh "docker build \ -t ${awsRegistry}/sanbase:${env.BRANCH_NAME} \ - -t ${awsRegistry}/sanbase:${scmVars.GIT_COMMIT} \ + -t ${awsRegistry}/sanbase:${env.GIT_COMMIT_FULL} \ --build-arg SECRET_KEY_BASE=${env.SECRET_KEY_BASE} \ --build-arg PARITY_URL=${env.PARITY_URL} \ - --build-arg GIT_HEAD=${gitHead} \ - --build-arg GIT_COMMIT=${scmVars.GIT_COMMIT} . \ + --build-arg GIT_HEAD=${env.GIT_HEAD} \ + --build-arg GIT_COMMIT=${env.GIT_COMMIT_FULL} . \ --progress plain" sh "docker push ${awsRegistry}/sanbase:${env.BRANCH_NAME}" - sh "docker push ${awsRegistry}/sanbase:${scmVars.GIT_COMMIT}" + sh "docker push ${awsRegistry}/sanbase:${env.GIT_COMMIT_FULL}" } } } diff --git a/config/test.exs b/config/test.exs index a179d3a338..42a691d443 100644 --- a/config/test.exs +++ b/config/test.exs @@ -14,11 +14,17 @@ config :sanbase, Sanbase.EventBus, config :sanbase, Sanbase, url: {:system, "SANBASE_URL", ""} +test_port = + case System.get_env("MIX_TEST_PARTITION") do + nil -> 4001 + partition -> 4001 + String.to_integer(partition) + end + config :sanbase, SanbaseWeb.Endpoint, - http: [port: 4001], + http: [port: test_port], server: true, - website_url: {:system, "WEBSITE_URL", "http://localhost:4001"}, - backend_url: {:system, "BACKEND_URL", "http://localhost:4001"} + website_url: {:system, "WEBSITE_URL", "http://localhost:#{test_port}"}, + backend_url: {:system, "BACKEND_URL", "http://localhost:#{test_port}"} config :ex_aws, access_key_id: "test_id", @@ -39,8 +45,8 @@ config :logger, :console, config :sanbase, Sanbase.RepoReader, projects_data_endpoint_secret: "no_secret" config :sanbase, Sanbase.ApiCallLimit, - quota_size: 10, - quota_size_max_offset: 10 + quota_size: 5, + quota_size_max_offset: 5 config :sanbase, Sanbase.Accounts.Interaction, interaction_cooldown_seconds: 0, @@ -73,7 +79,7 @@ config :sanbase, Sanbase.Repo, pool: Ecto.Adapters.SQL.Sandbox, username: "postgres", password: "postgres", - database: "sanbase_test", + database: "sanbase_test#{System.get_env("MIX_TEST_PARTITION")}", pool_size: 5, ssl: false, ssl_opts: [] diff --git a/lib/mix/failure_test_formatter.ex b/lib/mix/failure_test_formatter.ex index c7864f6968..477ddc99b5 100644 --- a/lib/mix/failure_test_formatter.ex +++ b/lib/mix/failure_test_formatter.ex @@ -2,7 +2,9 @@ defmodule Sanbase.FailedTestFormatter do @moduledoc false use GenServer - ## Callbacks + @failures_dir "_build/test/failures" + + def failures_dir, do: @failures_dir def init(_opts) do {:ok, @@ -17,23 +19,19 @@ defmodule Sanbase.FailedTestFormatter do case test do %ExUnit.Test{state: {:failed, [{kind, error, _stacktrace}]}} = test when kind in [:error, :invalid, :exit] -> - # Add a leading dot so the file:line string can be copy-pasted in the - # terminal to directly execute it file = String.replace_leading(test.tags.file, File.cwd!() <> "/", "") line = test.tags.line - # In case of :exit, the error tuple can contain more info, like :timeout, etc. - # In case of :error, the error is not a tuple, but a struct - reason = if kind == :exit and is_tuple(error), do: " (#{elem(error, 0)})", else: "" + # Do not add the reason for now + _reason = if kind == :exit and is_tuple(error), do: " (#{elem(error, 0)})", else: "" - test_identifier = "#{file}:#{line}#{reason}" + test_identifier = "#{file}:#{line}" config |> Map.update(kind, %{counter: 1, list: [test_identifier]}, fn map -> map |> Map.update!(:counter, &(&1 + 1)) |> Map.update!(:list, &[test_identifier | &1]) end) - # TODO: Support ExUnit.MultiError test -> IO.warn("Unexpected failed test format. Got: #{inspect(test)}") config @@ -44,6 +42,7 @@ defmodule Sanbase.FailedTestFormatter do def handle_cast({:suite_finished, _times_us}, config) do print_suite(config) + write_failures_to_file(config) {:noreply, config} end @@ -54,7 +53,6 @@ defmodule Sanbase.FailedTestFormatter do defp print_suite(config) do for kind <- Map.keys(config) do if (get_in(config, [kind, :counter]) || 0) > 0 do - # All tests that failed an assert will have `kind = :error` error_tests_message = get_in(config, [kind, :list]) |> Enum.map(&(" " <> &1)) |> Enum.join("\n") @@ -67,4 +65,23 @@ defmodule Sanbase.FailedTestFormatter do end end end + + defp write_failures_to_file(config) do + lines = + for kind <- Map.keys(config), + (get_in(config, [kind, :counter]) || 0) > 0, + test_id <- get_in(config, [kind, :list]) do + "#{kind}\t#{test_id}" + end + + if lines != [] do + partition = System.get_env("MIX_TEST_PARTITION") || "0" + File.mkdir_p!(@failures_dir) + + File.write!( + Path.join(@failures_dir, "partition_#{partition}.txt"), + Enum.join(lines, "\n") <> "\n" + ) + end + end end diff --git a/lib/sanbase_web/graphql/resolvers/entity_resolver.ex b/lib/sanbase_web/graphql/resolvers/entity_resolver.ex index 99190902a7..a8355389ea 100644 --- a/lib/sanbase_web/graphql/resolvers/entity_resolver.ex +++ b/lib/sanbase_web/graphql/resolvers/entity_resolver.ex @@ -191,9 +191,6 @@ defmodule SanbaseWeb.Graphql.Resolvers.EntityResolver do {:ok, %{query: :get_most_similar, args: args_with_embedding}} {:error, reason} -> - # Preserve the previous GraphQL shape expected by tests: - # - keep the top-level field non-null - # - surface the error via the nested data/stats resolvers {:error, reason} end end diff --git a/test/sanbase/accounts/access_attempt_test.exs b/test/sanbase/accounts/access_attempt_test.exs index 9b16d288c9..59ac23eae0 100644 --- a/test/sanbase/accounts/access_attempt_test.exs +++ b/test/sanbase/accounts/access_attempt_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Accounts.AccessAttemptTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true alias Sanbase.Accounts.{AccessAttempt, EmailLoginAttempt} alias Sanbase.Repo import Sanbase.Factory diff --git a/test/sanbase/accounts/user/user_email_test.exs b/test/sanbase/accounts/user/user_email_test.exs index 30c28d7175..c4f242c621 100644 --- a/test/sanbase/accounts/user/user_email_test.exs +++ b/test/sanbase/accounts/user/user_email_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Accounts.User.EmailTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias Sanbase.Accounts.User.Email diff --git a/test/sanbase/ai/academy_ai_service_test.exs b/test/sanbase/ai/academy_ai_service_test.exs index 33728e916c..34772da05f 100644 --- a/test/sanbase/ai/academy_ai_service_test.exs +++ b/test/sanbase/ai/academy_ai_service_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.AI.AcademyAIServiceTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory import Mox diff --git a/test/sanbase/ai/openai_client_test.exs b/test/sanbase/ai/openai_client_test.exs index f498437384..9987707978 100644 --- a/test/sanbase/ai/openai_client_test.exs +++ b/test/sanbase/ai/openai_client_test.exs @@ -1,6 +1,5 @@ defmodule Sanbase.AI.OpenAIClientTest do - use ExUnit.Case, async: false - use SanbaseWeb.ConnCase + use ExUnit.Case, async: true import Mox diff --git a/test/sanbase/alerts/trigger_restrictions_test.exs b/test/sanbase/alerts/trigger_restrictions_test.exs index c50e0fbbf1..e5717799bb 100644 --- a/test/sanbase/alerts/trigger_restrictions_test.exs +++ b/test/sanbase/alerts/trigger_restrictions_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Alert.TriggerRestrictionsTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase/alerts/trigger_test.exs b/test/sanbase/alerts/trigger_test.exs index 09eacc1c64..d9a4fcd04c 100644 --- a/test/sanbase/alerts/trigger_test.exs +++ b/test/sanbase/alerts/trigger_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Alert.TriggersTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory import ExUnit.CaptureLog diff --git a/test/sanbase/alerts/trigger_voting_test.exs b/test/sanbase/alerts/trigger_voting_test.exs index 3675f72411..bfd51fb8d4 100644 --- a/test/sanbase/alerts/trigger_voting_test.exs +++ b/test/sanbase/alerts/trigger_voting_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Alert.TriggerVotingTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase/app_notifications/app_notifications_test.exs b/test/sanbase/app_notifications/app_notifications_test.exs index fdd6a424ec..d0b66ecf28 100644 --- a/test/sanbase/app_notifications/app_notifications_test.exs +++ b/test/sanbase/app_notifications/app_notifications_test.exs @@ -641,8 +641,8 @@ defmodule Sanbase.AppNotificationsTest do {:ok, _vote} = Vote.create(%{user_id: voter.id, watchlist_id: watchlist.id}) {:ok, _vote} = Vote.create(%{user_id: voter.id, watchlist_id: watchlist.id}) - subscriber = Sanbase.EventBus.AppNotificationsSubscriber - Sanbase.EventBus.drain_topics(subscriber.topics(), 10_000) + Sanbase.EventBus.AppNotificationsSubscriber.topics() + |> Sanbase.EventBus.drain_topics() owner_notifications = AppNotifications.list_notifications_for_user(author.id, limit: 20) diff --git a/test/sanbase/auth/apikey/apikey_test.exs b/test/sanbase/auth/apikey/apikey_test.exs index 27c16eae2b..e2810365f7 100644 --- a/test/sanbase/auth/apikey/apikey_test.exs +++ b/test/sanbase/auth/apikey/apikey_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Accounts.ApiKeyTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true alias Sanbase.Accounts.{ User, diff --git a/test/sanbase/auth/user_permissions_test.exs b/test/sanbase/auth/user_permissions_test.exs index 2e1421485b..444af013b9 100644 --- a/test/sanbase/auth/user_permissions_test.exs +++ b/test/sanbase/auth/user_permissions_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Accounts.UserPermissionsTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory diff --git a/test/sanbase/comments/comment_test.exs b/test/sanbase/comments/comment_test.exs index 91d9e6fe01..039d9d1b16 100644 --- a/test/sanbase/comments/comment_test.exs +++ b/test/sanbase/comments/comment_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.CommentTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory alias Sanbase.Comments.EntityComment diff --git a/test/sanbase/comments/notification_test.exs b/test/sanbase/comments/notification_test.exs index e7ac4f272e..8bb878335d 100644 --- a/test/sanbase/comments/notification_test.exs +++ b/test/sanbase/comments/notification_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Comments.NotificationTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory alias Sanbase.Comments.{EntityComment, Notification} diff --git a/test/sanbase/email/mailjet_event_handler_test.exs b/test/sanbase/email/mailjet_event_handler_test.exs index fe272aa3a2..e6004e0198 100644 --- a/test/sanbase/email/mailjet_event_handler_test.exs +++ b/test/sanbase/email/mailjet_event_handler_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Email.MailjetEventHandlerTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory diff --git a/test/sanbase/email/newsletter_token_test.exs b/test/sanbase/email/newsletter_token_test.exs index 2bf8d7c127..4297c35da1 100644 --- a/test/sanbase/email/newsletter_token_test.exs +++ b/test/sanbase/email/newsletter_token_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Email.NewsletterTokenTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory alias Sanbase.DateTimeUtils diff --git a/test/sanbase/external_services/coinmarketcap/price_point_test.exs b/test/sanbase/external_services/coinmarketcap/price_point_test.exs index 9b17c0551a..af5a63982e 100644 --- a/test/sanbase/external_services/coinmarketcap/price_point_test.exs +++ b/test/sanbase/external_services/coinmarketcap/price_point_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.ExternalServices.Coinmarketcap.PricePointTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true alias Sanbase.ExternalServices.Coinmarketcap.PricePoint alias Sanbase.Project diff --git a/test/sanbase/external_services/coinmarketcap/scraper_test.exs b/test/sanbase/external_services/coinmarketcap/scraper_test.exs index 73f5574a5f..32cc253737 100644 --- a/test/sanbase/external_services/coinmarketcap/scraper_test.exs +++ b/test/sanbase/external_services/coinmarketcap/scraper_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.ExternalServices.Coinmarketcap.ScraperTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory diff --git a/test/sanbase/external_services/etherscan/scraper_test.exs b/test/sanbase/external_services/etherscan/scraper_test.exs index 71d793dc4c..9b587a29cf 100644 --- a/test/sanbase/external_services/etherscan/scraper_test.exs +++ b/test/sanbase/external_services/etherscan/scraper_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.ExternalServices.Etherscan.ScraperTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory diff --git a/test/sanbase/external_services/project_info_test.exs b/test/sanbase/external_services/project_info_test.exs index 83db63eff8..8881cb6cdb 100644 --- a/test/sanbase/external_services/project_info_test.exs +++ b/test/sanbase/external_services/project_info_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.ExternalServices.ProjectInfoTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import ExUnit.CaptureLog import Sanbase.Factory diff --git a/test/sanbase/featured_item/featured_item_test.exs b/test/sanbase/featured_item/featured_item_test.exs index 655efcd88a..dd3ef5df7b 100644 --- a/test/sanbase/featured_item/featured_item_test.exs +++ b/test/sanbase/featured_item/featured_item_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.FeaturedItemTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory diff --git a/test/sanbase/following/user_follower_test.exs b/test/sanbase/following/user_follower_test.exs index 82aea90c16..09550f3d41 100644 --- a/test/sanbase/following/user_follower_test.exs +++ b/test/sanbase/following/user_follower_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Accounts.UserFollowerTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory diff --git a/test/sanbase/insight/categorizer_test.exs b/test/sanbase/insight/categorizer_test.exs index e570d75758..55fe2bdd0b 100644 --- a/test/sanbase/insight/categorizer_test.exs +++ b/test/sanbase/insight/categorizer_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Insight.CategorizerTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory import Mox diff --git a/test/sanbase/insights/post_test.exs b/test/sanbase/insights/post_test.exs index 9e9292ebfc..08609de11d 100644 --- a/test/sanbase/insights/post_test.exs +++ b/test/sanbase/insights/post_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Insight.PostTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory alias Sanbase.Repo diff --git a/test/sanbase/mcp/mcp_utils_test.exs b/test/sanbase/mcp/mcp_utils_test.exs index 60084eb0c3..cc96c65d60 100644 --- a/test/sanbase/mcp/mcp_utils_test.exs +++ b/test/sanbase/mcp/mcp_utils_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.MCPUtilsTest do - use ExUnit.Case, async: true + use ExUnit.Case, async: false doctest(Sanbase.MCP.Utils) end diff --git a/test/sanbase/metric/ui_metadata/display_order/reorder_test.exs b/test/sanbase/metric/ui_metadata/display_order/reorder_test.exs index 8869377be7..01de50f84b 100644 --- a/test/sanbase/metric/ui_metadata/display_order/reorder_test.exs +++ b/test/sanbase/metric/ui_metadata/display_order/reorder_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Metric.UIMetadata.DisplayOrder.ReorderTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true alias Sanbase.Metric.UIMetadata.DisplayOrder.Reorder alias Sanbase.Metric.UIMetadata.{Category, Group, DisplayOrder} diff --git a/test/sanbase/notifications/email_notifier_test.exs b/test/sanbase/notifications/email_notifier_test.exs index e2395007c5..0451e06897 100644 --- a/test/sanbase/notifications/email_notifier_test.exs +++ b/test/sanbase/notifications/email_notifier_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Notifications.EmailNotifierTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true alias Sanbase.Notifications.{Notification, EmailNotifier} alias Sanbase.Metric.Registry diff --git a/test/sanbase/project/project_social_volume_query_test.exs b/test/sanbase/project/project_social_volume_query_test.exs index 76fcad7fcc..f43171d293 100644 --- a/test/sanbase/project/project_social_volume_query_test.exs +++ b/test/sanbase/project/project_social_volume_query_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiSocialVolumeQuery do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory diff --git a/test/sanbase/social_data/social_helper_test.exs b/test/sanbase/social_data/social_helper_test.exs index 5f44e3bf4f..e49f2ffa55 100644 --- a/test/sanbase/social_data/social_helper_test.exs +++ b/test/sanbase/social_data/social_helper_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.SocialHelperTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias Sanbase.SocialData.SocialHelper describe "split_by_source/1" do diff --git a/test/sanbase/timeline/timeline_event_test.exs b/test/sanbase/timeline/timeline_event_test.exs index 39e245d5d6..08d2a3c25b 100644 --- a/test/sanbase/timeline/timeline_event_test.exs +++ b/test/sanbase/timeline/timeline_event_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Timeline.TimelineEventTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true import Sanbase.Factory import Sanbase.TestHelpers diff --git a/test/sanbase_web/api_call_limit/api_call_limit_api_test.exs b/test/sanbase_web/api_call_limit/api_call_limit_api_test.exs index 4261bfcf0b..2ce614a626 100644 --- a/test/sanbase_web/api_call_limit/api_call_limit_api_test.exs +++ b/test/sanbase_web/api_call_limit/api_call_limit_api_test.exs @@ -289,13 +289,14 @@ defmodule SanbaseWeb.ApiCallLimitTest do assert api_calls_made == 0 max_quota = 20 - iterations = 10 - api_calls_per_iteration = 300 + iterations = 3 + api_calls_per_iteration = 20 - # `now` is set to 4 days before the end of next month. This way the `can_send_after` of - # KafkaExporter won't sleep forever (as it will be in the past). Setting it to 3 days before - # the month ends makes sure that 7 of the iteartions will be executed in the next day. - days_in_old_month = 4 + # `now` is set to `days_in_old_month` days before the end of next month. + # This way the `can_send_after` of KafkaExporter won't sleep forever + # (as it will be in the past). Some iterations run in the old month, + # and (iterations - days_in_old_month) run in the new month.days_in_old_month = 2 + days_in_old_month = 2 now = Timex.now() @@ -363,8 +364,8 @@ defmodule SanbaseWeb.ApiCallLimitTest do assert api_calls_made == 0 max_quota = 20 - iterations = 14 - api_calls_per_iteration = 300 + iterations = 2 + api_calls_per_iteration = 20 # Set now to be the beginning of a month so when it is shifted 14 times by 1 day # it won't go in the next month. We're shifting forward otherwise the KafkaExporter @@ -389,7 +390,7 @@ defmodule SanbaseWeb.ApiCallLimitTest do res = make_api_call(context.apikey_conn, []) assert res.status == 200 end, - max_concurrent: 50, + max_concurrent: 10, ordered: false ) end) @@ -437,8 +438,8 @@ defmodule SanbaseWeb.ApiCallLimitTest do assert api_calls_made == 0 max_quota = 20 - iterations = 5 - api_calls_per_iteration = 100 + iterations = 2 + api_calls_per_iteration = 20 # Set now to be the beginning of a month so when it is shifted 14 times by 1 day # it won't go in the next month. We're shifting forward otherwise the KafkaExporter @@ -641,7 +642,9 @@ defmodule SanbaseWeb.ApiCallLimitTest do test "self reset", context do {:ok, quota} = Sanbase.ApiCallLimit.get_quota_db(:user, context.user) - for _ <- 1..25, do: make_api_call(context.apikey_conn, []) + # This works if the number of api calls is less than + # quota_size + quota_size_max_offset + for _ <- 1..12, do: make_api_call(context.apikey_conn, []) {:ok, quota2} = Sanbase.ApiCallLimit.get_quota_db(:user, context.user) diff --git a/test/sanbase_web/cache/cachex_provider_test.exs b/test/sanbase_web/cache/cachex_provider_test.exs index 4c422d9c11..ebb457b9e0 100644 --- a/test/sanbase_web/cache/cachex_provider_test.exs +++ b/test/sanbase_web/cache/cachex_provider_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.CachexProviderTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias SanbaseWeb.Graphql.CachexProvider, as: CacheProvider diff --git a/test/sanbase_web/cache/con_cache_provider_test.exs b/test/sanbase_web/cache/con_cache_provider_test.exs index 0794c6b66c..93521ed6ff 100644 --- a/test/sanbase_web/cache/con_cache_provider_test.exs +++ b/test/sanbase_web/cache/con_cache_provider_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ConCacheProviderTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias SanbaseWeb.Graphql.ConCacheProvider, as: CacheProvider diff --git a/test/sanbase_web/controller/data_controller_test.exs b/test/sanbase_web/controller/data_controller_test.exs index 6337518f4b..dfa41e5e2c 100644 --- a/test/sanbase_web/controller/data_controller_test.exs +++ b/test/sanbase_web/controller/data_controller_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.DataControllerTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory diff --git a/test/sanbase_web/controllers/auth_controller_test.exs b/test/sanbase_web/controllers/auth_controller_test.exs index 79165790ed..fa796aa5d7 100644 --- a/test/sanbase_web/controllers/auth_controller_test.exs +++ b/test/sanbase_web/controllers/auth_controller_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.AuthControllerTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias SanbaseWeb.AuthController alias Sanbase.Factory diff --git a/test/sanbase_web/graphql/access_restrictions_test.exs b/test/sanbase_web/graphql/access_restrictions_test.exs index ddb309bd17..d013425697 100644 --- a/test/sanbase_web/graphql/access_restrictions_test.exs +++ b/test/sanbase_web/graphql/access_restrictions_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.AccessRestrictionsTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/alerts/triggers_historical_activity_api_test.exs b/test/sanbase_web/graphql/alerts/triggers_historical_activity_api_test.exs index 993d188c96..345f6eadab 100644 --- a/test/sanbase_web/graphql/alerts/triggers_historical_activity_api_test.exs +++ b/test/sanbase_web/graphql/alerts/triggers_historical_activity_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.TriggersHistoricalActivityApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/alerts/triggers_stats_test.exs b/test/sanbase_web/graphql/alerts/triggers_stats_test.exs index b465180dc2..5797b36f29 100644 --- a/test/sanbase_web/graphql/alerts/triggers_stats_test.exs +++ b/test/sanbase_web/graphql/alerts/triggers_stats_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.Alerts.TriggersStatsTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/alerts/update_trigger_api_test.exs b/test/sanbase_web/graphql/alerts/update_trigger_api_test.exs index 99956be0d6..129a9cca2f 100644 --- a/test/sanbase_web/graphql/alerts/update_trigger_api_test.exs +++ b/test/sanbase_web/graphql/alerts/update_trigger_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.UpdateTriggerApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/billing/current_user_subscriptions_api_test.exs b/test/sanbase_web/graphql/billing/current_user_subscriptions_api_test.exs index 1ff89ce1e8..b3de799eb5 100644 --- a/test/sanbase_web/graphql/billing/current_user_subscriptions_api_test.exs +++ b/test/sanbase_web/graphql/billing/current_user_subscriptions_api_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.Billing.CurrentUserSubscriptionsApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/blockchain/available_blockchain_api_test.exs b/test/sanbase_web/graphql/blockchain/available_blockchain_api_test.exs index b8360a8d4a..bb1337de78 100644 --- a/test/sanbase_web/graphql/blockchain/available_blockchain_api_test.exs +++ b/test/sanbase_web/graphql/blockchain/available_blockchain_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.AvailableBlockchainApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/changelog/changelog_api_test.exs b/test/sanbase_web/graphql/changelog/changelog_api_test.exs index 7c76c33fcb..9f5f975556 100644 --- a/test/sanbase_web/graphql/changelog/changelog_api_test.exs +++ b/test/sanbase_web/graphql/changelog/changelog_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ChangelogApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true test "get metrics changelog", context do query = """ diff --git a/test/sanbase_web/graphql/chart/chart_configuration_api_test.exs b/test/sanbase_web/graphql/chart/chart_configuration_api_test.exs index ad10ae8217..6f0c8984f4 100644 --- a/test/sanbase_web/graphql/chart/chart_configuration_api_test.exs +++ b/test/sanbase_web/graphql/chart/chart_configuration_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ChartConfigurationApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/clickhouse/api_call_data_api_test.exs b/test/sanbase_web/graphql/clickhouse/api_call_data_api_test.exs index 4a4cbf7423..230f907f6a 100644 --- a/test/sanbase_web/graphql/clickhouse/api_call_data_api_test.exs +++ b/test/sanbase_web/graphql/clickhouse/api_call_data_api_test.exs @@ -281,7 +281,7 @@ defmodule SanbaseWeb.Graphql.ApiCallDataApiTest do # so casing unification is tested query = """ { - get_metric(metric: "#{metric}") { + getMetric(metric: "#{metric}") { timeseriesDataJson(slug: "#{slug}", from: "#{from}", to: "#{to}", interval: "#{interval}") } } """ diff --git a/test/sanbase_web/graphql/comments/comments_feed_api_test.exs b/test/sanbase_web/graphql/comments/comments_feed_api_test.exs index 7efa7d2c9c..6a64e955a5 100644 --- a/test/sanbase_web/graphql/comments/comments_feed_api_test.exs +++ b/test/sanbase_web/graphql/comments/comments_feed_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.Comments.CommentsFeedApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/context_plug_test.exs b/test/sanbase_web/graphql/context_plug_test.exs index 54d28b57f6..420a0367d3 100644 --- a/test/sanbase_web/graphql/context_plug_test.exs +++ b/test/sanbase_web/graphql/context_plug_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ContextPlugTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/custom_types/interval_type_test.exs b/test/sanbase_web/graphql/custom_types/interval_type_test.exs index 6b9055cf77..8854f8bd97 100644 --- a/test/sanbase_web/graphql/custom_types/interval_type_test.exs +++ b/test/sanbase_web/graphql/custom_types/interval_type_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.CustomTypes.IntervalTypeTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/dashboards/dashboard_widgets_api_test.exs b/test/sanbase_web/graphql/dashboards/dashboard_widgets_api_test.exs index 621908b9e7..c85a7e79be 100644 --- a/test/sanbase_web/graphql/dashboards/dashboard_widgets_api_test.exs +++ b/test/sanbase_web/graphql/dashboards/dashboard_widgets_api_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.DashboardsWidgetsApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/entity/get_most_recent_api_test.exs b/test/sanbase_web/graphql/entity/get_most_recent_api_test.exs index 19c271c935..ff220ace8a 100644 --- a/test/sanbase_web/graphql/entity/get_most_recent_api_test.exs +++ b/test/sanbase_web/graphql/entity/get_most_recent_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.GetMostRecentApiTest do - use SanbaseWeb.ConnCase, async: true + use SanbaseWeb.ConnCase, async: false import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/featured_item/featured_insight_voting_test.exs b/test/sanbase_web/graphql/featured_item/featured_insight_voting_test.exs index cfa25b758b..ac8d775059 100644 --- a/test/sanbase_web/graphql/featured_item/featured_insight_voting_test.exs +++ b/test/sanbase_web/graphql/featured_item/featured_insight_voting_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.FeaturedInsihgtVotingTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/featured_item/featured_item_api_test.exs b/test/sanbase_web/graphql/featured_item/featured_item_api_test.exs index 97cb027612..4109371615 100644 --- a/test/sanbase_web/graphql/featured_item/featured_item_api_test.exs +++ b/test/sanbase_web/graphql/featured_item/featured_item_api_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.FeaturedItemApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/file_upload_test.exs b/test/sanbase_web/graphql/file_upload_test.exs index 96d56773b7..d699cca145 100644 --- a/test/sanbase_web/graphql/file_upload_test.exs +++ b/test/sanbase_web/graphql/file_upload_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.FileUploadTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias Sanbase.Accounts.User alias Sanbase.Repo diff --git a/test/sanbase_web/graphql/helpers/utils_test.exs b/test/sanbase_web/graphql/helpers/utils_test.exs index eea9f193d8..7dc3d349c0 100644 --- a/test/sanbase_web/graphql/helpers/utils_test.exs +++ b/test/sanbase_web/graphql/helpers/utils_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.Helpers.UtilsTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias SanbaseWeb.Graphql.Helpers.CalibrateInterval diff --git a/test/sanbase_web/graphql/insight/insight_voting_api_test.exs b/test/sanbase_web/graphql/insight/insight_voting_api_test.exs index fc0755eca7..4795ac80d2 100644 --- a/test/sanbase_web/graphql/insight/insight_voting_api_test.exs +++ b/test/sanbase_web/graphql/insight/insight_voting_api_test.exs @@ -1,5 +1,5 @@ defmodule Sanbase.InsihgtVotingApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/insight/paywalled_insights_api_test.exs b/test/sanbase_web/graphql/insight/paywalled_insights_api_test.exs index c40e343fc4..45a49e4dee 100644 --- a/test/sanbase_web/graphql/insight/paywalled_insights_api_test.exs +++ b/test/sanbase_web/graphql/insight/paywalled_insights_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.PaywalledInsightApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/insight/popular_insight_author_api_test.exs b/test/sanbase_web/graphql/insight/popular_insight_author_api_test.exs index 9859e80a4c..cf90f5e014 100644 --- a/test/sanbase_web/graphql/insight/popular_insight_author_api_test.exs +++ b/test/sanbase_web/graphql/insight/popular_insight_author_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.PopularInsightAuthorApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/insight/pulse_insight_api_test.exs b/test/sanbase_web/graphql/insight/pulse_insight_api_test.exs index e7a13b314a..26d8c1f57b 100644 --- a/test/sanbase_web/graphql/insight/pulse_insight_api_test.exs +++ b/test/sanbase_web/graphql/insight/pulse_insight_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.PulseInsightApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/insight/timeline_event_comment_api_test.exs b/test/sanbase_web/graphql/insight/timeline_event_comment_api_test.exs index ea7e29ce68..7f9fb86f76 100644 --- a/test/sanbase_web/graphql/insight/timeline_event_comment_api_test.exs +++ b/test/sanbase_web/graphql/insight/timeline_event_comment_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.TimelineEventCommentApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import Sanbase.TestHelpers diff --git a/test/sanbase_web/graphql/market_segment_resolver_test.exs b/test/sanbase_web/graphql/market_segment_resolver_test.exs index 4d59792b68..9d9cfed298 100644 --- a/test/sanbase_web/graphql/market_segment_resolver_test.exs +++ b/test/sanbase_web/graphql/market_segment_resolver_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.MarketSegmentResolverTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/menus/menu_api_test.exs b/test/sanbase_web/graphql/menus/menu_api_test.exs index 6832d5eaaa..aa16da13af 100644 --- a/test/sanbase_web/graphql/menus/menu_api_test.exs +++ b/test/sanbase_web/graphql/menus/menu_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.MenuApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/metric/api_metric_broken_data_test.exs b/test/sanbase_web/graphql/metric/api_metric_broken_data_test.exs index c093dae4d0..eaadc7182c 100644 --- a/test/sanbase_web/graphql/metric/api_metric_broken_data_test.exs +++ b/test/sanbase_web/graphql/metric/api_metric_broken_data_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ApiMetricBrokenDataTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/metric/api_metric_display_order_test.exs b/test/sanbase_web/graphql/metric/api_metric_display_order_test.exs index 1c03ff5e97..883195ec05 100644 --- a/test/sanbase_web/graphql/metric/api_metric_display_order_test.exs +++ b/test/sanbase_web/graphql/metric/api_metric_display_order_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ApiMetricDisplayOrderTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/metric/api_metric_required_selectors_test.exs b/test/sanbase_web/graphql/metric/api_metric_required_selectors_test.exs index 38eed08397..35db035b44 100644 --- a/test/sanbase_web/graphql/metric/api_metric_required_selectors_test.exs +++ b/test/sanbase_web/graphql/metric/api_metric_required_selectors_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ApiMetricRequiredSelectorsTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/middlewares/multiple_auth_test.exs b/test/sanbase_web/graphql/middlewares/multiple_auth_test.exs index 1223b6fbab..ee4552c535 100644 --- a/test/sanbase_web/graphql/middlewares/multiple_auth_test.exs +++ b/test/sanbase_web/graphql/middlewares/multiple_auth_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.Middlewares.MultipleAuthTest do - use Sanbase.DataCase, async: false + use Sanbase.DataCase, async: true alias SanbaseWeb.Graphql.Middlewares.MultipleAuth diff --git a/test/sanbase_web/graphql/monitored_twitter_handle/monitored_twitter_handle_api_test.exs b/test/sanbase_web/graphql/monitored_twitter_handle/monitored_twitter_handle_api_test.exs index 247cbbefd9..b0ad2768b9 100644 --- a/test/sanbase_web/graphql/monitored_twitter_handle/monitored_twitter_handle_api_test.exs +++ b/test/sanbase_web/graphql/monitored_twitter_handle/monitored_twitter_handle_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.MonitoredTwitterHandleApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/projects/project_api_contract_address_test.exs b/test/sanbase_web/graphql/projects/project_api_contract_address_test.exs index 5f66c79ddc..0527122b54 100644 --- a/test/sanbase_web/graphql/projects/project_api_contract_address_test.exs +++ b/test/sanbase_web/graphql/projects/project_api_contract_address_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiContractAddressTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/projects/project_api_forbidden_fields_test.exs b/test/sanbase_web/graphql/projects/project_api_forbidden_fields_test.exs index 2dbc8cab11..7889349974 100644 --- a/test/sanbase_web/graphql/projects/project_api_forbidden_fields_test.exs +++ b/test/sanbase_web/graphql/projects/project_api_forbidden_fields_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiForbiddenFieldsTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/projects/project_api_get_queries_test.exs b/test/sanbase_web/graphql/projects/project_api_get_queries_test.exs index 3b99ac7cdd..dfe322895a 100644 --- a/test/sanbase_web/graphql/projects/project_api_get_queries_test.exs +++ b/test/sanbase_web/graphql/projects/project_api_get_queries_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiGetQueriesTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/projects/project_api_min_volume_test.exs b/test/sanbase_web/graphql/projects/project_api_min_volume_test.exs index e7ed4e3bde..83c0be9766 100644 --- a/test/sanbase_web/graphql/projects/project_api_min_volume_test.exs +++ b/test/sanbase_web/graphql/projects/project_api_min_volume_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiMinVolumeTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/projects/project_api_social_volume_query_test.exs b/test/sanbase_web/graphql/projects/project_api_social_volume_query_test.exs index 74c373efbd..6e8765d987 100644 --- a/test/sanbase_web/graphql/projects/project_api_social_volume_query_test.exs +++ b/test/sanbase_web/graphql/projects/project_api_social_volume_query_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiSocialVolumeQueryTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/projects/project_api_source_slug_mapping_test.exs b/test/sanbase_web/graphql/projects/project_api_source_slug_mapping_test.exs index 5b95243880..4bfdcf18f8 100644 --- a/test/sanbase_web/graphql/projects/project_api_source_slug_mapping_test.exs +++ b/test/sanbase_web/graphql/projects/project_api_source_slug_mapping_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiSourceSlugMappingTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/projects/project_api_test.exs b/test/sanbase_web/graphql/projects/project_api_test.exs index 1bc79c80d9..c261a721fc 100644 --- a/test/sanbase_web/graphql/projects/project_api_test.exs +++ b/test/sanbase_web/graphql/projects/project_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias Sanbase.Utils.Config diff --git a/test/sanbase_web/graphql/projects/project_hidden_api_test.exs b/test/sanbase_web/graphql/projects/project_hidden_api_test.exs index 5fb4f0aeb5..59a1e748eb 100644 --- a/test/sanbase_web/graphql/projects/project_hidden_api_test.exs +++ b/test/sanbase_web/graphql/projects/project_hidden_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ProjectHiddenApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/questionnaire/questionnaire_api_test.exs b/test/sanbase_web/graphql/questionnaire/questionnaire_api_test.exs index 3fdcc22985..6e5622bfcb 100644 --- a/test/sanbase_web/graphql/questionnaire/questionnaire_api_test.exs +++ b/test/sanbase_web/graphql/questionnaire/questionnaire_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.QuestionnaireApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/short_url/short_url_api_test.exs b/test/sanbase_web/graphql/short_url/short_url_api_test.exs index 422225db73..a98320e9a2 100644 --- a/test/sanbase_web/graphql/short_url/short_url_api_test.exs +++ b/test/sanbase_web/graphql/short_url/short_url_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ShortUrlApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/signal/api_signal_metadata_test.exs b/test/sanbase_web/graphql/signal/api_signal_metadata_test.exs index 242fba8486..8344ba3652 100644 --- a/test/sanbase_web/graphql/signal/api_signal_metadata_test.exs +++ b/test/sanbase_web/graphql/signal/api_signal_metadata_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.Clickhouse.ApiSignalMetadataTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory, only: [rand_str: 0] import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/social_data/popular_search_terms_api_test.exs b/test/sanbase_web/graphql/social_data/popular_search_terms_api_test.exs index ef075a9319..40824f2f93 100644 --- a/test/sanbase_web/graphql/social_data/popular_search_terms_api_test.exs +++ b/test/sanbase_web/graphql/social_data/popular_search_terms_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.SocialData.PopularSearchTermApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/table_configuration/table_configuration_api_test.exs b/test/sanbase_web/graphql/table_configuration/table_configuration_api_test.exs index a131f94ab5..baab2fed95 100644 --- a/test/sanbase_web/graphql/table_configuration/table_configuration_api_test.exs +++ b/test/sanbase_web/graphql/table_configuration/table_configuration_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.TableConfigurationApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/timeline/seen_event_api_test.exs b/test/sanbase_web/graphql/timeline/seen_event_api_test.exs index 3f92ba6dca..b258b7d82a 100644 --- a/test/sanbase_web/graphql/timeline/seen_event_api_test.exs +++ b/test/sanbase_web/graphql/timeline/seen_event_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.SeenEventApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/timeline/timeline_event_api_test.exs b/test/sanbase_web/graphql/timeline/timeline_event_api_test.exs index facfca9f94..496af69f19 100644 --- a/test/sanbase_web/graphql/timeline/timeline_event_api_test.exs +++ b/test/sanbase_web/graphql/timeline/timeline_event_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.TimelineEventApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/user/apikey_resolver_test.exs b/test/sanbase_web/graphql/user/apikey_resolver_test.exs index 5e3c269bc6..047f41653a 100644 --- a/test/sanbase_web/graphql/user/apikey_resolver_test.exs +++ b/test/sanbase_web/graphql/user/apikey_resolver_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ApikeyResolverTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/user/current_user_api_test.exs b/test/sanbase_web/graphql/user/current_user_api_test.exs index c01b8857be..517b04b1e2 100644 --- a/test/sanbase_web/graphql/user/current_user_api_test.exs +++ b/test/sanbase_web/graphql/user/current_user_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.CurrentUserApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/user/following_api_test.exs b/test/sanbase_web/graphql/user/following_api_test.exs index 8202ba2436..774ff34974 100644 --- a/test/sanbase_web/graphql/user/following_api_test.exs +++ b/test/sanbase_web/graphql/user/following_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.User.FollowingApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/graphql/user/public_user_api_test.exs b/test/sanbase_web/graphql/user/public_user_api_test.exs index a4ec081bd0..8e8a940c48 100644 --- a/test/sanbase_web/graphql/user/public_user_api_test.exs +++ b/test/sanbase_web/graphql/user/public_user_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.PublicUserApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/graphql/user/user_eth_account_api_test.exs b/test/sanbase_web/graphql/user/user_eth_account_api_test.exs index 3bc90e676b..75eae9f375 100644 --- a/test/sanbase_web/graphql/user/user_eth_account_api_test.exs +++ b/test/sanbase_web/graphql/user/user_eth_account_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.UserEthAccountApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true alias Sanbase.Accounts.User alias Sanbase.Repo diff --git a/test/sanbase_web/graphql/watchlist/project/watchlist_api_test.exs b/test/sanbase_web/graphql/watchlist/project/watchlist_api_test.exs index 7aa28c4c94..b676f6dbb9 100644 --- a/test/sanbase_web/graphql/watchlist/project/watchlist_api_test.exs +++ b/test/sanbase_web/graphql/watchlist/project/watchlist_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.WatchlistApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.TestHelpers diff --git a/test/sanbase_web/graphql/watchlist/project/watchlist_settings_api_test.exs b/test/sanbase_web/graphql/watchlist/project/watchlist_settings_api_test.exs index cd2964be1f..d38db7f243 100644 --- a/test/sanbase_web/graphql/watchlist/project/watchlist_settings_api_test.exs +++ b/test/sanbase_web/graphql/watchlist/project/watchlist_settings_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.WatchlistSettingsApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.TestHelpers diff --git a/test/sanbase_web/graphql/widget/active_widgets_api_test.exs b/test/sanbase_web/graphql/widget/active_widgets_api_test.exs index db3b8baede..f246dea635 100644 --- a/test/sanbase_web/graphql/widget/active_widgets_api_test.exs +++ b/test/sanbase_web/graphql/widget/active_widgets_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ActiveWidgetsApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import SanbaseWeb.Graphql.TestHelpers import Sanbase.Factory diff --git a/test/sanbase_web/live/admin/ses_events_live_test.exs b/test/sanbase_web/live/admin/ses_events_live_test.exs index 09bfdfd13c..c81de83e14 100644 --- a/test/sanbase_web/live/admin/ses_events_live_test.exs +++ b/test/sanbase_web/live/admin/ses_events_live_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Admin.SesEventsLiveTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true @moduletag capture_log: true diff --git a/test/sanbase_web/reports_api_test.exs b/test/sanbase_web/reports_api_test.exs index 18f56b090e..af83af5a3c 100644 --- a/test/sanbase_web/reports_api_test.exs +++ b/test/sanbase_web/reports_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.ReportsApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/sheets_templates_api_test.exs b/test/sanbase_web/sheets_templates_api_test.exs index 720b4ef77f..0bbba83fce 100644 --- a/test/sanbase_web/sheets_templates_api_test.exs +++ b/test/sanbase_web/sheets_templates_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.SheetsTemplatesApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/sanbase_web/views/error_view_test.exs b/test/sanbase_web/views/error_view_test.exs index 3d3e94129b..0c8e06438d 100644 --- a/test/sanbase_web/views/error_view_test.exs +++ b/test/sanbase_web/views/error_view_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.ErrorViewTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true # Bring render/3 and render_to_string/3 for testing custom views import Phoenix.View diff --git a/test/sanbase_web/webinars_api_test.exs b/test/sanbase_web/webinars_api_test.exs index c46c904651..8aed2bae2b 100644 --- a/test/sanbase_web/webinars_api_test.exs +++ b/test/sanbase_web/webinars_api_test.exs @@ -1,5 +1,5 @@ defmodule SanbaseWeb.Graphql.WebinarsApiTest do - use SanbaseWeb.ConnCase, async: false + use SanbaseWeb.ConnCase, async: true import Sanbase.Factory import SanbaseWeb.Graphql.TestHelpers diff --git a/test/test_helper.exs b/test/test_helper.exs index 1ed8cf75fb..fedd5d924d 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,7 +1,10 @@ {:ok, _} = Application.ensure_all_started(:ex_machina) :erlang.system_flag(:backtrace_depth, 20) -ExUnit.configure(exclude: [skip_suite: true]) +ExUnit.configure( + exclude: [skip_suite: true], + max_cases: System.schedulers_online() * 2 +) # Set test environment variable for OpenAI to prevent runtime errors System.put_env("OPENAI_API_KEY", "test-key-for-testing") diff --git a/test_parallel.sh b/test_parallel.sh new file mode 100755 index 0000000000..fc52a9ad0d --- /dev/null +++ b/test_parallel.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Fail fast on errors, undefined vars, and pipeline failures +set -euo pipefail + +PARTITIONS=${1:-4} +FAILURES_DIR="_build/test/failures" + +# Validate PARTITIONS is a positive integer +if ! [[ "$PARTITIONS" =~ ^[0-9]+$ ]] || [ "$PARTITIONS" -lt 1 ]; then + echo "Usage: $0 [PARTITIONS]" >&2 + echo "PARTITIONS must be a positive integer (default: 4)" >&2 + exit 1 +fi + +# SECONDS is a bash built-in that auto-increments; assigning 0 resets the timer +SECONDS=0 + +echo "==> Running tests with $PARTITIONS partitions" + +rm -rf "$FAILURES_DIR" + +echo "==> Running $PARTITIONS test partitions in parallel" + +# Run each partition in parallel; subshell + pipefail so wait gets pipeline status +pids=() +for i in $(seq 1 "$PARTITIONS"); do + ( + set -euo pipefail + MIX_TEST_PARTITION=$i mix test --partitions "$PARTITIONS" \ + --formatter Sanbase.FailedTestFormatter \ + --formatter ExUnit.CLIFormatter \ + --trace \ + 2>&1 | sed "s/^/[partition $i] /" + ) & + pids+=($!) +done + +# Capture any partition failure; || prevents set -e from exiting early +exit_code=0 +for pid in "${pids[@]}"; do + wait "$pid" || exit_code=1 +done + +echo "" +echo "========================================" +echo " Combined results from all partitions" +echo "========================================" + +if ls "$FAILURES_DIR"/partition_*.txt 1>/dev/null 2>&1; then + error_tests=() + exit_tests=() + invalid_tests=() + + # || [[ -n "${kind:-}" ]] handles files without trailing newline (read returns false at EOF) + for f in "$FAILURES_DIR"/partition_*.txt; do + while IFS=$'\t' read -r kind test_id || [[ -n "${kind:-}" ]]; do + case "$kind" in + error) error_tests+=("$test_id") ;; + exit) exit_tests+=("$test_id") ;; + invalid) invalid_tests+=("$test_id") ;; + esac + done <"$f" + done + + RED='\033[0;31m' + YELLOW='\033[0;33m' + NC='\033[0m' + + total=$((${#error_tests[@]} + ${#exit_tests[@]} + ${#invalid_tests[@]})) + echo -e "${RED}$total failing test(s) across all partitions:${NC}" + + if [ ${#error_tests[@]} -gt 0 ]; then + echo -e "\n${RED}Error tests (${#error_tests[@]}):${NC}" + for t in "${error_tests[@]}"; do echo " $t"; done + fi + + if [ ${#exit_tests[@]} -gt 0 ]; then + echo -e "\n${YELLOW}Exit tests (${#exit_tests[@]}):${NC}" + for t in "${exit_tests[@]}"; do echo " $t"; done + fi + + if [ ${#invalid_tests[@]} -gt 0 ]; then + echo -e "\n${YELLOW}Invalid tests (${#invalid_tests[@]}):${NC}" + for t in "${invalid_tests[@]}"; do echo " $t"; done + fi + + echo "" + echo "Re-run all failing tests with:" + all_tests=("${error_tests[@]}" "${exit_tests[@]}" "${invalid_tests[@]}") + # printf %q safely escapes test names with spaces or special chars for copy-paste + printf ' mix test' + printf ' %q' "${all_tests[@]}" + echo +else + echo -e "\033[0;32mAll $PARTITIONS partitions passed!\033[0m" +fi + +elapsed=$SECONDS +mins=$((elapsed / 60)) +secs=$((elapsed % 60)) +echo "" +echo "Total time: ${mins}m ${secs}s" + +exit $exit_code