Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
ace54425
Unverified
Commit
ace54425
authored
Sep 03, 2020
by
Jenn Magder
Committed by
GitHub
Sep 03, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add observatory Bonjour service to built iOS Info.plist bundle (#65138)
parent
020215bb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
352 additions
and
97 deletions
+352
-97
ios_content_validation_test.dart
dev/devicelab/bin/tasks/ios_content_validation_test.dart
+46
-16
ios.dart
dev/devicelab/lib/framework/ios.dart
+36
-0
xcode_backend.sh
packages/flutter_tools/bin/xcode_backend.sh
+64
-17
xcode_backend_test.dart
...tter_tools/test/general.shard/ios/xcode_backend_test.dart
+0
-64
xcode_backend_test.dart
...tter_tools/test/integration.shard/xcode_backend_test.dart
+206
-0
No files found.
dev/devicelab/bin/tasks/ios_content_validation_test.dart
View file @
ace54425
...
@@ -14,8 +14,6 @@ import 'package:path/path.dart' as path;
...
@@ -14,8 +14,6 @@ import 'package:path/path.dart' as path;
Future
<
void
>
main
()
async
{
Future
<
void
>
main
()
async
{
await
task
(()
async
{
await
task
(()
async
{
try
{
try
{
bool
foundProjectName
=
false
;
bool
bitcode
=
false
;
await
runProjectTest
((
FlutterProject
flutterProject
)
async
{
await
runProjectTest
((
FlutterProject
flutterProject
)
async
{
section
(
'Build app with with --obfuscate'
);
section
(
'Build app with with --obfuscate'
);
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
...
@@ -52,6 +50,13 @@ Future<void> main() async {
...
@@ -52,6 +50,13 @@ Future<void> main() async {
fail
(
'Failed to produce expected output at
${outputAppFrameworkBinary.path}
'
);
fail
(
'Failed to produce expected output at
${outputAppFrameworkBinary.path}
'
);
}
}
if
(
await
dartObservatoryBonjourServiceFound
(
outputAppPath
))
{
throw
TaskResult
.
failure
(
'Release bundle has unexpected NSBonjourServices'
);
}
if
(
await
localNetworkUsageFound
(
outputAppPath
))
{
throw
TaskResult
.
failure
(
'Release bundle has unexpected NSLocalNetworkUsageDescription'
);
}
section
(
'Validate obfuscation'
);
section
(
'Validate obfuscation'
);
// Verify that an identifier from the Dart project code is not present
// Verify that an identifier from the Dart project code is not present
...
@@ -63,11 +68,11 @@ Future<void> main() async {
...
@@ -63,11 +68,11 @@ Future<void> main() async {
canFail:
true
,
canFail:
true
,
);
);
if
(
response
.
trim
().
contains
(
'matches'
))
{
if
(
response
.
trim
().
contains
(
'matches'
))
{
foundProjectName
=
true
;
throw
TaskResult
.
failure
(
'Found project name in obfuscated dart library'
)
;
}
}
});
});
section
(
'Validate
bitcode
'
);
section
(
'Validate
release contents
'
);
final
Directory
outputFlutterFramework
=
Directory
(
path
.
join
(
final
Directory
outputFlutterFramework
=
Directory
(
path
.
join
(
flutterProject
.
rootPath
,
flutterProject
.
rootPath
,
...
@@ -83,7 +88,13 @@ Future<void> main() async {
...
@@ -83,7 +88,13 @@ Future<void> main() async {
if
(!
outputFlutterFrameworkBinary
.
existsSync
())
{
if
(!
outputFlutterFrameworkBinary
.
existsSync
())
{
fail
(
'Failed to produce expected output at
${outputFlutterFrameworkBinary.path}
'
);
fail
(
'Failed to produce expected output at
${outputFlutterFrameworkBinary.path}
'
);
}
}
bitcode
=
await
containsBitcode
(
outputFlutterFrameworkBinary
.
path
);
// Archiving should contain a bitcode blob, but not building in release.
// This mimics Xcode behavior and present a developer from having to install a
// 300+MB app to test devices.
if
(
await
containsBitcode
(
outputFlutterFrameworkBinary
.
path
))
{
throw
TaskResult
.
failure
(
'Bitcode present in Flutter.framework'
);
}
section
(
'Xcode backend script'
);
section
(
'Xcode backend script'
);
...
@@ -101,7 +112,7 @@ Future<void> main() async {
...
@@ -101,7 +112,7 @@ Future<void> main() async {
'xcode_backend.sh'
'xcode_backend.sh'
);
);
// Simulate a common
ly
Xcode build setting misconfiguration
// Simulate a common Xcode build setting misconfiguration
// where FLUTTER_APPLICATION_PATH is missing
// where FLUTTER_APPLICATION_PATH is missing
final
int
result
=
await
exec
(
final
int
result
=
await
exec
(
xcodeBackendPath
,
xcodeBackendPath
,
...
@@ -111,6 +122,7 @@ Future<void> main() async {
...
@@ -111,6 +122,7 @@ Future<void> main() async {
'TARGET_BUILD_DIR'
:
buildPath
,
'TARGET_BUILD_DIR'
:
buildPath
,
'FRAMEWORKS_FOLDER_PATH'
:
'Runner.app/Frameworks'
,
'FRAMEWORKS_FOLDER_PATH'
:
'Runner.app/Frameworks'
,
'VERBOSE_SCRIPT_LOGGING'
:
'1'
,
'VERBOSE_SCRIPT_LOGGING'
:
'1'
,
'FLUTTER_BUILD_MODE'
:
'release'
,
'ACTION'
:
'install'
,
// Skip bitcode stripping since we just checked that above.
'ACTION'
:
'install'
,
// Skip bitcode stripping since we just checked that above.
},
},
);
);
...
@@ -126,17 +138,35 @@ Future<void> main() async {
...
@@ -126,17 +138,35 @@ Future<void> main() async {
if
(!
outputAppFrameworkBinary
.
existsSync
())
{
if
(!
outputAppFrameworkBinary
.
existsSync
())
{
fail
(
'Failed to re-embed
${outputAppFrameworkBinary.path}
'
);
fail
(
'Failed to re-embed
${outputAppFrameworkBinary.path}
'
);
}
}
});
if
(
foundProjectName
)
{
section
(
'Clean build'
);
return
TaskResult
.
failure
(
'Found project name in obfuscated dart library'
);
}
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
// Archiving should contain a bitcode blob, but not building in release.
await
flutter
(
'clean'
);
// This mimics Xcode behavior and present a developer from having to install a
});
// 300+MB app to test devices.
if
(
bitcode
)
{
section
(
'Validate debug contents'
);
return
TaskResult
.
failure
(
'Bitcode present in Flutter.framework'
);
}
await
inDirectory
(
flutterProject
.
rootPath
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'ios'
,
'--debug'
,
'--no-codesign'
,
]);
});
// Debug should also not contain bitcode.
if
(
await
containsBitcode
(
outputFlutterFrameworkBinary
.
path
))
{
throw
TaskResult
.
failure
(
'Bitcode present in Flutter.framework'
);
}
if
(!
await
dartObservatoryBonjourServiceFound
(
outputAppPath
))
{
throw
TaskResult
.
failure
(
'Debug bundle is missing NSBonjourServices'
);
}
if
(!
await
localNetworkUsageFound
(
outputAppPath
))
{
throw
TaskResult
.
failure
(
'Debug bundle is missing NSLocalNetworkUsageDescription'
);
}
});
return
TaskResult
.
success
(
null
);
return
TaskResult
.
success
(
null
);
}
on
TaskResult
catch
(
taskResult
)
{
}
on
TaskResult
catch
(
taskResult
)
{
...
...
dev/devicelab/lib/framework/ios.dart
View file @
ace54425
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
import
'dart:async'
;
import
'dart:async'
;
import
'dart:convert'
;
import
'dart:convert'
;
import
'package:path/path.dart'
as
path
;
import
'utils.dart'
;
import
'utils.dart'
;
typedef
SimulatorFunction
=
Future
<
void
>
Function
(
String
deviceId
);
typedef
SimulatorFunction
=
Future
<
void
>
Function
(
String
deviceId
);
...
@@ -102,6 +104,40 @@ Future<bool> containsBitcode(String pathToBinary) async {
...
@@ -102,6 +104,40 @@ Future<bool> containsBitcode(String pathToBinary) async {
return
!
emptyBitcodeMarkerFound
;
return
!
emptyBitcodeMarkerFound
;
}
}
Future
<
bool
>
dartObservatoryBonjourServiceFound
(
String
appBundlePath
)
async
=>
(
await
eval
(
'plutil'
,
<
String
>[
'-extract'
,
'NSBonjourServices'
,
'xml1'
,
'-o'
,
'-'
,
path
.
join
(
appBundlePath
,
'Info.plist'
,
),
],
canFail:
true
,
)).
contains
(
'_dartobservatory._tcp'
);
Future
<
bool
>
localNetworkUsageFound
(
String
appBundlePath
)
async
=>
await
exec
(
'plutil'
,
<
String
>[
'-extract'
,
'NSLocalNetworkUsageDescription'
,
'xml1'
,
'-o'
,
'-'
,
path
.
join
(
appBundlePath
,
'Info.plist'
,
),
],
canFail:
true
,
)
==
0
;
/// Creates and boots a new simulator, passes the new simulator's identifier to
/// Creates and boots a new simulator, passes the new simulator's identifier to
/// `testFunction`.
/// `testFunction`.
///
///
...
...
packages/flutter_tools/bin/xcode_backend.sh
View file @
ace54425
...
@@ -38,6 +38,32 @@ AssertExists() {
...
@@ -38,6 +38,32 @@ AssertExists() {
return
0
return
0
}
}
ParseFlutterBuildMode
()
{
# Use FLUTTER_BUILD_MODE if it's set, otherwise use the Xcode build configuration name
# This means that if someone wants to use an Xcode build config other than Debug/Profile/Release,
# they _must_ set FLUTTER_BUILD_MODE so we know what type of artifact to build.
local
build_mode
=
"
$(
echo
"
${
FLUTTER_BUILD_MODE
:-${
CONFIGURATION
}}
"
|
tr
"[:upper:]"
"[:lower:]"
)
"
case
"
$build_mode
"
in
*
release
*
)
build_mode
=
"release"
;;
*
profile
*
)
build_mode
=
"profile"
;;
*
debug
*
)
build_mode
=
"debug"
;;
*
)
EchoError
"========================================================================"
EchoError
"ERROR: Unknown FLUTTER_BUILD_MODE:
${
build_mode
}
."
EchoError
"Valid values are 'Debug', 'Profile', or 'Release' (case insensitive)."
EchoError
"This is controlled by the FLUTTER_BUILD_MODE environment variable."
EchoError
"If that is not set, the CONFIGURATION environment variable is used."
EchoError
""
EchoError
"You can fix this by either adding an appropriately named build"
EchoError
"configuration, or adding an appropriate value for FLUTTER_BUILD_MODE to the"
EchoError
".xcconfig file for the current build configuration (
${
CONFIGURATION
}
)."
EchoError
"========================================================================"
exit
-1
;;
esac
echo
"
${
build_mode
}
"
}
BuildApp
()
{
BuildApp
()
{
local
project_path
=
"
${
SOURCE_ROOT
}
/.."
local
project_path
=
"
${
SOURCE_ROOT
}
/.."
if
[[
-n
"
$FLUTTER_APPLICATION_PATH
"
]]
;
then
if
[[
-n
"
$FLUTTER_APPLICATION_PATH
"
]]
;
then
...
@@ -72,24 +98,12 @@ BuildApp() {
...
@@ -72,24 +98,12 @@ BuildApp() {
# Use FLUTTER_BUILD_MODE if it's set, otherwise use the Xcode build configuration name
# Use FLUTTER_BUILD_MODE if it's set, otherwise use the Xcode build configuration name
# This means that if someone wants to use an Xcode build config other than Debug/Profile/Release,
# This means that if someone wants to use an Xcode build config other than Debug/Profile/Release,
# they _must_ set FLUTTER_BUILD_MODE so we know what type of artifact to build.
# they _must_ set FLUTTER_BUILD_MODE so we know what type of artifact to build.
local
build_mode
=
"
$(
echo
"
${
FLUTTER_BUILD_MODE
:-${
CONFIGURATION
}}
"
|
tr
"[:upper:]"
"[:lower:]"
)
"
local
build_mode
=
"
$(
ParseFlutterBuildMode
)
"
local
artifact_variant
=
"unknown"
local
artifact_variant
=
"unknown"
case
"
$build_mode
"
in
case
"
$build_mode
"
in
*
release
*
)
build_mode
=
"release"
;
artifact_variant
=
"ios-release"
;;
release
)
artifact_variant
=
"ios-release"
;;
*
profile
*
)
build_mode
=
"profile"
;
artifact_variant
=
"ios-profile"
;;
profile
)
artifact_variant
=
"ios-profile"
;;
*
debug
*
)
build_mode
=
"debug"
;
artifact_variant
=
"ios"
;;
debug
)
artifact_variant
=
"ios"
;;
*
)
EchoError
"========================================================================"
EchoError
"ERROR: Unknown FLUTTER_BUILD_MODE:
${
build_mode
}
."
EchoError
"Valid values are 'Debug', 'Profile', or 'Release' (case insensitive)."
EchoError
"This is controlled by the FLUTTER_BUILD_MODE environment variable."
EchoError
"If that is not set, the CONFIGURATION environment variable is used."
EchoError
""
EchoError
"You can fix this by either adding an appropriately named build"
EchoError
"configuration, or adding an appropriate value for FLUTTER_BUILD_MODE to the"
EchoError
".xcconfig file for the current build configuration (
${
CONFIGURATION
}
)."
EchoError
"========================================================================"
exit
-1
;;
esac
esac
# Warn the user if not archiving (ACTION=install) in release mode.
# Warn the user if not archiving (ACTION=install) in release mode.
...
@@ -127,7 +141,7 @@ is set to release or run \"flutter build ios --release\", then re-run Archive fr
...
@@ -127,7 +141,7 @@ is set to release or run \"flutter build ios --release\", then re-run Archive fr
fi
fi
local
bitcode_flag
=
""
local
bitcode_flag
=
""
if
[[
$ENABLE_BITCODE
==
"YES"
]]
;
then
if
[[
"
$ENABLE_BITCODE
"
==
"YES"
]]
;
then
bitcode_flag
=
"true"
bitcode_flag
=
"true"
fi
fi
...
@@ -306,6 +320,36 @@ EmbedFlutterFrameworks() {
...
@@ -306,6 +320,36 @@ EmbedFlutterFrameworks() {
RunCommand codesign
--force
--verbose
--sign
"
${
EXPANDED_CODE_SIGN_IDENTITY
}
"
--
"
${
xcode_frameworks_dir
}
/App.framework/App"
RunCommand codesign
--force
--verbose
--sign
"
${
EXPANDED_CODE_SIGN_IDENTITY
}
"
--
"
${
xcode_frameworks_dir
}
/App.framework/App"
RunCommand codesign
--force
--verbose
--sign
"
${
EXPANDED_CODE_SIGN_IDENTITY
}
"
--
"
${
xcode_frameworks_dir
}
/Flutter.framework/Flutter"
RunCommand codesign
--force
--verbose
--sign
"
${
EXPANDED_CODE_SIGN_IDENTITY
}
"
--
"
${
xcode_frameworks_dir
}
/Flutter.framework/Flutter"
fi
fi
AddObservatoryBonjourService
}
# Add the observatory publisher Bonjour service to the produced app bundle Info.plist.
AddObservatoryBonjourService
()
{
local
build_mode
=
"
$(
ParseFlutterBuildMode
)
"
# Debug and profile only.
if
[[
"
${
build_mode
}
"
==
"release"
]]
;
then
return
fi
local
built_products_plist
=
"
${
BUILT_PRODUCTS_DIR
}
/
${
INFOPLIST_PATH
}
"
if
[[
!
-f
"
${
built_products_plist
}
"
]]
;
then
EchoError
"error:
${
INFOPLIST_PATH
}
does not exist. The Flutter
\"
Thin Binary
\"
build phase must run after
\"
Copy Bundle Resources
\"
."
exit
-1
fi
# If there are already NSBonjourServices specified by the app (uncommon), insert the observatory service name to the existing list.
if
plutil
-extract
NSBonjourServices xml1
-o
-
"
${
built_products_plist
}
"
;
then
RunCommand plutil
-insert
NSBonjourServices.0
-string
"_dartobservatory._tcp"
"
${
built_products_plist
}
"
else
# Otherwise, add the NSBonjourServices key and observatory service name.
RunCommand plutil
-insert
NSBonjourServices
-json
"[
\"
_dartobservatory._tcp
\"
]"
"
${
built_products_plist
}
"
fi
# Don't override the local network description the Flutter app developer specified (uncommon).
# This text will appear below the "Your app would like to find and connect to devices on your local network" permissions popup.
if
!
plutil
-extract
NSLocalNetworkUsageDescription xml1
-o
-
"
${
built_products_plist
}
"
;
then
RunCommand plutil
-insert
NSLocalNetworkUsageDescription
-string
"Allow Flutter tools on your computer to connect and debug your application. This prompt will not appear on release builds."
"
${
built_products_plist
}
"
fi
}
}
EmbedAndThinFrameworks
()
{
EmbedAndThinFrameworks
()
{
...
@@ -328,5 +372,8 @@ else
...
@@ -328,5 +372,8 @@ else
EmbedFlutterFrameworks
;;
EmbedFlutterFrameworks
;;
"embed_and_thin"
)
"embed_and_thin"
)
EmbedAndThinFrameworks
;;
EmbedAndThinFrameworks
;;
"test_observatory_bonjour_service"
)
# Exposed for integration testing only.
AddObservatoryBonjourService
;;
esac
esac
fi
fi
packages/flutter_tools/test/general.shard/ios/xcode_backend_test.dart
deleted
100644 → 0
View file @
020215bb
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter_tools/src/base/io.dart'
;
import
'../../src/common.dart'
;
const
String
xcodeBackendPath
=
'bin/xcode_backend.sh'
;
const
String
xcodeBackendErrorHeader
=
'========================================================================'
;
// Acceptable $CONFIGURATION/$FLUTTER_BUILD_MODE values should be debug, profile, or release
const
Map
<
String
,
String
>
unknownConfiguration
=
<
String
,
String
>{
'CONFIGURATION'
:
'Custom'
,
};
// $FLUTTER_BUILD_MODE will override $CONFIGURATION
const
Map
<
String
,
String
>
unknownFlutterBuildMode
=
<
String
,
String
>{
'FLUTTER_BUILD_MODE'
:
'Custom'
,
'CONFIGURATION'
:
'Debug'
,
};
// Can't archive a non-release build.
const
Map
<
String
,
String
>
installWithoutRelease
=
<
String
,
String
>{
'CONFIGURATION'
:
'Debug'
,
'ACTION'
:
'install'
,
};
// Can't use a debug engine build with a release build.
const
Map
<
String
,
String
>
localEngineDebugBuildModeRelease
=
<
String
,
String
>{
'SOURCE_ROOT'
:
'../../../examples/hello_world'
,
'FLUTTER_ROOT'
:
'../../..'
,
'LOCAL_ENGINE'
:
'/engine/src/out/ios_debug_unopt'
,
'CONFIGURATION'
:
'Release'
,
};
// Can't use a debug build with a profile engine.
const
Map
<
String
,
String
>
localEngineProfileBuildeModeRelease
=
<
String
,
String
>{
'SOURCE_ROOT'
:
'../../../examples/hello_world'
,
'FLUTTER_ROOT'
:
'../../..'
,
'LOCAL_ENGINE'
:
'/engine/src/out/ios_profile'
,
'CONFIGURATION'
:
'Debug'
,
'FLUTTER_BUILD_MODE'
:
'Debug'
,
};
void
main
(
)
{
Future
<
void
>
expectXcodeBackendFails
(
Map
<
String
,
String
>
environment
)
async
{
final
ProcessResult
result
=
await
Process
.
run
(
xcodeBackendPath
,
<
String
>[
'build'
],
environment:
environment
,
);
expect
(
result
.
stderr
,
startsWith
(
xcodeBackendErrorHeader
));
expect
(
result
.
exitCode
,
isNot
(
0
));
}
test
(
'Xcode backend fails for on unsupported configuration combinations'
,
()
async
{
await
expectXcodeBackendFails
(
unknownConfiguration
);
await
expectXcodeBackendFails
(
unknownFlutterBuildMode
);
await
expectXcodeBackendFails
(
installWithoutRelease
);
await
expectXcodeBackendFails
(
localEngineDebugBuildModeRelease
);
await
expectXcodeBackendFails
(
localEngineProfileBuildeModeRelease
);
},
skip:
true
);
// https://github.com/flutter/flutter/issues/35707 (non-hermetic test requires precache to have run)
}
packages/flutter_tools/test/integration.shard/xcode_backend_test.dart
0 → 100644
View file @
ace54425
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:io'
as
io
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
import
'../src/common.dart'
;
const
String
xcodeBackendPath
=
'bin/xcode_backend.sh'
;
const
String
xcodeBackendErrorHeader
=
'========================================================================'
;
// Acceptable $CONFIGURATION/$FLUTTER_BUILD_MODE values should be debug, profile, or release
const
Map
<
String
,
String
>
unknownConfiguration
=
<
String
,
String
>{
'CONFIGURATION'
:
'Custom'
,
};
// $FLUTTER_BUILD_MODE will override $CONFIGURATION
const
Map
<
String
,
String
>
unknownFlutterBuildMode
=
<
String
,
String
>{
'FLUTTER_BUILD_MODE'
:
'Custom'
,
'CONFIGURATION'
:
'Debug'
,
};
// Can't use a debug engine build with a release build.
const
Map
<
String
,
String
>
localEngineDebugBuildModeRelease
=
<
String
,
String
>{
'SOURCE_ROOT'
:
'../examples/hello_world'
,
'FLUTTER_ROOT'
:
'../..'
,
'LOCAL_ENGINE'
:
'/engine/src/out/ios_debug_unopt'
,
'CONFIGURATION'
:
'Release'
,
};
// Can't use a debug build with a profile engine.
const
Map
<
String
,
String
>
localEngineProfileBuildeModeRelease
=
<
String
,
String
>{
'SOURCE_ROOT'
:
'../examples/hello_world'
,
'FLUTTER_ROOT'
:
'../..'
,
'LOCAL_ENGINE'
:
'/engine/src/out/ios_profile'
,
'CONFIGURATION'
:
'Debug'
,
'FLUTTER_BUILD_MODE'
:
'Debug'
,
};
void
main
(
)
{
Future
<
void
>
expectXcodeBackendFails
(
Map
<
String
,
String
>
environment
)
async
{
final
ProcessResult
result
=
await
Process
.
run
(
xcodeBackendPath
,
<
String
>[
'build'
],
environment:
environment
,
);
expect
(
result
.
stderr
,
startsWith
(
xcodeBackendErrorHeader
));
expect
(
result
.
exitCode
,
isNot
(
0
));
}
test
(
'Xcode backend fails with no arguments'
,
()
async
{
final
ProcessResult
result
=
await
Process
.
run
(
xcodeBackendPath
,
<
String
>[],
environment:
<
String
,
String
>{
'SOURCE_ROOT'
:
'../examples/hello_world'
,
'FLUTTER_ROOT'
:
'../..'
,
},
);
expect
(
result
.
stderr
,
startsWith
(
'error: Your Xcode project is incompatible with this version of Flutter.'
));
expect
(
result
.
exitCode
,
isNot
(
0
));
},
skip:
!
io
.
Platform
.
isMacOS
);
test
(
'Xcode backend fails for on unsupported configuration combinations'
,
()
async
{
await
expectXcodeBackendFails
(
unknownConfiguration
);
await
expectXcodeBackendFails
(
unknownFlutterBuildMode
);
await
expectXcodeBackendFails
(
localEngineDebugBuildModeRelease
);
await
expectXcodeBackendFails
(
localEngineProfileBuildeModeRelease
);
},
skip:
!
io
.
Platform
.
isMacOS
);
test
(
'Xcode backend warns archiving a non-release build.'
,
()
async
{
final
ProcessResult
result
=
await
Process
.
run
(
xcodeBackendPath
,
<
String
>[
'build'
],
environment:
<
String
,
String
>{
'CONFIGURATION'
:
'Debug'
,
'ACTION'
:
'install'
,
},
);
expect
(
result
.
stdout
,
contains
(
'warning: Flutter archive not built in Release mode.'
));
expect
(
result
.
exitCode
,
isNot
(
0
));
},
skip:
!
io
.
Platform
.
isMacOS
);
group
(
'observatory Bonjour service keys'
,
()
{
Directory
buildDirectory
;
File
infoPlist
;
setUp
(()
{
buildDirectory
=
globals
.
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_tools_xcode_backend_test.'
);
infoPlist
=
buildDirectory
.
childFile
(
'Info.plist'
);
});
test
(
'fails when the Info.plist is missing'
,
()
async
{
final
ProcessResult
result
=
await
Process
.
run
(
xcodeBackendPath
,
<
String
>[
'test_observatory_bonjour_service'
],
environment:
<
String
,
String
>{
'CONFIGURATION'
:
'Debug'
,
'BUILT_PRODUCTS_DIR'
:
buildDirectory
.
path
,
'INFOPLIST_PATH'
:
'Info.plist'
,
},
);
expect
(
result
.
stderr
,
startsWith
(
'error: Info.plist does not exist.'
));
expect
(
result
.
exitCode
,
isNot
(
0
));
});
const
String
emptyPlist
=
'''
<?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>
</dict>
</plist>'''
;
test
(
'does not add keys in Release'
,
()
async
{
infoPlist
.
writeAsStringSync
(
emptyPlist
);
final
ProcessResult
result
=
await
Process
.
run
(
xcodeBackendPath
,
<
String
>[
'test_observatory_bonjour_service'
],
environment:
<
String
,
String
>{
'CONFIGURATION'
:
'Release'
,
'BUILT_PRODUCTS_DIR'
:
buildDirectory
.
path
,
'INFOPLIST_PATH'
:
'Info.plist'
,
},
);
final
String
actualInfoPlist
=
infoPlist
.
readAsStringSync
();
expect
(
actualInfoPlist
,
isNot
(
contains
(
'NSBonjourServices'
)));
expect
(
actualInfoPlist
,
isNot
(
contains
(
'dartobservatory'
)));
expect
(
actualInfoPlist
,
isNot
(
contains
(
'NSLocalNetworkUsageDescription'
)));
expect
(
result
.
exitCode
,
0
);
});
for
(
final
String
buildConfiguration
in
<
String
>[
'Debug'
,
'Profile'
])
{
test
(
'add keys in
$buildConfiguration
'
,
()
async
{
infoPlist
.
writeAsStringSync
(
emptyPlist
);
final
ProcessResult
result
=
await
Process
.
run
(
xcodeBackendPath
,
<
String
>[
'test_observatory_bonjour_service'
],
environment:
<
String
,
String
>{
'CONFIGURATION'
:
buildConfiguration
,
'BUILT_PRODUCTS_DIR'
:
buildDirectory
.
path
,
'INFOPLIST_PATH'
:
'Info.plist'
,
},
);
final
String
actualInfoPlist
=
infoPlist
.
readAsStringSync
();
expect
(
actualInfoPlist
,
contains
(
'NSBonjourServices'
));
expect
(
actualInfoPlist
,
contains
(
'dartobservatory'
));
expect
(
actualInfoPlist
,
contains
(
'NSLocalNetworkUsageDescription'
));
expect
(
result
.
exitCode
,
0
);
});
}
test
(
'adds to existing Bonjour services, does not override network usage description'
,
()
async
{
infoPlist
.
writeAsStringSync
(
'''
<?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>NSBonjourServices</key>
<array>
<string>_bogus._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>Don'
t
override
this
</
string
>
</
dict
>
</
plist
>
''');
final ProcessResult result = await Process.run(
xcodeBackendPath,
<String>['
test_observatory_bonjour_service
'],
environment: <String, String>{
'
CONFIGURATION
': '
Debug
',
'
BUILT_PRODUCTS_DIR
': buildDirectory.path,
'
INFOPLIST_PATH
': '
Info
.
plist
',
},
);
expect(infoPlist.readAsStringSync(), '''
<?
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
>
NSBonjourServices
</
key
>
<
array
>
<
string
>
_dartobservatory
.
_tcp
</
string
>
<
string
>
_bogus
.
_tcp
</
string
>
</
array
>
<
key
>
NSLocalNetworkUsageDescription
</
key
>
<
string
>
Don
't override this</string>
</dict>
</plist>
'''
);
expect
(
result
.
exitCode
,
0
);
});
},
skip:
!
io
.
Platform
.
isMacOS
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment