Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,12 @@
{
"product_name" : "AzTestRunner Project",
"android_settings": {
"package_name" : "com.lumberyard.tests",
"version_number": 1,
"version_name" : "1.0.0",
"orientation" : "landscape",
"app_obfuscator_salt" : "MY_OBFUSCATOR_SALT_BASE_64",
"use_main_obb" : "false",
"use_patch_obb" : "false"
}
}
@@ -0,0 +1,15 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Include the required native app glue source from the configured NDK path directly
#include <android_native_app_glue.c>
@@ -0,0 +1,15 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(LY_INCLUDE_DIRECTORIES
PRIVATE
${LY_NDK_NATIVE_APP_GLUE_SRC_DIR}
)
@@ -0,0 +1,456 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <atomic>
#include <chrono>
#include <thread>
#include <AzTest/AzTest.h>
#include <AzTest/Platform.h>
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/std/functional.h>
#include <AzCore/Android/AndroidEnv.h>
#include <AzCore/Android/Utils.h>
#include <AzCore/Android/JNI/JNI.h>
#include <AzCore/Android/JNI/Object.h>
#include <AzCore/Android/JNI/scoped_ref.h>
#include <AzCore/Component/TickBus.h>
#include <AzFramework/API/ApplicationAPI_Platform.h>
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
#include "aztestrunner.h"
#include <android/asset_manager_jni.h>
#include <android/log.h>
#include <android/native_activity.h>
#include <android/native_window.h>
#include <android_native_app_glue.h>
#include <sys/resource.h>
#include <sys/types.h>
constexpr const char* s_logTag = "LMBR";
#define MAIN_EXIT_FAILURE(_appState, ...) \
__android_log_print(ANDROID_LOG_INFO, s_logTag, "****************************************************************"); \
__android_log_print(ANDROID_LOG_INFO, s_logTag, "STARTUP FAILURE - EXITING"); \
__android_log_print(ANDROID_LOG_INFO, s_logTag, "REASON:"); \
__android_log_print(ANDROID_LOG_INFO, s_logTag, __VA_ARGS__); \
__android_log_print(ANDROID_LOG_INFO, s_logTag, "****************************************************************"); \
_appState->userData = nullptr; \
ANativeActivity_finish(_appState->activity); \
while (_appState->destroyRequested == 0) { \
g_eventDispatcher.PumpAllEvents(); \
} \
return;
namespace AzTestRunner
{
void set_quiet_mode()
{
}
const char* get_current_working_directory()
{
static char cwd_buffer[AZ_MAX_PATH_LEN] = { '\0' };
AZ::Utils::ExecutablePathResult result = AZ::Utils::GetExecutableDirectory(cwd_buffer, AZ_ARRAY_SIZE(cwd_buffer));
AZ_Assert(result == AZ::Utils::ExecutablePathResult::Success, "Error retrieving executable path");
return static_cast<const char*>(cwd_buffer);
}
void pause_on_completion()
{
}
}
static AZ::EnvironmentInstance s_envInst = nullptr;
AZTEST_EXPORT AZ::EnvironmentInstance GetTestRunnerEnvironment()
{
return s_envInst;
}
namespace
{
class NativeEventDispatcher
: public AzFramework::AndroidEventDispatcher
{
public:
NativeEventDispatcher()
: m_appState(nullptr)
{
}
~NativeEventDispatcher()
{
}
void PumpAllEvents() override
{
bool continueRunning = true;
while (continueRunning)
{
continueRunning = PumpEvents(&ALooper_pollAll);
}
}
void PumpEventLoopOnce() override
{
PumpEvents(&ALooper_pollOnce);
}
void SetAppState(android_app* appState)
{
m_appState = appState;
}
private:
// signature of ALooper_pollOnce and ALooper_pollAll -> int timeoutMillis, int* outFd, int* outEvents, void** outData
typedef int (*EventPumpFunc)(int, int*, int*, void**);
bool PumpEvents(EventPumpFunc looperFunc)
{
if (!m_appState)
{
return false;
}
int events = 0;
android_poll_source* source = nullptr;
const AZ::Android::AndroidEnv* androidEnv = AZ::Android::AndroidEnv::Get();
// when timeout is negative, the function will block until an event is received
const int result = looperFunc(androidEnv->IsRunning() ? 0 : -1, nullptr, &events, reinterpret_cast<void**>(&source));
// the value returned from the looper poll func is either:
// 1. the identifier associated with the event source (>= 0) and has event data that needs to be processed manually
// 2. an ALOOPER_POLL_* enum (< 0) indicating there is no data to be processed due to error or callback(s) registered
// with the event source were called
const bool validIdentifier = (result >= 0);
if (validIdentifier && source)
{
source->process(m_appState, source);
}
const bool destroyRequested = (m_appState->destroyRequested != 0);
return (validIdentifier && !destroyRequested);
}
android_app* m_appState;
};
NativeEventDispatcher g_eventDispatcher;
bool g_windowInitialized = false;
int32_t HandleInputEvents(android_app* app, AInputEvent* event)
{
AzFramework::RawInputNotificationBusAndroid::Broadcast(&AzFramework::RawInputNotificationsAndroid::OnRawInputEvent, event);
return 0;
}
void HandleApplicationLifecycleEvents(android_app* appState, int32_t command)
{
AZ::Android::AndroidEnv* androidEnv = static_cast<AZ::Android::AndroidEnv*>(appState->userData);
if (!androidEnv)
{
return;
}
switch (command)
{
case APP_CMD_GAINED_FOCUS:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnGainedFocus);
}
break;
case APP_CMD_LOST_FOCUS:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnLostFocus);
}
break;
case APP_CMD_PAUSE:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnPause);
androidEnv->SetIsRunning(false);
}
break;
case APP_CMD_RESUME:
{
androidEnv->SetIsRunning(true);
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnResume);
}
break;
case APP_CMD_DESTROY:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnDestroy);
}
break;
case APP_CMD_INIT_WINDOW:
{
g_windowInitialized = true;
androidEnv->SetWindow(appState->window);
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnWindowInit);
}
break;
case APP_CMD_TERM_WINDOW:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnWindowDestroy);
androidEnv->SetWindow(nullptr);
}
break;
case APP_CMD_LOW_MEMORY:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnLowMemory);
}
break;
case APP_CMD_CONFIG_CHANGED:
{
androidEnv->UpdateConfiguration();
}
break;
case APP_CMD_WINDOW_REDRAW_NEEDED:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnWindowRedrawNeeded);
}
break;
}
}
void OnWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* rect)
{
android_app* app = static_cast<android_app*>(activity->instance);
int8_t cmd = APP_CMD_WINDOW_REDRAW_NEEDED;
if (write(app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd))
{
__android_log_print(ANDROID_LOG_ERROR, s_logTag, "Failure writing android_app cmd: %s\n", strerror(errno));
}
}
}
// In order to read the logcat from adb, stdout and stderr needs to be redirected custom handles and we will need
// to spawn a thread to read from the custom handles and pass the output of those streams through __android_log_print
// to a specia 'LMBR' tag
static int s_pfd[2];
static std::atomic_bool s_testRunComplete { false };
static void *thread_logger_func(void*)
{
ssize_t readSize;
char logBuffer[256] = {'\0'};
while (!s_testRunComplete)
{
readSize = read(s_pfd[0], logBuffer, sizeof(logBuffer)-1);
if (readSize>0) {
// Trim the tailing return character
if (logBuffer[readSize - 1] == '\n') {
--readSize;
}
logBuffer[readSize] = '\0';
((void) __android_log_print(ANDROID_LOG_INFO, s_logTag, logBuffer));
}
}
return 0;
}
constexpr const char* s_defaultAppName = "AzTestRunner";
constexpr size_t s_maxArgCount = 8;
constexpr size_t s_maxArgLength = 64;
void android_main(android_app* appState)
{
// Adding a start up banner so you can see when the test runner is starting up in amongst the logcat spam
__android_log_print(ANDROID_LOG_INFO, s_logTag, "****************************************************************");
__android_log_print(ANDROID_LOG_INFO, s_logTag, " Starting %s", s_defaultAppName);
__android_log_print(ANDROID_LOG_INFO, s_logTag, "****************************************************************");
// setup the android environment
AZ::AllocatorInstance<AZ::OSAllocator>::Create();
s_envInst = AZ::Environment::GetInstance();
// setup the system command handler which are guaranteed to be called on the same
// thread the events are pumped
appState->onAppCmd = HandleApplicationLifecycleEvents;
appState->onInputEvent = HandleInputEvents;
g_eventDispatcher.SetAppState(appState);
// This callback will notify us when the orientation of the device changes.
// While Android does have an onNativeWindowResized callback, it is never called in android_native_app_glue when the window size changes.
// The onNativeConfigChanged callback is called too early(before the window size has changed), so we won't have the correct window size at that point.
appState->activity->callbacks->onNativeWindowRedrawNeeded = OnWindowRedrawNeeded;
{
AZ::Android::AndroidEnv::Descriptor descriptor;
descriptor.m_jvm = appState->activity->vm;
descriptor.m_activityRef = appState->activity->clazz;
descriptor.m_assetManager = appState->activity->assetManager;
descriptor.m_configuration = appState->config;
descriptor.m_appPrivateStoragePath = appState->activity->internalDataPath;
descriptor.m_appPublicStoragePath = appState->activity->externalDataPath;
descriptor.m_obbStoragePath = appState->activity->obbPath;
if (!AZ::Android::AndroidEnv::Create(descriptor))
{
AZ::Android::AndroidEnv::Destroy();
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
MAIN_EXIT_FAILURE(appState, "Failed to create the AndroidEnv");
}
AZ::Android::AndroidEnv* androidEnv = AZ::Android::AndroidEnv::Get();
appState->userData = androidEnv;
androidEnv->SetIsRunning(true);
}
g_eventDispatcher.PumpAllEvents();
// Prepare the command line args to pass to main
char commandLineArgs[s_maxArgCount][s_maxArgLength] = { {'\0'} };
size_t currentCommandLineIndex = 0;
// Always add the app as the first arg to mimic the way other platforms start with the executable name.
const char* packageName = AZ::Android::Utils::GetPackageName();
const char* appName = (packageName) ? packageName : s_defaultAppName;
size_t appNameLen = strlen(appName);
azstrncpy(commandLineArgs[currentCommandLineIndex++], s_maxArgLength, appName, appNameLen + 1);
// "activityObject" and "intent" need to be destroyed before we call Destroy() on the allocator to ensure graceful shutdown.
{
// Get the string extras and pass them along as cmd line params
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> activityObject(AZ::Android::JNI::GetEnv()->GetObjectClass(appState->activity->clazz), appState->activity->clazz);
activityObject.RegisterMethod("getIntent", "()Landroid/content/Intent;");
jobject intent = activityObject.InvokeObjectMethod<jobject>("getIntent");
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> intentObject(AZ::Android::JNI::GetEnv()->GetObjectClass(intent), intent);
intentObject.RegisterMethod("getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
intentObject.RegisterMethod("getExtras", "()Landroid/os/Bundle;");
jobject extras = intentObject.InvokeObjectMethod<jobject>("getExtras");
int start_delay = 0;
if (extras)
{
// Get the set of keys
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> extrasObject(AZ::Android::JNI::GetEnv()->GetObjectClass(extras), extras);
extrasObject.RegisterMethod("keySet", "()Ljava/util/Set;");
jobject extrasKeySet = extrasObject.InvokeObjectMethod<jobject>("keySet");
// get the array of string objects
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> extrasKeySetObject(AZ::Android::JNI::GetEnv()->GetObjectClass(extrasKeySet), extrasKeySet);
extrasKeySetObject.RegisterMethod("toArray", "()[Ljava/lang/Object;");
jobjectArray extrasKeySetArray = extrasKeySetObject.InvokeObjectMethod<jobjectArray>("toArray");
int extrasKeySetArraySize = AZ::Android::JNI::GetEnv()->GetArrayLength(extrasKeySetArray);
for (int x = 0; x < extrasKeySetArraySize; x++)
{
jstring keyObject = static_cast<jstring>(AZ::Android::JNI::GetEnv()->GetObjectArrayElement(extrasKeySetArray, x));
AZ::OSString value = intentObject.InvokeStringMethod("getStringExtra", keyObject);
const char* keyChars = AZ::Android::JNI::GetEnv()->GetStringUTFChars(keyObject, 0);
if (azstricmp("startdelay", keyChars) == 0)
{
start_delay = strtol(value.c_str(), nullptr, 10);
}
else if (azstricmp("gtest_filter", keyChars) == 0)
{
azsnprintf(commandLineArgs[currentCommandLineIndex++], s_maxArgLength, "--gtest_filter=%.*s", aznumeric_cast<int>(value.size()), value.c_str());
}
else
{
azstrncpy(commandLineArgs[currentCommandLineIndex++], s_maxArgLength, keyChars, strlen(keyChars) + 1);
azstrncpy(commandLineArgs[currentCommandLineIndex++], s_maxArgLength, value.c_str(), value.length() + 1);
}
AZ::Android::JNI::GetEnv()->ReleaseStringUTFChars(keyObject, keyChars);
}
}
if (start_delay > 0)
{
std::this_thread::sleep_for(std::chrono::seconds(start_delay));
}
}
char* argv[s_maxArgCount];
for (size_t index = 0; index < s_maxArgCount; index++)
{
argv[index] = commandLineArgs[index];
}
// Redirect stdout and stderr to custom handles and prepare the thread to read from the custom handles
pthread_t log_thread;
setvbuf(stdout, 0, _IOLBF, 0);
setvbuf(stderr, 0, _IONBF, 0);
pipe(s_pfd);
dup2(s_pfd[1], 1);
dup2(s_pfd[1], 2);
if (pthread_create(&log_thread, 0, thread_logger_func, 0) == -1)
{
((void)__android_log_print(ANDROID_LOG_INFO, s_logTag, "[FAILURE] Unable to spawn logging thread"));
return;
}
// Execute the unit test main
int result = AzTestRunner::wrapped_main(aznumeric_cast<int>(currentCommandLineIndex), argv);
g_eventDispatcher.PumpAllEvents();
s_testRunComplete = true;
std::this_thread::sleep_for(std::chrono::seconds(1));
if (result == 0)
{
((void)__android_log_print(ANDROID_LOG_INFO, s_logTag, "[SUCCESS]"));
}
else
{
((void)__android_log_print(ANDROID_LOG_INFO, s_logTag, "[FAILURE]"));
}
AZ::Android::AndroidEnv::Destroy();
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
}
@@ -0,0 +1,15 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
platform_android.cpp
native_app_glue_include.c
)
@@ -0,0 +1,13 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(PAL_TRAIT_AZTESTRUNNER_LAUNCHER_TYPE MODULE)
@@ -0,0 +1,22 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "aztestrunner.h"
#include <iostream>
int main(int argc, char** argv)
{
int result = AzTestRunner::wrapped_main(argc, argv);
std::cout << "Returning code: " << result << std::endl;
return result;
}
@@ -0,0 +1,34 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <stdio.h> // for freopen
#include <unistd.h> // for getcwd
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
namespace AzTestRunner
{
void set_quiet_mode()
{
freopen("/dev/null", "a", stdout);
}
const char* get_current_working_directory()
{
static char cwd_buffer[AZ_MAX_PATH_LEN] = { '\0' };
return getcwd(cwd_buffer, sizeof(cwd_buffer));
}
void pause_on_completion()
{
system("pause");
}
}
@@ -0,0 +1,11 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,15 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/platform_host_main.cpp
../Common/platform_host_posix.cpp
)
@@ -0,0 +1,13 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(PAL_TRAIT_AZTESTRUNNER_LAUNCHER_TYPE EXECUTABLE)
@@ -0,0 +1,11 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,15 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/platform_host_main.cpp
../Common/platform_host_posix.cpp
)
@@ -0,0 +1,13 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(PAL_TRAIT_AZTESTRUNNER_LAUNCHER_TYPE EXECUTABLE)
@@ -0,0 +1,13 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(PAL_TRAIT_AZTESTRUNNER_LAUNCHER_TYPE EXECUTABLE)
@@ -0,0 +1,11 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,35 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <sstream> // for freopen_s
#include <direct.h> // for _getcwd
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
namespace AzTestRunner
{
void set_quiet_mode()
{
FILE* stream;
freopen_s(&stream, "nul", "w", stdout);
}
const char* get_current_working_directory()
{
static char cwd_buffer[AZ_MAX_PATH_LEN] = { '\0' };
return _getcwd(cwd_buffer, sizeof(cwd_buffer));
}
void pause_on_completion()
{
system("pause");
}
}
@@ -0,0 +1,15 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/platform_host_main.cpp
platform_windows.cpp
)
@@ -0,0 +1,24 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#import <UIKit/UIKit.h>
int main(int argc, char* argv[])
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
UIApplicationMain(argc,
argv,
nil,
nil);
[pool release];
return 0;
}
@@ -0,0 +1,116 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "iPhoneNotificationIcon40x40.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0c25ffb1af8160b3202977de8c32aaa235e22c643ffd8004e4546c96868ef3b9
size 18317
@@ -0,0 +1,169 @@
{
"images" : [
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "2436h",
"filename" : "iPadLaunchImage1024x768.png",
"minimum-system-version" : "11.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "2436h",
"filename" : "iPadLaunchImage1024x768.png",
"minimum-system-version" : "11.0",
"orientation" : "landscape",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "iPadLaunchImage1024x768.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"filename" : "iPadLaunchImage1024x768.png",
"minimum-system-version" : "8.0",
"orientation" : "landscape",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"filename" : "iPadLaunchImage1024x768.png",
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"filename" : "iPadLaunchImage1024x768.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"filename" : "iPadLaunchImage1024x768.png",
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "iPadLaunchImage1024x768.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"filename" : "iPadLaunchImage1024x768.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"filename" : "iPadLaunchImage1024x768.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"filename" : "iPadLaunchImage1024x768.png",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"subtype" : "retina4",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"extent" : "full-screen",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:31afa7ed44c5d9844c8d6ce08beccac482c3f43590869a3d190d06e2df377ccc
size 137472
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>AzTestRunner</string>
<key>CFBundleExecutable</key>
<string>AzTestRunner</string>
<key>CFBundleIdentifier</key>
<string>com.lumberyard.tests</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>AzTestRunner</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
<string>metal</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<key>UIStatusBarHidden</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
</array>
</dict>
</plist>
@@ -0,0 +1,90 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#import <XCTest/XCTest.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Utils/Utils.h>
#include "aztestrunner.h"
constexpr size_t s_maxArgCount = 8;
constexpr size_t s_maxArgLength = 256;
namespace AzTestRunner
{
void set_quiet_mode()
{
}
const char* get_current_working_directory()
{
static char cwd_buffer[AZ_MAX_PATH_LEN] = { '\0' };
AZ::Utils::ExecutablePathResult result = AZ::Utils::GetExecutableDirectory(cwd_buffer, AZ_ARRAY_SIZE(cwd_buffer));
AZ_Assert(result == AZ::Utils::ExecutablePathResult::Success, "Error retrieving executable path");
return static_cast<const char*>(cwd_buffer);
}
void pause_on_completion()
{
}
}
@interface TestLauncherTarget : XCTestCase
@property(strong) NSArray* commandLineArgs;
@property size_t argCount;
@property bool testSuccessful;
@end
@implementation TestLauncherTarget
-(void) setUp
{
NSLog(@"TEST STARTED");
self.commandLineArgs = [[NSProcessInfo processInfo] arguments];
self.argCount = [self.commandLineArgs count];
self.testSuccessful = false;
}
-(void) tearDown
{
if (self.testSuccessful)
{
NSLog(@"TEST SUCCEEDED");
}
else
{
NSLog(@"TEST FAILED");
}
}
-(void) testLibrary
{
char args[s_maxArgCount][s_maxArgLength] = { {'\0'} };
char *argv[s_maxArgCount];
size_t argc = self.argCount;
for (size_t argIndex = 0; argIndex < s_maxArgCount && argIndex < argc; ++argIndex)
{
const char* arg = [self.commandLineArgs[argIndex] UTF8String];
azstrncpy(args[argIndex], s_maxArgLength, arg, strlen(arg));
argv[argIndex] = args[argIndex];
}
int status = AzTestRunner::wrapped_main(argc, argv);
self.testSuccessful = (status == 0);
XCTAssert(self.testSuccessful);
}
@end
@@ -0,0 +1,47 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(TEST_LAUNCHER_BUILD_DEPENDENCIES AzCore AzTest)
set(LY_LINK_OPTIONS
PRIVATE
-ObjC
)
set(ly_game_resource_folder ${CMAKE_CURRENT_LIST_DIR}/Resources)
if (NOT EXISTS ${ly_game_resource_folder})
message(FATAL_ERROR "Missing expected resources folder")
endif()
target_sources(AzTestRunner PRIVATE ${ly_game_resource_folder}/Images.xcassets)
set_target_properties(AzTestRunner PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${ly_game_resource_folder}/Info.plist
RESOURCE ${ly_game_resource_folder}/Images.xcassets
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AzTestRunnerAppIcon
)
find_package(XCTest REQUIRED)
xctest_add_bundle(TestLauncherTarget AzTestRunner
${ly_game_resource_folder}/Info.plist
${CMAKE_CURRENT_LIST_DIR}/TestLauncherTarget.mm
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
# XCTest adds the test as a target, but we still need to set dependencies.
set(include_directories "${CMAKE_CURRENT_SOURCE_DIR}/src")
foreach(dependency ${TEST_LAUNCHER_BUILD_DEPENDENCIES})
get_target_property(includes ${dependency} INCLUDE_DIRECTORIES)
LIST(APPEND include_directories ${includes})
target_link_libraries(TestLauncherTarget PRIVATE ${dependency})
endforeach()
set_property(TARGET TestLauncherTarget PROPERTY INCLUDE_DIRECTORIES ${include_directories})
@@ -0,0 +1,15 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
Resources/Info.plist
Launcher_iOS.mm
)
@@ -0,0 +1,13 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(PAL_TRAIT_AZTESTRUNNER_LAUNCHER_TYPE EXECUTABLE)