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
1155f966
Commit
1155f966
authored
Dec 08, 2016
by
Todd Volkert
Committed by
GitHub
Dec 08, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add tests for process_manager.dart (#7178)
parent
a4f2ad98
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
252 additions
and
5 deletions
+252
-5
process.dart
packages/flutter_tools/lib/src/base/process.dart
+12
-2
process_manager.dart
packages/flutter_tools/lib/src/base/process_manager.dart
+5
-3
all.dart
packages/flutter_tools/test/all.dart
+2
-0
001.sing.100.stderr
...ools/test/data/process_manager/replay/001.sing.100.stderr
+1
-0
001.sing.100.stdout
...ools/test/data/process_manager/replay/001.sing.100.stdout
+2
-0
002.dance.101.stderr
...ols/test/data/process_manager/replay/002.dance.101.stderr
+1
-0
002.dance.101.stdout
...ols/test/data/process_manager/replay/002.dance.101.stdout
+0
-0
MANIFEST.txt
...utter_tools/test/data/process_manager/replay/MANIFEST.txt
+23
-0
process_manager_test.dart
packages/flutter_tools/test/process_manager_test.dart
+206
-0
No files found.
packages/flutter_tools/lib/src/base/process.dart
View file @
1155f966
...
...
@@ -15,13 +15,23 @@ typedef Future<dynamic> ShutdownHook();
// TODO(ianh): We have way too many ways to run subprocesses in this project.
List
<
ShutdownHook
>
_shutdownHooks
=
<
ShutdownHook
>[];
bool
_shutdownHooksRunning
=
false
;
void
addShutdownHook
(
ShutdownHook
shutdownHook
)
{
assert
(!
_shutdownHooksRunning
);
_shutdownHooks
.
add
(
shutdownHook
);
}
Future
<
Null
>
runShutdownHooks
()
async
{
for
(
ShutdownHook
shutdownHook
in
_shutdownHooks
)
await
shutdownHook
();
List
<
ShutdownHook
>
hooks
=
new
List
<
ShutdownHook
>.
from
(
_shutdownHooks
);
_shutdownHooks
.
clear
();
_shutdownHooksRunning
=
true
;
try
{
for
(
ShutdownHook
shutdownHook
in
hooks
)
await
shutdownHook
();
}
finally
{
_shutdownHooksRunning
=
false
;
}
assert
(
_shutdownHooks
.
isEmpty
);
}
Map
<
String
,
String
>
_environment
(
bool
allowReentrantFlutter
,
[
Map
<
String
,
String
>
environment
])
{
...
...
packages/flutter_tools/lib/src/base/process_manager.dart
View file @
1155f966
...
...
@@ -423,7 +423,7 @@ class RecordingProcessManager implements ProcessManager {
/// A lightweight class that provides a builder pattern for building a
/// manifest entry.
class
_ManifestEntryBuilder
{
Map
<
String
,
dynamic
>
entry
;
Map
<
String
,
dynamic
>
entry
=
<
String
,
dynamic
>{}
;
/// Adds the specified key/value pair to the manifest entry iff the value
/// is non-null. If [jsonValue] is specified, its value will be used instead
...
...
@@ -602,8 +602,8 @@ class ReplayProcessManager implements ProcessManager {
try
{
List
<
Map
<
String
,
dynamic
>>
manifest
=
new
JsonDecoder
().
convert
(
content
);
return
new
ReplayProcessManager
.
_
(
manifest
,
dir
);
}
on
FormatException
{
throw
new
ArgumentError
(
'
$_kManifestName
is not a valid JSON file
.
'
);
}
on
FormatException
catch
(
e
)
{
throw
new
ArgumentError
(
'
$_kManifestName
is not a valid JSON file
:
$e
'
);
}
}
...
...
@@ -835,6 +835,8 @@ class _ReplayProcess implements Process {
@override
bool
kill
([
ProcessSignal
signal
=
ProcessSignal
.
SIGTERM
])
{
if
(!
_exitCodeCompleter
.
isCompleted
)
{
_stdoutController
.
close
();
_stderrController
.
close
();
_exitCodeCompleter
.
complete
(
_exitCode
);
return
true
;
}
...
...
packages/flutter_tools/test/all.dart
View file @
1155f966
...
...
@@ -33,6 +33,7 @@ import 'install_test.dart' as install_test;
import
'logs_test.dart'
as
logs_test
;
import
'os_utils_test.dart'
as
os_utils_test
;
import
'packages_test.dart'
as
packages_test
;
import
'process_manager_test.dart'
as
process_manager_test
;
import
'protocol_discovery_test.dart'
as
protocol_discovery_test
;
import
'run_test.dart'
as
run_test
;
import
'stop_test.dart'
as
stop_test
;
...
...
@@ -68,6 +69,7 @@ void main() {
logs_test
.
main
();
os_utils_test
.
main
();
packages_test
.
main
();
process_manager_test
.
main
();
protocol_discovery_test
.
main
();
run_test
.
main
();
stop_test
.
main
();
...
...
packages/flutter_tools/test/data/process_manager/replay/001.sing.100.stderr
0 → 100644
View file @
1155f966
Uh, pineapple pen
packages/flutter_tools/test/data/process_manager/replay/001.sing.100.stdout
0 → 100644
View file @
1155f966
I have a pen
I have a pineapple
packages/flutter_tools/test/data/process_manager/replay/002.dance.101.stderr
0 → 100644
View file @
1155f966
No one can dance like Psy
packages/flutter_tools/test/data/process_manager/replay/002.dance.101.stdout
0 → 100644
View file @
1155f966
packages/flutter_tools/test/data/process_manager/replay/MANIFEST.txt
0 → 100644
View file @
1155f966
[
{
"pid": 100,
"basename": "001.sing.100",
"executable": "sing",
"arguments": [
"ppap"
],
"mode": "ProcessStartMode.NORMAL",
"exitCode": 0
},
{
"pid": 101,
"basename": "002.dance.101",
"executable": "dance",
"arguments": [
"gangnam-style"
],
"stdoutEncoding": "system",
"stderrEncoding": "system",
"exitCode": 2
}
]
packages/flutter_tools/test/process_manager_test.dart
0 → 100644
View file @
1155f966
// Copyright 2016 The Chromium 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:async'
;
import
'dart:convert'
;
import
'dart:io'
;
import
'package:archive/archive.dart'
;
import
'package:flutter_tools/src/base/context.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/base/os.dart'
;
import
'package:flutter_tools/src/base/process.dart'
;
import
'package:flutter_tools/src/base/process_manager.dart'
;
import
'package:path/path.dart'
as
path
;
import
'package:test/test.dart'
;
typedef
bool
Predicate
<
T
>(
T
item
);
/// Decodes a UTF8-encoded byte array into a list of Strings, where each list
/// entry represents a line of text.
List
<
String
>
_decode
(
List
<
int
>
data
)
=>
const
LineSplitter
().
convert
(
UTF8
.
decode
(
data
));
/// Consumes and returns an entire stream of bytes.
Future
<
List
<
int
>>
_consume
(
Stream
<
List
<
int
>>
stream
)
=>
stream
.
expand
((
List
<
int
>
data
)
=>
data
).
toList
();
void
main
(
)
{
group
(
'RecordingProcessManager'
,
()
{
Directory
tmp
;
ProcessManager
manager
;
setUp
(()
{
tmp
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_tools_'
);
manager
=
new
RecordingProcessManager
(
tmp
.
path
);
});
tearDown
(()
{
tmp
.
deleteSync
(
recursive:
true
);
});
test
(
'start'
,
()
async
{
Process
process
=
await
manager
.
start
(
'echo'
,
<
String
>[
'foo'
]);
int
pid
=
process
.
pid
;
int
exitCode
=
await
process
.
exitCode
;
List
<
int
>
stdout
=
await
_consume
(
process
.
stdout
);
List
<
int
>
stderr
=
await
_consume
(
process
.
stderr
);
expect
(
exitCode
,
0
);
expect
(
_decode
(
stdout
),
<
String
>[
'foo'
]);
expect
(
stderr
,
isEmpty
);
// Force the recording to be written to disk.
await
runShutdownHooks
();
_Recording
recording
=
_Recording
.
readFrom
(
tmp
);
expect
(
recording
.
manifest
,
hasLength
(
1
));
Map
<
String
,
dynamic
>
entry
=
recording
.
manifest
.
first
;
expect
(
entry
[
'pid'
],
pid
);
expect
(
entry
[
'exitCode'
],
exitCode
);
expect
(
recording
.
stdoutForEntryAt
(
0
),
stdout
);
expect
(
recording
.
stderrForEntryAt
(
0
),
stderr
);
});
test
(
'run'
,
()
async
{
ProcessResult
result
=
await
manager
.
run
(
'echo'
,
<
String
>[
'bar'
]);
int
pid
=
result
.
pid
;
int
exitCode
=
result
.
exitCode
;
String
stdout
=
result
.
stdout
;
String
stderr
=
result
.
stderr
;
expect
(
exitCode
,
0
);
expect
(
stdout
,
'bar
\n
'
);
expect
(
stderr
,
isEmpty
);
// Force the recording to be written to disk.
await
runShutdownHooks
();
_Recording
recording
=
_Recording
.
readFrom
(
tmp
);
expect
(
recording
.
manifest
,
hasLength
(
1
));
Map
<
String
,
dynamic
>
entry
=
recording
.
manifest
.
first
;
expect
(
entry
[
'pid'
],
pid
);
expect
(
entry
[
'exitCode'
],
exitCode
);
expect
(
recording
.
stdoutForEntryAt
(
0
),
stdout
);
expect
(
recording
.
stderrForEntryAt
(
0
),
stderr
);
});
test
(
'runSync'
,
()
async
{
ProcessResult
result
=
manager
.
runSync
(
'echo'
,
<
String
>[
'baz'
]);
int
pid
=
result
.
pid
;
int
exitCode
=
result
.
exitCode
;
String
stdout
=
result
.
stdout
;
String
stderr
=
result
.
stderr
;
expect
(
exitCode
,
0
);
expect
(
stdout
,
'baz
\n
'
);
expect
(
stderr
,
isEmpty
);
// Force the recording to be written to disk.
await
runShutdownHooks
();
_Recording
recording
=
_Recording
.
readFrom
(
tmp
);
expect
(
recording
.
manifest
,
hasLength
(
1
));
Map
<
String
,
dynamic
>
entry
=
recording
.
manifest
.
first
;
expect
(
entry
[
'pid'
],
pid
);
expect
(
entry
[
'exitCode'
],
exitCode
);
expect
(
recording
.
stdoutForEntryAt
(
0
),
stdout
);
expect
(
recording
.
stderrForEntryAt
(
0
),
stderr
);
});
});
group
(
'ReplayProcessManager'
,
()
{
ProcessManager
manager
;
setUp
(()
async
{
await
runInMinimalContext
(()
async
{
Directory
dir
=
new
Directory
(
'test/data/process_manager/replay'
);
manager
=
await
ReplayProcessManager
.
create
(
dir
.
path
);
});
});
tearDown
(()
async
{
// Allow the replay manager to clean up
await
runShutdownHooks
();
});
test
(
'start'
,
()
async
{
Process
process
=
await
manager
.
start
(
'sing'
,
<
String
>[
'ppap'
]);
int
exitCode
=
await
process
.
exitCode
;
List
<
int
>
stdout
=
await
_consume
(
process
.
stdout
);
List
<
int
>
stderr
=
await
_consume
(
process
.
stderr
);
expect
(
process
.
pid
,
100
);
expect
(
exitCode
,
0
);
expect
(
_decode
(
stdout
),
<
String
>[
'I have a pen'
,
'I have a pineapple'
]);
expect
(
_decode
(
stderr
),
<
String
>[
'Uh, pineapple pen'
]);
});
test
(
'run'
,
()
async
{
ProcessResult
result
=
await
manager
.
run
(
'dance'
,
<
String
>[
'gangnam-style'
]);
expect
(
result
.
pid
,
101
);
expect
(
result
.
exitCode
,
2
);
expect
(
result
.
stdout
,
''
);
expect
(
result
.
stderr
,
'No one can dance like Psy
\n
'
);
});
test
(
'runSync'
,
()
{
ProcessResult
result
=
manager
.
runSync
(
'dance'
,
<
String
>[
'gangnam-style'
]);
expect
(
result
.
pid
,
101
);
expect
(
result
.
exitCode
,
2
);
expect
(
result
.
stdout
,
''
);
expect
(
result
.
stderr
,
'No one can dance like Psy
\n
'
);
});
});
}
Future
<
Null
>
runInMinimalContext
(
Future
<
dynamic
>
method
())
async
{
AppContext
context
=
new
AppContext
();
context
.
putIfAbsent
(
ProcessManager
,
()
=>
new
ProcessManager
());
context
.
putIfAbsent
(
Logger
,
()
=>
new
BufferLogger
());
context
.
putIfAbsent
(
OperatingSystemUtils
,
()
=>
new
OperatingSystemUtils
());
await
context
.
runInZone
(
method
);
}
/// A testing utility class that encapsulates a recording.
class
_Recording
{
final
File
file
;
final
Archive
_archive
;
_Recording
(
this
.
file
,
this
.
_archive
);
static
_Recording
readFrom
(
Directory
dir
)
{
File
file
=
new
File
(
path
.
join
(
dir
.
path
,
RecordingProcessManager
.
kDefaultRecordTo
));
Archive
archive
=
new
ZipDecoder
().
decodeBytes
(
file
.
readAsBytesSync
());
return
new
_Recording
(
file
,
archive
);
}
List
<
Map
<
String
,
dynamic
>>
get
manifest
{
return
JSON
.
decoder
.
convert
(
_getFileContent
(
'MANIFEST.txt'
,
UTF8
));
}
dynamic
stdoutForEntryAt
(
int
index
)
=>
_getStdioContent
(
manifest
[
index
],
'stdout'
);
dynamic
stderrForEntryAt
(
int
index
)
=>
_getStdioContent
(
manifest
[
index
],
'stderr'
);
dynamic
_getFileContent
(
String
name
,
Encoding
encoding
)
{
List
<
int
>
bytes
=
_fileNamed
(
name
).
content
;
return
encoding
==
null
?
bytes
:
encoding
.
decode
(
bytes
);
}
dynamic
_getStdioContent
(
Map
<
String
,
dynamic
>
entry
,
String
type
)
{
String
basename
=
entry
[
'basename'
];
String
encodingName
=
entry
[
'
${type}
Encoding'
];
Encoding
encoding
;
if
(
encodingName
!=
null
)
encoding
=
encodingName
==
'system'
?
const
SystemEncoding
()
:
Encoding
.
getByName
(
encodingName
);
return
_getFileContent
(
'
$basename
.
$type
'
,
encoding
);
}
ArchiveFile
_fileNamed
(
String
name
)
=>
_archive
.
firstWhere
(
_hasName
(
name
));
Predicate
<
ArchiveFile
>
_hasName
(
String
name
)
=>
(
ArchiveFile
file
)
=>
file
.
name
==
name
;
}
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