Skip to content

Commit f9afaae

Browse files
authored
Fix push-available-update, and add some tests for the future (#2370)
With the addition of `firmware_proxy_url` in #2354 , the ability to skip the queue was broken and was only discovered from a Sentry error. This PR fixes the bork, and adds some tests for `Skip the queue`, which we were lacking.
1 parent d2f83d8 commit f9afaae

File tree

2 files changed

+186
-1
lines changed

2 files changed

+186
-1
lines changed

lib/nerves_hub_web/components/device_page/details_tab.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ defmodule NervesHubWeb.Components.DevicePage.DetailsTab do
607607

608608
%{device: device, user: user} = socket.assigns
609609

610-
deployment_group = NervesHub.Repo.preload(device.deployment_group, :firmware)
610+
deployment_group = NervesHub.Repo.preload(device.deployment_group, [:firmware, :org])
611611

612612
case Devices.told_to_update(device, deployment_group) do
613613
{:ok, _inflight_update} ->

test/nerves_hub_web/live/new_ui/devices/show_test.exs

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ defmodule NervesHubWeb.Live.NewUI.Devices.ShowTest do
77
alias NervesHub.Accounts
88
alias NervesHub.Accounts.Org
99
alias NervesHub.Devices
10+
alias NervesHub.Devices.Connections
1011
alias NervesHub.Devices.Device
1112
alias NervesHub.Devices.DeviceConnection
1213
alias NervesHub.Firmwares
1314
alias NervesHub.Firmwares.Firmware
1415
alias NervesHub.Fixtures
16+
alias NervesHub.ManagedDeployments.DeploymentGroup
1517
alias NervesHub.Repo
1618

1719
alias NervesHubWeb.Endpoint
@@ -442,6 +444,189 @@ defmodule NervesHubWeb.Live.NewUI.Devices.ShowTest do
442444
end
443445
end
444446

447+
describe "skip the queue when there is an available update" do
448+
test "only shows the button if an update is available", %{
449+
conn: conn,
450+
org: org,
451+
org_key: org_key,
452+
product: product,
453+
device: device,
454+
deployment_group: deployment_group,
455+
tmp_dir: tmp_dir
456+
} do
457+
assert device.updates_enabled
458+
459+
device = Devices.update_deployment_group(device, deployment_group)
460+
{:ok, connection} = Connections.device_connecting(device, device.product_id)
461+
:ok = Connections.device_connected(device, connection.id)
462+
device = Devices.set_as_provisioned!(device)
463+
464+
conn
465+
|> visit("/org/#{org.name}/#{product.name}/devices/#{device.identifier}")
466+
|> refute_has("button", text: "Skip the queue")
467+
468+
new_firmware = Fixtures.firmware_fixture(org_key, product, %{dir: tmp_dir})
469+
470+
DeploymentGroup
471+
|> where(id: ^deployment_group.id)
472+
|> Repo.update_all(set: [is_active: true, firmware_id: new_firmware.id])
473+
474+
conn
475+
|> visit("/org/#{org.name}/#{product.name}/devices/#{device.identifier}")
476+
|> assert_has("button", text: "Skip the queue")
477+
end
478+
479+
test "allows a device to be sent the available update immediately, using the default url config", %{
480+
conn: conn,
481+
org: org,
482+
org_key: org_key,
483+
product: product,
484+
device: device,
485+
deployment_group: deployment_group,
486+
tmp_dir: tmp_dir
487+
} do
488+
assert device.updates_enabled
489+
490+
device = Devices.update_deployment_group(device, deployment_group)
491+
{:ok, connection} = Connections.device_connecting(device, device.product_id)
492+
:ok = Connections.device_connected(device, connection.id)
493+
device = Devices.set_as_provisioned!(device)
494+
495+
new_firmware = Fixtures.firmware_fixture(org_key, product, %{dir: tmp_dir})
496+
497+
DeploymentGroup
498+
|> where(id: ^deployment_group.id)
499+
|> Repo.update_all(set: [is_active: true, firmware_id: new_firmware.id])
500+
501+
conn
502+
|> visit("/org/#{org.name}/#{product.name}/devices/#{device.identifier}")
503+
|> click_button("Skip the queue")
504+
505+
%{version: version, architecture: architecture, platform: platform} = new_firmware
506+
507+
assert_receive %Phoenix.Socket.Broadcast{
508+
payload: %{
509+
firmware_url: firmware_url,
510+
firmware_meta: %{
511+
version: ^version,
512+
architecture: ^architecture,
513+
platform: ^platform
514+
}
515+
},
516+
event: "update"
517+
}
518+
519+
assert String.starts_with?(firmware_url, "http://localhost:1234")
520+
521+
assert Repo.reload(device) |> Map.get(:updates_enabled)
522+
end
523+
524+
test "allows a device to be sent the available update immediately, using the available Org `firmware_proxy_url` setting",
525+
%{
526+
conn: conn,
527+
org: org,
528+
org_key: org_key,
529+
product: product,
530+
device: device,
531+
deployment_group: deployment_group,
532+
tmp_dir: tmp_dir
533+
} do
534+
Org
535+
|> where(id: ^org.id)
536+
|> Repo.update_all(set: [settings: %Org.Settings{firmware_proxy_url: "https://files.customer.com/download"}])
537+
538+
assert device.updates_enabled
539+
540+
device = Devices.update_deployment_group(device, deployment_group)
541+
{:ok, connection} = Connections.device_connecting(device, device.product_id)
542+
:ok = Connections.device_connected(device, connection.id)
543+
device = Devices.set_as_provisioned!(device)
544+
545+
new_firmware = Fixtures.firmware_fixture(org_key, product, %{dir: tmp_dir})
546+
547+
DeploymentGroup
548+
|> where(id: ^deployment_group.id)
549+
|> Repo.update_all(set: [is_active: true, firmware_id: new_firmware.id])
550+
551+
conn
552+
|> visit("/org/#{org.name}/#{product.name}/devices/#{device.identifier}")
553+
|> click_button("Skip the queue")
554+
555+
%{version: version, architecture: architecture, platform: platform} = new_firmware
556+
557+
assert_receive %Phoenix.Socket.Broadcast{
558+
payload: %{
559+
firmware_url: firmware_url,
560+
firmware_meta: %{
561+
version: ^version,
562+
architecture: ^architecture,
563+
platform: ^platform
564+
}
565+
},
566+
event: "update"
567+
}
568+
569+
assert String.starts_with?(firmware_url, "https://files.customer.com/download?")
570+
571+
assert Repo.reload(device) |> Map.get(:updates_enabled)
572+
end
573+
574+
test "allows a device to be sent the available delta update immediately, if a delta is available", %{
575+
conn: conn,
576+
org: org,
577+
org_key: org_key,
578+
product: product,
579+
device: device,
580+
deployment_group: deployment_group,
581+
tmp_dir: tmp_dir
582+
} do
583+
assert device.updates_enabled
584+
585+
metadata = Map.put(device.firmware_metadata, :fwup_version, "1.13.0") |> Map.from_struct()
586+
Devices.update_device(device, %{firmware_metadata: metadata})
587+
588+
device = Devices.update_deployment_group(device, deployment_group)
589+
{:ok, connection} = Connections.device_connecting(device, device.product_id)
590+
:ok = Connections.device_connected(device, connection.id)
591+
device = Devices.set_as_provisioned!(device)
592+
593+
new_firmware = Fixtures.firmware_fixture(org_key, product, %{dir: tmp_dir})
594+
595+
Firmware
596+
|> where(id: ^new_firmware.id)
597+
|> Repo.update_all(set: [delta_updatable: true, version: "2.0.0"])
598+
599+
{:ok, firmware} = Firmwares.get_firmware_by_product_id_and_uuid(device.product_id, device.firmware_metadata.uuid)
600+
_ = Fixtures.firmware_delta_fixture(firmware, new_firmware)
601+
602+
DeploymentGroup
603+
|> where(id: ^deployment_group.id)
604+
|> Repo.update_all(set: [is_active: true, firmware_id: new_firmware.id, delta_updatable: true])
605+
606+
conn
607+
|> visit("/org/#{org.name}/#{product.name}/devices/#{device.identifier}")
608+
|> click_button("Skip the queue")
609+
610+
%{architecture: architecture, platform: platform} = new_firmware
611+
612+
assert_receive %Phoenix.Socket.Broadcast{
613+
payload: %{
614+
firmware_url: firmware_url,
615+
firmware_meta: %{
616+
version: "2.0.0",
617+
architecture: ^architecture,
618+
platform: ^platform
619+
}
620+
},
621+
event: "update"
622+
}
623+
624+
assert String.ends_with?(firmware_url, ".delta.fw")
625+
626+
assert Repo.reload(device) |> Map.get(:updates_enabled)
627+
end
628+
end
629+
445630
test "enabling and disabling priority updates", %{
446631
conn: conn,
447632
org: org,

0 commit comments

Comments
 (0)