[test-runner] Enable IOS RenderTestRunner and run it on Firebase (#16111)

* [test-runner] Setup iOS RenderTestRunner

* [test-runner] Make app runnable on firebase

* Add iOS platform dependent expectation and ignores; Run prepare script via cmake

* Make RenderTestRunner report test status
This commit is contained in:
zmiao
2020-01-21 23:23:35 +02:00
committed by GitHub
parent 6dc435f664
commit 1ade6c7784
39 changed files with 1140 additions and 7 deletions

5
.gitignore vendored
View File

@@ -49,6 +49,11 @@ render-test/android/package.json
render-test/android/app/app.iml
render-test/android/android.iml
# IOS RenderTestRunner
render-test/ios/codesigning/*.xcent
render-test/ios/fastlane/README.md
test-data/
# Generated file from npm/yarn
package-lock.json

View File

@@ -9,6 +9,7 @@ workflows:
- next-android-api-breakage
- next-android-render-test-runner
- next-android-unit-test-runner
- next-ios-render-test-runner
- next-baselines:
requires:
- next-android-arm64-v8a-release
@@ -140,12 +141,7 @@ workflows:
- next-macos-xcode11-release
config_params: '-G Ninja -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Debug'
style_tests: true
- next-build-template:
name: next-ios-xcode11-release
executor_name: macos-11_0_0
target_is_macos: true
config_params: '-G Xcode -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_SYSROOT=iphonesimulator'
test_params: '-Q -N'
- next-ios-xcode11-release
mbgl-legacy:
jobs:
#
@@ -241,11 +237,23 @@ commands:
command: |
Xvfb :99 -noreset -screen 0 1280x1024x24
next-prepare-macos:
parameters:
build-ios-test-runner:
type: boolean
default: false
steps:
- run:
name: Prepare macOS
command: |
brew install cmake ccache glfw ninja pkgconfig qt
- when:
condition: << parameters.build-ios-test-runner >>
steps:
- run:
name: Prepare macOS with extra environment
command: |
brew cask install google-cloud-sdk
brew install chargepoint/xcparse/xcparse
- run:
name: Code Generators macOS
command: |
@@ -671,6 +679,88 @@ commands:
fi
jobs:
next-ios-xcode11-release:
executor: macos-11_0_0
steps:
- checkout
- next-prepare
- next-prepare-macos
- run:
name: Build
command: |
cmake next -B Build -G Xcode -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_SYSROOT=iphonesimulator
cd Build && xcodebuild -sdk iphonesimulator -project Mapbox\ GL\ Native.xcodeproj -configuration Release
- next-save
next-ios-render-test-runner:
executor: macos-11_0_0
steps:
- checkout
- next-prepare
- next-prepare-macos:
build-ios-test-runner: true
- run:
name: Prepare codesign keychain
command: |
cd render-test/ios
fastlane run create_keychain name:fastlane_keychain password:$FASTLANE_PASSWORD timeout:false unlock:true
fastlane match
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $FASTLANE_PASSWORD fastlane_keychain
/usr/bin/env xcrun security find-identity -v -p codesigning
- run:
name: Build IOS RenderTestApp
command: |
cd render-test/ios
cmake ../../next -B Build -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DMBGL_IOS_RENDER_TEST=ON
cd Build
xcodebuild -sdk iphoneos -project Mapbox\ GL\ Native.xcodeproj -scheme RenderTestApp build-for-testing -arch arm64 CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -configuration Release
xcodebuild -sdk iphoneos -project Mapbox\ GL\ Native.xcodeproj build -target RenderTestAppTests -arch arm64 CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -configuration Release
- run:
name: Codesign RenderTestApp for running on a physical device
command: |
cd render-test/ios
./codesigning/generate-entitlements.swift
ls codesigning
cd Build
../codesigning/codesign_all.sh
codesign -dv --verbose=4 Release-iphoneos/RenderTestApp.app # for debugging that app is signed or not
- run:
name: Login to IOS Google Cloud Platform
command: |
if [[ -n "${GCLOUD_SERVICE_ACCOUNT_JSON_IOS}" ]]; then
echo "${GCLOUD_SERVICE_ACCOUNT_JSON_IOS}" > iosAccount.json
gcloud auth activate-service-account --key-file iosAccount.json --project ios-mapbox-gl-native
rm iosAccount.json
fi
- run:
name: Run IOSRenderTestApp Tests on Firebase
no_output_timeout: 20m
command: |
if [[ -n "${GCLOUD_SERVICE_ACCOUNT_JSON_IOS}" ]]; then
# arrange files in a way Firebase expects it, and package them in a zip file
cd render-test/ios/Build
cp ../RenderTestApp_iphoneos13.2-arm64e-release.xctestrun .
zip testapp.zip -r Release-iphoneos/RenderTestApp.app
zip testapp.zip RenderTestApp_iphoneos13.2-arm64e-release.xctestrun
gcloud firebase test ios models list
gcloud firebase test ios run \
--test testapp.zip \
--device model=iphonexs,version=12.0,locale=en,orientation=portrait --xcode-version=11.1 --timeout 20m \
--verbosity=debug --no-record-video --results-dir ios-render-test-app-${CIRCLE_BUILD_NUM}
fi
- run:
name: Retrieve Test Result from gcloud
when: always
command: |
if [[ -n "${GCLOUD_SERVICE_ACCOUNT_JSON_IOS}" ]]; then
testResult=$(gsutil ls -d gs://test-lab-hn7kwqcz3108z-hjm4qtbqqkymk/ios-render-test-app-${CIRCLE_BUILD_NUM}/iphonexs-12.0-en-portrait/TestLogs/)
mkdir -p render-test-app
gsutil -m cp -r $testResult render-test-app
cd render-test-app/TestLogs && ls
xcparse attachments *.xcresult
cd ../.. && mkdir -p /tmp/tests/ios-render-test
if ls render-test-app/TestLogs/*.html 1> /dev/null 2>&1; then cp render-test-app/TestLogs/*.html /tmp/tests/ios-render-test; fi
fi
- next-save
next-android-benchmark-runner:
executor: ubuntu-disco
steps:

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,12 @@
{
"render-tests/icon-text-fit/enlargen-both": "Needs to be investigated and fixed.",
"render-tests/line-pattern/overscaled": "Needs to be investigated and fixed.",
"render-tests/runtime-styling/image-update-pattern": "Needs to be investigated and fixed.",
"render-tests/runtime-styling/image-add-pattern": "Needs to be investigated and fixed.",
"render-tests/text-font/chinese": "Needs to be investigated and fixed.",
"render-tests/regressions/mapbox-gl-native#9976": "Needs to be investigated and fixed.",
"render-tests/regressions/mapbox-gl-js#2305": "Needs to be investigated and fixed.",
"render-tests/regressions/mapbox-gl-js#5911a": "Needs to be investigated and fixed.",
"render-tests/text-field/formatted-images": "Needs to be investigated and fixed.",
"render-tests/symbol-visibility/visible": "Needs to be investigated and fixed."
}

View File

@@ -0,0 +1,13 @@
{
"base_test_path": "integration",
"cache_path": "cache-style.db",
"expectation_paths": [
"expectations/platform-all",
"expectations/platform-ios"
],
"ignore_paths": [
"ignores/platform-all.json",
"ignores/platform-macos.json",
"ignores/platform-ios.json"
]
}

View File

@@ -23,6 +23,7 @@ target_sources(
${MBGL_ROOT}/platform/darwin/src/collator.mm
${MBGL_ROOT}/platform/darwin/src/gl_functions.cpp
${MBGL_ROOT}/platform/darwin/src/headless_backend_eagl.mm
${MBGL_ROOT}/platform/darwin/src/native_apple_interface.m
${MBGL_ROOT}/platform/darwin/src/http_file_source.mm
${MBGL_ROOT}/platform/darwin/src/native_apple_interface.m
${MBGL_ROOT}/platform/darwin/src/image.mm
@@ -56,6 +57,8 @@ target_sources(
${MBGL_ROOT}/platform/default/src/mbgl/util/png_writer.cpp
${MBGL_ROOT}/platform/default/src/mbgl/util/thread_local.cpp
${MBGL_ROOT}/platform/default/src/mbgl/util/utf.cpp
${MBGL_ROOT}/platform/default/src/mbgl/util/thread_local.cpp
${MBGL_ROOT}/platform/default/src/mbgl/layermanager/layer_manager.cpp
)
target_include_directories(
@@ -90,4 +93,101 @@ target_link_libraries(
z
)
if(MBGL_IOS_RENDER_TEST)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
set(PREPARE_CMD "${MBGL_ROOT}/render-test/ios/setup_test_data.sh")
message("COMMAND: ${PREPARE_CMD}")
execute_process(COMMAND ${PREPARE_CMD} RESULT_VARIABLE CMD_ERROR)
message(STATUS "CMD_ERROR:" ${CMD_ERROR})
set(RESOURCES ${MBGL_ROOT}/render-test/ios/Main.storyboard ${MBGL_ROOT}/render-test/ios/LaunchScreen.storyboard ${MBGL_ROOT}/test-data)
set(PUBLIC_HEADER ${MBGL_ROOT}/render-test/ios/iosTestRunner.h)
add_executable(
RenderTestApp
${MBGL_ROOT}/render-test/ios/ios_test_runner.hpp
${MBGL_ROOT}/render-test/ios/ios_test_runner.cpp
${MBGL_ROOT}/render-test/ios/AppDelegate.h
${MBGL_ROOT}/render-test/ios/AppDelegate.m
${MBGL_ROOT}/render-test/ios/ViewController.h
${MBGL_ROOT}/render-test/ios/ViewController.m
${MBGL_ROOT}/render-test/ios/iosTestRunner.h
${MBGL_ROOT}/render-test/ios/iosTestRunner.mm
${MBGL_ROOT}/render-test/ios/main.m
${RESOURCES}
)
initialize_ios_target(RenderTestApp)
# Turn on ARC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fobjc-arc")
set_target_properties(
RenderTestApp
PROPERTIES
MACOSX_BUNDLE
TRUE
MACOSX_BUNDLE_IDENTIFIER
com.mapbox.RenderTestAPP
MACOSX_BUNDLE_INFO_PLIST
${MBGL_ROOT}/render-test/ios/Info.plist
RESOURCE
"${RESOURCES}"
)
target_include_directories(
RenderTestApp
PUBLIC {MBGL_ROOT}/render-test/include ${MBGL_ROOT}/include
)
target_include_directories(
RenderTestApp
PRIVATE
${MBGL_ROOT}/platform/darwin/src
${MBGL_ROOT}/platform/darwin/include
${MBGL_ROOT}/platform/darwin/include/mbgl/interface/
${MBGL_ROOT}/platform/default/include
${MBGL_ROOT}/src
)
target_include_directories(
RenderTestApp
PUBLIC ${MBGL_ROOT}/render-test/ios
)
target_link_libraries(
RenderTestApp
PRIVATE
"-framework CoreGraphics"
"-framework CoreLocation"
"-framework Foundation"
"-framework OpenGLES"
"-framework QuartzCore"
"-framework UIKit"
mbgl-render-test
)
find_package(XCTest REQUIRED)
xctest_add_bundle(RenderTestAppTests RenderTestApp ${MBGL_ROOT}/render-test/ios/tests/Tests.m)
set_target_properties(
RenderTestAppTests
PROPERTIES
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET
"${IOS_DEPLOYMENT_TARGET}"
XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH
$<$<CONFIG:Debug>:YES>
)
target_include_directories(
RenderTestAppTests
PUBLIC ${MBGL_ROOT}/render-test/ios
)
xctest_add_test(XCTest.RenderTestApp RenderTestAppTests)
set_target_properties(RenderTestAppTests PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${MBGL_ROOT}/render-test/ios/tests/Info.plist)
endif()
unset(IOS_DEPLOYMENT_TARGET CACHE)

View File

@@ -18,6 +18,13 @@ add_library(
${MBGL_ROOT}/render-test/runner.hpp
)
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
set_target_properties(mbgl-render-test PROPERTIES XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "${IOS_DEPLOYMENT_TARGET}")
set_target_properties(mbgl-render-test PROPERTIES XCODE_ATTRIBUTE_ENABLE_BITCODE "YES")
set_target_properties(mbgl-render-test PROPERTIES XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE bitcode)
set_target_properties(mbgl-render-test PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH $<$<CONFIG:Debug>:YES>)
endif()
# FIXME: Should not use core private interface
target_include_directories(
mbgl-render-test

View File

@@ -0,0 +1,7 @@
#import <UIKit/UIApplication.h> // UIApplicationDelegate
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

View File

@@ -0,0 +1,38 @@
#import "AppDelegate.h"
@interface AppDelegate()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Insert code here to initialize your application
NSLog(@"didFinishLaunchingWithOptions");
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

3
render-test/ios/Gemfile Normal file
View File

@@ -0,0 +1,3 @@
source "https://rubygems.org"
gem "fastlane"

View File

@@ -0,0 +1,159 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
atomos (0.1.3)
babosa (1.0.3)
claide (1.0.3)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
highline (~> 1.7.2)
declarative (0.0.10)
declarative-option (0.1.0)
digest-crc (0.4.1)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.5)
emoji_regex (1.0.1)
excon (0.71.1)
faraday (0.17.3)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.7)
fastlane (2.139.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander-fastlane (>= 4.4.6, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 2.0)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 0.17)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.13.1)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.29.2, < 0.37.0)
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
jwt (~> 2.1.0)
mini_magick (>= 4.9.4, < 5.0.0)
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
public_suffix (~> 2.0.0)
rubyzip (>= 1.3.0, < 2.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-api-client (0.36.4)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.9)
httpclient (>= 2.8.1, < 3.0)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.12)
google-cloud-core (1.4.1)
google-cloud-env (~> 1.0)
google-cloud-env (1.3.0)
faraday (~> 0.11)
google-cloud-storage (1.25.0)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-api-client (~> 0.33)
google-cloud-core (~> 1.2)
googleauth (~> 0.9)
mini_mime (~> 1.0)
googleauth (0.10.0)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.12)
highline (1.7.10)
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.3)
json (2.3.0)
jwt (2.1.0)
memoist (0.16.2)
mini_magick (4.10.1)
mini_mime (1.0.2)
multi_json (1.14.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.6)
naturally (2.2.0)
os (1.0.1)
plist (3.5.0)
public_suffix (2.0.5)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rouge (2.0.7)
rubyzip (1.3.0)
security (0.1.3)
signet (0.12.0)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.7)
CFPropertyList
naturally
slack-notifier (2.3.2)
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
tty-cursor (0.7.0)
tty-screen (0.7.0)
tty-spinner (0.9.2)
tty-cursor (~> 0.7)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.6)
unicode-display_width (1.6.0)
word_wrap (1.0.0)
xcodeproj (1.14.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.0)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
DEPENDENCIES
fastlane
BUNDLED WITH
2.1.4

View File

@@ -0,0 +1,62 @@
<?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>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>RenderTestApp</string>
<key>CFBundleIdentifier</key>
<string>com.mapbox.RenderTestApp</string>
<key>CFBundleGetInfoString</key>
<string>com.mapbox.RenderTestApp</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>1.0</string>
<key>CFBundleLongVersionString</key>
<string>1.0</string>
<key>CFBundleName</key>
<string>com.mapbox.RenderTestApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>MBGL</string>
<key>CFBundleVersion</key>
<string>7877</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>© 2014–2020 Mapbox</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@@ -0,0 +1,68 @@
<?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>RenderTestAppTests</key>
<dict>
<key>BlueprintName</key>
<string>RenderTestAppTests</string>
<key>BundleIdentifiersForCrashReportEmphasis</key>
<array>
<string>com.mapbox.RenderTestApp</string>
<string>com.mapbox.RenderTestAppTests</string>
</array>
<key>CommandLineArguments</key>
<array/>
<key>DependentProductPaths</key>
<array>
<string>__TESTROOT__/Debug-iphoneos/RenderTestApp.app</string>
<string>__TESTROOT__/Debug-iphoneos/RenderTestApp.app/PlugIns/RenderTestAppTests.xctest</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>OS_ACTIVITY_DT_MODE</key>
<string>YES</string>
<key>SQLITE_ENABLE_THREAD_ASSERTIONS</key>
<string>1</string>
</dict>
<key>IsAppHostedTestBundle</key>
<true/>
<key>ProductModuleName</key>
<string>RenderTestAppTests</string>
<key>RunOrder</key>
<integer>0</integer>
<key>SystemAttachmentLifetime</key>
<string>deleteOnSuccess</string>
<key>TestBundlePath</key>
<string>__TESTHOST__/PlugIns/RenderTestAppTests.xctest</string>
<key>TestHostBundleIdentifier</key>
<string>com.mapbox.RenderTestApp</string>
<key>TestHostPath</key>
<string>__TESTROOT__/Debug-iphoneos/RenderTestApp.app</string>
<key>TestLanguage</key>
<string></string>
<key>TestRegion</key>
<string></string>
<key>TestingEnvironmentVariables</key>
<dict>
<key>DYLD_FALLBACK_FRAMEWORK_PATH</key>
<string></string>
<key>DYLD_INSERT_LIBRARIES</key>
<string>__PLATFORMS__/iPhoneOS.platform/Developer/usr/lib/libXCTestBundleInject.dylib</string>
<key>XCInjectBundleInto</key>
<string>unused</string>
</dict>
<key>ToolchainsSettingValue</key>
<array/>
<key>UITargetAppCommandLineArguments</key>
<array/>
<key>UserAttachmentLifetime</key>
<string>deleteOnSuccess</string>
</dict>
<key>__xctestrun_metadata__</key>
<dict>
<key>FormatVersion</key>
<integer>1</integer>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,68 @@
<?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>RenderTestAppTests</key>
<dict>
<key>BlueprintName</key>
<string>RenderTestAppTests</string>
<key>BundleIdentifiersForCrashReportEmphasis</key>
<array>
<string>com.mapbox.RenderTestApp</string>
<string>com.mapbox.RenderTestAppTests</string>
</array>
<key>CommandLineArguments</key>
<array/>
<key>DependentProductPaths</key>
<array>
<string>__TESTROOT__/Release-iphoneos/RenderTestApp.app</string>
<string>__TESTROOT__/Release-iphoneos/RenderTestApp.app/PlugIns/RenderTestAppTests.xctest</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>OS_ACTIVITY_DT_MODE</key>
<string>YES</string>
<key>SQLITE_ENABLE_THREAD_ASSERTIONS</key>
<string>1</string>
</dict>
<key>IsAppHostedTestBundle</key>
<true/>
<key>ProductModuleName</key>
<string>RenderTestAppTests</string>
<key>RunOrder</key>
<integer>0</integer>
<key>SystemAttachmentLifetime</key>
<string>deleteOnSuccess</string>
<key>TestBundlePath</key>
<string>__TESTHOST__/PlugIns/RenderTestAppTests.xctest</string>
<key>TestHostBundleIdentifier</key>
<string>com.mapbox.RenderTestApp</string>
<key>TestHostPath</key>
<string>__TESTROOT__/Release-iphoneos/RenderTestApp.app</string>
<key>TestLanguage</key>
<string></string>
<key>TestRegion</key>
<string></string>
<key>TestingEnvironmentVariables</key>
<dict>
<key>DYLD_FALLBACK_FRAMEWORK_PATH</key>
<string></string>
<key>DYLD_INSERT_LIBRARIES</key>
<string>__PLATFORMS__/iPhoneOS.platform/Developer/usr/lib/libXCTestBundleInject.dylib</string>
<key>XCInjectBundleInto</key>
<string>unused</string>
</dict>
<key>ToolchainsSettingValue</key>
<array/>
<key>UITargetAppCommandLineArguments</key>
<array/>
<key>UserAttachmentLifetime</key>
<string>deleteOnSuccess</string>
</dict>
<key>__xctestrun_metadata__</key>
<dict>
<key>FormatVersion</key>
<integer>1</integer>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

View File

@@ -0,0 +1,22 @@
#import "ViewController.h"
#import "iosTestRunner.h"
@interface ViewController ()
{
IosTestRunner* i;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// In order to run test runner with app itself instead of with unit test, comment out the following line.
// i = [[IosTestRunner alloc]init];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end

View File

@@ -0,0 +1,16 @@
<?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>application-identifier</key>
<string>$TEAM_ID.com.mapbox.RenderTestApp</string>
<key>com.apple.developer.team-identifier</key>
<string>$TEAM_ID</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$TEAM_ID.com.mapbox.RenderTestApp</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,16 @@
<?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>application-identifier</key>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
<key>com.apple.developer.team-identifier</key>
<string>$TEAM_ID</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,16 @@
<?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>application-identifier</key>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
<key>com.apple.developer.team-identifier</key>
<string>$TEAM_ID</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,16 @@
<?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>application-identifier</key>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
<key>com.apple.developer.team-identifier</key>
<string>$TEAM_ID</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
#!/bin/bash
codesign --force --sign $CODESIGNIDENTITY --entitlements ../codesigning/RenderTestApp.app.xcent --timestamp=none ./Release-iphoneos/RenderTestApp.app
codesign --force --sign $CODESIGNIDENTITY --deep --preserve-metadata=identifier,entitlements,flags --timestamp=none ./Release-iphoneos/RenderTestApp.app/Frameworks/libXCTestSwiftSupport.dylib
codesign --force --sign $CODESIGNIDENTITY --deep --preserve-metadata=identifier,entitlements,flags --timestamp=none ./Release-iphoneos/RenderTestApp.app/Frameworks/libXCTestBundleInject.dylib
codesign --force --sign $CODESIGNIDENTITY --deep --preserve-metadata=identifier,entitlements,flags --timestamp=none ./Release-iphoneos/RenderTestApp.app/Frameworks/XCTAutomationSupport.framework
codesign --force --sign $CODESIGNIDENTITY --deep --preserve-metadata=identifier,entitlements,flags --timestamp=none ./Release-iphoneos/RenderTestApp.app/Frameworks/XCTest.framework
codesign --force --sign $CODESIGNIDENTITY --deep --entitlements ../codesigning/RenderTestAppTests.xctest.xcent --timestamp=none ./Release-iphoneos/RenderTestApp.app/PlugIns/RenderTestAppTests.xctest

View File

@@ -0,0 +1,40 @@
#!/usr/bin/swift
/// Generates Entitlement files .xcent for codesigning, containing the correct team id
import Swift
import Foundation
let fileManager = FileManager.default
let contentsOfCurrentWorkingDirectory = try FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: "./codesigning/"), includingPropertiesForKeys: nil, options: [])
guard let rawTeamIdEnv = getenv("IOS_DEVELOPMENT_TEAM") else {
print("Please add a IOS_DEVELOPMENT_TEAM environment variable.")
exit(1)
}
let teamId2 = String(utf8String: rawTeamIdEnv)
for file in contentsOfCurrentWorkingDirectory {
if (file.pathExtension == "template") {
var content = ""
do {
content = try String(contentsOf: file, encoding: .utf8)
}
catch {
print("Error reading xcent file: \(error).")
}
content = content.replacingOccurrences(of: "$TEAM_ID", with: teamId2!)
var targetFile = file
targetFile.deletePathExtension()
do {
try content.write(to: targetFile, atomically: false, encoding: .utf8)
print("Entitlement " + targetFile.absoluteString + " generated.")
}
catch {
print("Error writing xcent file: \(error).")
}
}
}

View File

@@ -0,0 +1,16 @@
<?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>application-identifier</key>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
<key>com.apple.developer.team-identifier</key>
<string>$TEAM_ID</string>
<key>get-task-allow</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$TEAM_ID.com.mapbox.RenderTestAppTests</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,3 @@
app_identifier("com.mapbox.RenderTestApp") # The bundle identifier of your app
apple_id ENV['MAPBOX_APPLE_ID']
team_id ENV['MAPBOX_APPLE_TEAM_ID'] # Developer Portal Team ID

View File

@@ -0,0 +1,5 @@
git_url("git@github.com:mapbox/apple-certificates.git")
type("development") # The default type, can be: appstore, adhoc, enterprise or development
app_identifier(["com.mapbox.RenderTestApp", "com.mapbox.RenderTestAppTests"])
username ENV['MAPBOX_APPLE_ID']
keychain_name("fastlane_keychain")

View File

@@ -0,0 +1,44 @@
fastlane documentation
================
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```
xcode-select --install
```
Install _fastlane_ using
```
[sudo] gem install fastlane -NV
```
or alternatively using `brew cask install fastlane`
# Available Actions
## iOS
### ios ios_build
```
fastlane ios ios_build
```
Description of what the lane does
### ios gym_build
```
fastlane ios gym_build
```
Description of what the lane does
### ios xcode_build
```
fastlane ios xcode_build
```
Description of what the lane does
### ios ci_build
```
fastlane ios ci_build
```
Description of what the lane does
----
This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

View File

@@ -0,0 +1,6 @@
#import <Foundation/Foundation.h>
__attribute__((visibility ("default")))
@interface IosTestRunner : NSObject
- (NSString*) getResultPath;
- (BOOL) getTestStatus;
@end

View File

@@ -0,0 +1,98 @@
#import "iosTestRunner.h"
#include "ios_test_runner.hpp"
#include <string>
@interface IosTestRunner ()
@property (nullable) TestRunner* runner;
@property (copy, nullable) NSString *resultPath;
@property BOOL testStatus;
@end
@implementation IosTestRunner
-(instancetype)init
{
self = [super init];
if (self) {
self.testStatus = false;
self.runner = new TestRunner();
NSString *path = nil;
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *bundleContents = [fileManager contentsOfDirectoryAtPath: bundleRoot error: &error];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex: 0];
for (uint32_t i = 0; i < bundleContents.count; i++) {
NSString *dirName = [bundleContents objectAtIndex: i];
if ([dirName isEqualToString:@"test-data"]) {
NSString *destinationPath = [documentsDir stringByAppendingPathComponent: dirName];
//Using NSFileManager we can perform many file system operations.
BOOL success = [fileManager fileExistsAtPath: destinationPath];
if (success) {
success = [fileManager removeItemAtPath:destinationPath error:NULL];
}
break;
}
}
for (uint32_t i = 0; i < bundleContents.count; i++) {
NSString *dirName = [bundleContents objectAtIndex: i];
if ([dirName isEqualToString:@"test-data"]) {
NSString *destinationPath = [documentsDir stringByAppendingPathComponent: dirName];
BOOL success = [fileManager fileExistsAtPath: destinationPath];
if (!success) {
NSString *copyDirPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: dirName];
success = [fileManager copyItemAtPath: copyDirPath toPath: destinationPath error: &error];
if (!success){
NSAssert1(0, @"Failed to copy file '%@'.", [error localizedDescription]);
NSLog(@"Failed to copy %@ file, error %@", dirName, [error localizedDescription]);
}
else {
path = destinationPath;
NSLog(@"File copied %@ OK", dirName);
}
}
else {
NSLog(@"File exits %@, skip copy", dirName);
}
break;
}
}
if (path) {
NSString *manifestPath = [path stringByAppendingPathComponent:@"/next-ios-render-test-runner-style.json"];
std::string manifest = std::string([manifestPath UTF8String]);
self.testStatus = self.runner->startTest(manifest);
self.resultPath = [path stringByAppendingPathComponent:@"/next-ios-render-test-runner-style.html"];
BOOL fileFound = [fileManager fileExistsAtPath: self.resultPath];
if (!fileFound) {
NSLog(@"File doese not exit %@", self.resultPath);
}
self.testStatus &= fileFound;
}
delete self.runner;
self.runner = nullptr;
}
return self;
}
- (NSString*) getResultPath {
return self.resultPath;
}
- (BOOL) getTestStatus {
return self.testStatus;
}
@end

View File

@@ -0,0 +1,40 @@
#include "ios_test_runner.hpp"
#include <mbgl/render_test.hpp>
#include <mbgl/util/logging.hpp>
#include <vector>
#define EXPORT __attribute__((visibility("default")))
EXPORT
bool TestRunner::startTest(const std::string& manifest) {
auto runTestWithManifest = [](const std::string& manifest) -> bool {
std::vector<std::string> arguments = {"mbgl-render-test-runner", "-p", manifest};
std::vector<char*> argv;
for (const auto& arg : arguments) {
argv.push_back(const_cast<char*>(arg.data()));
}
argv.push_back(nullptr);
int finishedTestCount = 0;
std::function<void()> testStatus = [&]() {
mbgl::Log::Info(mbgl::Event::General, "Current finished tests number is '%d' ", ++finishedTestCount);
};
mbgl::Log::Info(mbgl::Event::General, "Start running RenderTestRunner with manifest: '%s'", manifest.c_str());
auto result = mbgl::runRenderTests(static_cast<int>(argv.size() - 1), argv.data(), testStatus) == 0;
mbgl::Log::Info(mbgl::Event::General, "End running RenderTestRunner with manifest: '%s'", manifest.c_str());
return result;
};
auto ret = false;
try {
ret = runTestWithManifest(manifest);
} catch (...) {
mbgl::Log::Info(mbgl::Event::General, "testFailed");
}
mbgl::Log::Info(mbgl::Event::General, "All tests are finished!");
return ret;
}

View File

@@ -0,0 +1,14 @@
#ifndef ios_test_runner_hpp
#define ios_test_runner_hpp
#include <string>
class TestRunner {
public:
TestRunner() = default;
~TestRunner() = default;
bool startTest(const std::string& manifest);
};
#endif /* ios_test_runner_hpp */

9
render-test/ios/main.m Normal file
View File

@@ -0,0 +1,9 @@
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

View File

@@ -0,0 +1,12 @@
#!/bin/bash
rm -rf ../../test-data
mkdir ../../test-data
mkdir ../../test-data/integration
cp -r ../../mapbox-gl-js/test/integration/render-tests ../../test-data/integration/
cp -r ../../mapbox-gl-js/test/integration/query-tests ../../test-data/integration/
cp -r ../../metrics/expectations ../../test-data/
cp -r ../../metrics/ignores ../../test-data/
cp -r ../../metrics/next-ios-render-test-runner-style.json ../../test-data/
cp -r ../../metrics/cache-metrics.db ../../test-data/
cp -r ../../metrics/cache-style.db ../../test-data/

View File

@@ -0,0 +1,22 @@
<?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>CFBundleExecutable</key>
<string>RenderTestAppTests</string>
<key>CFBundleIdentifier</key>
<string>com.mapbox.RenderTestAppTests</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>1.0</string>
<key>CFBundleName</key>
<string>RenderTestAppTests</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@@ -0,0 +1,38 @@
#import <XCTest/XCTest.h>
#import "iosTestRunner.h"
@interface Tests : XCTestCase
@end
@implementation Tests
- (void)setUp {
[super setUp];
}
- (void)tearDown {
[super tearDown];
}
- (void)testStartRenderTestRunner {
IosTestRunner* runner = [[IosTestRunner alloc] init];
XCTAssert(runner, @"IOSTestRunner is not initialized correctly");
NSString* result = [runner getResultPath];
XCTAssert(result, @"IOSTestRunner does not produce a result file");
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL fileFound = [fileManager fileExistsAtPath: result];
XCTAssert(fileFound, @"Test result html '%@' doese not exit", result);
NSURL *url = [NSURL fileURLWithPath:result];
XCTAttachment *attachmentURL = [XCTAttachment attachmentWithContentsOfFileAtURL: url];
XCTAssert(attachmentURL, @"Failed to attach test result '%@'", result);
attachmentURL.lifetime = XCTAttachmentLifetimeKeepAlways;
[self addAttachment:attachmentURL];
BOOL success = [runner getTestStatus];
XCTAssert(success, @"IOSTestRunner reports error because some of the tests are not passed, please check the test report");
}
@end

View File

@@ -666,7 +666,7 @@ uint32_t getImageTileOffset(const std::set<uint32_t>& dims, uint32_t dim) {
assert(false);
return 0;
}
return std::distance(dims.begin(), it) * kTileSizeUint;
return static_cast<uint32_t>(std::distance(dims.begin(), it)) * kTileSizeUint;
}
} // namespace