public async Task WhenCommandInvalidAndExtendedDataModeIsNormal_ThenExecuteSucceedsAndStderrContainsError( [LinuxInstance] ResourceTask <InstanceLocator> instanceLocatorTask) { var endpoint = new IPEndPoint( await InstanceUtil.PublicIpAddressForInstanceAsync(await instanceLocatorTask), 22); using (var key = new RsaSshKey(new RSACng())) { await InstanceUtil.AddPublicKeyToMetadata( await instanceLocatorTask, "testuser", key).ConfigureAwait(true); using (var session = CreateSession()) using (var connection = session.Connect(endpoint)) using (var authSession = connection.Authenticate("testuser", key)) using (var channel = authSession.OpenExecChannel( "invalidcommand", LIBSSH2_CHANNEL_EXTENDED_DATA.NORMAL)) { channel.WaitForEndOfStream(); var buffer = new byte[1024]; var bytesRead = channel.Read( buffer, LIBSSH2_STREAM.EXTENDED_DATA_STDERR); Assert.AreNotEqual(0, bytesRead); Assert.AreEqual( "bash: invalidcommand: command not found\n", Encoding.ASCII.GetString(buffer, 0, (int)bytesRead)); Assert.AreEqual(127, channel.ExitCode); Assert.IsNull(channel.ExitSignal); channel.Close(); } } }
public async Task WhenUpdateConflictingOnFirstAttempt_ThenUpdateInstanceMetadataRetriesAndSucceeds( [WindowsInstance] ResourceTask <InstanceLocator> testInstance) { var locator = await testInstance; var key = Guid.NewGuid().ToString(); int callbacks = 0; await this.instancesResource.UpdateMetadataAsync( locator, metadata => { if (callbacks++ == 0) { // Provoke a conflict on the first attempt. this.instancesResource.AddMetadataAsync( locator, key, "conflict #" + callbacks, CancellationToken.None).Wait(); } metadata.Add(key, "value"); }, CancellationToken.None, 2); var instance = await this.instancesResource.Get( locator.ProjectId, locator.Zone, locator.Name) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.AreEqual( "value", instance.Metadata.Items.First(i => i.Key == key).Value); }
public async Task WhenImageNotFoundButFromWindowsProject_ThenAnnotationIsAdded( [Credential(Role = PredefinedRole.ComputeViewer)] ResourceTask <ICredential> credential) { var annotatedSet = CreateSet( new ImageLocator("windows-cloud", "windows-95")); Assert.AreEqual(0, annotatedSet.LicenseAnnotations.Count()); var computeEngineAdapter = new ComputeEngineAdapter( await credential); await LicenseLoader.LoadLicenseAnnotationsAsync( annotatedSet, computeEngineAdapter, CancellationToken.None); Assert.AreEqual(1, annotatedSet.LicenseAnnotations.Count()); var annotation = annotatedSet.LicenseAnnotations.Values.First(); Assert.AreEqual(OperatingSystemTypes.Windows, annotation.OperatingSystem); Assert.AreEqual(LicenseTypes.Spla, annotation.LicenseType); }
public async Task WhenConnected_ThenActiveAlgorithmsAreSet( [LinuxInstance] ResourceTask <InstanceLocator> instanceLocatorTask) { var endpoint = new IPEndPoint( await InstanceUtil.PublicIpAddressForInstanceAsync(await instanceLocatorTask), 22); using (var session = CreateSession()) using (var connection = session.Connect(endpoint)) { Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.KEX)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.HOSTKEY)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.CRYPT_CS)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.CRYPT_SC)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.MAC_CS)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.MAC_SC)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.COMP_CS)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.COMP_SC)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.LANG_CS)); Assert.IsNotNull(connection.GetActiveAlgorithms(LIBSSH2_METHOD.LANG_SC)); } }
public async Task WhenPublicKeyValidAndKnownFromMetadata_ThenAuthenticateThrowsAuthenticationSucceeds( [LinuxInstance] ResourceTask <InstanceLocator> instanceLocatorTask) { var endpoint = new IPEndPoint( await InstanceUtil.PublicIpAddressForInstanceAsync(await instanceLocatorTask), 22); using (var key = new RsaSshKey(new RSACng())) { await InstanceUtil.AddPublicKeyToMetadata( await instanceLocatorTask, "testuser", key); using (var session = CreateSession()) using (var connection = session.Connect(endpoint)) { var authSession = connection.Authenticate("testuser", key); Assert.IsNotNull(authSession); } } }
public async Task WhenUserNotInRole_ThenProcessInstanceEventsAsyncThrowsResourceAccessDeniedException( [LinuxInstance] ResourceTask <InstanceLocator> testInstance, [Credential(Role = PredefinedRole.ComputeViewer)] ResourceTask <ICredential> credential) { await testInstance; var instanceRef = await testInstance; var instanceBuilder = new InstanceSetHistoryBuilder( DateTime.UtcNow.AddDays(-7), DateTime.UtcNow); var adapter = new AuditLogAdapter(await credential); AssertEx.ThrowsAggregateException <ResourceAccessDeniedException>( () => adapter.ProcessInstanceEventsAsync( new[] { TestProject.ProjectId }, null, // all zones. null, // all instances. instanceBuilder.StartDate, instanceBuilder, CancellationToken.None).Wait()); }
public async Task WhenCommandIsValid_ThenOpenExecChannelAsyncSucceeds( [LinuxInstance] ResourceTask <InstanceLocator> instanceLocatorTask) { var endpoint = new IPEndPoint( await InstanceUtil.PublicIpAddressForInstanceAsync(await instanceLocatorTask), 22); using (var key = new RsaSshKey(new RSACng())) { await InstanceUtil.AddPublicKeyToMetadata( await instanceLocatorTask, "testuser", key).ConfigureAwait(true); using (var session = CreateSession()) using (var connection = session.Connect(endpoint)) using (var authSession = connection.Authenticate( "testuser", key, UnexpectedAuthenticationCallback)) using (var channel = authSession.OpenExecChannel( "whoami", LIBSSH2_CHANNEL_EXTENDED_DATA.NORMAL)) { channel.WaitForEndOfStream(); var buffer = new byte[1024]; var bytesRead = channel.Read(buffer); Assert.AreNotEqual(0, bytesRead); Assert.AreEqual("testuser\n", Encoding.ASCII.GetString(buffer, 0, (int)bytesRead)); Assert.AreEqual(0, channel.ExitCode); Assert.IsNull(channel.ExitSignal); channel.Close(); } } }
public async Task When2faRequiredAndPromptReturnsNull_ThenPromptIsRetried( [LinuxInstance(InitializeScript = RequireSshPassword)] ResourceTask <InstanceLocator> instanceLocatorTask) { var endpoint = new IPEndPoint( await InstanceUtil.PublicIpAddressForInstanceAsync(await instanceLocatorTask), 22); using (var key = new RsaSshKey(new RSACng())) { await InstanceUtil.AddPublicKeyToMetadata( await instanceLocatorTask, "testuser", key); using (var session = CreateSession()) using (var connection = session.Connect(endpoint)) { var callbackCount = 0; SshAssert.ThrowsNativeExceptionWithError( session, LIBSSH2_ERROR.AUTHENTICATION_FAILED, () => connection.Authenticate( "testuser", key, (name, instruction, prompt, echo) => { callbackCount++; Assert.AreEqual("Password: ", prompt); Assert.IsFalse(echo); return(null); })); Assert.AreEqual(SshConnectedSession.KeyboardInteractiveRetries, callbackCount); } } }
public async Task WhenFirstReadCompleted_ThenSidIsAvailable( [LinuxInstance(InitializeScript = InstallApache)] ResourceTask <InstanceLocator> vm, [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential) { var locator = await vm; var stream = (SshRelayStream)ConnectToWebServer( locator, await credential); byte[] request = new ASCIIEncoding().GetBytes( $"GET / HTTP/1.1\r\nHost:www\r\nConnection: keep-alive\r\n\r\n"); Assert.IsNull(stream.Sid); await stream.WriteAsync(request, 0, request.Length, CancellationToken.None); Assert.IsNull(stream.Sid); // Read a bit. byte[] buffer = new byte[stream.MinReadSize]; await stream.ReadAsync(buffer, 0, buffer.Length, CancellationToken.None); Assert.IsNotNull(stream.Sid); }
public async Task WhenClientClosesConnectionAfterSingleHttpRequest_ThenRelayEnds( [LinuxInstance(InitializeScript = InstallApache)] ResourceTask <InstanceLocator> vm, [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential) { var locator = await vm; var stream = ConnectToWebServer( locator, await credential); byte[] request = new ASCIIEncoding().GetBytes( $"GET / HTTP/1.1\r\nHost:www\r\nConnection: keep-alive\r\n\r\n"); await stream.WriteAsync(request, 0, request.Length, this.tokenSource.Token); byte[] buffer = new byte[stream.MinReadSize]; // Read a bit. var response = new HttpResponseAccumulator(); int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, this.tokenSource.Token); response.Accumulate(buffer, 0, bytesRead); await stream.CloseAsync(this.tokenSource.Token); }
public async Task WhenInstanceNotAvailable_ThenProbeFails( [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential) { var service = new TunnelService(CreateAuthorizationAdapter( await credential, null)); var destination = new TunnelDestination( new InstanceLocator( TestProject.ProjectId, "us-central1-a", "nonexistinginstance"), 3389); using (var tunnel = await service.CreateTunnelAsync( destination, new SameProcessRelayPolicy())) { Assert.AreEqual(destination, tunnel.Destination); AssertEx.ThrowsAggregateException <UnauthorizedException>( () => tunnel.Probe(TimeSpan.FromSeconds(20)).Wait()); } }
public async Task WhenInstanceCreated_ThenProcessInstanceEventsAsyncCanFeedHistorySetBuilder( [LinuxInstance] ResourceTask <InstanceLocator> testInstance, [Credential(Roles = new[] { PredefinedRole.ComputeViewer, PredefinedRole.LogsViewer })] ResourceTask <ICredential> credential) { await testInstance; var instanceRef = await testInstance; var instanceBuilder = new InstanceSetHistoryBuilder( DateTime.UtcNow.AddDays(-7), DateTime.UtcNow); var computeAdapter = new ComputeEngineAdapter(await credential); instanceBuilder.AddExistingInstances( await computeAdapter.ListInstancesAsync(TestProject.ProjectId, CancellationToken.None), await computeAdapter.ListNodesAsync(TestProject.ProjectId, CancellationToken.None), await computeAdapter.ListDisksAsync(TestProject.ProjectId, CancellationToken.None), TestProject.ProjectId); var adapter = new AuditLogAdapter(await credential); await adapter.ProcessInstanceEventsAsync( new[] { TestProject.ProjectId }, null, // all zones. null, // all instances. instanceBuilder.StartDate, instanceBuilder, CancellationToken.None); var set = instanceBuilder.Build(); var testInstanceHistory = set.Instances.FirstOrDefault(i => i.Reference == instanceRef); Assert.IsNotNull(testInstanceHistory, "Instance found in history"); }
public async Task WhenNonWhitelistedEnvironmentVariablePassed_ThenOpenShellChannelAsyncThrowsRequestDenied( [LinuxInstance] ResourceTask <InstanceLocator> instanceLocatorTask) { var endpoint = new IPEndPoint( await InstanceUtil.PublicIpAddressForInstanceAsync(await instanceLocatorTask), 22); using (var key = new RsaSshKey(new RSACng())) { await InstanceUtil.AddPublicKeyToMetadata( await instanceLocatorTask, "testuser", key).ConfigureAwait(true); using (var session = CreateSession()) using (var connection = session.Connect(endpoint)) using (var authSession = connection.Authenticate( "testuser", key, UnexpectedAuthenticationCallback)) { SshAssert.ThrowsNativeExceptionWithError( session, LIBSSH2_ERROR.CHANNEL_REQUEST_DENIED, () => authSession.OpenShellChannel( LIBSSH2_CHANNEL_EXTENDED_DATA.MERGE, DefaultTerminal, 80, 24, new[] { new EnvironmentVariable("FOO", "foo", true), new EnvironmentVariable("BAR", "bar", true) })); } } }
public async Task WhenNotBlocked_ThenEnableControlsTailing( [WindowsInstance] ResourceTask <InstanceLocator> testInstance, [Credential(Role = PredefinedRole.ComputeViewer)] ResourceTask <ICredential> credential) { var viewModel = CreateViewModel(await credential); var node = await CreateNode(testInstance, true); await viewModel.SwitchToModelAsync(node); Assert.IsNull(viewModel.TailCancellationTokenSource, "not tailing yet"); viewModel.IsTailBlocked = false; viewModel.IsTailEnabled = true; var tailCts = viewModel.TailCancellationTokenSource; Assert.IsNotNull(tailCts, "tailing"); viewModel.IsTailEnabled = false; // CTS cancelled => not tailing. Assert.IsTrue(tailCts.IsCancellationRequested, "tailing stopped"); Assert.IsNull(viewModel.TailCancellationTokenSource); }
public async Task WhenConnectingWithInvalidAccessToken_ThenReadingFailsWithUnauthorizedException ([LinuxInstance(InitializeScript = InstallApache)] ResourceTask <InstanceLocator> vm) { // NB. Fiddler might cause this test to fail. byte[] request = new ASCIIEncoding().GetBytes( "GET / HTTP/1.0\r\n\r\n"); var stream = new SshRelayStream( new IapTunnelingEndpoint( GoogleCredential.FromAccessToken("invalid"), await vm, 80, IapTunnelingEndpoint.DefaultNetworkInterface, TestProject.UserAgent)); await stream.WriteAsync(request, 0, request.Length, CancellationToken.None); AssertEx.ThrowsAggregateException <UnauthorizedException>(() => { byte[] buffer = new byte[64 * 1024]; stream.ReadAsync(buffer, 0, buffer.Length, CancellationToken.None).Wait(); }); }
public async Task WhenConnected_ThenPseudoterminalHasRightEncoding( [LinuxInstance] ResourceTask <InstanceLocator> instanceLocatorTask, [Credential(Role = PredefinedRole.ComputeInstanceAdminV1)] ResourceTask <ICredential> credential) { using (var pane = await ConnectSshTerminalPane( await instanceLocatorTask, await credential, new CultureInfo("en-AU"))) { await pane.SendAsync("locale;sleep 1;exit\n"); AwaitEvent <SessionEndedEvent>(); var buffer = pane.Terminal.GetBuffer(); StringAssert.Contains( "LC_ALL=en_AU.UTF-8", buffer); StringAssert.Contains( "LC_CTYPE=\"en_AU.UTF-8\"", buffer); } CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture; }
public async Task WhenLaunchingInstance_ThenInstanceSetupFinishedTextAppearsInStream( [WindowsInstance] ResourceTask <InstanceLocator> testInstance, [Credential(Role = PredefinedRole.ComputeViewer)] ResourceTask <ICredential> credential) { var adapter = new ComputeEngineAdapter(await credential); var stream = adapter.GetSerialPortOutput( await testInstance, 1); var startTime = DateTime.Now; while (DateTime.Now < startTime.AddMinutes(3)) { var log = await stream.ReadAsync(CancellationToken.None); if (log.Contains("Finished running startup scripts")) { return; } } Assert.Fail("Timeout waiting for serial console output to appear"); }
public async Task WhenSendingMessagesToEchoServer_ThenStatisticsAreUpdated( [LinuxInstance(InitializeScript = InitializeScripts.InstallEchoServer)] ResourceTask <InstanceLocator> vm, [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential, [Values( 1, (int)DataMessage.MaxDataLength, (int)DataMessage.MaxDataLength * 2)] int length) { var message = new byte[length]; FillArray(message); var locator = await vm; var listener = SshRelayListener.CreateLocalListener( new IapTunnelingEndpoint( await credential, await vm, 7, IapTunnelingEndpoint.DefaultNetworkInterface, TestProject.UserAgent), new AllowAllRelayPolicy()); listener.ClientAcceptLimit = 1; // Terminate after first connection. listener.ListenAsync(CancellationToken.None).ContinueWith(_ => { }); var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(new IPEndPoint(IPAddress.Loopback, listener.LocalPort)); var clientStreamStats = new ConnectionStatistics(); var clientStream = new SocketStream(socket, clientStreamStats); using (var tokenSource = new CancellationTokenSource()) { // Write full payload. await clientStream.WriteAsync(message, 0, message.Length, tokenSource.Token); Assert.AreEqual(length, clientStreamStats.BytesTransmitted); // Read entire response. var response = new byte[length]; int totalBytesRead = 0; while (true) { var bytesRead = await clientStream.ReadAsync( response, totalBytesRead, response.Length - totalBytesRead, tokenSource.Token); totalBytesRead += bytesRead; if (bytesRead == 0 || totalBytesRead >= length) { break; } } await clientStream.CloseAsync(tokenSource.Token); await Task.Delay(50); Assert.AreEqual(length, totalBytesRead, "bytes read"); Assert.AreEqual(length, clientStreamStats.BytesReceived, "client received"); Assert.AreEqual(length, listener.Statistics.BytesReceived, "server received"); Assert.AreEqual(length, listener.Statistics.BytesTransmitted, "server sent"); } }
public async Task WhenConnected_ThenActiveSessionIsSetAndTryActivateReturnsTrue( [LinuxInstance] ResourceTask <InstanceLocator> testInstance, [Credential(Role = PredefinedRole.ComputeInstanceAdminV1)] ResourceTask <ICredential> credential) { var locator = await testInstance; using (var key = new RsaSshKey(new RSACng())) using (var gceAdapter = new ComputeEngineAdapter( this.serviceProvider.GetService <IAuthorizationAdapter>())) using (var keyAdapter = new AuthorizedKeyService( this.serviceProvider.GetService <IAuthorizationAdapter>(), new ComputeEngineAdapter(await credential), new ResourceManagerAdapter(await credential), new Mock <IOsLoginService>().Object)) { var authorizedKey = await keyAdapter.AuthorizeKeyAsync( locator, key, TimeSpan.FromMinutes(10), null, AuthorizeKeyMethods.InstanceMetadata, CancellationToken.None) .ConfigureAwait(true); var instance = await gceAdapter.GetInstanceAsync( locator, CancellationToken.None) .ConfigureAwait(true); // Connect var broker = new SshTerminalSessionBroker(this.serviceProvider); ISshTerminalSession session = null; await AssertRaisesEventAsync <SessionStartedEvent>( async() => session = await broker.ConnectAsync( locator, new IPEndPoint(instance.PublicAddress(), 22), authorizedKey)); Assert.IsNull(this.ExceptionShown); // Verify session is connected. Assert.IsTrue(broker.IsConnected(locator)); Assert.AreSame(session, broker.ActiveSession); Assert.IsTrue(broker.TryActivate(locator)); // Verify dummy session is not connected. Assert.IsFalse(broker.TryActivate(SampleLocator)); Assert.IsFalse(broker.IsConnected(SampleLocator)); Assert.IsTrue(broker.IsConnected(locator)); Assert.AreSame(session, broker.ActiveSession); Assert.IsTrue(broker.TryActivate(locator)); Assert.IsFalse(broker.TryActivate(SampleLocator)); Assert.IsFalse(broker.IsConnected(SampleLocator)); AssertRaisesEvent <SessionEndedEvent>( () => session.Close()); //await AssertRaisesEventAsync<SessionEndedEvent>( // async () => await session.DisconnectAsync()); } }
public async Task WhenCredentialsValid_ThenConnectingSucceeds( [Values(RdpConnectionBarState.AutoHide, RdpConnectionBarState.Off, RdpConnectionBarState.Pinned)] RdpConnectionBarState connectionBarState, [Values(RdpDesktopSize.ClientSize, RdpDesktopSize.ScreenSize)] RdpDesktopSize desktopSize, [Values(RdpAudioMode.DoNotPlay, RdpAudioMode.PlayLocally, RdpAudioMode.PlayOnServer)] RdpAudioMode audioMode, [Values(RdpRedirectClipboard.Disabled, RdpRedirectClipboard.Enabled)] RdpRedirectClipboard redirectClipboard, // Use a slightly larger machine type as all this RDP'ing consumes a fair // amount of memory. [WindowsInstance(MachineType = "n1-standard-2")] ResourceTask <InstanceLocator> testInstance, [Credential(Role = PredefinedRole.IapTunnelUser)] ResourceTask <ICredential> credential) { var locator = await testInstance; using (var tunnel = RdpTunnel.Create( locator, await credential)) using (var gceAdapter = new ComputeEngineAdapter(this.serviceProvider.GetService <IAuthorizationAdapter>())) { var credentials = await gceAdapter.ResetWindowsUserAsync( locator, CreateRandomUsername(), TimeSpan.FromSeconds(60), CancellationToken.None); var settings = VmInstanceConnectionSettings.CreateNew( locator.ProjectId, locator.Name); settings.Username.StringValue = credentials.UserName; settings.Password.Value = credentials.SecurePassword; settings.ConnectionBar.EnumValue = connectionBarState; settings.DesktopSize.EnumValue = desktopSize; settings.AudioMode.EnumValue = audioMode; settings.RedirectClipboard.EnumValue = redirectClipboard; settings.AuthenticationLevel.EnumValue = RdpAuthenticationLevel.NoServerAuthentication; settings.BitmapPersistence.EnumValue = RdpBitmapPersistence.Disabled; var rdpService = new RemoteDesktopConnectionBroker(this.serviceProvider); var session = rdpService.Connect( locator, "localhost", (ushort)tunnel.LocalPort, settings); AwaitEvent <ConnectionSuceededEvent>(); Assert.IsNull(this.ExceptionShown); ConnectionClosedEvent expectedEvent = null; this.serviceProvider.GetService <IEventService>() .BindHandler <ConnectionClosedEvent>(e => { expectedEvent = e; }); session.Close(); Assert.IsNotNull(expectedEvent); } }
public static void Main(string[] args) { var tasks = new ResourceTask[] { // test new ResourceTask { N = 3, C = 6, F = new Func <int, int>[] { (x) => new int[] { 0, 3, 4, 5, 8, 9, 10 }[x], (x) => new int[] { 0, 2, 3, 7, 9, 12, 13 }[x], (x) => new int[] { 0, 1, 2, 6, 11, 11, 13 }[x], } }, // 1 new ResourceTask { N = 3, C = 6, F = new Func <int, int>[] { (x) => new int[] { 0, 1, 2, 2, 4, 5, 6 }[x], (x) => new int[] { 0, 2, 3, 5, 7, 7, 8 }[x], (x) => new int[] { 0, 2, 4, 5, 6, 7, 7 }[x], } }, // 2 new ResourceTask { N = 3, C = 6, F = new Func <int, int>[] { (x) => new int[] { 0, 1, 1, 3, 6, 10, 11 }[x], (x) => new int[] { 0, 2, 3, 5, 6, 7, 13 }[x], (x) => new int[] { 0, 1, 4, 4, 7, 8, 9 }[x], } }, // 3 new ResourceTask { N = 3, C = 7, F = new Func <int, int>[] { (x) => new int[] { 0, 1, 2, 4, 8, 9, 9, 23 }[x], (x) => new int[] { 0, 2, 4, 6, 6, 8, 10, 11 }[x], (x) => new int[] { 0, 3, 4, 7, 7, 8, 8, 24 }[x], } }, // 4 new ResourceTask { N = 3, C = 7, F = new Func <int, int>[] { (x) => new int[] { 0, 3, 3, 6, 7, 8, 9, 14 }[x], (x) => new int[] { 0, 2, 4, 4, 5, 6, 8, 13 }[x], (x) => new int[] { 0, 1, 1, 2, 3, 3, 10, 11 }[x], } }, // 5 new ResourceTask { N = 4, C = 8, F = new Func <int, int>[] { (x) => new int[] { 0, 2, 2, 3, 5, 8, 8, 10, 17 }[x], (x) => new int[] { 0, 1, 2, 5, 8, 10, 11, 13, 15 }[x], (x) => new int[] { 0, 4, 4, 5, 6, 7, 13, 14, 14 }[x], (x) => new int[] { 0, 1, 3, 6, 9, 10, 11, 14, 16 }[x], } }, // 6 new ResourceTask { N = 4, C = 11, F = new Func <int, int>[] { (x) => new int[] { 0, 1, 3, 4, 5, 8, 9, 9, 11, 12, 12, 14 }[x], (x) => new int[] { 0, 1, 2, 3, 3, 3, 7, 12, 13, 14, 17, 19 }[x], (x) => new int[] { 0, 4, 4, 7, 7, 8, 12, 14, 14, 16, 18, 22 }[x], (x) => new int[] { 0, 5, 5, 5, 7, 9, 13, 13, 15, 15, 19, 24 }[x], } }, // 7 new ResourceTask { N = 5, C = 11, F = new Func <int, int>[] { (x) => new int[] { 0, 4, 4, 6, 9, 12, 12, 15, 16, 19, 19, 19 }[x], (x) => new int[] { 0, 1, 1, 1, 4, 7, 8, 8, 13, 13, 19, 20 }[x], (x) => new int[] { 0, 2, 5, 6, 7, 8, 9, 11, 11, 13, 13, 18 }[x], (x) => new int[] { 0, 1, 2, 4, 5, 7, 8, 8, 9, 9, 15, 19 }[x], (x) => new int[] { 0, 2, 5, 7, 8, 9, 10, 10, 11, 14, 17, 21 }[x], } }, // 8 new ResourceTask { N = 6, C = 10, F = new Func <int, int>[] { (x) => new int[] { 0, 1, 2, 2, 2, 3, 5, 8, 9, 13, 14 }[x], (x) => new int[] { 0, 1, 3, 4, 5, 5, 5, 7, 7, 10, 12, 12 }[x], (x) => new int[] { 0, 2, 2, 3, 4, 6, 6, 8, 9, 11, 17 }[x], (x) => new int[] { 0, 1, 1, 1, 2, 3, 9, 9, 11, 12, 15 }[x], (x) => new int[] { 0, 2, 7, 7, 7, 9, 9, 10, 11, 12, 13 }[x], (x) => new int[] { 0, 2, 5, 5, 5, 6, 6, 7, 12, 18, 22 }[x], } }, }; Console.WriteLine(tasks [7].SolveBellman()); }
public static void UpdateResourceTask(this IMemoryCache cache, UserChat userChat, ResourceTask task) { cache.Set(GetKey(userChat, "task"), task); }