public async Task StopReentrantLoop() { var callback = new RSessionCallbackStub(); var session = new RSession(0, _testMethod.FileSystemSafeName, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { }); await session.StartHostAsync(new RHostStartupInfo(), callback, 50000); var testMrs = new AsyncManualResetEvent(); callback.PlotHandler = (message, ct) => { testMrs.Set(); return(session.EvaluateAsync("x <- 1\n")); }; Task responceTask; using (var interaction = await session.BeginInteractionAsync()) { responceTask = interaction.RespondAsync("plot(1)\n"); } await testMrs.WaitAsync().Should().BeCompletedAsync(); await session.StopHostAsync().Should().BeCompletedAsync(20000); session.IsHostRunning.Should().BeFalse(); await responceTask.Should().BeCanceledAsync(); }
public ReadInput(TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _testMethod = testMethod.MethodInfo; _session = new RSession(0, () => { }); _callback = new RSessionCallbackStub(); }
public async Task GetBlob_DisconnectedFromTheStart() { using (var session = new RSession(0, _testMethod.FileSystemSafeName, _fileSystem, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { })) { Func <Task> f = () => session.BlobReadAllAsync(1); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public async Task <IRSession> StartSessionAsync(CancellationToken ct) { if (RSession == null) { var workflow = _services.GetService <IRInteractiveWorkflowProvider>().GetOrCreate(); RSession = workflow.RSessions.GetOrCreate(_sessionId); } else { await _sessionStart; } if (!RSession.IsHostRunning) { var settings = _services.GetService <IRSettings>(); await RSession.EnsureHostStartedAsync(new RHostStartupInfo(isInteractive : true), SessionCallback, 3000, ct); await RSession.SetVsCranSelectionAsync(CranMirrorList.UrlFromName(settings.CranMirror), ct); await RSession.SetCodePageAsync(settings.RCodePage, ct); await RSession.SetVsGraphicsDeviceAsync(); } return(RSession); }
public ReadInput(CoreServicesFixture coreServices, TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _brokerClient = CreateLocalBrokerClient(coreServices, nameof(RSessionTest) + nameof(ReadInput)); _session = new RSession(0, testMethod.FileSystemSafeName, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { }); _callback = new RSessionCallbackStub(); }
public Blobs(IServiceContainer services, TestMethodFixture testMethod) { _testMethod = testMethod; _brokerClient = CreateLocalBrokerClient(services, nameof(RSessionTest) + nameof(Blobs)); _fileSystem = services.FileSystem(); _session = new RSession(0, testMethod.FileSystemSafeName, _fileSystem, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { }); }
public CancelAll(IServiceContainer services, TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _callback = new RSessionCallbackStub(); _brokerClient = CreateLocalBrokerClient(services, nameof(RSessionTest) + nameof(CancelAll)); _session = new RSession(0, testMethod.FileSystemSafeName, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => {}); }
public InteractionEvaluation(IServiceContainer services, TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _testMethod = testMethod; _brokerClient = CreateLocalBrokerClient(services, nameof(RSessionTest) + nameof(InteractionEvaluation)); _session = new RSession(0, _testMethod.FileSystemSafeName, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { }); }
public async Task EnsureStarted_KillProcess_EnsureStarted() { var session = new RSession(0, _testMethod.FileSystemSafeName, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { }); session.HostStarted.Should().NotBeCompleted(); session.IsHostRunning.Should().BeFalse(); await session.EnsureHostStartedAsync(new RHostStartupInfo(), null, 50000); session.HostStarted.Should().BeRanToCompletion(); session.IsHostRunning.Should().BeTrue(); var sessionDisconnectedTask = EventTaskSources.IRSession.Disconnected.Create(session); var processId = await GetRSessionProcessId(session); Process.GetProcessById(processId).Kill(); await sessionDisconnectedTask; session.IsHostRunning.Should().BeFalse(); await session.EnsureHostStartedAsync(new RHostStartupInfo(), null, 50000); session.HostStarted.Should().BeRanToCompletion(); session.IsHostRunning.Should().BeTrue(); }
public ReadInput(TestMethodFixture testMethod) { _testMethodFixture = testMethod; _testMethod = testMethod.MethodInfo; _session = new RSession(0, () => { }); _callback = new RSessionCallbackStub(); }
public async Task StartStop() { var session = new RSession(0, _brokerClient, () => { }); session.HostStarted.Status.Should().Be(TaskStatus.WaitingForActivation); session.IsHostRunning.Should().BeFalse(); await session.StartHostAsync(new RHostStartupInfo { Name = _testMethod.Name }, null, 50000); session.HostStarted.Status.Should().Be(TaskStatus.RanToCompletion); session.IsHostRunning.Should().BeTrue(); await session.StopHostAsync(); session.HostStarted.Status.Should().Be(TaskStatus.WaitingForActivation); session.IsHostRunning.Should().BeFalse(); await session.StartHostAsync(new RHostStartupInfo { Name = _testMethod.Name }, null, 50000); session.HostStarted.Status.Should().Be(TaskStatus.RanToCompletion); session.IsHostRunning.Should().BeTrue(); }
public async Task StartStopMultipleSessions() { Func <int, Task <RSession> > start = async i => { var session = new RSession(i, _brokerClient, () => { }); await session.StartHostAsync(new RHostStartupInfo { Name = _testMethod.Name + i }, null, 50000); return(session); }; var sessionsTasks = await ParallelTools.InvokeAsync(4, start); if (sessionsTasks.Any(t => t.Status != TaskStatus.RanToCompletion)) { Debugger.Launch(); } sessionsTasks.Should().OnlyContain(t => t.Status == TaskStatus.RanToCompletion); var sessions = sessionsTasks.Select(t => t.Result).ToList(); sessions.Should().OnlyContain(t => t.IsHostRunning); var sessionStopTasks = await ParallelTools.InvokeAsync(4, i => sessionsTasks[i].Result.StopHostAsync()); sessionStopTasks.Should().OnlyContain(t => t.Status == TaskStatus.RanToCompletion); sessions.Should().OnlyContain(t => !t.IsHostRunning); }
public Blobs(TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _testMethod = testMethod.MethodInfo; _brokerClient = CreateLocalBrokerClient(nameof(RSessionTest) + nameof(Blobs)); _session = new RSession(0, _brokerClient, () => { }); }
public Output(TestMethodFixture testMethod) { _testMethod = testMethod.MethodInfo; _brokerConnector = new RHostBrokerConnector(); _brokerConnector.SwitchToLocalBroker(nameof(RSessionTest) + nameof(Output)); _session = new RSession(0, _brokerConnector, () => { }); }
public async Task GetBlob_DisconnectedFromTheStart() { using (var session = new RSession(0, _brokerConnector, () => { })) { Func <Task> f = () => session.GetBlobAsync(1); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public Blobs(CoreServicesFixture coreServices, TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _coreServices = coreServices; _taskObserver = taskObserver; _testMethod = testMethod; _brokerClient = CreateLocalBrokerClient(_coreServices, nameof(RSessionTest) + nameof(Blobs)); _session = new RSession(0, testMethod.FileSystemSafeName, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { }); }
public async Task BeginInteractionAsync_DisconnectedFromTheStart() { using (var session = new RSession(0, _testMethod.FileSystemSafeName, _fileSystem, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { })) { // ReSharper disable once AccessToDisposedClosure Func <Task> f = () => session.BeginInteractionAsync(); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public async Task DestroyBlob_DisconnectedFromTheStart() { using (var session = new RSession(0, _brokerConnector, () => { })) { var blobids = new ulong[] { 1, 2, 3, 4, 5 }; Func <Task> f = () => session.DestroyBlobsAsync(blobids); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public async Task CreateBlob_DisconnectedFromTheStart() { using (var session = new RSession(0, _brokerConnector, () => { })) { var data = new byte[] { 1, 2, 3, 4, 5 }; Func <Task> f = () => session.CreateBlobAsync(data); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public ReadInput(TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _testMethod = testMethod.MethodInfo; _brokerClient = CreateLocalBrokerClient(nameof(RSessionTest) + nameof(ReadInput)); _session = new RSession(0, _brokerClient, () => { }); _callback = new RSessionCallbackStub(); }
public async Task EvaluateAsync_DisconnectedFromTheStart() { using (var session = new RSession(0, _brokerClient, () => { })) { // ReSharper disable once AccessToDisposedClosure Func <Task> f = () => session.EvaluateAsync("x <- 1"); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public Blobs(TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _testMethod = testMethod.MethodInfo; _brokerConnector = new RHostBrokerConnector(); _brokerConnector.SwitchToLocalBroker(nameof(RSessionTest) + nameof(Blobs)); _session = new RSession(0, _brokerConnector, () => { }); }
public async Task DestroyBlob_DisconnectedFromTheStart() { using (var session = new RSession(0, _testMethod.FileSystemSafeName, _fileSystem, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { })) { var blobids = new ulong[] { 1, 2, 3, 4, 5 }; Func <Task> f = () => session.DestroyBlobsAsync(blobids); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public async Task BeginInteractionAsync_DisconnectedFromTheStart() { using (var session = new RSession(0, _brokerConnector, () => { })) { // ReSharper disable once AccessToDisposedClosure Func <Task> f = () => session.BeginInteractionAsync(); await f.ShouldThrowAsync <RHostDisconnectedException>(); } }
public async Task BreakAsync(CancellationToken ct = default(CancellationToken)) { await TaskUtilities.SwitchToBackgroundThread(); using (var inter = await RSession.BeginInteractionAsync(true, ct)) { await inter.RespondAsync("browser()\n"); } }
public void StartRHostMissing() { var brokerClient = new LocalBrokerClient(nameof(RSessionTest), BrokerConnectionInfo.Create(null, "C", @"C:\"), _services, new NullConsole(), Environment.SystemDirectory); var session = new RSession(0, _testMethod.FileSystemSafeName, brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { }); Func <Task> start = () => session.StartHostAsync(new RHostStartupInfo(), null, 10000); start.ShouldThrow <ComponentBinaryMissingException>(); }
public ReadInput(TestMethodFixture testMethod, TaskObserverMethodFixture taskObserver) { _taskObserver = taskObserver; _testMethod = testMethod.MethodInfo; _brokerConnector = new RHostBrokerConnector(); _brokerConnector.SwitchToLocalBroker(nameof(RSessionTest) + nameof(ReadInput)); _session = new RSession(0, _brokerConnector, () => { }); _callback = new RSessionCallbackStub(); }
public async Task EnableBreakpointsAsync(bool enable, CancellationToken ct = default(CancellationToken)) { ThrowIfDisposed(); await TaskUtilities.SwitchToBackgroundThread(); using (var eval = await RSession.BeginEvaluationAsync(ct)) { await eval.EvaluateAsync($"rtvs:::enable_breakpoints({(enable ? "TRUE" : "FALSE")})", REvaluationKind.Mutating); } }
public void StartRHostMissing() { var session = new RSession(0, () => { }); Func <Task> start = () => session.StartHostAsync(new RHostStartupInfo { Name = _testMethod.Name, RHostDirectory = Environment.SystemDirectory }, null, 10000); start.ShouldThrow <RHostBinaryMissingException>(); }
public async Task CreateBlob_DisconnectedFromTheStart() { using (var session = new RSession(0, _testMethod.FileSystemSafeName, _fileSystem, _brokerClient, new AsyncReaderWriterLock().CreateExclusiveReaderLock(), () => { })) { var data = new byte[] { 1, 2, 3, 4, 5 }; using (DataTransferSession dts = new DataTransferSession(session, null)) { Func <Task> f = () => dts.SendBytesAsync(data, false, null, CancellationToken.None); await f.ShouldThrowAsync <RHostDisconnectedException>(); } } }
private MPack Execute(MPack p) { var map = (MPackMap)p; //var responseBody = new RResponseBody(); RSession sesh = null; DateTime start = DateTime.Now; string method = null; MPackMap result = new MPackMap(); if (map.ContainsKey(CONST.HDR_ID)) result[CONST.HDR_ID] = map[CONST.HDR_ID]; try { // parse client input packet var token = map[CONST.HDR_TOKEN].To<string>(); var sig = map[CONST.HDR_METHOD].To<string>(); var parsedSig = RemoteCallHelper.ParseMethodName(sig); method = parsedSig.Name; sesh = _parent.Sessions.Get(token); if (sesh == null) throw new ArgumentException("Specified token is invalid"); result[CONST.HDR_TOKEN] = MPack.From(token); // get method details, parameters, return type, etc //sesh = _parent._sessions[token]; var methodInfo = sesh.Endpoint.Methods.Single(mth => mth.Name == method); var methodParams = methodInfo.Parameters; var serverArgTypes = methodParams .Select(x => x.ParameterType) .ToArray(); var serverRetType = methodInfo.ReturnType; if (!RemoteCallHelper.CheckMethodSignature(methodInfo.Method, parsedSig)) throw new InvalidOperationException("Method signature does not match that of the server's implementation"); // check if user is authorized to execute this method //if (methodInfo.Attributes.FirstOrDefault(a => a is RRequireAuth) != null) // if (!_authenticated && _parent.CredentialValidator != null) // throw new MethodAccessException("This method requires authentication"); //var role = methodInfo.Attributes.FirstOrDefault(a => a is RRequireRole) as RRequireRole; //if (role != null && _parent.CredentialValidator != null) //{ // if (!_authenticated || !_parent.CredentialValidator.IsInRole(_user, role.RequiredRole)) // throw new MethodAccessException( // $"User must be in {role.RequiredRole} role to access this method."); //} // deserialize the request body //var requestBody = ClassifyJson.Deserialize<RRequestBody>(JsonValue.Parse(p.Payload)); var mpackArgs = map[CONST.HDR_ARGS]; object[] reconArgs = new object[serverArgTypes.Length]; List<int> refParams = new List<int>(); for (int i = 0; i < reconArgs.Length; i++) { var mpk = mpackArgs[i]; var type = serverArgTypes[i]; var byref = methodParams[i].IsOut || type.IsByRef; var streamed = serverArgTypes[i].IsAssignableFrom(typeof(Stream)); if (streamed) { reconArgs[i] = new MessageConsumerStream(mpk.To<string>(), _protocol.Buffer, _cancelSource.Token, WritePacket); } else { if (byref) refParams.Add(i); reconArgs[i] = RemoteCallHelper.ParamaterToObject(type, mpk); } } // validate that we have all the required parameters for (int i = 0; i < reconArgs.Length; i++) { //if (reconArgs[i] == null && !methodParams[i].IsOptional && !methodParams[i].IsOut) // throw new ArgumentException("A required method parameter is missing."); if (reconArgs[i] == null && methodParams[i].IsOptional) reconArgs[i] = Type.Missing; } //var returnValue = methodInfo.Delegate(sesh.Instance, reconArgs); var returnValue = methodInfo.Method.Invoke(sesh.Instance, reconArgs); if (returnValue != null && !serverRetType.IsInstanceOfType(returnValue)) throw new InvalidOperationException("Return value type mismatch"); // populate ref / out parameters to the response body if (refParams.Any()) { var refoutParams = new MPackArray(Enumerable.Range(0, reconArgs.Length).Select(v => MPack.Null())); for (int i = 0; i < refParams.Count; i++) { var paramIndex = refParams[i]; refoutParams[paramIndex] = RemoteCallHelper.ObjectToParamater(reconArgs[paramIndex]); } result[CONST.HDR_ARGS] = refoutParams; } // set the return value of response body if (typeof(Stream).IsAssignableFrom(serverRetType)) { bool writable = methodInfo.Method.ReturnParameter.GetCustomAttributes(typeof(RWritable)).Any(); string tkn = Guid.NewGuid().ToString(); var wrappedStream = new MessageProviderStream(tkn, (Stream)returnValue, _protocol.Buffer, WritePacket, _cancelSource.Token, writable); result[CONST.HDR_STATUS] = MPack.From(CONST.STA_STREAM); result[CONST.HDR_VALUE] = MPack.From(tkn); } else if (serverRetType == typeof(void)) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_VOID); } else if (Attribute.IsDefined(serverRetType ?? typeof(object), typeof(RContractProvider))) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_SERVICE); REndpoint endpoint = _parent.Endpoints.SingleOrDefault(ed => ed.Interface == serverRetType); if (endpoint == null) endpoint = new REndpoint(RandomEx.GetString(20), serverRetType, context => null); // create new session var ses = new RSession(endpoint, returnValue); var policy = new CacheItemPolicy() { SlidingExpiration = _parent.SessionTimeout }; _parent.Sessions.Add(ses.Token, ses, policy); if (returnValue is IDisposable) { policy.RemovedCallback = args => ((IDisposable)args.CacheItem.Value).Dispose(); } result[CONST.HDR_VALUE] = MPack.From(ses.Token); } else { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_NORMAL); result[CONST.HDR_VALUE] = RemoteCallHelper.ObjectToParamater(returnValue); } } catch (Exception ex) { string message; string type; if (ex is TargetInvocationException || ex is AggregateException) { type = ex.InnerException.GetType().Name; message = ex.InnerException.Message; } else { type = ex.GetType().Name; message = ex.Message; } result[CONST.HDR_STATUS] = MPack.From(CONST.STA_ERROR); result[CONST.HDR_VALUE] = MPack.From($"({type}){message}"); result[CONST.HDR_LOCATION] = MPack.From($"{sesh?.Endpoint.Path ?? "[invalid]"}/{method ?? "[invalid]"}()"); } DateTime end = DateTime.Now; var time = end - start; result[CONST.HDR_TIME] = MPack.From(time.TotalMilliseconds); return result; }
private MPack Open(MPack p) { var map = (MPackMap)p; REndpoint endpoint = null; string clToken = null; if (map.ContainsKey(CONST.HDR_LOCATION)) endpoint = _parent.Endpoints.SingleOrDefault(end => end.Path.EqualsNoCase(map[CONST.HDR_LOCATION].To<string>())); if (map.ContainsKey(CONST.HDR_TOKEN)) clToken = map[CONST.HDR_TOKEN].To<string>(); RSession session = null; MPackMap result = new MPackMap(); if (map.ContainsKey(CONST.HDR_ID)) result[CONST.HDR_ID] = map[CONST.HDR_ID]; if (clToken != null) { session = _parent.Sessions.Get(clToken); LogTo.Debug($"Session opened (existing). {_parent.Sessions.Count} in cache."); if (session != null && _sessions.Contains(clToken)) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_NORMAL); result[CONST.HDR_VALUE] = MPack.From(clToken); return result; } } else if (endpoint != null) { object service = endpoint.GenerateService(new RContext(_client.RemoteEndpoint)); clToken = Guid.NewGuid().ToString(); session = new RSession(endpoint, service, clToken); var policy = new CacheItemPolicy() { SlidingExpiration = _parent.SessionTimeout }; if (service is IDisposable) { policy.RemovedCallback = args => { ((IDisposable)args.CacheItem.Value).Dispose(); LogTo.Debug($"[{args.CacheItem.Key}] Session object timed out and destroyed"); }; } _parent.Sessions.Set(clToken, session, policy); LogTo.Debug($"Session opened (new). {_parent.Sessions.Count} in cache."); //_parent._sessions.Add(clToken, session); } if (session == null) { result[CONST.HDR_STATUS] = MPack.From(CONST.STA_ERROR); result[CONST.HDR_VALUE] = MPack.From("No valid path or token was provided."); return result; } else { _sessions.Add(clToken); } foreach (var evt in session.Endpoint.Events) { _events.Add(clToken, new EventPropegator(session.Instance, evt, (o, args) => { MPackMap evtP = new MPackMap { {CONST.HDR_CMD, MPack.From(CONST.CMD_EVENT)}, {CONST.HDR_TOKEN, MPack.From(clToken)}, {CONST.HDR_METHOD, MPack.From(evt.Name)}, {CONST.HDR_VALUE, ClassifyMPack.Serialize(args)} }; WritePacket(evtP); })); } result[CONST.HDR_STATUS] = MPack.From(CONST.STA_NORMAL); result[CONST.HDR_VALUE] = MPack.From(clToken); return result; }