LimitsCheckingWorkspaceManager extends WorkspaceManager { @VisibleForTesting void checkRamResourcesAvailability( String accountId, String namespace, WorkspaceConfig config, @Nullable String envName) throws NotFoundException, ServerException, ConflictException { if (config.getEnvironments().isEmpty()) { return; } final Environment environment = config.getEnvironments().get(firstNonNull(envName, config.getDefaultEnv())); final ResourceImpl ramToUse = new ResourceImpl( RamResourceType.ID, environmentRamCalculator.calculate(environment), RamResourceType.UNIT); try { resourceManager.checkResourcesAvailability(accountId, singletonList(ramToUse)); } catch (NoEnoughResourcesException e) { final Resource requiredRam = e.getRequiredResources().get(0); final Resource availableRam = getResourceOrDefault( e.getAvailableResources(), RamResourceType.ID, 0, RamResourceType.UNIT); final Resource usedRam = getResourceOrDefault( resourceManager.getUsedResources(accountId), RamResourceType.ID, 0, RamResourceType.UNIT); throw new LimitExceededException( format( "Workspace %s/%s needs %s to start. Your account has %s available and %s in use. " + "The workspace can't be start. Stop other workspaces or grant more resources.", namespace, config.getName(), printResourceInfo(requiredRam), printResourceInfo(availableRam), printResourceInfo(usedRam))); } } @Inject  LimitsCheckingWorkspaceManager(
      WorkspaceDao workspaceDao,
      WorkspaceRuntimes runtimes,
      EventService eventService,
      AccountManager accountManager,
      PreferenceManager preferenceManager,
      WorkspaceValidator workspaceValidator,
      // own injects
      @Named("che.limits.workspace.env.ram") String maxRamPerEnv,
      EnvironmentRamCalculator environmentRamCalculator,
      ResourceManager resourceManager,
      ResourcesLocks resourcesLocks,
      DevfileIntegrityValidator devfileIntegrityValidator); @Override @Traced WorkspaceImpl createWorkspace(
      WorkspaceConfig config, String namespace, @Nullable Map<String, String> attributes); @Override WorkspaceImpl startWorkspace(
      String workspaceId, @Nullable String envName, @Nullable Map<String, String> options); @Override WorkspaceImpl startWorkspace(
      WorkspaceConfig config, String namespace, boolean isTemporary, Map<String, String> options); @Override WorkspaceImpl updateWorkspace(String id, Workspace update);  }
@Test public void shouldUseRamOfSpecifiedEnvironmentOnCheckingAvailabilityOfRamResource() throws Exception { LimitsCheckingWorkspaceManager manager = managerBuilder() .setResourceManager(resourceManager) .setEnvironmentRamCalculator(environmentRamCalculator) .build(); when(environmentRamCalculator.calculate(any(Environment.class))).thenReturn(3000L); WorkspaceConfig config = createConfig("3gb"); String envToStart = config.getDefaultEnv(); manager.checkRamResourcesAvailability(ACCOUNT_ID, NAMESPACE, config, envToStart); verify(environmentRamCalculator).calculate(config.getEnvironments().get(envToStart)); verify(resourceManager) .checkResourcesAvailability( ACCOUNT_ID, singletonList(new ResourceImpl(RamResourceType.ID, 3000, RamResourceType.UNIT))); }
@Test public void shouldUseRamOfDefaultEnvironmentOnCheckingAvailabilityOfRamResourceWhen() throws Exception { LimitsCheckingWorkspaceManager manager = managerBuilder() .setResourceManager(resourceManager) .setEnvironmentRamCalculator(environmentRamCalculator) .build(); when(environmentRamCalculator.calculate(any(Environment.class))).thenReturn(3000L); WorkspaceConfig config = createConfig("3gb"); manager.checkRamResourcesAvailability(ACCOUNT_ID, NAMESPACE, config, null); verify(environmentRamCalculator) .calculate(config.getEnvironments().get(config.getDefaultEnv())); verify(resourceManager) .checkResourcesAvailability( ACCOUNT_ID, singletonList(new ResourceImpl(RamResourceType.ID, 3000, RamResourceType.UNIT))); }
@Test( expectedExceptions = LimitExceededException.class, expectedExceptionsMessageRegExp = "Workspace namespace/workspace.. needs 3000MB to start\\. " + "Your account has 200MB available and 100MB in use\\. " + "The workspace can't be start. Stop other workspaces or grant more resources\\.") public void shouldThrowLimitExceedExceptionIfAccountDoesNotHaveEnoughAvailableRamResource() throws Exception { doThrow( new NoEnoughResourcesException( singletonList(new ResourceImpl(RamResourceType.ID, 200L, RamResourceType.UNIT)), singletonList(new ResourceImpl(RamResourceType.ID, 3000L, RamResourceType.UNIT)), emptyList())) .when(resourceManager) .checkResourcesAvailability(any(), any()); doReturn(singletonList(new ResourceImpl(RamResourceType.ID, 100L, RamResourceType.UNIT))) .when(resourceManager) .getUsedResources(any()); LimitsCheckingWorkspaceManager manager = managerBuilder() .setResourceManager(resourceManager) .setEnvironmentRamCalculator(environmentRamCalculator) .build(); when(environmentRamCalculator.calculate(any(Environment.class))).thenReturn(3000L); WorkspaceConfig config = createConfig("3gb"); manager.checkRamResourcesAvailability(ACCOUNT_ID, NAMESPACE, config, null); }