[ios] Run core unit tests in CI

This commit is contained in:
John Firebaugh
2016-04-07 18:55:48 -07:00
parent c507b8a693
commit 1c7c5af69d
21 changed files with 181 additions and 94 deletions

View File

@@ -21,17 +21,17 @@ OSX_PROJ_PATH = build/osx-x86_64/platform/osx/platform.xcodeproj
osx:
$(RUN) PLATFORM=osx Xcode/All
$(OSX_PROJ_PATH): platform/osx/platform.gyp platform/osx/scripts/configure.sh mbgl.gypi
$(OSX_PROJ_PATH): platform/osx/platform.gyp platform/osx/scripts/configure.sh mbgl.gypi test/test.gypi
$(RUN) PLATFORM=osx Xcode/__project__
xproj: $(OSX_PROJ_PATH)
open $(OSX_PROJ_PATH)
$(OSX_PROJ_PATH)/xcshareddata/xcschemes/osxtest.xcscheme: platform/osx/scripts/osxtest.xcscheme $(OSX_PROJ_PATH)
$(OSX_PROJ_PATH)/xcshareddata/xcschemes/osxtest.xcscheme: platform/osx/scripts/osxtest.xcscheme
mkdir -p $(basename $@)
cp $< $@
test-osx: $(OSX_PROJ_PATH)/xcshareddata/xcschemes/osxtest.xcscheme node_modules/express
test-osx: $(OSX_PROJ_PATH) $(OSX_PROJ_PATH)/xcshareddata/xcschemes/osxtest.xcscheme node_modules/express
xcodebuild -project $(OSX_PROJ_PATH) -configuration $(BUILDTYPE) -target test build
build/osx-x86_64/$(BUILDTYPE)/test
xcodebuild -project $(OSX_PROJ_PATH) -configuration $(BUILDTYPE) -scheme osxtest test
@@ -43,14 +43,18 @@ IOS_PROJ_PATH = build/ios-all/platform/ios/platform.xcodeproj
ios:
$(RUN) PLATFORM=ios Xcode/All
$(IOS_PROJ_PATH): platform/ios/platform.gyp platform/ios/scripts/configure.sh mbgl.gypi
$(IOS_PROJ_PATH): platform/ios/platform.gyp platform/ios/scripts/configure.sh mbgl.gypi test/test.gypi
$(RUN) PLATFORM=ios Xcode/__project__
iproj: $(IOS_PROJ_PATH)
open $(IOS_PROJ_PATH)
test-ios:
# Currently nothing
test-ios: $(IOS_PROJ_PATH)
xcodebuild -project $(IOS_PROJ_PATH) -configuration $(BUILDTYPE) \
-sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' \
-target test build
ios-sim start
ios-sim launch build/ios-all/$(BUILDTYPE)-iphonesimulator/ios-test.app --verbose
ipackage: $(IOS_PROJ_PATH)
BITCODE=$(BITCODE) FORMAT=$(FORMAT) BUILD_DEVICE=$(BUILD_DEVICE) SYMBOLS=$(SYMBOLS) \

View File

@@ -20,6 +20,13 @@ The Mapbox iOS SDK and iosapp demo application build against the iOS 7.0 SDK. Th
[sudo] gem install jazzy
```
1. Install ios-sim version 3.2.0 (not any other version) for running `make test-ios`:
```
brew tap mapbox/homebrew-ios-sim-3
brew install mapbox/homebrew-ios-sim-3/ios-sim
```
1. Run `make ipackage`. The packaging script will produce a `build/ios/pkg/` folder containing:
- a `dynamic` folder containing a dynamically-linked fat framework with debug symbols for devices and the iOS Simulator
- a `static` folder containing a statically-linked framework with debug symbols for devices and the iOS Simulator

View File

@@ -29,6 +29,8 @@ workflows:
- content: |-
#!/bin/bash
set -eu -o pipefail
brew tap mapbox/homebrew-ios-sim-3
brew install mapbox/homebrew-ios-sim-3/ios-sim
gem install jazzy --no-rdoc --no-ri
export BUILDTYPE=Debug
make ios

View File

@@ -10,6 +10,7 @@
},
'includes': [
'../../mbgl.gypi',
'../../test/test.gypi',
],
'target_defaults': {
'target_conditions': [
@@ -33,6 +34,40 @@
],
},
'targets': [
{
'target_name': 'test',
'type': 'executable',
'product_name': 'ios-test',
'product_extension': 'app',
'mac_bundle': 1,
'dependencies': [
'test-lib',
'platform-lib',
],
'sources': [
'../../test/src/main.mm',
# '../../src/mbgl/util/premultiply.cpp',
],
'xcode_settings': {
'SDKROOT': 'iphoneos',
'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',
'INFOPLIST_FILE': '../../test/src/app-info.plist',
'IPHONEOS_DEPLOYMENT_TARGET': '8.0',
'TARGETED_DEVICE_FAMILY': '1,2',
'COPY_PHASE_STRIP': 'NO',
'CLANG_ENABLE_OBJC_ARC': 'YES',
'CLANG_ENABLE_MODULES': 'YES',
'CODE_SIGN_IDENTITY': 'iPhone Developer',
},
'copies': [{
'destination': '<(PRODUCT_DIR)/$(WRAPPER_NAME)/test',
'files': [ '../../test/fixtures' ],
}]
},
{
'target_name': 'platform-lib',
'product_name': 'mbgl-platform-ios',

View File

@@ -18,6 +18,20 @@
'../../bin/offline.gypi',
],
'targets': [
{
'target_name': 'test',
'type': 'executable',
'dependencies': [
'test-lib',
'platform-lib',
'copy_certificate_bundle',
],
'sources': [
'../../test/src/main.cpp',
],
},
{
'target_name': 'platform-lib',
'product_name': 'mbgl-platform-linux',

View File

@@ -16,6 +16,19 @@
'../../bin/offline.gypi',
],
'targets': [
{
'target_name': 'test',
'type': 'executable',
'dependencies': [
'test-lib',
'platform-lib',
],
'sources': [
'../../test/src/main.cpp',
],
},
{
'target_name': 'platform-lib',
'product_name': 'mbgl-platform-osx',

View File

@@ -1,53 +0,0 @@
#include <mbgl/test/util.hpp>
#include <mbgl/platform/default/headless_display.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/storage/offline_database.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/work_request.hpp>
#include <mbgl/util/io.hpp>
using namespace mbgl;
using namespace std::literals::chrono_literals;
using namespace std::literals::string_literals;
namespace {
Response expiredItem(const std::string& path) {
Response response;
response.data = std::make_shared<std::string>(util::read_file("test/fixtures/"s + path));
response.expires = SystemClock::from_time_t(0);
return response;
}
const std::string prefix = "http://127.0.0.1:3000";
}
auto display = std::make_shared<mbgl::HeadlessDisplay>();
TEST(API, Offline) {
HeadlessView view(display, 1);
DefaultFileSource fileSource(":memory:", ".");
fileSource.put(Resource::style(prefix + "/offline/style.json"), expiredItem("offline/style.json"));
fileSource.put(Resource::source(prefix + "/offline/streets.json"), expiredItem("offline/streets.json"));
fileSource.put(Resource::spriteJSON(prefix + "/offline/sprite", 1.0), expiredItem("offline/sprite.json"));
fileSource.put(Resource::spriteImage(prefix + "/offline/sprite", 1.0), expiredItem("offline/sprite.png"));
fileSource.put(Resource::tile(prefix + "/offline/{z}-{x}-{y}.vector.pbf", 1.0, 0, 0, 0), expiredItem("offline/0-0-0.vector.pbf"));
fileSource.put(Resource::glyphs(prefix + "/offline/{fontstack}/{range}.pbf", "Helvetica", {0, 255}), expiredItem("offline/glyph.pbf"));
NetworkStatus::Set(NetworkStatus::Status::Offline);
Map map(view, fileSource, MapMode::Still);
map.setStyleURL(prefix + "/offline/style.json");
test::checkImage("test/fixtures/offline"s,
test::render(map),
0.0015,
0.1);
NetworkStatus::Set(NetworkStatus::Status::Online);
}

View File

@@ -0,0 +1,7 @@
#pragma once
namespace mbgl {
int runTests(int argc, char* argv[]);
}

View File

@@ -4,12 +4,15 @@
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/headless_display.hpp>
#include <mbgl/storage/online_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/storage/offline_database.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/io.hpp>
using namespace mbgl;
using namespace std::literals::string_literals;
TEST(Map, PauseResume) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
OnlineFileSource fileSource;
@@ -21,8 +24,6 @@ TEST(Map, PauseResume) {
}
TEST(Map, DoublePause) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
OnlineFileSource fileSource;
@@ -35,8 +36,6 @@ TEST(Map, DoublePause) {
}
TEST(Map, ResumeWithoutPause) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
OnlineFileSource fileSource;
@@ -47,8 +46,6 @@ TEST(Map, ResumeWithoutPause) {
}
TEST(Map, DestroyPaused) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
OnlineFileSource fileSource;
@@ -57,3 +54,35 @@ TEST(Map, DestroyPaused) {
map.pause();
}
TEST(Map, Offline) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
DefaultFileSource fileSource(":memory:", ".");
auto expiredItem = [] (const std::string& path) {
Response response;
response.data = std::make_shared<std::string>(util::read_file("test/fixtures/"s + path));
response.expires = SystemClock::from_time_t(0);
return response;
};
const std::string prefix = "http://127.0.0.1:3000";
fileSource.put(Resource::style(prefix + "/offline/style.json"), expiredItem("offline/style.json"));
fileSource.put(Resource::source(prefix + "/offline/streets.json"), expiredItem("offline/streets.json"));
fileSource.put(Resource::spriteJSON(prefix + "/offline/sprite", 1.0), expiredItem("offline/sprite.json"));
fileSource.put(Resource::spriteImage(prefix + "/offline/sprite", 1.0), expiredItem("offline/sprite.png"));
fileSource.put(Resource::tile(prefix + "/offline/{z}-{x}-{y}.vector.pbf", 1.0, 0, 0, 0), expiredItem("offline/0-0-0.vector.pbf"));
fileSource.put(Resource::glyphs(prefix + "/offline/{fontstack}/{range}.pbf", "Helvetica", {0, 255}), expiredItem("offline/glyph.pbf"));
NetworkStatus::Set(NetworkStatus::Status::Offline);
Map map(view, fileSource, MapMode::Still);
map.setStyleURL(prefix + "/offline/style.json");
test::checkImage("test/fixtures/offline",
test::render(map),
0.0015,
0.1);
NetworkStatus::Set(NetworkStatus::Status::Online);
}

View File

@@ -1,6 +1,5 @@
#include <mbgl/test/util.hpp>
#include <mbgl/test.hpp>
GTEST_API_ int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
int main(int argc, char *argv[]) {
return mbgl::runTests(argc, argv);
}

View File

@@ -1,10 +1,8 @@
#import <Foundation/Foundation.h>
#include <mbgl/test.hpp>
#include <mbgl/test/util.hpp>
#import <Foundation/Foundation.h>
int main(int argc, char* argv[]) {
[[NSFileManager defaultManager] changeCurrentDirectoryPath:[[NSBundle mainBundle] bundlePath]];
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
return mbgl::runTests(argc, argv);
}

View File

@@ -0,0 +1,11 @@
#include <mbgl/test.hpp>
#include <gtest/gtest.h>
namespace mbgl {
int runTests(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
}

View File

@@ -1,31 +1,20 @@
{
'targets': [
{
'target_name': 'test',
'type': 'executable',
'target_name': 'test-lib',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'include_dirs': [
'../include',
'../src',
'../platform/default',
'include',
],
'dependencies': [
'platform-lib',
'copy_certificate_bundle',
'src',
],
'sources': [
# Test helper files
'src/stub_file_source.cpp',
'include/mbgl/test/stub_file_source.hpp',
'include/mbgl/test/mock_view.hpp',
'include/mbgl/test/util.hpp',
'src/util.cpp',
'include/mbgl/test/fixture_log_observer.hpp',
'src/fixture_log_observer.cpp',
'util/assert.cpp',
'util/async_task.cpp',
'util/clip_ids.cpp',
@@ -49,7 +38,6 @@
'api/render_missing.cpp',
'api/set_style.cpp',
'api/custom_layer.cpp',
'api/offline.cpp',
'geometry/binpack.cpp',
@@ -92,7 +80,14 @@
'sprite/sprite_parser.cpp',
'sprite/sprite_store.cpp',
'src/main.cpp',
'src/mbgl/test/stub_file_source.hpp',
'src/mbgl/test/stub_file_source.cpp',
'src/mbgl/test/mock_view.hpp',
'src/mbgl/test/util.hpp',
'src/mbgl/test/util.cpp',
'src/mbgl/test/fixture_log_observer.hpp',
'src/mbgl/test/fixture_log_observer.cpp',
'src/mbgl/test/test.cpp'
],
'variables': {
@@ -136,6 +131,32 @@
}]
],
},
'direct_dependent_settings': {
'include_dirs': [
'include',
],
# Force the linker to include all the objects from the lib-test archive. Otherwise they'd
# be discarded because there are no undefined symbols to pull them in, and the resulting
# executable would run zero tests.
'conditions': [
['OS == "mac"', {
'xcode_settings': {
'OTHER_LDFLAGS': [
'-Wl,-force_load,<(PRODUCT_DIR)/libtest-lib.a',
],
}
}, {
'link_settings': {
'ldflags': [
'-Wl,-whole-archive <(PRODUCT_DIR)/libtest-lib.a -Wl,-no-whole-archive',
],
},
}],
],
},
},
]
}