protected async Task RunStoreTestAsync(Func <Context, IContentStore, Task> funcAsync, LocalServerConfiguration localContentServerConfiguration = null, TimeSpan?heartbeatOverride = null) { var context = new Context(Logger); using (var directory = new DisposableDirectory(FileSystem)) { var config = new ContentStoreConfiguration(new MaxSizeQuota($"{DefaultMaxSize}")); using (var store = CreateStore(directory.Path, config, localContentServerConfiguration ?? TestConfigurationHelper.LocalContentServerConfiguration, heartbeatOverride)) { try { await store.StartupAsync(context).ShouldBeSuccess(); await funcAsync(context, store); } finally { await store.ShutdownAsync(context).ShouldBeSuccess(); } } } }
protected override ICache CreateCache(DisposableDirectory testDirectory) { var rootPathForStream = RootPathOfContentStoreForStream(testDirectory); var rootPathForPath = RootPathOfContentStoreForPath(testDirectory); FileSystem.CreateDirectory(rootPathForStream); FileSystem.CreateDirectory(rootPathForPath); var configuration1 = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1); var configuration2 = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1); configuration1.Write(FileSystem, rootPathForStream).Wait(); configuration2.Write(FileSystem, rootPathForPath).Wait(); var memoConfig = new SQLiteMemoizationStoreConfiguration(rootPathForPath) { MaxRowCount = MaxContentHashListItems }; memoConfig.Database.JournalMode = ContentStore.SQLite.JournalMode.OFF; return(LocalCache.CreateStreamPathContentStoreInProcMemoizationStoreCache(Logger, rootPathForStream, rootPathForPath, memoConfig, clock: Clock)); }
protected override IContentStore CreateStore(AbsolutePath rootPath, ContentStoreConfiguration configuration) { configuration.Write(FileSystem, rootPath); var grpcPortFileName = Guid.NewGuid().ToString(); var serviceConfiguration = new ServiceConfiguration( new Dictionary <string, AbsolutePath> { { CacheName, rootPath } }, rootPath, MaxConnections, GracefulShutdownSeconds, PortExtensions.GetNextAvailablePort(), grpcPortFileName); return(new TestServiceClientContentStore( Logger, FileSystem, new ServiceClientContentStoreConfiguration(CacheName, null, Scenario), null, serviceConfiguration)); }
public TestFileSystemContentStoreInternal( IAbsFileSystem fileSystem, IClock clock, AbsolutePath rootPath, ContentStoreConfiguration configuration, Action <ContentHashWithSize> onContentAdded = null, Action <ContentHashWithSize> onContentEvicted = null, NagleQueue <ContentHash> nagleQueue = null) : base(fileSystem, clock, rootPath, new ConfigurationModel(configuration), nagleQueue: nagleQueue) { Contract.Requires(fileSystem != null); Contract.Requires(clock != null); Contract.Requires(rootPath != null); Contract.Requires(configuration != null); _onContentAdded = onContentAdded; _onContentEvicted = onContentEvicted; if (_onContentAdded != null || _onContentEvicted != null) { Announcer = this; } }
protected override IStartupShutdown CreateInstance(DisposableDirectory testDirectory, int singleInstanceTimeoutSeconds) { var rootPath = testDirectory.Path; var config = new ContentStoreConfiguration(new MaxSizeQuota("1MB"), singleInstanceTimeoutSeconds: singleInstanceTimeoutSeconds); return(LocalCache.CreateUnknownContentStoreInProcMemoizationStoreCache( Logger, rootPath, new RocksDbMemoizationStoreConfiguration() { Database = new RocksDbContentLocationDatabaseConfiguration(rootPath) { CleanOnInitialize = false, OnFailureDeleteExistingStoreAndRetry = true, LogsKeepLongTerm = true, MetadataGarbageCollectionEnabled = true, MetadataGarbageCollectionMaximumNumberOfEntriesToKeep = MaxStrongFingerprints, }, }, LocalCacheConfiguration.CreateServerDisabled(), clock: Clock, configurationModel: new ConfigurationModel(config))); }
public TestFileSystemContentStoreInternal( IAbsFileSystem fileSystem, IClock clock, AbsolutePath rootPath, ContentStoreConfiguration configuration, Action <ContentHashWithSize> onContentAdded = null, Action <ContentHashWithSize> onContentEvicted = null, ContentStoreSettings settings = null, IDistributedLocationStore distributedStore = null) : base(fileSystem, clock, rootPath, new ConfigurationModel(configuration), settings: settings, distributedStore: distributedStore) { Contract.Requires(fileSystem != null); Contract.Requires(clock != null); Contract.Requires(rootPath != null); Contract.Requires(configuration != null); _onContentAdded = onContentAdded; _onContentEvicted = onContentEvicted; if (_onContentAdded != null || _onContentEvicted != null) { Announcer = this; } }
public async Task HardlinkTestAsync() { var clock = new MemoryClock(); var configuration = new ContentStoreConfiguration(); var configurationModel = new ConfigurationModel(inProcessConfiguration: configuration, ConfigurationSelection.RequireAndUseInProcessConfiguration); var root1 = TestRootDirectoryPath / "Store1"; var store1 = new FileSystemContentStore(FileSystem, clock, root1, configurationModel); var fakeDrive = new AbsolutePath(@"X:\"); var root2 = fakeDrive / "Store2"; var redirectedFileSystem = new RedirectionFileSystem(FileSystem, fakeDrive, TestRootDirectoryPath); var store2 = new FileSystemContentStore(redirectedFileSystem, clock, fakeDrive, configurationModel); var stores = new Dictionary <string, IContentStore> { { root1.GetPathRoot(), store1 }, { root2.GetPathRoot(), store2 }, }; var multiplexed = new MultiplexedContentStore(stores, preferredCacheDrive: root1.GetPathRoot(), tryAllSessions: true); var context = new Context(Logger); await multiplexed.StartupAsync(context).ShouldBeSuccess(); var sessionResult = multiplexed.CreateSession(context, "Default", ImplicitPin.None).ShouldBeSuccess(); var session = sessionResult.Session; // Put random content which should go to preferred drive var putResult = await session.PutRandomAsync(context, ContentStore.Hashing.HashType.MD5, provideHash : true, size : 1024, CancellationToken.None) .ShouldBeSuccess(); // Should be able to place it with hardlink in primary drive var destination1 = TestRootDirectoryPath / "destination1.txt"; var placeResult1 = await session.PlaceFileAsync( context, putResult.ContentHash, destination1, FileAccessMode.ReadOnly, FileReplacementMode.FailIfExists, FileRealizationMode.HardLink, CancellationToken.None) .ShouldBeSuccess(); placeResult1.Code.Should().Be(PlaceFileResult.ResultCode.PlacedWithHardLink); // Should be able to place it with hardlink in secondary drive. // The cache should copy the contents internally, and then place from the correct drive. var destination2 = fakeDrive / "destination2.txt"; var placeResult2 = await session.PlaceFileAsync( context, putResult.ContentHash, destination2, FileAccessMode.ReadOnly, FileReplacementMode.FailIfExists, FileRealizationMode.HardLink, CancellationToken.None) .ShouldBeSuccess(); placeResult2.Code.Should().Be(PlaceFileResult.ResultCode.PlacedWithHardLink); }
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { throw new NotImplementedException(); }
private void RunFileSystemContentStore(AbsolutePath rootPath, System.Func <Context, IContentSession, Task> funcAsync) { System.Func <IContentStore> createFunc = () => new FileSystemContentStore( _fileSystem, SystemClock.Instance, rootPath, new ConfigurationModel(ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(Constants.OneMB))); RunContentStore(createFunc, funcAsync); }
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { var rootPath = testDirectory.Path / "Root"; var tempPath = testDirectory.Path / "Temp"; var configurationModel = new ConfigurationModel(configuration); var fileCopier = new TestFileCopier(); var localDatabase = LocalRedisProcessDatabase.CreateAndStartEmpty(_redis, TestGlobal.Logger, SystemClock.Instance); var localMachineDatabase = LocalRedisProcessDatabase.CreateAndStartEmpty(_redis, TestGlobal.Logger, SystemClock.Instance); var localMachineLocation = new MachineLocation(rootPath.Path); var storeFactory = new MockRedisContentLocationStoreFactory(localDatabase, localMachineDatabase, rootPath); return(new DistributedContentStore <AbsolutePath>( localMachineLocation.Data, (nagleBlock, distributedEvictionSettings, contentStoreSettings, trimBulkAsync) => new FileSystemContentStore( FileSystem, SystemClock.Instance, rootPath, configurationModel, nagleQueue: nagleBlock, distributedEvictionSettings: distributedEvictionSettings, settings: contentStoreSettings, trimBulkAsync: trimBulkAsync), storeFactory, fileCopier, fileCopier, storeFactory.PathTransformer, copyRequester: null, ReadOnlyDistributedContentSession <AbsolutePath> .ContentAvailabilityGuarantee.FileRecordsExist, tempPath, FileSystem, RedisContentLocationStoreConstants.DefaultBatchSize, settings: new DistributedContentStoreSettings { RetryIntervalForCopies = DefaultRetryIntervalsForTest, PinConfiguration = new PinConfiguration() }, setPostInitializationCompletionAfterStartup: true)); }
private void ShowConfiguration(ContentStoreConfiguration configuration, bool json) { var message = $"{(json ? configuration.SerializeToJSON() : configuration.ToString())}"; _logger.Log(Severity.Always, message); }
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { var rootPath = testDirectory.Path / "Root"; var configurationModel = new ConfigurationModel(configuration); var fileCopier = new TestFileCopier(); var localDatabase = LocalRedisProcessDatabase.CreateAndStartEmpty(_redis, TestGlobal.Logger, SystemClock.Instance); var localMachineDatabase = LocalRedisProcessDatabase.CreateAndStartEmpty(_redis, TestGlobal.Logger, SystemClock.Instance); var localMachineLocation = new MachineLocation(rootPath.Path); var storeFactory = new MockRedisContentLocationStoreFactory(localDatabase, localMachineDatabase, rootPath); var settings = CreateSettings(); var distributedCopier = new DistributedContentCopier <AbsolutePath>( settings, FileSystem, fileCopier, fileCopier, copyRequester: null, storeFactory.PathTransformer, SystemClock.Instance); return(new DistributedContentStore <AbsolutePath>( localMachineLocation, rootPath, (nagleBlock, distributedEvictionSettings, contentStoreSettings, trimBulkAsync) => new FileSystemContentStore( FileSystem, SystemClock.Instance, rootPath, configurationModel, nagleQueue: nagleBlock, distributedEvictionSettings: distributedEvictionSettings, settings: contentStoreSettings, trimBulkAsync: trimBulkAsync), storeFactory, settings: settings, distributedCopier: distributedCopier)); }
protected override IContentStore CreateStore(AbsolutePath rootPath, string cacheName, ContentStoreConfiguration configuration) { configuration.Write(FileSystem, rootPath).Wait(); var grpcPortFileName = Guid.NewGuid().ToString(); var serviceConfig = new ServiceConfiguration( new Dictionary <string, AbsolutePath> { { cacheName, rootPath } }, rootPath, _maxConnections, GracefulShutdownSeconds, PortExtensions.GetNextAvailablePort(), grpcPortFileName); return(new TestInProcessServiceClientContentStore( FileSystem, Logger, cacheName, _scenario, null, serviceConfig)); }
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { return(new FileSystemContentStore(FileSystem, Logger, SystemClock.Instance, testDirectory.Path, new ConfigurationModel(configuration))); }
protected override IContentStore CreateStore(AbsolutePath rootPath, string cacheName, ContentStoreConfiguration configuration) { var configurationModel = new ConfigurationModel(configuration); return(new TestFileSystemContentStore(FileSystem, SystemClock.Instance, rootPath, configurationModel)); }
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { var rootPath = testDirectory.Path; var configurationModel = new ConfigurationModel(configuration); var fsStore = new FileSystemContentStore(FileSystem, SystemClock.Instance, rootPath / "fs", configurationModel); _vfsStore = new VirtualizedContentStore(fsStore, Logger, new VfsCasConfiguration.Builder() { RootPath = rootPath / "vfs", }.Build()); return(_vfsStore); }
protected abstract IContentStore CreateStore(AbsolutePath rootPath, ContentStoreConfiguration configuration);
[Trait("Category", "QTestSkip")] // Skipped public async Task RestoredSessionReleasedAfterInactivity() { const string scenario = nameof(RestoredSessionReleasedAfterInactivity); var context = new Context(Logger); using (var directory = new DisposableDirectory(FileSystem)) { var rootPath = directory.Path; var contentHash = ContentHash.Random(); var pins = new List <string> { contentHash.Serialize() }; var hibernatedSessionInfo = new HibernatedSessionInfo(SessionId, SessionName, ImplicitPin.None, CacheName, pins, DateTime.UtcNow.Ticks, Capabilities.None); var hibernatedSessions = new HibernatedSessions(new List <HibernatedSessionInfo> { hibernatedSessionInfo }); await hibernatedSessions.WriteAsync(FileSystem, rootPath); var namedCacheRoots = new Dictionary <string, AbsolutePath> { { CacheName, rootPath } }; var grpcPort = PortExtensions.GetNextAvailablePort(); var grpcPortFileName = Guid.NewGuid().ToString(); var configuration = new ServiceConfiguration(namedCacheRoots, rootPath, MaxConnections, GracefulShutdownSeconds, grpcPort, grpcPortFileName); var storeConfig = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1); Func <AbsolutePath, IContentStore> contentStoreFactory = (path) => new FileSystemContentStore( FileSystem, SystemClock.Instance, directory.Path, new ConfigurationModel(storeConfig)); var localContentServerConfiguration = new LocalServerConfiguration(configuration) { UnusedSessionHeartbeatTimeout = TimeSpan.FromSeconds(TimeoutSecs), RequestCallTokensPerCompletionQueue = 10, }; using (var server = new LocalContentServer(FileSystem, Logger, scenario, contentStoreFactory, localContentServerConfiguration)) { var r1 = await server.StartupAsync(context); r1.ShouldBeSuccess(); var beforeIds = server.GetSessionIds(); beforeIds.Should().Contain(SessionId); // Wait one period to ensure that it times out, another to ensure that the checker finds it, and another to give it time to release it. await Task.Delay(TimeSpan.FromSeconds(TimeoutSecs * 3)); var afterIds = server.GetSessionIds(); afterIds.Count.Should().Be(0); var r2 = await server.ShutdownAsync(context); r2.ShouldBeSuccess(); } } }
/// <inheritdoc /> protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { var rootPath = testDirectory.Path; var configurationModel = new ConfigurationModel(configuration); return(new StreamPathContentStore( () => new FileSystemContentStore(FileSystem, SystemClock.Instance, rootPath / RootOfContentStoreForStream, configurationModel), () => new FileSystemContentStore(FileSystem, SystemClock.Instance, rootPath / RootOfContentStoreForPath, configurationModel))); }
protected abstract T CreateStore(AbsolutePath rootPath, ContentStoreConfiguration configuration, LocalServerConfiguration localContentServerConfiguration, TimeSpan?heartbeatOverride);
protected override TestFileSystemContentStoreInternal Create(AbsolutePath rootPath, ITestClock clock) { var config = new ContentStoreConfiguration(_quota); return new TestFileSystemContentStoreInternal(FileSystem, clock, rootPath, config, settings: ContentStoreSettings); }
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { var rootPath = testDirectory.Path / "Root"; var configurationModel = new ConfigurationModel(configuration); var primaryDatabase = LocalRedisProcessDatabase.CreateAndStartEmpty(_redis, TestGlobal.Logger, SystemClock.Instance); var secondaryDatabase = LocalRedisProcessDatabase.CreateAndStartEmpty(_redis, TestGlobal.Logger, SystemClock.Instance); var localMachineLocation = new MachineLocation(rootPath.Path); var storeFactory = new MockContentLocationStoreFactory(primaryDatabase, secondaryDatabase, rootPath); var settings = CreateSettings(); return(new DistributedContentStore( localMachineLocation, rootPath, (distributedStore) => new FileSystemContentStore( FileSystem, SystemClock.Instance, rootPath, configurationModel, settings: ContentStoreSettings.DefaultSettings, distributedStore: distributedStore), storeFactory, settings: settings, distributedCopier: storeFactory.GetCopier())); }
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { var rootPath = testDirectory.Path; configuration.Write(FileSystem, rootPath).Wait(); var grpcPortFileName = Guid.NewGuid().ToString(); var serviceConfiguration = new ServiceConfiguration( new Dictionary <string, AbsolutePath> { { CacheName, rootPath } }, rootPath, MaxConnections, GracefulShutdownSeconds, PortExtensions.GetNextAvailablePort(), grpcPortFileName); return(new TestInProcessServiceClientContentStore( FileSystem, Logger, CacheName, Scenario, null, serviceConfiguration )); }
internal void Service ( [Description("Cache names")] string[] names, [Description("Cache root paths")] string[] paths, [DefaultValue(DefaultMaxConnections), Description(MaxConnectionsDescription)] uint maxConnections, [DefaultValue(DefaultGracefulShutdownSeconds), Description(GracefulShutdownSecondsDescription)] uint gracefulShutdownSeconds, [DefaultValue(ServiceConfiguration.GrpcDisabledPort), Description(GrpcPortDescription)] int grpcPort, [Description("Name of the memory mapped file used to share GRPC port. 'CASaaS GRPC port' if not specified.")] string grpcPortFileName, [DefaultValue(null), Description("Writable directory for service operations (use CWD if null)")] string dataRootPath, [DefaultValue(null), Description("Duration of inactivity after which a session will be timed out.")] double?unusedSessionTimeoutSeconds, [DefaultValue(null), Description("Duration of inactivity after which a session with a heartbeat will be timed out.")] double?unusedSessionHeartbeatTimeoutSeconds, [DefaultValue(false), Description("Stop running service")] bool stop, [DefaultValue(Constants.OneMB), Description("Max size quota in MB")] int maxSizeQuotaMB ) { Initialize(); if (stop) { IpcUtilities.SetShutdown(_scenario); return; } if (names == null || paths == null) { throw new CacheException("At least one cache name/path is required."); } if (names.Length != paths.Length) { throw new CacheException("Mismatching lengths of names/paths arguments."); } var caches = new Dictionary <string, string>(); for (var i = 0; i < names.Length; i++) { caches.Add(names[i], paths[i]); } var serverDataRootPath = !string.IsNullOrWhiteSpace(dataRootPath) ? new AbsolutePath(dataRootPath) : new AbsolutePath(Environment.CurrentDirectory); var cancellationTokenSource = new CancellationTokenSource(); #if !FEATURE_CORECLR var configuration = new ServiceConfiguration(caches, serverDataRootPath, maxConnections, gracefulShutdownSeconds, grpcPort, grpcPortFileName); if (!configuration.IsValid) { throw new CacheException($"Invalid service configuration, error=[{configuration.Error}]"); } var localContentServerConfiguration = new LocalServerConfiguration(configuration); if (unusedSessionTimeoutSeconds != null) { localContentServerConfiguration.UnusedSessionTimeout = TimeSpan.FromSeconds(unusedSessionTimeoutSeconds.Value); } if (unusedSessionHeartbeatTimeoutSeconds != null) { localContentServerConfiguration.UnusedSessionHeartbeatTimeout = TimeSpan.FromSeconds(unusedSessionHeartbeatTimeoutSeconds.Value); } if (_scenario != null) { _logger.Debug($"scenario=[{_scenario}]"); } var exitSignal = new ManualResetEvent(false); Console.CancelKeyPress += (sender, args) => { exitSignal.Set(); args.Cancel = true; }; using (var exitEvent = IpcUtilities.GetShutdownWaitHandle(_scenario)) { var server = new LocalContentServer( _fileSystem, _logger, _scenario, path => new FileSystemContentStore( _fileSystem, SystemClock.Instance, path, new ConfigurationModel(inProcessConfiguration: ContentStoreConfiguration.CreateWithMaxSizeQuotaMB((uint)maxSizeQuotaMB))), localContentServerConfiguration); using (server) { var context = new Context(_logger); try { var result = server.StartupAsync(context).Result; if (!result.Succeeded) { throw new CacheException(result.ErrorMessage); } int completedIndex = WaitHandle.WaitAny(new WaitHandle[] { exitSignal, exitEvent }); var source = completedIndex == 0 ? "control-C" : "exit event"; _tracer.Always(context, $"Shutdown by {source}."); } finally { var result = server.ShutdownAsync(context).Result; if (!result.Succeeded) { _tracer.Warning(context, $"Failed to shutdown store: {result.ErrorMessage}"); } } } } #else Console.CancelKeyPress += (sender, args) => { cancellationTokenSource.Cancel(); args.Cancel = true; }; var localCasSettings = LocalCasSettings.Default(maxSizeQuotaMB, serverDataRootPath.Path, names[0], (uint)grpcPort); var distributedContentSettings = DistributedContentSettings.CreateDisabled(); var distributedCacheServiceConfiguration = new DistributedCacheServiceConfiguration(localCasSettings, distributedContentSettings); // Ensure the computed keyspace is computed based on the hostInfo's StampId distributedCacheServiceConfiguration.UseStampBasedIsolation = false; var distributedCacheServiceArguments = new DistributedCacheServiceArguments( logger: _logger, copier: null, pathTransformer: null, host: new EnvironmentVariableHost(), hostInfo: new HostInfo(null, null, new List <string>()), cancellation: cancellationTokenSource.Token, dataRootPath: serverDataRootPath.Path, configuration: distributedCacheServiceConfiguration, keyspace: null); DistributedCacheServiceFacade.RunAsync(distributedCacheServiceArguments).GetAwaiter().GetResult(); // Because the facade completes immediately and named wait handles don't exist in CORECLR, // completion here is gated on Control+C. In the future, this can be redone with another option, // such as a MemoryMappedFile or GRPC heartbeat. This is just intended to be functional. cancellationTokenSource.Token.WaitHandle.WaitOne(); #endif }
private FileSystemContentStoreInternal CreateInternal(AbsolutePath rootPath) { return(new FileSystemContentStoreInternal( _fileSystem, SystemClock.Instance, rootPath, new ConfigurationModel(ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(Constants.OneMB)))); }
protected override TestFileSystemContentStoreInternal Create(AbsolutePath rootPath, ITestClock clock, NagleQueue <ContentHash> nagleBlock = null) { var config = new ContentStoreConfiguration(_quota); return(new TestFileSystemContentStoreInternal(FileSystem, clock, rootPath, config, nagleQueue: nagleBlock)); }
protected abstract IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration);
protected override IContentStore CreateStore(DisposableDirectory testDirectory, ContentStoreConfiguration configuration) { var rootPath = testDirectory.Path; configuration.Write(FileSystem, rootPath); var grpcPortFileName = Guid.NewGuid().ToString(); var serviceConfig = new ServiceConfiguration( new Dictionary <string, AbsolutePath> { { CacheName, rootPath } }, rootPath, GracefulShutdownSeconds, PortExtensions.GetNextAvailablePort(), grpcPortFileName); return(new TestServiceClientContentStore( Logger, FileSystem, new ServiceClientContentStoreConfiguration(CacheName, rpcConfiguration: null, scenario: Scenario), heartbeatInterval: null, serviceConfiguration: serviceConfig)); }