Exemplo n.º 1
0
        protected override Task RunTestAsync(
            Context context, DisposableDirectory testDirectory, Func <IMemoizationStore, IMemoizationSession, Task> funcAsync, Func <DisposableDirectory, IMemoizationStore> createStoreFunc = null)
        {
            return(RunTestAsync(
                       context,
                       testDirectory,
                       async store =>
            {
                var configuration = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1);
                var configurationModel = new ConfigurationModel(configuration);

                using (var contentStore = new FileSystemContentStore(
                           FileSystem, SystemClock.Instance, testDirectory.Path, configurationModel))
                {
                    try
                    {
                        var startupContentStoreResult = await contentStore.StartupAsync(context);
                        startupContentStoreResult.ShouldBeSuccess();

                        var contentSessionResult = contentStore.CreateSession(context, Name, ImplicitPin.None);
                        contentSessionResult.ShouldBeSuccess();

                        var sessionResult = store.CreateSession(context, Name, contentSessionResult.Session);
                        sessionResult.ShouldBeSuccess();

                        using (var cacheSession = new OneLevelCacheSession(Name, ImplicitPin.None, sessionResult.Session, contentSessionResult.Session))
                        {
                            try
                            {
                                var r = await cacheSession.StartupAsync(context);
                                r.ShouldBeSuccess();

                                await funcAsync(store, cacheSession);
                            }
                            finally
                            {
                                var r = await cacheSession.ShutdownAsync(context);
                                r.ShouldBeSuccess();
                            }
                        }
                    }
                    finally
                    {
                        var shutdownContentStoreResult = await contentStore.ShutdownAsync(context);
                        shutdownContentStoreResult.ShouldBeSuccess();
                    }
                }
            },
                       createStoreFunc));
        }
Exemplo n.º 2
0
        protected override ICache CreateCache(DisposableDirectory testDirectory)
        {
            var rootPath      = testDirectory.Path;
            var configuration = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1);

            configuration.Write(FileSystem, rootPath).Wait();

            var memoConfig = new SQLiteMemoizationStoreConfiguration(rootPath)
            {
                MaxRowCount = MaxContentHashListItems
            };

            memoConfig.Database.JournalMode = ContentStore.SQLite.JournalMode.OFF;
            return(LocalCache.CreateUnknownContentStoreInProcMemoizationStoreCache(Logger, rootPath, memoConfig, LocalCacheConfiguration.CreateServerDisabled(), clock: Clock));
        }
Exemplo n.º 3
0
        private async Task RunTestCase(string testName, Func<AbsolutePath, IContentSession, GrpcCopyClient, Task> testAct)
        {
            var cacheName = testName + "_cache";

            using (var directory = new DisposableDirectory(FileSystem))
            {
                var rootPath = directory.Path;

                var namedCacheRoots = new Dictionary<string, AbsolutePath> { { cacheName, rootPath } };
                var grpcPort = PortExtensions.GetNextAvailablePort();
                var grpcPortFileName = Guid.NewGuid().ToString();
                var configuration = new ServiceConfiguration(
                    namedCacheRoots,
                    rootPath,
                    42,
                    ServiceConfiguration.DefaultGracefulShutdownSeconds,
                    grpcPort,
                    grpcPortFileName);

                var storeConfig = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1);
                Func<AbsolutePath, IContentStore> contentStoreFactory = (path) =>
                    new FileSystemContentStore(
                        FileSystem,
                        SystemClock.Instance,
                        directory.Path,
                        new ConfigurationModel(storeConfig));

                var server = new LocalContentServer(FileSystem, Logger, testName, contentStoreFactory, new LocalServerConfiguration(configuration));

                await server.StartupAsync(_context).ShouldBeSuccess();
                var createSessionResult = await server.CreateSessionAsync(new OperationContext(_context), testName, cacheName, ImplicitPin.PutAndGet, Capabilities.ContentOnly);
                createSessionResult.ShouldBeSuccess();

                (int sessionId, AbsolutePath tempDir) = createSessionResult.Value;
                var session = server.GetSession(sessionId);

                // Create a GRPC client to connect to the server
                var port = new MemoryMappedFilePortReader(grpcPortFileName, Logger).ReadPort();
                using (var client = GrpcCopyClient.Create("localhost", port))
                {
                    // Run validation
                    await testAct(rootPath, session, client);
                }

                await server.ShutdownAsync(_context).ShouldBeSuccess();
            }
        }
Exemplo n.º 4
0
        private async Task RunTestAsync(Context context, Func <IContentSession, Task> funcAsync)
        {
            using (var testDirectory = new DisposableDirectory(FileSystem))
            {
                var rootPath           = testDirectory.Path;
                var configuration      = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1);
                var configurationModel = new ConfigurationModel(configuration);

                using (var store = new FileSystemContentStore(
                           FileSystem, SystemClock.Instance, rootPath, configurationModel))
                {
                    try
                    {
                        var startupStoreResult = await store.StartupAsync(context);

                        startupStoreResult.ShouldBeSuccess();

                        var createResult = store.CreateSession(context, Name, ImplicitPin.None);
                        createResult.ShouldBeSuccess();
                        using (var session = createResult.Session)
                        {
                            try
                            {
                                var startupSessionResult = await session.StartupAsync(context);

                                startupSessionResult.ShouldBeSuccess();

                                await funcAsync(session);
                            }
                            finally
                            {
                                var shutdownSessionResult = await session.ShutdownAsync(context);

                                shutdownSessionResult.ShouldBeSuccess();
                            }
                        }
                    }
                    finally
                    {
                        var shutdownStoreResult = await store.ShutdownAsync(context);

                        shutdownStoreResult.ShouldBeSuccess();
                    }
                }
            }
        }
Exemplo n.º 5
0
        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();

            return(new LocalCache(Logger, rootPathForStream, rootPathForPath, new SQLiteMemoizationStoreConfiguration(rootPathForPath)
            {
                MaxRowCount = MaxContentHashListItems, JournalMode = ContentStore.SQLite.JournalMode.OFF
            }, clock: Clock));
        }
Exemplo n.º 6
0
        protected override ICache CreateCache(DisposableDirectory testDirectory)
        {
            var rootPath      = testDirectory.Path;
            var configuration = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1);

            configuration.Write(FileSystem, rootPath);

            var memoConfig = new RocksDbMemoizationStoreConfiguration()
            {
                Database = new RocksDbContentLocationDatabaseConfiguration(rootPath)
                {
                    CleanOnInitialize = false,
                    OnFailureDeleteExistingStoreAndRetry = true,
                    LogsKeepLongTerm = true,
                    MetadataGarbageCollectionEnabled = true,
                    MetadataGarbageCollectionMaximumNumberOfEntriesToKeep = MaxContentHashListItems,
                },
            };

            return(LocalCache.CreateUnknownContentStoreInProcMemoizationStoreCache(Logger, rootPath, memoConfig, LocalCacheConfiguration.CreateServerDisabled(), clock: Clock));
        }
Exemplo n.º 7
0
 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);
 }
Exemplo n.º 8
0
 private FileSystemContentStoreInternal CreateInternal(AbsolutePath rootPath)
 {
     return(new FileSystemContentStoreInternal(
                _fileSystem, SystemClock.Instance, rootPath, new ConfigurationModel(ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(Constants.OneMB))));
 }
Exemplo n.º 9
0
        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
        }
Exemplo n.º 10
0
        [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();
                }
            }
        }
Exemplo n.º 11
0
        public async Task HardlinkTestAsync()
        {
            var clock = new MemoryClock();

            var configuration      = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(10);
            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());

            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);
        }