Ensure that cache dirs and files have appropriate permissions (#28090)
This is a partial re-application of #24669, which was
reverted due to Fuchsia breakages.
https://github.com/flutter/flutter/issues/24413
diff --git a/packages/flutter_tools/test/general.shard/cache_test.dart b/packages/flutter_tools/test/general.shard/cache_test.dart
index ca29c69..e2fe07e 100644
--- a/packages/flutter_tools/test/general.shard/cache_test.dart
+++ b/packages/flutter_tools/test/general.shard/cache_test.dart
@@ -6,14 +6,20 @@
import 'package:file/file.dart';
import 'package:file/memory.dart';
+import 'package:file_testing/file_testing.dart';
+import 'package:meta/meta.dart';
import 'package:mockito/mockito.dart';
import 'package:platform/platform.dart';
import 'package:flutter_tools/src/cache.dart';
+import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart' show InternetAddress, SocketException;
+import 'package:flutter_tools/src/base/net.dart';
+import 'package:flutter_tools/src/base/os.dart';
import '../src/common.dart';
import '../src/context.dart';
+import '../src/testbed.dart';
void main() {
group('$Cache.checkLockAcquired', () {
@@ -51,8 +57,13 @@
});
group('Cache', () {
- final MockCache mockCache = MockCache();
- final MemoryFileSystem fs = MemoryFileSystem();
+ MockCache mockCache;
+ MemoryFileSystem memoryFileSystem;
+
+ setUp(() {
+ mockCache = MockCache();
+ memoryFileSystem = MemoryFileSystem();
+ });
testUsingContext('Gradle wrapper should not be up to date, if some cached artifact is not available', () {
final GradleWrapper gradleWrapper = GradleWrapper(mockCache);
@@ -63,7 +74,7 @@
expect(gradleWrapper.isUpToDateInner(), false);
}, overrides: <Type, Generator>{
Cache: ()=> mockCache,
- FileSystem: () => fs,
+ FileSystem: () => memoryFileSystem,
});
testUsingContext('Gradle wrapper should be up to date, only if all cached artifact are available', () {
@@ -78,7 +89,7 @@
expect(gradleWrapper.isUpToDateInner(), true);
}, overrides: <Type, Generator>{
Cache: ()=> mockCache,
- FileSystem: () => fs,
+ FileSystem: () => memoryFileSystem,
});
test('should not be up to date, if some cached artifact is not', () {
@@ -157,6 +168,74 @@
}, overrides: <Type, Generator>{
FileSystem: () => MockFileSystem(),
});
+
+ group('EngineCachedArtifact', () {
+ FakeHttpClient fakeHttpClient;
+ FakePlatform fakePlatform;
+ MemoryFileSystem memoryFileSystem;
+ MockCache mockCache;
+ MockOperatingSystemUtils mockOperatingSystemUtils;
+
+ setUp(() {
+ fakeHttpClient = FakeHttpClient();
+ fakePlatform = FakePlatform()..environment = const <String, String>{};
+ memoryFileSystem = MemoryFileSystem();
+ mockCache = MockCache();
+ mockOperatingSystemUtils = MockOperatingSystemUtils();
+ when(mockOperatingSystemUtils.verifyZip(any)).thenReturn(true);
+ });
+
+ testUsingContext('makes binary dirs readable and executable by all', () async {
+ final Directory artifactDir = fs.systemTempDirectory.createTempSync('artifact.');
+ final Directory downloadDir = fs.systemTempDirectory.createTempSync('download.');
+ when(mockCache.getArtifactDirectory(any)).thenReturn(artifactDir);
+ when(mockCache.getDownloadDir()).thenReturn(downloadDir);
+ final FakeCachedArtifact artifact = FakeCachedArtifact(
+ cache: mockCache,
+ binaryDirs: <List<String>>[
+ <String>['bin_dir', 'unused_url_path'],
+ ],
+ );
+ await artifact.updateInner();
+ final Directory dir = memoryFileSystem.systemTempDirectory
+ .listSync(recursive: true)
+ .whereType<Directory>()
+ .singleWhere((Directory directory) => directory.basename == 'bin_dir', orElse: () => null);
+ expect(dir, isNotNull);
+ expect(dir.path, artifactDir.childDirectory('bin_dir').path);
+ verify(mockOperatingSystemUtils.chmod(argThat(hasPath(dir.path)), 'a+r,a+x'));
+ }, overrides: <Type, Generator>{
+ Cache: ()=> mockCache,
+ FileSystem: () => memoryFileSystem,
+ HttpClientFactory: () => () => fakeHttpClient,
+ OperatingSystemUtils: () => mockOperatingSystemUtils,
+ Platform: () => fakePlatform,
+ });
+ });
+}
+
+class FakeCachedArtifact extends EngineCachedArtifact {
+ FakeCachedArtifact({
+ String stampName = 'STAMP',
+ @required Cache cache,
+ Set<DevelopmentArtifact> requiredArtifacts = const <DevelopmentArtifact>{},
+ this.binaryDirs = const <List<String>>[],
+ this.licenseDirs = const <String>[],
+ this.packageDirs = const <String>[],
+ }) : super(stampName, cache, requiredArtifacts);
+
+ final List<List<String>> binaryDirs;
+ final List<String> licenseDirs;
+ final List<String> packageDirs;
+
+ @override
+ List<List<String>> getBinaryDirs() => binaryDirs;
+
+ @override
+ List<String> getLicenseDirs() => licenseDirs;
+
+ @override
+ List<String> getPackageDirs() => packageDirs;
}
class MockFileSystem extends ForwardingFileSystem {
@@ -179,3 +258,4 @@
class MockCachedArtifact extends Mock implements CachedArtifact {}
class MockInternetAddress extends Mock implements InternetAddress {}
class MockCache extends Mock implements Cache {}
+class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}