1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <freertos/FreeRTOS.h>
5 #include <freertos/task.h>
6 #include <freertos/semphr.h>
7 
8 #include <unity.h>
9 #include <test_utils.h>
10 #include <esp_ota_ops.h>
11 #include "bootloader_common.h"
12 
13 /* These OTA tests currently don't assume an OTA partition exists
14    on the device, so they're a bit limited
15 */
16 
17 TEST_CASE("esp_ota_begin() verifies arguments", "[ota]")
18 {
19     const esp_partition_t *running = esp_ota_get_running_partition();
20     esp_partition_t partition;
21     static esp_ota_handle_t handle = 0;
22 
23     if (handle != 0) { /* clean up from any previous test */
24         esp_ota_end(handle);
25         handle = 0;
26     }
27 
28     /* running partition & configured boot partition are same */
29     TEST_ASSERT_NOT_NULL(running);
30 
31     /* trying to 'begin' on running partition fails */
32     TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_ota_begin(running, OTA_SIZE_UNKNOWN, &handle));
33     TEST_ASSERT_EQUAL(0, handle);
34 
35     memcpy(&partition, running, sizeof(esp_partition_t));
36     partition.address--;
37 
38     /* non existent partition fails */
39     TEST_ASSERT_EQUAL_HEX(ESP_ERR_NOT_FOUND, esp_ota_begin(&partition, OTA_SIZE_UNKNOWN, &handle));
40     TEST_ASSERT_EQUAL(0, handle);
41 }
42 
43 TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
44 {
45     const esp_partition_t *running = esp_ota_get_running_partition();
46     const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
47                                                               ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
48     const esp_partition_t *ota_0 = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
49                                                             ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL);
50     const esp_partition_t *ota_1 = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
51                                                             ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL);
52     const esp_partition_t *ota_2 = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
53                                                             ESP_PARTITION_SUBTYPE_APP_OTA_2, NULL);
54 
55     TEST_ASSERT_NOT_NULL(running);
56     TEST_ASSERT_NOT_NULL(factory);
57     TEST_ASSERT_NOT_NULL(ota_0);
58     TEST_ASSERT_NOT_NULL(ota_1);
59     TEST_ASSERT_NULL(ota_2); /* this partition shouldn't exist in test partition table */
60 
61     TEST_ASSERT_EQUAL_PTR(factory, running); /* this may not be true if/when we get OTA tests that do OTA updates */
62 
63     /* (The test steps verify subtypes before verifying pointer equality, because the failure messages are more readable
64        this way.)
65      */
66 
67     /* Factory app OTA updates OTA 0 slot */
68     const esp_partition_t *p = esp_ota_get_next_update_partition(NULL);
69     TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_0, p->subtype);
70     TEST_ASSERT_EQUAL_PTR(ota_0, p);
71 
72     p = esp_ota_get_next_update_partition(factory);
73     TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_0, p->subtype);
74     TEST_ASSERT_EQUAL_PTR(ota_0, p);
75 
76 
77     /* OTA slot 0 updates OTA slot 1 */
78     p = esp_ota_get_next_update_partition(ota_0);
79     TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_1, p->subtype);
80     TEST_ASSERT_EQUAL_PTR(ota_1, p);
81     /* OTA slot 1 updates OTA slot 0 */
82     p = esp_ota_get_next_update_partition(ota_1);
83     TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_0, p->subtype);;
84     TEST_ASSERT_EQUAL_PTR(ota_0, p);
85 }
86 
87 TEST_CASE("esp_ota_get_partition_description", "[ota]")
88 {
89     const esp_partition_t *running = esp_ota_get_running_partition();
90     TEST_ASSERT_NOT_NULL(running);
91     esp_app_desc_t app_desc1, app_desc2;
92     TEST_ESP_OK(esp_ota_get_partition_description(running, &app_desc1));
93     const esp_partition_pos_t running_pos = {
94             .offset = running->address,
95             .size = running->size
96     };
97     TEST_ESP_OK(bootloader_common_get_partition_description(&running_pos, &app_desc2));
98 
99     TEST_ASSERT_EQUAL_MEMORY_MESSAGE((uint8_t *)&app_desc1, (uint8_t *)&app_desc2, sizeof(app_desc1), "must be the same");
100 
101     const esp_partition_t *not_app = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
102     TEST_ASSERT_NOT_NULL(not_app);
103     TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_partition_description(not_app, &app_desc1));
104     const esp_partition_pos_t not_app_pos = {
105             .offset = not_app->address,
106             .size = not_app->size
107     };
108     TEST_ESP_ERR(ESP_ERR_NOT_FOUND, bootloader_common_get_partition_description(&not_app_pos, &app_desc1));
109 }
110