pebble/tests/fw/test_process_manager.c

238 lines
7.4 KiB
C
Raw Permalink Normal View History

/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "clar.h"
#include "applib/rockyjs/rocky_res.h"
#include "process_management/process_manager.h"
#include "process_management/app_install_manager.h"
#include "process_management/pebble_process_info.h"
#include "util/size.h"
// Stubs
#include "stubs_accel_service.h"
#include "stubs_analytics.h"
#include "stubs_analytics_external.h"
#include "stubs_animation_service.h"
#include "stubs_app_cache.h"
#include "stubs_app_manager.h"
#include "stubs_app_state.h"
#include "stubs_dls.h"
#include "stubs_evented_timer.h"
#include "stubs_expandable_dialog.h"
#include "stubs_freertos.h"
#include "stubs_heap.h"
#include "stubs_i18n.h"
#include "stubs_logging.h"
#include "stubs_modal_manager.h"
#include "stubs_new_timer.h"
#include "stubs_passert.h"
#include "stubs_pbl_malloc.h"
#include "stubs_pebble_process_md.h"
#include "stubs_pebble_tasks.h"
#include "stubs_persist.h"
#include "stubs_queue.h"
#include "stubs_resources.h"
#include "stubs_syscalls.h"
#include "stubs_task.h"
#include "stubs_tick.h"
#include "stubs_watchface.h"
#include "stubs_worker_manager.h"
#include "stubs_worker_state.h"
char __APP_RAM__[1024*128];
char *__APP_RAM_end__ = &__APP_RAM__[1024*128];
char __WORKER_RAM__[1024*12];
char *__WORKER_RAM_end__ = &__APP_RAM__[1024*12];
typedef struct {
AppInstallEntry entry;
bool should_pass;
} AppInstallEntryTestCase;
static AppInstallEntryTestCase s_test_cases[] = {
{
.entry = (AppInstallEntry) {
.install_id = 1,
.sdk_version = (Version) {
.major = PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR,
.minor = PROCESS_INFO_CURRENT_SDK_VERSION_MINOR
}
},
.should_pass = true
}, {
.entry = (AppInstallEntry) {
.install_id = 2,
.sdk_version = (Version) {
.major = PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR - 1,
.minor = PROCESS_INFO_CURRENT_SDK_VERSION_MINOR
}
},
.should_pass = false
}, {
.entry = (AppInstallEntry) {
.install_id = 3,
.sdk_version = (Version) {
.major = PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR + 1,
.minor = PROCESS_INFO_CURRENT_SDK_VERSION_MINOR
}
},
.should_pass = false
}, {
.entry = (AppInstallEntry) {
.install_id = 4,
.sdk_version = (Version) {
.major = PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR,
.minor = PROCESS_INFO_CURRENT_SDK_VERSION_MINOR - 10
}
},
.should_pass = true
}, {
.entry = (AppInstallEntry) {
.install_id = 5,
.sdk_version = (Version) {
.major = PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR,
.minor = PROCESS_INFO_CURRENT_SDK_VERSION_MINOR + 10
}
},
.should_pass = false
}, {
.entry = (AppInstallEntry) {
.install_id = 6,
.sdk_version = (Version) {
.major = PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR + 1,
.minor = PROCESS_INFO_CURRENT_SDK_VERSION_MINOR + 10
}
},
.should_pass = false
}, {
.entry = (AppInstallEntry) {
.install_id = 7,
.sdk_version = (Version) {
.major = PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR - 1,
.minor = PROCESS_INFO_CURRENT_SDK_VERSION_MINOR - 10
}
},
.should_pass = false
}
};
PlatformType process_metadata_get_app_sdk_platform(const PebbleProcessMd *md) {
cl_fail("should not be called");
return (PlatformType)-1;
}
UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue) {
return 0;
}
BaseType_t event_queue_cleanup_and_reset(QueueHandle_t queue) {
return pdPASS;
}
void event_service_clear_process_subscriptions(void) {
}
bool app_install_entry_is_watchface(const AppInstallEntry *entry) {
return false;
}
AppInstallId app_install_get_id_for_uuid(const Uuid *uuid) {
return 1;
}
bool app_install_get_entry_for_install_id(AppInstallId install_id, AppInstallEntry *entry) {
*entry = s_test_cases[install_id - 1].entry;
return true;
}
bool app_install_id_from_app_db(AppInstallId id) {
return (id > INSTALL_ID_INVALID);
}
bool app_install_entry_is_SDK_compatible(const AppInstallEntry *entry) {
return (entry->sdk_version.major == PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR &&
entry->sdk_version.minor <= PROCESS_INFO_CURRENT_SDK_VERSION_MINOR);
}
static PebbleProcessMd *s_app_install_get_md__result;
const PebbleProcessMd *app_install_get_md(AppInstallId id, bool worker) {
return s_app_install_get_md__result;
}
void app_install_release_md(const PebbleProcessMd *md) {
}
static int s_process_metadata_get_res_bank_num__result;
int process_metadata_get_res_bank_num(const PebbleProcessMd *md) {
return s_process_metadata_get_res_bank_num__result;
}
static RockyResourceValidation s_rocky_app_validate_resources__result;
RockyResourceValidation rocky_app_validate_resources(const PebbleProcessMd *md) {
return s_rocky_app_validate_resources__result;
}
static PebbleEvent* s_event_put__event;
void event_put(PebbleEvent* event) {
s_event_put__event = event;
cl_assert(event != NULL);
}
void event_put_from_app(PebbleEvent* event) { cl_fail("unexpected"); }
void event_put_from_process(PebbleTask task, PebbleEvent* event) { cl_fail("unexpected"); }
void event_reset_from_process_queue(PebbleTask task) { cl_fail("unexpected"); }
void test_process_manager__initialize(void) {
s_app_install_get_md__result = NULL;
s_process_metadata_get_res_bank_num__result = 123;
s_rocky_app_validate_resources__result = RockyResourceValidation_NotRocky;
s_app_manager_launch_new_app__callcount = 0;
s_app_manager_launch_new_app__config = (__typeof__(s_app_manager_launch_new_app__config)){};
s_event_put__event = NULL;
}
void test_process_manager__check_SDK_compatible(void) {
for (uint32_t i = 0; i < ARRAY_LENGTH(s_test_cases); i++) {
// skipping 0, since it's INSTALL_ID_INVALID
cl_assert_equal_b(process_manager_check_SDK_compatible(i + 1), s_test_cases[i].should_pass);
}
}
void test_process_manager__launch_valid_rocky_app(void) {
s_app_install_get_md__result = &(PebbleProcessMd){.is_rocky_app = true};
s_rocky_app_validate_resources__result = RockyResourceValidation_Valid;
process_manager_launch_process(&(ProcessLaunchConfig){.id=1});
// app was launched, no events (especially no fetch event) on the queue
cl_assert_equal_b(1, s_app_manager_launch_new_app__callcount);
cl_assert_equal_p(s_app_install_get_md__result,
s_app_manager_launch_new_app__config.md);
cl_assert(s_event_put__event == NULL);
}
void test_process_manager__launch_invalid_rocky_app(void) {
s_app_install_get_md__result = &(PebbleProcessMd){.is_rocky_app = true};
s_rocky_app_validate_resources__result = RockyResourceValidation_Invalid;
process_manager_launch_process(&(ProcessLaunchConfig){.id=1});
// app wasn't launched, instead we see a fetch request
cl_assert_equal_b(0, s_app_manager_launch_new_app__callcount);
cl_assert(s_event_put__event != NULL);
cl_assert_equal_i(PEBBLE_APP_FETCH_REQUEST_EVENT, s_event_put__event->type);
}