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
2717eb64
Unverified
Commit
2717eb64
authored
Mar 27, 2020
by
Jonah Williams
Committed by
GitHub
Mar 27, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter tools] rewrite launch non-prebuilt app tests (#53351)
parent
c5800fe1
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
304 additions
and
314 deletions
+304
-314
devices_test.dart
...es/flutter_tools/test/general.shard/ios/devices_test.dart
+4
-314
ios_device_start_nonprebuilt_test.dart
.../general.shard/ios/ios_device_start_nonprebuilt_test.dart
+300
-0
No files found.
packages/flutter_tools/test/general.shard/ios/devices_test.dart
View file @
2717eb64
...
...
@@ -3,11 +3,12 @@
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:convert'
;
import
'package:args/command_runner.dart'
;
import
'package:file/file.dart'
;
import
'package:file/memory.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:platform/platform.dart'
;
import
'package:flutter_tools/src/application_package.dart'
;
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
...
...
@@ -15,26 +16,15 @@ import 'package:flutter_tools/src/base/io.dart';
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/create.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/doctor.dart'
;
import
'package:flutter_tools/src/ios/devices.dart'
;
import
'package:flutter_tools/src/ios/mac.dart'
;
import
'package:flutter_tools/src/ios/ios_deploy.dart'
;
import
'package:flutter_tools/src/ios/ios_workflow.dart'
;
import
'package:flutter_tools/src/macos/xcode.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
import
'package:meta/meta.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:platform/platform.dart'
;
import
'package:process/process.dart'
;
import
'package:quiver/testing/async.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/fakes.dart'
;
import
'../../src/mocks.dart'
;
void
main
(
)
{
...
...
@@ -59,7 +49,6 @@ void main() {
mockCache
=
MockCache
();
const
MapEntry
<
String
,
String
>
dyLdLibEntry
=
MapEntry
<
String
,
String
>(
'DYLD_LIBRARY_PATH'
,
'/path/to/libs'
);
when
(
mockCache
.
dyLdLibEntry
).
thenReturn
(
dyLdLibEntry
);
mockFileSystem
=
MockFileSystem
();
logger
=
BufferLogger
.
test
();
iosDeploy
=
IOSDeploy
(
artifacts:
mockArtifacts
,
...
...
@@ -231,7 +220,6 @@ void main() {
forwardedPort
=
ForwardedPort
.
withContext
(
123
,
456
,
mockProcess3
);
mockArtifacts
=
MockArtifacts
();
mockCache
=
MockCache
();
mockFileSystem
=
MockFileSystem
();
iosDeploy
=
IOSDeploy
(
artifacts:
mockArtifacts
,
cache:
mockCache
,
...
...
@@ -268,271 +256,12 @@ void main() {
verify
(
mockProcess3
.
kill
());
});
});
group
(
'startApp'
,
()
{
MockIOSApp
mockApp
;
MockArtifacts
mockArtifacts
;
MockCache
mockCache
;
MockFileSystem
mockFileSystem
;
MockPlatform
mockPlatform
;
MockProcessManager
mockProcessManager
;
FakeDeviceLogReader
mockLogReader
;
MockPortForwarder
mockPortForwarder
;
MockIMobileDevice
mockIMobileDevice
;
MockIOSDeploy
mockIosDeploy
;
Directory
tempDir
;
Directory
projectDir
;
const
int
devicePort
=
499
;
const
int
hostPort
=
42
;
const
String
installerPath
=
'/path/to/ideviceinstaller'
;
const
String
iosDeployPath
=
'/path/to/iosdeploy'
;
const
String
iproxyPath
=
'/path/to/iproxy'
;
const
MapEntry
<
String
,
String
>
libraryEntry
=
MapEntry
<
String
,
String
>(
'DYLD_LIBRARY_PATH'
,
'/path/to/libraries'
,
);
final
Map
<
String
,
String
>
env
=
Map
<
String
,
String
>.
fromEntries
(
<
MapEntry
<
String
,
String
>>[
libraryEntry
]
);
setUp
(()
{
Cache
.
disableLocking
();
mockApp
=
MockIOSApp
();
mockArtifacts
=
MockArtifacts
();
mockCache
=
MockCache
();
when
(
mockCache
.
dyLdLibEntry
).
thenReturn
(
libraryEntry
);
mockFileSystem
=
MockFileSystem
();
mockPlatform
=
MockPlatform
();
when
(
mockPlatform
.
isMacOS
).
thenReturn
(
true
);
mockProcessManager
=
MockProcessManager
();
mockLogReader
=
FakeDeviceLogReader
();
mockPortForwarder
=
MockPortForwarder
();
mockIMobileDevice
=
MockIMobileDevice
();
mockIosDeploy
=
MockIOSDeploy
();
tempDir
=
globals
.
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_tools_create_test.'
);
projectDir
=
tempDir
.
childDirectory
(
'flutter_project'
);
when
(
mockArtifacts
.
getArtifactPath
(
Artifact
.
ideviceinstaller
,
platform:
anyNamed
(
'platform'
),
),
).
thenReturn
(
installerPath
);
when
(
mockArtifacts
.
getArtifactPath
(
Artifact
.
iosDeploy
,
platform:
anyNamed
(
'platform'
),
),
).
thenReturn
(
iosDeployPath
);
when
(
mockArtifacts
.
getArtifactPath
(
Artifact
.
iproxy
,
platform:
anyNamed
(
'platform'
),
),
).
thenReturn
(
iproxyPath
);
when
(
mockPortForwarder
.
forward
(
devicePort
,
hostPort:
anyNamed
(
'hostPort'
)))
.
thenAnswer
((
_
)
async
=>
hostPort
);
when
(
mockPortForwarder
.
forwardedPorts
)
.
thenReturn
(<
ForwardedPort
>[
ForwardedPort
(
hostPort
,
devicePort
)]);
when
(
mockPortForwarder
.
unforward
(
any
))
.
thenAnswer
((
_
)
async
=>
null
);
final
MemoryFileSystem
memoryFileSystem
=
MemoryFileSystem
();
when
(
mockFileSystem
.
currentDirectory
)
.
thenReturn
(
memoryFileSystem
.
currentDirectory
);
const
String
bundlePath
=
'/path/to/bundle'
;
final
List
<
String
>
installArgs
=
<
String
>[
installerPath
,
'-i'
,
bundlePath
];
when
(
mockApp
.
deviceBundlePath
).
thenReturn
(
bundlePath
);
final
MockDirectory
directory
=
MockDirectory
();
when
(
mockFileSystem
.
directory
(
bundlePath
)).
thenReturn
(
directory
);
when
(
directory
.
existsSync
()).
thenReturn
(
true
);
when
(
mockProcessManager
.
run
(
installArgs
,
workingDirectory:
anyNamed
(
'workingDirectory'
),
environment:
env
,
)).
thenAnswer
(
(
_
)
=>
Future
<
ProcessResult
>.
value
(
ProcessResult
(
1
,
0
,
''
,
''
))
);
});
tearDown
(()
{
mockLogReader
.
dispose
();
tryToDelete
(
tempDir
);
Cache
.
enableLocking
();
});
void
testNonPrebuilt
(
String
name
,
{
@required
bool
showBuildSettingsFlakes
,
void
Function
()
additionalSetup
,
void
Function
()
additionalExpectations
,
})
{
testUsingContext
(
'non-prebuilt succeeds in debug mode
$name
'
,
()
async
{
final
Directory
targetBuildDir
=
projectDir
.
childDirectory
(
'build/ios/iphoneos/Debug-arm64'
);
// The -showBuildSettings calls have a timeout and so go through
// globals.processManager.start().
mockProcessManager
.
processFactory
=
flakyProcessFactory
(
flakes:
showBuildSettingsFlakes
?
1
:
0
,
delay:
const
Duration
(
seconds:
62
),
filter:
(
List
<
String
>
args
)
=>
args
.
contains
(
'-showBuildSettings'
),
stdout:
()
=>
Stream
<
String
>
.
fromIterable
(
<
String
>[
'TARGET_BUILD_DIR =
${targetBuildDir.path}
\n
'
])
.
transform
(
utf8
.
encoder
),
);
// Make all other subcommands succeed.
when
(
mockProcessManager
.
run
(
any
,
workingDirectory:
anyNamed
(
'workingDirectory'
),
environment:
anyNamed
(
'environment'
),
)).
thenAnswer
((
Invocation
inv
)
{
return
Future
<
ProcessResult
>.
value
(
ProcessResult
(
0
,
0
,
''
,
''
));
});
when
(
mockProcessManager
.
run
(
argThat
(
contains
(
'find-identity'
)),
environment:
anyNamed
(
'environment'
),
workingDirectory:
anyNamed
(
'workingDirectory'
),
)).
thenAnswer
((
_
)
=>
Future
<
ProcessResult
>.
value
(
ProcessResult
(
1
,
// pid
0
,
// exitCode
'''
1) 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 "iPhone Developer: Profile 1 (1111AAAA11)"
2) da4b9237bacccdf19c0760cab7aec4a8359010b0 "iPhone Developer: Profile 2 (2222BBBB22)"
3) 5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 "iPhone Developer: Profile 3 (3333CCCC33)"
3 valid identities found'''
,
''
,
)));
// Deploy works.
when
(
mockIosDeploy
.
runApp
(
deviceId:
anyNamed
(
'deviceId'
),
bundlePath:
anyNamed
(
'bundlePath'
),
launchArguments:
anyNamed
(
'launchArguments'
),
)).
thenAnswer
((
_
)
=>
Future
<
int
>.
value
(
0
));
// Create a dummy project to avoid mocking out the whole directory
// structure expected by device.startApp().
Cache
.
flutterRoot
=
'../..'
;
final
CreateCommand
command
=
CreateCommand
();
final
CommandRunner
<
void
>
runner
=
createTestCommandRunner
(
command
);
await
runner
.
run
(<
String
>[
'create'
,
'--no-pub'
,
projectDir
.
path
,
]);
if
(
additionalSetup
!=
null
)
{
additionalSetup
();
}
final
IOSApp
app
=
await
AbsoluteBuildableIOSApp
.
fromProject
(
FlutterProject
.
fromDirectory
(
projectDir
).
ios
);
final
IOSDevice
device
=
IOSDevice
(
'123'
,
name:
'iPhone 1'
,
sdkVersion:
'13.3'
,
artifacts:
mockArtifacts
,
fileSystem:
globals
.
fs
,
logger:
testLogger
,
platform:
macPlatform
,
iosDeploy:
mockIosDeploy
,
iMobileDevice:
iMobileDevice
,
cpuArchitecture:
DarwinArch
.
arm64
,
);
// Pre-create the expected build products.
targetBuildDir
.
createSync
(
recursive:
true
);
projectDir
.
childDirectory
(
'build/ios/iphoneos/Runner.app'
).
createSync
(
recursive:
true
);
final
Completer
<
LaunchResult
>
completer
=
Completer
<
LaunchResult
>();
FakeAsync
().
run
((
FakeAsync
time
)
{
device
.
startApp
(
app
,
prebuiltApplication:
false
,
debuggingOptions:
DebuggingOptions
.
disabled
(
const
BuildInfo
(
BuildMode
.
debug
,
null
,
treeShakeIcons:
false
)),
platformArgs:
<
String
,
dynamic
>{},
).
then
((
LaunchResult
result
)
{
completer
.
complete
(
result
);
});
time
.
flushMicrotasks
();
time
.
elapse
(
const
Duration
(
seconds:
65
));
});
final
LaunchResult
launchResult
=
await
completer
.
future
;
expect
(
launchResult
.
started
,
isTrue
);
expect
(
launchResult
.
hasObservatory
,
isFalse
);
expect
(
await
device
.
stopApp
(
mockApp
),
isFalse
);
if
(
additionalExpectations
!=
null
)
{
additionalExpectations
();
}
},
overrides:
<
Type
,
Generator
>{
DoctorValidatorsProvider:
()
=>
FakeIosDoctorProvider
(),
IMobileDevice:
()
=>
mockIMobileDevice
,
Platform:
()
=>
macPlatform
,
ProcessManager:
()
=>
mockProcessManager
,
});
}
testNonPrebuilt
(
'flaky: false'
,
showBuildSettingsFlakes:
false
);
testNonPrebuilt
(
'flaky: true'
,
showBuildSettingsFlakes:
true
);
testNonPrebuilt
(
'with concurrent build failiure'
,
showBuildSettingsFlakes:
false
,
additionalSetup:
()
{
int
callCount
=
0
;
when
(
mockProcessManager
.
run
(
argThat
(
allOf
(
contains
(
'xcodebuild'
),
contains
(
'-configuration'
),
contains
(
'Debug'
),
)),
workingDirectory:
anyNamed
(
'workingDirectory'
),
environment:
anyNamed
(
'environment'
),
)).
thenAnswer
((
Invocation
inv
)
{
// Succeed after 2 calls.
if
(++
callCount
>
2
)
{
return
Future
<
ProcessResult
>.
value
(
ProcessResult
(
0
,
0
,
''
,
''
));
}
// Otherwise fail with the Xcode concurrent error.
return
Future
<
ProcessResult
>.
value
(
ProcessResult
(
0
,
1
,
'''
"/Developer/Xcode/DerivedData/foo/XCBuildData/build.db":
database is locked
Possibly there are two concurrent builds running in the same filesystem location.
'''
,
''
,
));
});
},
additionalExpectations:
()
{
expect
(
testLogger
.
statusText
,
contains
(
'will retry in 2 seconds'
));
expect
(
testLogger
.
statusText
,
contains
(
'will retry in 4 seconds'
));
expect
(
testLogger
.
statusText
,
contains
(
'Xcode build done.'
));
},
);
});
});
group
(
'pollingGetDevices'
,
()
{
MockXcdevice
mockXcdevice
;
MockArtifacts
mockArtifacts
;
MockCache
mockCache
;
MockFileSystem
mockFileSystem
;
FakeProcessManager
fakeProcessManager
;
Logger
logger
;
IOSDeploy
iosDeploy
;
...
...
@@ -544,7 +273,6 @@ void main() {
mockArtifacts
=
MockArtifacts
();
mockCache
=
MockCache
();
logger
=
BufferLogger
.
test
();
mockFileSystem
=
MockFileSystem
();
mockIosWorkflow
=
MockIOSWorkflow
();
fakeProcessManager
=
FakeProcessManager
.
any
();
iosDeploy
=
IOSDeploy
(
...
...
@@ -596,7 +324,7 @@ void main() {
iMobileDevice:
iMobileDevice
,
logger:
logger
,
platform:
macPlatform
,
fileSystem:
mockFileSystem
,
fileSystem:
MemoryFileSystem
.
test
()
,
);
when
(
mockXcdevice
.
getAvailableTetheredIOSDevices
())
.
thenAnswer
((
Invocation
invocation
)
=>
Future
<
List
<
IOSDevice
>>.
value
(<
IOSDevice
>[
device
]));
...
...
@@ -646,48 +374,10 @@ void main() {
});
}
class
AbsoluteBuildableIOSApp
extends
BuildableIOSApp
{
AbsoluteBuildableIOSApp
(
IosProject
project
,
String
projectBundleId
)
:
super
(
project
,
projectBundleId
);
static
Future
<
AbsoluteBuildableIOSApp
>
fromProject
(
IosProject
project
)
async
{
final
String
projectBundleId
=
await
project
.
productBundleIdentifier
;
return
AbsoluteBuildableIOSApp
(
project
,
projectBundleId
);
}
@override
String
get
deviceBundlePath
=>
globals
.
fs
.
path
.
join
(
project
.
parent
.
directory
.
path
,
'build'
,
'ios'
,
'iphoneos'
,
name
);
}
class
FakeIosDoctorProvider
implements
DoctorValidatorsProvider
{
List
<
Workflow
>
_workflows
;
@override
List
<
DoctorValidator
>
get
validators
=>
<
DoctorValidator
>[];
@override
List
<
Workflow
>
get
workflows
{
if
(
_workflows
==
null
)
{
_workflows
=
<
Workflow
>[];
if
(
globals
.
iosWorkflow
.
appliesToHostPlatform
)
{
_workflows
.
add
(
globals
.
iosWorkflow
);
}
}
return
_workflows
;
}
}
class
MockIOSApp
extends
Mock
implements
IOSApp
{}
class
MockArtifacts
extends
Mock
implements
Artifacts
{}
class
MockCache
extends
Mock
implements
Cache
{}
class
MockDirectory
extends
Mock
implements
Directory
{}
class
MockFile
extends
Mock
implements
File
{}
class
MockFileSystem
extends
Mock
implements
FileSystem
{}
class
MockIMobileDevice
extends
Mock
implements
IMobileDevice
{}
class
MockIOSDeploy
extends
Mock
implements
IOSDeploy
{}
class
MockIOSWorkflow
extends
Mock
implements
IOSWorkflow
{}
class
MockPlatform
extends
Mock
implements
Platform
{}
class
MockPortForwarder
extends
Mock
implements
DevicePortForwarder
{}
class
MockXcdevice
extends
Mock
implements
XCDevice
{}
packages/flutter_tools/test/general.shard/ios/ios_device_start_nonprebuilt_test.dart
0 → 100644
View file @
2717eb64
// 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:file/memory.dart'
;
import
'package:flutter_tools/src/application_package.dart'
;
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/device.dart'
;
import
'package:flutter_tools/src/ios/devices.dart'
;
import
'package:flutter_tools/src/ios/ios_deploy.dart'
;
import
'package:flutter_tools/src/ios/mac.dart'
;
import
'package:flutter_tools/src/project.dart'
;
import
'package:mockito/mockito.dart'
;
import
'package:platform/platform.dart'
;
import
'package:quiver/testing/async.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/fake_process_manager.dart'
;
const
List
<
String
>
kRunReleaseArgs
=
<
String
>[
'/usr/bin/env'
,
'xcrun'
,
'xcodebuild'
,
'-configuration'
,
'Release'
,
'-quiet'
,
'-workspace'
,
'Runner.xcworkspace'
,
'-scheme'
,
'Runner'
,
'BUILD_DIR=/build/ios'
,
'-sdk'
,
'iphoneos'
,
'ONLY_ACTIVE_ARCH=YES'
,
'ARCHS=arm64'
,
'FLUTTER_SUPPRESS_ANALYTICS=true'
,
'COMPILER_INDEX_STORE_ENABLE=NO'
,
];
const
String
kConcurrentBuildErrorMessage
=
'''
"/Developer/Xcode/DerivedData/foo/XCBuildData/build.db":
database is locked
Possibly there are two concurrent builds running in the same filesystem location.
'''
;
final
FakePlatform
macPlatform
=
FakePlatform
(
operatingSystem:
'macos'
,
environment:
<
String
,
String
>{},
);
void
main
(
)
{
FileSystem
fileSystem
;
FakeProcessManager
processManager
;
BufferLogger
logger
;
setUp
(()
{
logger
=
BufferLogger
.
test
();
fileSystem
=
MemoryFileSystem
.
test
();
processManager
=
FakeProcessManager
.
list
(<
FakeCommand
>[]);
});
testUsingContext
(
'IOSDevice.startApp succeeds in release mode with buildable app'
,
()
async
{
final
IOSDevice
iosDevice
=
setUpIOSDevice
(
fileSystem:
fileSystem
,
processManager:
processManager
,
logger:
logger
,
);
setUpIOSProject
(
fileSystem
);
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
fileSystem
.
currentDirectory
);
final
BuildableIOSApp
buildableIOSApp
=
BuildableIOSApp
(
flutterProject
.
ios
,
'flutter'
);
processManager
.
addCommand
(
const
FakeCommand
(
command:
kRunReleaseArgs
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
]));
processManager
.
addCommand
(
FakeCommand
(
command:
<
String
>[
'ios-deploy'
,
'--id'
,
'123'
,
'--bundle'
,
'build/ios/iphoneos/Runner.app'
,
'--no-wifi'
,
'--justlaunch'
,
'--args'
,
const
<
String
>[
'--enable-dart-profiling'
,
'--enable-service-port-fallback'
,
'--disable-service-auth-codes'
,
'--observatory-port=53781'
,
].
join
(
' '
)
])
);
final
LaunchResult
launchResult
=
await
iosDevice
.
startApp
(
buildableIOSApp
,
debuggingOptions:
DebuggingOptions
.
disabled
(
BuildInfo
.
release
),
platformArgs:
<
String
,
Object
>{},
);
expect
(
launchResult
.
started
,
true
);
expect
(
processManager
.
hasRemainingExpectations
,
false
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
processManager
,
FileSystem:
()
=>
fileSystem
,
Logger:
()
=>
logger
,
Platform:
()
=>
macPlatform
,
});
testUsingContext
(
'IOSDevice.startApp succeeds in release mode with buildable '
'app with flaky buildSettings call'
,
()
async
{
LaunchResult
launchResult
;
FakeAsync
().
run
((
FakeAsync
time
)
{
final
IOSDevice
iosDevice
=
setUpIOSDevice
(
fileSystem:
fileSystem
,
processManager:
processManager
,
logger:
logger
,
);
setUpIOSProject
(
fileSystem
);
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
fileSystem
.
currentDirectory
);
final
BuildableIOSApp
buildableIOSApp
=
BuildableIOSApp
(
flutterProject
.
ios
,
'flutter'
);
processManager
.
addCommand
(
const
FakeCommand
(
command:
kRunReleaseArgs
));
// The first showBuildSettings call should timeout.
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
],
duration:
Duration
(
minutes:
5
),
// this is longer than the timeout of 1 minute.
));
// The second call succeedes and is made after the first times out.
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
],
exitCode:
0
,
));
processManager
.
addCommand
(
FakeCommand
(
command:
<
String
>[
'ios-deploy'
,
'--id'
,
'123'
,
'--bundle'
,
'build/ios/iphoneos/Runner.app'
,
'--no-wifi'
,
'--justlaunch'
,
'--args'
,
const
<
String
>[
'--enable-dart-profiling'
,
'--enable-service-port-fallback'
,
'--disable-service-auth-codes'
,
'--observatory-port=53781'
,
].
join
(
' '
)
])
);
iosDevice
.
startApp
(
buildableIOSApp
,
debuggingOptions:
DebuggingOptions
.
disabled
(
BuildInfo
.
release
),
platformArgs:
<
String
,
Object
>{},
).
then
((
LaunchResult
result
)
{
launchResult
=
result
;
});
// Elapse duration for process timeout.
time
.
flushMicrotasks
();
time
.
elapse
(
const
Duration
(
minutes:
1
));
// Elapse duration for overall process timer.
time
.
flushMicrotasks
();
time
.
elapse
(
const
Duration
(
minutes:
5
));
time
.
flushTimers
();
});
expect
(
launchResult
?.
started
,
true
);
expect
(
processManager
.
hasRemainingExpectations
,
false
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
processManager
,
FileSystem:
()
=>
fileSystem
,
Logger:
()
=>
logger
,
Platform:
()
=>
macPlatform
,
});
testUsingContext
(
'IOSDevice.startApp succeeds in release mode with buildable '
'app with concurrent build failure'
,
()
async
{
final
IOSDevice
iosDevice
=
setUpIOSDevice
(
fileSystem:
fileSystem
,
processManager:
processManager
,
logger:
logger
,
);
setUpIOSProject
(
fileSystem
);
final
FlutterProject
flutterProject
=
FlutterProject
.
fromDirectory
(
fileSystem
.
currentDirectory
);
final
BuildableIOSApp
buildableIOSApp
=
BuildableIOSApp
(
flutterProject
.
ios
,
'flutter'
);
// The first xcrun call should fail with a
// concurrent build exception.
processManager
.
addCommand
(
const
FakeCommand
(
command:
kRunReleaseArgs
,
exitCode:
1
,
stdout:
kConcurrentBuildErrorMessage
,
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
kRunReleaseArgs
));
processManager
.
addCommand
(
const
FakeCommand
(
command:
<
String
>[...
kRunReleaseArgs
,
'-showBuildSettings'
],
exitCode:
0
,
));
processManager
.
addCommand
(
FakeCommand
(
command:
<
String
>[
'ios-deploy'
,
'--id'
,
'123'
,
'--bundle'
,
'build/ios/iphoneos/Runner.app'
,
'--no-wifi'
,
'--justlaunch'
,
'--args'
,
const
<
String
>[
'--enable-dart-profiling'
,
'--enable-service-port-fallback'
,
'--disable-service-auth-codes'
,
'--observatory-port=53781'
,
].
join
(
' '
)
])
);
final
LaunchResult
launchResult
=
await
iosDevice
.
startApp
(
buildableIOSApp
,
debuggingOptions:
DebuggingOptions
.
disabled
(
BuildInfo
.
release
),
platformArgs:
<
String
,
Object
>{},
);
expect
(
logger
.
statusText
,
contains
(
'Xcode build failed due to concurrent builds, will retry in 2 seconds'
));
expect
(
launchResult
.
started
,
true
);
expect
(
processManager
.
hasRemainingExpectations
,
false
);
},
overrides:
<
Type
,
Generator
>{
ProcessManager:
()
=>
processManager
,
FileSystem:
()
=>
fileSystem
,
Logger:
()
=>
logger
,
Platform:
()
=>
macPlatform
,
});
}
void
setUpIOSProject
(
FileSystem
fileSystem
)
{
fileSystem
.
file
(
'pubspec.yaml'
).
createSync
();
fileSystem
.
file
(
'.packages'
).
writeAsStringSync
(
'
\n
'
);
fileSystem
.
directory
(
'ios'
).
createSync
();
fileSystem
.
directory
(
'ios/Runner.xcworkspace'
).
createSync
();
fileSystem
.
directory
(
'ios/Runner.xcodeproj'
).
createSync
();
fileSystem
.
file
(
'ios/Runner.xcodeproj/project.pbxproj'
).
createSync
();
// This is the expected output directory.
fileSystem
.
directory
(
'build/ios/iphoneos/Runner.app'
).
createSync
(
recursive:
true
);
}
IOSDevice
setUpIOSDevice
(
{
String
sdkVersion
=
'13.0.1'
,
FileSystem
fileSystem
,
Logger
logger
,
ProcessManager
processManager
,
})
{
const
MapEntry
<
String
,
String
>
dyldLibraryEntry
=
MapEntry
<
String
,
String
>(
'DYLD_LIBRARY_PATH'
,
'/path/to/libraries'
,
);
final
MockCache
cache
=
MockCache
();
final
MockArtifacts
artifacts
=
MockArtifacts
();
logger
??=
BufferLogger
.
test
();
when
(
cache
.
dyLdLibEntry
).
thenReturn
(
dyldLibraryEntry
);
when
(
artifacts
.
getArtifactPath
(
Artifact
.
iosDeploy
,
platform:
anyNamed
(
'platform'
)))
.
thenReturn
(
'ios-deploy'
);
return
IOSDevice
(
'123'
,
name:
'iPhone 1'
,
sdkVersion:
sdkVersion
,
fileSystem:
fileSystem
??
MemoryFileSystem
.
test
(),
platform:
macPlatform
,
artifacts:
artifacts
,
logger:
logger
,
iosDeploy:
IOSDeploy
(
logger:
logger
,
platform:
macPlatform
,
processManager:
processManager
??
FakeProcessManager
.
any
(),
artifacts:
artifacts
,
cache:
cache
,
),
iMobileDevice:
IMobileDevice
(
logger:
logger
,
processManager:
processManager
??
FakeProcessManager
.
any
(),
artifacts:
artifacts
,
cache:
cache
,
),
cpuArchitecture:
DarwinArch
.
arm64
,
);
}
class
MockArtifacts
extends
Mock
implements
Artifacts
{}
class
MockCache
extends
Mock
implements
Cache
{}
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