diff --git a/.github/workflows/part_test.yml b/.github/workflows/part_test.yml index 2d594192..b82f109a 100644 --- a/.github/workflows/part_test.yml +++ b/.github/workflows/part_test.yml @@ -7,6 +7,33 @@ env: BUILD_EMBEDDED: true jobs: + detectToolVersions: + name: "Detect Tool Versions" + + runs-on: ubuntu-latest + + outputs: + otpVersion: "${{ steps.toolVersions.outputs.OTP_VERSION }}" + elixirVersion: "${{ steps.toolVersions.outputs.ELIXIR_VERSION }}" + + steps: + - name: Harden Runner + uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: audit + + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: "Read .tool-versions" + id: toolVersions + run: | + OTP_VERSION="$(cat .tool-versions | grep erlang | cut -d' ' -f2-)" + echo OTP: $OTP_VERSION + echo "OTP_VERSION=${OTP_VERSION}" >> $GITHUB_OUTPUT + + ELIXIR_VERSION="$(cat .tool-versions | grep elixir | cut -d' ' -f2-)" + echo Rebar: $ELIXIR_VERSION + echo "ELIXIR_VERSION=${ELIXIR_VERSION}" >> $GITHUB_OUTPUT + format: name: Check Formatting @@ -39,26 +66,32 @@ jobs: - run: mix format --check-formatted test: - name: Run Tests & Submit Coverage + name: Run Tests & Submit Coverage (${{ matrix.name }}) - runs-on: ubuntu-latest + needs: ["detectToolVersions"] + + runs-on: ${{ matrix.runs-on }} strategy: fail-fast: false matrix: include: - - otp: '24.3' - elixir: '1.12' - - otp: '25.2' - elixir: '1.13' - - otp: '25.2' - elixir: '1.14' - - otp: '26.1' - elixir: '1.15' - - otp: '26.1' - elixir: 'main' - - currentMainVersion: true - enable_coverage_export: 'true' + # Lowest Supported + - otp: "24.2" + elixir: "1.15" + runs-on: ubuntu-22.04 + name: "lowest" + # Latest Supported + - otp: "${{ needs.detectToolVersions.outputs.otpVersion }}" + elixir: "${{ needs.detectToolVersions.outputs.elixirVersion }}" + runs-on: ubuntu-24.04 + name: "latest" + enable_coverage_export: "true" + # Test Main + - otp: "${{ needs.detectToolVersions.outputs.otpVersion }}" + elixir: "main" + runs-on: ubuntu-24.04 + name: "main" env: MIX_ENV: test @@ -66,30 +99,23 @@ jobs: steps: - uses: actions/checkout@v4 - uses: erlef/setup-elixir@v1 - if: ${{ !matrix.currentMainVersion }} - id: setupBEAMDynamic + id: setupBEAM with: otp-version: ${{ matrix.otp }} elixir-version: ${{ matrix.elixir }} - - uses: erlef/setup-elixir@v1 - if: ${{ matrix.currentMainVersion }} - id: setupBEAMCurrent - with: - version-file: '.tool-versions' - version-type: strict - uses: actions/cache@v4 with: path: deps - key: deps-${{ runner.os }}-${{ steps.setupBEAMCurrent.outputs.otp-version }}${{ steps.setupBEAMDynamic.outputs.otp-version }}-${{ steps.setupBEAMCurrent.outputs.elixir-version }}${{ steps.setupBEAMDynamic.outputs.elixir-version }}-${{ hashFiles('mix.lock') }} + key: deps-${{ runner.os }}-${{ steps.setupBEAM.outputs.otp-version }}-${{ steps.setupBEAM.outputs.elixir-version }}-${{ hashFiles('mix.lock') }} restore-keys: | - deps-${{ runner.os }}-${{ steps.setupBEAMCurrent.outputs.otp-version }}${{ steps.setupBEAMDynamic.outputs.otp-version }}-${{ steps.setupBEAMCurrent.outputs.elixir-version }}${{ steps.setupBEAMDynamic.outputs.elixir-version }}- + deps-${{ runner.os }}-${{ steps.setupBEAM.outputs.otp-version }}-${{ steps.setupBEAM.outputs.elixir-version }}- - run: mix deps.get - uses: actions/cache@v4 with: path: _build/test - key: compile-${{ env.MIX_ENV }}-${{ runner.os }}-${{ steps.setupBEAMCurrent.outputs.otp-version }}${{ steps.setupBEAMDynamic.outputs.otp-version }}-${{ steps.setupBEAMCurrent.outputs.elixir-version }}${{ steps.setupBEAMDynamic.outputs.elixir-version }}-${{ hashFiles('mix.lock') }} + key: compile-${{ env.MIX_ENV }}-${{ runner.os }}-${{ steps.setupBEAM.outputs.otp-version }}-${{ steps.setupBEAM.outputs.elixir-version }}-${{ hashFiles('mix.lock') }} restore-keys: | - compile-${{ env.MIX_ENV }}-${{ runner.os }}-${{ steps.setupBEAMCurrent.outputs.otp-version }}${{ steps.setupBEAMDynamic.outputs.otp-version }}-${{ steps.setupBEAMCurrent.outputs.elixir-version }}${{ steps.setupBEAMDynamic.outputs.elixir-version }}- + compile-${{ env.MIX_ENV }}-${{ runner.os }}-${{ steps.setupBEAM.outputs.otp-version }}-${{ steps.setupBEAM.outputs.elixir-version }}- - run: mix deps.compile - run: mix compile --warning-as-errors - run: mix coveralls.github diff --git a/lib/quantum/clock_broadcaster.ex b/lib/quantum/clock_broadcaster.ex index d84e134f..934559aa 100644 --- a/lib/quantum/clock_broadcaster.ex +++ b/lib/quantum/clock_broadcaster.ex @@ -44,11 +44,11 @@ defmodule Quantum.ClockBroadcaster do |> storage.last_execution_date() |> case do :unknown -> start_time - date -> date + date -> DateTime.from_naive!(date, "Etc/UTC") end - |> NaiveDateTime.truncate(:second) + |> DateTime.truncate(:second) # Roll back one second since handle_tick will start at `now + 1`. - |> NaiveDateTime.add(-1, :second) + |> DateTime.add(-1, :second) :timer.send_interval(1000, :tick) @@ -80,16 +80,16 @@ defmodule Quantum.ClockBroadcaster do defp handle_tick(%State{remaining_demand: remaining_demand, time: time} = state) when remaining_demand > 0 do - now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + now = DateTime.truncate(DateTime.utc_now(), :second) {events, new_time} = Enum.reduce_while( 1..remaining_demand, {[], time}, fn _, {list, time} = acc -> - new_time = NaiveDateTime.add(time, 1, :second) + new_time = DateTime.add(time, 1, :second) - case NaiveDateTime.compare(new_time, now) do + case DateTime.compare(new_time, now) do :lt -> {:cont, {[%Event{time: new_time, catch_up: true} | list], new_time}} diff --git a/lib/quantum/clock_broadcaster/event.ex b/lib/quantum/clock_broadcaster/event.ex index e16a2d95..49878d83 100644 --- a/lib/quantum/clock_broadcaster/event.ex +++ b/lib/quantum/clock_broadcaster/event.ex @@ -4,7 +4,7 @@ defmodule Quantum.ClockBroadcaster.Event do # Clock Event @type t :: %__MODULE__{ - time: NaiveDateTime.t(), + time: DateTime.t(), catch_up: boolean() } diff --git a/lib/quantum/clock_broadcaster/init_opts.ex b/lib/quantum/clock_broadcaster/init_opts.ex index 66629de5..8078f513 100644 --- a/lib/quantum/clock_broadcaster/init_opts.ex +++ b/lib/quantum/clock_broadcaster/init_opts.ex @@ -6,7 +6,7 @@ defmodule Quantum.ClockBroadcaster.InitOpts do alias Quantum.{Scheduler, Storage} @type t :: %__MODULE__{ - start_time: NaiveDateTime.t(), + start_time: DateTime.t(), storage: Storage, scheduler: Scheduler, debug_logging: boolean() diff --git a/lib/quantum/clock_broadcaster/start_opts.ex b/lib/quantum/clock_broadcaster/start_opts.ex index b6150a02..0382d039 100644 --- a/lib/quantum/clock_broadcaster/start_opts.ex +++ b/lib/quantum/clock_broadcaster/start_opts.ex @@ -7,7 +7,7 @@ defmodule Quantum.ClockBroadcaster.StartOpts do @type t :: %__MODULE__{ name: GenServer.server(), - start_time: NaiveDateTime.t(), + start_time: DateTime.t(), storage: Storage, scheduler: Scheduler, debug_logging: boolean() diff --git a/lib/quantum/clock_broadcaster/state.ex b/lib/quantum/clock_broadcaster/state.ex index 7ec15745..0f49306a 100644 --- a/lib/quantum/clock_broadcaster/state.ex +++ b/lib/quantum/clock_broadcaster/state.ex @@ -5,7 +5,7 @@ defmodule Quantum.ClockBroadcaster.State do @type t :: %__MODULE__{ debug_logging: boolean(), - time: NaiveDateTime.t(), + time: DateTime.t(), remaining_demand: non_neg_integer } diff --git a/lib/quantum/date_library.ex b/lib/quantum/date_library.ex deleted file mode 100644 index cdff2e57..00000000 --- a/lib/quantum/date_library.ex +++ /dev/null @@ -1,80 +0,0 @@ -defmodule Quantum.DateLibrary do - @moduledoc false - - require Logger - - alias Quantum.DateLibrary.{InvalidDateTimeForTimezoneError, InvalidTimezoneError} - - # Convert Date to Utc - @spec to_utc!(NaiveDateTime.t(), :utc | String.t()) :: NaiveDateTime.t() - - def to_utc!(date, :utc), do: date - - def to_utc!(date, tz) when is_binary(tz) do - dt = - case DateTime.from_naive(date, tz) do - {:ok, dt} -> - dt - - {:ambiguous, _, _} -> - raise InvalidDateTimeForTimezoneError - - {:gap, _, _} -> - raise InvalidDateTimeForTimezoneError - - {:error, :incompatible_calendars} -> - raise InvalidDateTimeForTimezoneError - - {:error, :time_zone_not_found} -> - raise InvalidTimezoneError - - {:error, :utc_only_time_zone_database} -> - Logger.warning("Timezone database not set up") - raise InvalidTimezoneError - end - - case DateTime.shift_zone(dt, "Etc/UTC") do - {:ok, dt} -> - DateTime.to_naive(dt) - - {:error, :utc_only_time_zone_database} -> - Logger.warning("Timezone database not set up") - raise InvalidTimezoneError - end - end - - # Convert Date to TZ - @spec to_tz!(NaiveDateTime.t(), :utc | String.t()) :: NaiveDateTime.t() - def to_tz!(date, :utc), do: date - - def to_tz!(date, tz) when is_binary(tz) do - result = - date - |> DateTime.from_naive!("Etc/UTC") - |> DateTime.shift_zone(tz) - - case result do - {:ok, dt} -> - DateTime.to_naive(dt) - - {:error, :time_zone_not_found} -> - raise InvalidTimezoneError - - {:error, :utc_only_time_zone_database} -> - Logger.warning("Timezone database not set up") - raise InvalidTimezoneError - end - end - - defmodule InvalidDateTimeForTimezoneError do - @moduledoc false - - defexception message: "The requested time does not exist in the given timezone." - end - - defmodule InvalidTimezoneError do - @moduledoc false - - defexception message: "The requested timezone is invalid." - end -end diff --git a/lib/quantum/execution_broadcaster.ex b/lib/quantum/execution_broadcaster.ex index 4a019543..3f4a5d96 100644 --- a/lib/quantum/execution_broadcaster.ex +++ b/lib/quantum/execution_broadcaster.ex @@ -12,12 +12,6 @@ defmodule Quantum.ExecutionBroadcaster do alias Quantum.ClockBroadcaster.Event, as: ClockEvent - alias Quantum.{ - DateLibrary, - DateLibrary.InvalidDateTimeForTimezoneError, - DateLibrary.InvalidTimezoneError - } - alias Quantum.ExecutionBroadcaster.Event, as: ExecuteEvent alias Quantum.ExecutionBroadcaster.InitOpts alias Quantum.ExecutionBroadcaster.State @@ -202,7 +196,7 @@ defmodule Quantum.ExecutionBroadcaster do } = state, time ) do - case NaiveDateTime.compare(time, time_to_execute) do + case DateTime.compare(time, time_to_execute) do :gt -> raise "Jobs were skipped" @@ -226,7 +220,7 @@ defmodule Quantum.ExecutionBroadcaster do jobs |> Enum.reduce( %{state | execution_timeline: tail}, - &add_job_to_state(&1, &2, NaiveDateTime.add(time, 1, :second)) + &add_job_to_state(&1, &2, DateTime.add(time, 1, :second)) ) |> sort_state |> execute_events_to_fire(time) @@ -240,11 +234,17 @@ defmodule Quantum.ExecutionBroadcaster do state, time ) do - job - |> get_next_execution_time(time) - |> case do - {:ok, date} -> - add_to_state(state, time, date, job) + with {:ok, execution_date} <- get_next_execution_time(job, time) do + add_to_state(state, time, execution_date, job) + else + {:error, :time_zone_not_found} -> + Logger.error( + "Invalid Timezone #{inspect(timezone)} provided for job #{inspect(name)}.", + job: job, + error: :time_zone_not_found + ) + + state {:error, _} -> Logger.warning(fn -> @@ -256,54 +256,32 @@ defmodule Quantum.ExecutionBroadcaster do state end - rescue - e in InvalidTimezoneError -> - Logger.error( - "Invalid Timezone #{inspect(timezone)} provided for job #{inspect(name)}.", - job: job, - error: e - ) - - state end defp get_next_execution_time( - %Job{schedule: schedule, timezone: timezone, name: name} = job, + %Job{schedule: schedule, timezone: :utc}, time ) do - schedule - |> CrontabScheduler.get_next_run_date(DateLibrary.to_tz!(time, timezone)) - |> case do - {:ok, date} -> - {:ok, DateLibrary.to_utc!(date, timezone)} + CrontabScheduler.get_next_run_date(schedule, time) + end - {:error, _} = error -> - error + defp get_next_execution_time( + %Job{schedule: schedule, timezone: timezone}, + time + ) do + with {:ok, localized_time} <- DateTime.shift_zone(time, timezone), + {:ok, localized_execution_time} <- + CrontabScheduler.get_next_run_date(schedule, localized_time) do + DateTime.shift_zone(localized_execution_time, "Etc/UTC") end - rescue - _ in InvalidDateTimeForTimezoneError -> - next_time = NaiveDateTime.add(time, 60, :second) - - Logger.warning(fn -> - """ - Next execution time for job #{inspect(name)} is not a valid time. - Retrying with #{inspect(next_time)} - """ - end) - - get_next_execution_time(job, next_time) end defp sort_state(%State{execution_timeline: execution_timeline} = state) do - %{ - state - | execution_timeline: - Enum.sort_by(execution_timeline, fn {date, _} -> NaiveDateTime.to_erl(date) end) - } + %{state | execution_timeline: Enum.sort_by(execution_timeline, &elem(&1, 0), DateTime)} end defp add_to_state(%State{execution_timeline: execution_timeline} = state, time, date, job) do - unless NaiveDateTime.compare(time, date) in [:lt, :eq] do + unless DateTime.compare(time, date) in [:lt, :eq] do raise Quantum.ExecutionBroadcaster.JobInPastError end diff --git a/lib/quantum/execution_broadcaster/state.ex b/lib/quantum/execution_broadcaster/state.ex index 20af38cf..ed885b13 100644 --- a/lib/quantum/execution_broadcaster/state.ex +++ b/lib/quantum/execution_broadcaster/state.ex @@ -8,7 +8,7 @@ defmodule Quantum.ExecutionBroadcaster.State do @type t :: %__MODULE__{ uninitialized_jobs: [Job.t()], - execution_timeline: [{NaiveDateTime.t(), [Job.t()]}], + execution_timeline: [{DateTime.t(), [Job.t()]}], storage: StorageAdapter, storage_pid: StorageAdapter.storage_pid(), scheduler: Quantum, diff --git a/lib/quantum/storage.ex b/lib/quantum/storage.ex index f88e9af9..238d1b34 100644 --- a/lib/quantum/storage.ex +++ b/lib/quantum/storage.ex @@ -62,14 +62,14 @@ defmodule Quantum.Storage do Returns `:unknown` if the storage does not know the last execution time. In this case all jobs will be run at the next applicable date. """ - @callback last_execution_date(storage_pid :: storage_pid) :: :unknown | NaiveDateTime.t() + @callback last_execution_date(storage_pid :: storage_pid) :: :unknown | DateTime.t() @doc """ Update last execution time to given date. """ @callback update_last_execution_date( storage_pid :: storage_pid, - last_execution_date :: NaiveDateTime.t() + last_execution_date :: DateTime.t() ) :: :ok @doc """ diff --git a/lib/quantum/supervisor.ex b/lib/quantum/supervisor.ex index eb2a315a..7aba015f 100644 --- a/lib/quantum/supervisor.ex +++ b/lib/quantum/supervisor.ex @@ -46,7 +46,7 @@ defmodule Quantum.Supervisor do opts |> Map.take([:debug_logging, :storage, :scheduler]) |> Map.put(:name, clock_broadcaster_name) - |> Map.put(:start_time, NaiveDateTime.utc_now()) + |> Map.put(:start_time, DateTime.utc_now()) ) job_broadcaster_opts = diff --git a/mix.exs b/mix.exs index 4b09fd76..89c9624b 100644 --- a/mix.exs +++ b/mix.exs @@ -13,7 +13,7 @@ defmodule Quantum.Mixfile do deps: deps(), description: "Cron-like job scheduler for Elixir.", docs: docs(), - elixir: "~> 1.12", + elixir: "~> 1.15", name: "Quantum", elixirc_paths: elixirc_paths(Mix.env()), package: package(), @@ -100,7 +100,7 @@ defmodule Quantum.Mixfile do defp deps do [ - {:crontab, "~> 1.1"}, + {:crontab, "~> 1.2"}, {:gen_stage, "~> 0.14 or ~> 1.0"}, {:telemetry, "~> 0.4.3 or ~> 1.0"}, {:tzdata, "~> 1.0", only: [:dev, :test]}, diff --git a/test/quantum/clock_broadcaster_test.exs b/test/quantum/clock_broadcaster_test.exs index bea22b4d..8d7c1d17 100644 --- a/test/quantum/clock_broadcaster_test.exs +++ b/test/quantum/clock_broadcaster_test.exs @@ -32,7 +32,7 @@ defmodule Quantum.ClockBroadcasterTest do |> stream_broadcaster!() |> Stream.take(@listen_events) |> Stream.each(fn event -> - send(self, {:event, event, NaiveDateTime.utc_now()}) + send(self, {:event, event, DateTime.utc_now()}) end) |> Enum.to_list() @@ -46,7 +46,7 @@ defmodule Quantum.ClockBroadcasterTest do test "catches up fast and then one every second", %{test: test} do self = self() - start_time = NaiveDateTime.add(NaiveDateTime.utc_now(), -@listen_events, :second) + start_time = DateTime.add(DateTime.utc_now(), -@listen_events, :second) test |> stream_broadcaster!(start_time: start_time) @@ -68,7 +68,7 @@ defmodule Quantum.ClockBroadcasterTest do test "should wait for future date until", %{test: test} do self = self() - start_time = NaiveDateTime.add(NaiveDateTime.utc_now(), 2, :second) + start_time = DateTime.add(DateTime.utc_now(), 2, :second) test |> stream_broadcaster!(start_time: start_time) @@ -84,14 +84,14 @@ defmodule Quantum.ClockBroadcasterTest do end defp receive_send(pid, event) do - send(pid, {:event, event, NaiveDateTime.utc_now()}) + send(pid, {:event, event, DateTime.utc_now()}) end defp assert_live_event(message) do assert {:event, %Event{ time: - %NaiveDateTime{ + %DateTime{ year: year, month: month, day: day, @@ -101,7 +101,7 @@ defmodule Quantum.ClockBroadcasterTest do } = event_time, catch_up: false }, - %NaiveDateTime{ + %DateTime{ year: year, month: month, day: day, @@ -110,7 +110,7 @@ defmodule Quantum.ClockBroadcasterTest do second: second } = receive_time} = message - assert NaiveDateTime.diff(event_time, receive_time, :millisecond) < 100 + assert DateTime.diff(event_time, receive_time, :millisecond) < 100 end defp assert_catch_up_event(message) do @@ -129,7 +129,7 @@ defmodule Quantum.ClockBroadcasterTest do [ name: Module.concat(__MODULE__, test), debug_logging: false, - start_time: NaiveDateTime.utc_now(), + start_time: DateTime.utc_now(), storage: Quantum.Storage.Test, scheduler: NotNeeded ], diff --git a/test/quantum/date_library_test.exs b/test/quantum/date_library_test.exs deleted file mode 100644 index c50715cf..00000000 --- a/test/quantum/date_library_test.exs +++ /dev/null @@ -1,41 +0,0 @@ -defmodule Quantum.DateLibraryTest do - use ExUnit.Case, async: true - - alias Quantum.DateLibrary - - describe "to_tz!/2" do - test "shifts zone" do - date = ~N[2015-01-01 01:00:00] - expected = ~N[2015-01-01 02:00:00] - - assert DateLibrary.to_tz!(date, "Europe/Copenhagen") == expected - end - - test "errors with invalid timezone" do - assert_raise Quantum.DateLibrary.InvalidTimezoneError, fn -> - DateLibrary.to_tz!(~N[2018-03-25 02:00:00], "Foobar") - end - end - end - - describe "to_utc!/2" do - test "shifts zone" do - date = ~N[2015-01-01 02:00:00] - expected = ~N[2015-01-01 01:00:00] - - assert DateLibrary.to_utc!(date, "Europe/Copenhagen") == expected - end - - test "detects non-existent times" do - assert_raise Quantum.DateLibrary.InvalidDateTimeForTimezoneError, fn -> - DateLibrary.to_utc!(~N[2018-03-25 02:00:00], "Europe/Zurich") - end - end - - test "errors with invalid timezone" do - assert_raise Quantum.DateLibrary.InvalidTimezoneError, fn -> - DateLibrary.to_utc!(~N[2018-03-25 02:00:00], "Foobar") - end - end - end -end diff --git a/test/quantum/execution_broadcaster_test.exs b/test/quantum/execution_broadcaster_test.exs index 9f3ae280..20d85283 100644 --- a/test/quantum/execution_broadcaster_test.exs +++ b/test/quantum/execution_broadcaster_test.exs @@ -66,7 +66,7 @@ defmodule Quantum.ExecutionBroadcasterTest do # Some schedule that is valid but will not trigger the next 10 years non_reboot_job = TestScheduler.new_job() - |> Job.set_schedule(~e[* * * * * #{NaiveDateTime.utc_now().year + 1}]) + |> Job.set_schedule(~e[* * * * * #{DateTime.utc_now().year + 1}]) capture_log(fn -> TestProducer.send(producer, {:add, reboot_job}) @@ -94,13 +94,13 @@ defmodule Quantum.ExecutionBroadcasterTest do TestProducer.send(producer, {:add, job}) spawn(fn -> - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) Process.sleep(1_000) TestProducer.send(producer, %ClockEvent{ - time: NaiveDateTime.add(now, 1, :second), + time: DateTime.add(now, 1, :second), catch_up: false }) end) @@ -118,10 +118,10 @@ defmodule Quantum.ExecutionBroadcasterTest do capture_log(fn -> TestProducer.send(producer, {:add, job}) - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) - assert_receive {:update_last_execution_date, %NaiveDateTime{}, _}, @max_timeout + assert_receive {:update_last_execution_date, %DateTime{}, _}, @max_timeout assert_receive {:received, %ExecuteEvent{job: ^job}}, @max_timeout end) @@ -137,8 +137,8 @@ defmodule Quantum.ExecutionBroadcasterTest do TestProducer.send(producer, {:add, job}) spawn(fn -> - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} - add1 = NaiveDateTime.add(now, 1, :second) + now = DateTime.truncate(DateTime.utc_now(), :second) + add1 = DateTime.add(now, 1, :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) Process.sleep(1_000) TestProducer.send(producer, %ClockEvent{time: add1, catch_up: false}) @@ -158,7 +158,7 @@ defmodule Quantum.ExecutionBroadcasterTest do assert capture_log(fn -> TestProducer.send(producer, {:add, job}) - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) refute_receive {:received, %ExecuteEvent{job: ^job}}, @max_timeout @@ -177,7 +177,7 @@ defmodule Quantum.ExecutionBroadcasterTest do assert capture_log(fn -> TestProducer.send(producer, {:add, job}) - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) refute_receive {:received, %ExecuteEvent{job: ^job}}, @max_timeout @@ -197,7 +197,7 @@ defmodule Quantum.ExecutionBroadcasterTest do capture_log(fn -> TestProducer.send(producer, {:add, job}) - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) assert_receive {:received, %ExecuteEvent{job: ^job}}, @max_timeout @@ -205,7 +205,7 @@ defmodule Quantum.ExecutionBroadcasterTest do TestProducer.send(producer, {:add, job_new}) TestProducer.send(producer, %ClockEvent{ - time: NaiveDateTime.add(now, 1, :second), + time: DateTime.add(now, 1, :second), catch_up: false }) @@ -226,7 +226,7 @@ defmodule Quantum.ExecutionBroadcasterTest do TestProducer.send(producer, {:add, job}) TestProducer.send(producer, {:add, job_new}) - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) assert_receive {:received, %ExecuteEvent{job: ^job_new}}, @max_timeout @@ -242,7 +242,7 @@ defmodule Quantum.ExecutionBroadcasterTest do capture_log(fn -> TestProducer.send(producer, {:add, job}) - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) assert_receive {:received, %ExecuteEvent{job: ^job}}, @max_timeout @@ -250,7 +250,7 @@ defmodule Quantum.ExecutionBroadcasterTest do TestProducer.send(producer, {:remove, job.name}) TestProducer.send(producer, %ClockEvent{ - time: NaiveDateTime.add(now, 1, :second), + time: DateTime.add(now, 1, :second), catch_up: false }) @@ -266,7 +266,7 @@ defmodule Quantum.ExecutionBroadcasterTest do capture_log(fn -> TestProducer.send(producer, {:add, job}) - now = %{NaiveDateTime.utc_now() | microsecond: {0, 0}} + now = DateTime.truncate(DateTime.utc_now(), :second) TestProducer.send(producer, %ClockEvent{time: now, catch_up: false}) assert_receive {:received, %ExecuteEvent{job: ^job}}, @max_timeout @@ -274,7 +274,7 @@ defmodule Quantum.ExecutionBroadcasterTest do TestProducer.send(producer, {:remove, make_ref()}) TestProducer.send(producer, %ClockEvent{ - time: NaiveDateTime.add(now, 1, :second), + time: DateTime.add(now, 1, :second), catch_up: false }) diff --git a/test/quantum/job_broadcaster_test.exs b/test/quantum/job_broadcaster_test.exs index 834015b4..28e33b3f 100644 --- a/test/quantum/job_broadcaster_test.exs +++ b/test/quantum/job_broadcaster_test.exs @@ -581,8 +581,8 @@ defmodule Quantum.JobBroadcasterTest do end end - @tag jobs: :active describe "find_job" do + @tag jobs: :active test "finds correct one", %{broadcaster: broadcaster, active_job: active_job} do active_job_name = active_job.name diff --git a/test/quantum/scheduler_test.exs b/test/quantum/scheduler_test.exs index 1bf274a0..1c30a93c 100644 --- a/test/quantum/scheduler_test.exs +++ b/test/quantum/scheduler_test.exs @@ -78,8 +78,8 @@ defmodule Quantum.SchedulerTest do end end - @tag schedulers: [Scheduler] describe "add_job/2" do + @tag schedulers: [Scheduler] test "adding a job at run time" do spec = ~e[1 * * * *] fun = fn -> :ok end