text:
package com.sequenceiq.redbeams.converter.stack;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Answers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.springframework.test.util.ReflectionTestUtils;

import com.sequenceiq.cloudbreak.api.endpoint.v4.common.DatabaseVendor;
import com.sequenceiq.cloudbreak.auth.CrnUser;
import com.sequenceiq.cloudbreak.auth.altus.EntitlementService;
import com.sequenceiq.cloudbreak.auth.crn.Crn;
import com.sequenceiq.cloudbreak.auth.crn.CrnTestUtil;
import com.sequenceiq.cloudbreak.auth.security.CrnUserDetailsService;
import com.sequenceiq.cloudbreak.cloud.model.CloudSubnet;
import com.sequenceiq.cloudbreak.cloud.model.StackTags;
import com.sequenceiq.cloudbreak.common.exception.BadRequestException;
import com.sequenceiq.cloudbreak.common.mappable.CloudPlatform;
import com.sequenceiq.cloudbreak.common.mappable.MappableBase;
import com.sequenceiq.cloudbreak.common.mappable.ProviderParameterCalculator;
import com.sequenceiq.cloudbreak.common.mappable.ProviderParametersBase;
import com.sequenceiq.cloudbreak.common.service.Clock;
import com.sequenceiq.cloudbreak.tag.CostTagging;
import com.sequenceiq.environment.api.v1.environment.model.response.DetailedEnvironmentResponse;
import com.sequenceiq.environment.api.v1.environment.model.response.EnvironmentNetworkResponse;
import com.sequenceiq.environment.api.v1.environment.model.response.LocationResponse;
import com.sequenceiq.environment.api.v1.environment.model.response.SecurityAccessResponse;
import com.sequenceiq.environment.api.v1.environment.model.response.TagResponse;
import com.sequenceiq.redbeams.api.endpoint.v4.databaseserver.requests.AllocateDatabaseServerV4Request;
import com.sequenceiq.redbeams.api.endpoint.v4.databaseserver.requests.SslConfigV4Request;
import com.sequenceiq.redbeams.api.endpoint.v4.databaseserver.requests.SslMode;
import com.sequenceiq.redbeams.api.endpoint.v4.databaseserver.responses.SslCertificateType;
import com.sequenceiq.redbeams.api.endpoint.v4.stacks.DatabaseServerV4StackRequest;
import com.sequenceiq.redbeams.api.endpoint.v4.stacks.NetworkV4StackRequest;
import com.sequenceiq.redbeams.api.endpoint.v4.stacks.SecurityGroupV4StackRequest;
import com.sequenceiq.redbeams.api.endpoint.v4.stacks.aws.AwsNetworkV4Parameters;
import com.sequenceiq.redbeams.api.model.common.DetailedDBStackStatus;
import com.sequenceiq.redbeams.api.model.common.Status;
import com.sequenceiq.redbeams.configuration.DatabaseServerSslCertificateConfig;
import com.sequenceiq.redbeams.configuration.SslCertificateEntry;
import com.sequenceiq.redbeams.domain.stack.DBStack;
import com.sequenceiq.redbeams.domain.stack.Network;
import com.sequenceiq.redbeams.domain.stack.SslConfig;
import com.sequenceiq.redbeams.service.AccountTagService;
import com.sequenceiq.redbeams.service.EnvironmentService;
import com.sequenceiq.redbeams.service.PasswordGeneratorService;
import com.sequenceiq.redbeams.service.UserGeneratorService;
import com.sequenceiq.redbeams.service.UuidGeneratorService;
import com.sequenceiq.redbeams.service.crn.CrnService;
import com.sequenceiq.redbeams.service.network.NetworkBuilderService;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class AllocateDatabaseServerV4RequestToDBStackConverterTest {

    private static final String OWNER_CRN = "crn:cdp:iam:us-west-1:cloudera:user:external/bob@cloudera.com";

    private static final String ENVIRONMENT_CRN = "myenv";

    private static final String CLUSTER_CRN = "crn:cdp:datahub:us-west-1:cloudera:stack:id";

    private static final String ENVIRONMENT_NAME = "myenv-amazing-env";

    private static final Instant NOW = Instant.now();

    private static final Map<String, Object> ALLOCATE_REQUEST_PARAMETERS = Map.of("key", "value");

    private static final Map<String, Object> SUBNET_ID_REQUEST_PARAMETERS = Map.of("netkey", "netvalue");

    private static final String PASSWORD = "password";

    private static final String USERNAME = "username";

    private static final String DEFAULT_SECURITY_GROUP_ID = "defaultSecurityGroupId";

    private static final String UNKNOWN_CLOUD_PLATFORM = "UnknownCloudPlatform";

    private static final String USER_EMAIL = "userEmail";

    private static final CloudPlatform AWS_CLOUD_PLATFORM = CloudPlatform.AWS;

    private static final CloudPlatform AZURE_CLOUD_PLATFORM = CloudPlatform.AZURE;

    private static final String CLOUD_PROVIDER_IDENTIFIER_V2 = "cert-id-2";

    private static final String CLOUD_PROVIDER_IDENTIFIER_V3 = "cert-id-3";

    private static final String CERT_PEM_V2 = "super-cert-2";

    private static final String CERT_PEM_V3 = "super-cert-3";

    private static final String REGION = "myRegion";

    private static final String DATABASE_VENDOR = "postgres";

    private static final String REDBEAMS_DB_MAJOR_VERSION = "10";

    private static final String FIELD_DB_SERVICE_SUPPORTED_PLATFORMS = "dbServiceSupportedPlatforms";

    private static final String FIELD_REDBEAMS_DB_MAJOR_VERSION = "redbeamsDbMajorVersion";

    private static final String FIELD_SSL_ENABLED = "sslEnabled";

    private static final int MAX_VERSION = 3;

    private static final int VERSION_1 = 1;

    private static final int VERSION_2 = 2;

    private static final int VERSION_3 = 3;

    private static final int NO_CERTS = 0;

    private static final int SINGLE_CERT = 1;

    private static final int TWO_CERTS = 2;

    private static final int THREE_CERTS = 3;

    @Mock
    private EnvironmentService environmentService;

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private ProviderParameterCalculator providerParameterCalculator;

    @Mock
    private Clock clock;

    @Mock
    private UserGeneratorService userGeneratorService;

    @Mock
    private PasswordGeneratorService passwordGeneratorService;

    @Mock
    private UuidGeneratorService uuidGeneratorService;

    @Mock
    private CrnUserDetailsService crnUserDetailsService;

    @Mock
    private CostTagging costTagging;

    @Mock
    private CrnService crnService;

    @Mock
    private EntitlementService entitlementService;

    @Mock
    private AccountTagService accountTagService;

    @Mock
    private DatabaseServerSslCertificateConfig databaseServerSslCertificateConfig;

    @Mock
    private X509Certificate x509Certificate;

    @Mock
    private NetworkBuilderService networkBuilderService;

    @InjectMocks
    private AllocateDatabaseServerV4RequestToDBStackConverter underTest;

    private AllocateDatabaseServerV4Request allocateRequest;

    private NetworkV4StackRequest networkRequest;

    private DatabaseServerV4StackRequest databaseServerRequest;

    private SecurityGroupV4StackRequest securityGroupRequest;

    private SslCertificateEntry sslCertificateEntryV2;

    private SslCertificateEntry sslCertificateEntryV3;

    @BeforeEach
    public void setUp() {
        ReflectionTestUtils.setField(underTest, FIELD_DB_SERVICE_SUPPORTED_PLATFORMS, Set.of("AWS", "AZURE"));
        ReflectionTestUtils.setField(underTest, FIELD_REDBEAMS_DB_MAJOR_VERSION, REDBEAMS_DB_MAJOR_VERSION);
        ReflectionTestUtils.setField(underTest, FIELD_SSL_ENABLED, true);

        allocateRequest = new AllocateDatabaseServerV4Request();

        networkRequest = new NetworkV4StackRequest();
        allocateRequest.setNetwork(networkRequest);

        databaseServerRequest = new DatabaseServerV4StackRequest();
        allocateRequest.setDatabaseServer(databaseServerRequest);

        securityGroupRequest = new SecurityGroupV4StackRequest();
        databaseServerRequest.setSecurityGroup(securityGroupRequest);

        when(crnUserDetailsService.loadUserByUsername(OWNER_CRN)).thenReturn(getCrnUser());
        when(uuidGeneratorService.randomUuid()).thenReturn("uuid");
        when(accountTagService.list()).thenReturn(new HashMap<>());
        when(uuidGeneratorService.uuidVariableParts(anyInt())).thenReturn("parts");
        when(entitlementService.internalTenant(anyString())).thenReturn(true);

        sslCertificateEntryV2 = new SslCertificateEntry(VERSION_2, CLOUD_PROVIDER_IDENTIFIER_V2, CERT_PEM_V2, x509Certificate);
        sslCertificateEntryV3 = new SslCertificateEntry(VERSION_3, CLOUD_PROVIDER_IDENTIFIER_V3, CERT_PEM_V3, x509Certificate);
        when(databaseServerSslCertificateConfig.getMaxVersionByCloudPlatformAndRegion(anyString(), eq(REGION))).thenReturn(MAX_VERSION);

        when(clock.getCurrentInstant()).thenReturn(NOW);
        when(crnService.createCrn(any(DBStack.class))).thenReturn(CrnTestUtil.getDatabaseServerCrnBuilder()
                .setAccountId("accountid")
                .setResource("1")
                .build());
    }

    @Test
    void conversionTestWhenOptionalElementsAreProvided() throws IOException {
        setupAllocateRequest(true);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AWS_CLOUD_PLATFORM.name(), REGION)).thenReturn(SINGLE_CERT);
        when(databaseServerSslCertificateConfig.getCertByCloudPlatformAndRegionAndVersion(AWS_CLOUD_PLATFORM.name(), REGION, VERSION_3))
                .thenReturn(sslCertificateEntryV3);

        DetailedEnvironmentResponse environment = DetailedEnvironmentResponse.builder()
                .withCloudPlatform(AWS_CLOUD_PLATFORM.name())
                .withCrn(ENVIRONMENT_CRN)
                .withLocation(LocationResponse.LocationResponseBuilder.aLocationResponse().withName(REGION).build())
                .withName(ENVIRONMENT_NAME)
                .withTag(new TagResponse())
                .build();
        when(environmentService.getByCrn(ENVIRONMENT_CRN)).thenReturn(environment);
        Network network = new Network();
        when(networkBuilderService.buildNetwork(eq(networkRequest), eq(environment), eq(AWS_CLOUD_PLATFORM), any(DBStack.class))).thenReturn(network);
        DBStack dbStack = underTest.convert(allocateRequest, OWNER_CRN);

        assertEquals(allocateRequest.getName(), dbStack.getName());
        assertEquals(allocateRequest.getEnvironmentCrn(), dbStack.getEnvironmentId());
        assertEquals(REGION, dbStack.getRegion());
        assertEquals(AWS_CLOUD_PLATFORM.name(), dbStack.getCloudPlatform());
        assertEquals(AWS_CLOUD_PLATFORM.name(), dbStack.getPlatformVariant());
        assertEquals(1, dbStack.getParameters().size());
        assertEquals("value", dbStack.getParameters().get("key"));
        assertEquals(Crn.safeFromString(OWNER_CRN), dbStack.getOwnerCrn());
        assertEquals(USER_EMAIL, dbStack.getUserName());
        assertEquals(Status.REQUESTED, dbStack.getStatus());
        assertEquals(DetailedDBStackStatus.PROVISION_REQUESTED, dbStack.getDbStackStatus().getDetailedDBStackStatus());
        assertEquals(NOW.toEpochMilli(), dbStack.getDbStackStatus().getCreated().longValue());
        assertEquals("dbsvr-uuid", dbStack.getDatabaseServer().getName());
        assertEquals(databaseServerRequest.getInstanceType(), dbStack.getDatabaseServer().getInstanceType());
        assertEquals(DatabaseVendor.fromValue(databaseServerRequest.getDatabaseVendor()), dbStack.getDatabaseServer().getDatabaseVendor());
        assertEquals("org.postgresql.Driver", dbStack.getDatabaseServer().getConnectionDriver());
        assertEquals(databaseServerRequest.getStorageSize(), dbStack.getDatabaseServer().getStorageSize());
        assertEquals(databaseServerRequest.getRootUserName(), dbStack.getDatabaseServer().getRootUserName());
        assertEquals(databaseServerRequest.getRootUserPassword(), dbStack.getDatabaseServer().getRootPassword());
        assertEquals(2, dbStack.getDatabaseServer().getAttributes().getMap().size());
        assertEquals("dbvalue", dbStack.getDatabaseServer().getAttributes().getMap().get("dbkey"));
        assertEquals(REDBEAMS_DB_MAJOR_VERSION, dbStack.getDatabaseServer().getAttributes().getMap().get("engineVersion"));
        assertEquals(securityGroupRequest.getSecurityGroupIds(), dbStack.getDatabaseServer().getSecurityGroup().getSecurityGroupIds());
        assertEquals(network, dbStack.getNetwork());
        assertEquals(dbStack.getTags().get(StackTags.class).getUserDefinedTags().get("DistroXKey1"), "DistroXValue1");

        verifySsl(dbStack, Set.of(CERT_PEM_V3), CLOUD_PROVIDER_IDENTIFIER_V3);
        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());

        verify(providerParameterCalculator).get(allocateRequest);
        verify(userGeneratorService, never()).generateUserName();
        verify(passwordGeneratorService, never()).generatePassword(any());
    }

    private CrnUser getCrnUser() {
        return new CrnUser("", "", "", USER_EMAIL, "", "");
    }

    @Test
    void conversionTestWhenOptionalElementsGenerated() throws IOException {
        setupAllocateRequest(false);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AWS_CLOUD_PLATFORM.name(), REGION)).thenReturn(SINGLE_CERT);
        when(databaseServerSslCertificateConfig.getCertByCloudPlatformAndRegionAndVersion(AWS_CLOUD_PLATFORM.name(), REGION, VERSION_3))
                .thenReturn(sslCertificateEntryV3);

        List<CloudSubnet> cloudSubnets = List.of(
                new CloudSubnet("subnet-1", "", "az-a", ""),
                new CloudSubnet("subnet-2", "", "az-b", "")
        );
        DetailedEnvironmentResponse environment = DetailedEnvironmentResponse.builder()
                .withCloudPlatform(AWS_CLOUD_PLATFORM.name())
                .withName(ENVIRONMENT_NAME)
                .withCrn(ENVIRONMENT_CRN)
                .withTag(new TagResponse())
                .withLocation(LocationResponse.LocationResponseBuilder.aLocationResponse().withName(REGION).build())
                .withSecurityAccess(SecurityAccessResponse.builder().withDefaultSecurityGroupId(DEFAULT_SECURITY_GROUP_ID).build())
                .withNetwork(EnvironmentNetworkResponse.builder()
                        .withSubnetMetas(
                                Map.of(
                                        "subnet-1", cloudSubnets.get(0),
                                        "subnet-2", cloudSubnets.get(1)
                                )
                        )
                        .build())
                .build();
        when(environmentService.getByCrn(ENVIRONMENT_CRN)).thenReturn(environment);
        when(userGeneratorService.generateUserName()).thenReturn(USERNAME);
        when(passwordGeneratorService.generatePassword(any())).thenReturn(PASSWORD);

        DBStack dbStack = underTest.convert(allocateRequest, OWNER_CRN);

        assertEquals(ENVIRONMENT_NAME + "-dbstck-parts", dbStack.getName());
        assertEquals(PASSWORD, dbStack.getDatabaseServer().getRootPassword());
        assertEquals(USERNAME, dbStack.getDatabaseServer().getRootUserName());
        assertThat(dbStack.getDatabaseServer().getSecurityGroup().getSecurityGroupIds()).hasSize(1);
        assertEquals(dbStack.getDatabaseServer().getSecurityGroup().getSecurityGroupIds().iterator().next(), DEFAULT_SECURITY_GROUP_ID);
        assertEquals(dbStack.getTags().get(StackTags.class).getUserDefinedTags().get("DistroXKey1"), "DistroXValue1");

        verifySsl(dbStack, Set.of(CERT_PEM_V3), CLOUD_PROVIDER_IDENTIFIER_V3);
        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());

        verify(providerParameterCalculator).get(allocateRequest);
        verify(providerParameterCalculator, never()).get(networkRequest);
        verify(userGeneratorService).generateUserName();
        verify(passwordGeneratorService).generatePassword(any());
    }

    @Test
    void conversionTestWhenRequestAndEnvironmentCloudPlatformsDiffer() {
        allocateRequest.setCloudPlatform(AWS_CLOUD_PLATFORM);
        allocateRequest.setTags(new HashMap<>());
        allocateRequest.setEnvironmentCrn(ENVIRONMENT_CRN);
        DetailedEnvironmentResponse environment = DetailedEnvironmentResponse.builder()
                .withCloudPlatform(UNKNOWN_CLOUD_PLATFORM)
                .build();
        when(environmentService.getByCrn(ENVIRONMENT_CRN)).thenReturn(environment);

        BadRequestException badRequestException = assertThrows(BadRequestException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));

        assertThat(badRequestException).hasMessage("Cloud platform of the request AWS and the environment " + UNKNOWN_CLOUD_PLATFORM + " do not match.");
    }

    @Test
    void conversionTestWhenUnsupportedCloudPlatform() {
        allocateRequest.setCloudPlatform(CloudPlatform.YARN);
        allocateRequest.setTags(new HashMap<>());
        allocateRequest.setEnvironmentCrn(ENVIRONMENT_CRN);
        DetailedEnvironmentResponse environment = DetailedEnvironmentResponse.builder()
                .withCloudPlatform(CloudPlatform.YARN.name())
                .build();
        when(environmentService.getByCrn(ENVIRONMENT_CRN)).thenReturn(environment);

        BadRequestException badRequestException = assertThrows(BadRequestException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));

        assertThat(badRequestException).hasMessage("Cloud platform YARN not supported yet.");
    }

    static Object[][] conversionTestWhenSslDisabledDataProvider() {
        return new Object[][]{
                // testCaseName fieldSslEnabled sslConfigV4Request
                {"false, null", false, null},
                {"true, null", true, null},
                {"false, request with sslMode=null", false, new SslConfigV4Request()},
                {"true, request with sslMode=null", true, new SslConfigV4Request()},
                {"false, request with sslMode=DISABLED", false, createSslConfigV4Request(SslMode.DISABLED)},
                {"true, request with sslMode=DISABLED", true, createSslConfigV4Request(SslMode.DISABLED)},
                {"false, request with sslMode=ENABLED", false, createSslConfigV4Request(SslMode.ENABLED)},
        };
    }

    @ParameterizedTest(name = "{0}")
    @MethodSource("conversionTestWhenSslDisabledDataProvider")
    void conversionTestWhenSslDisabled(String testCaseName, boolean fieldSslEnabled, SslConfigV4Request sslConfigV4Request) {
        setupMinimalValid(sslConfigV4Request, AWS_CLOUD_PLATFORM);
        ReflectionTestUtils.setField(underTest, FIELD_SSL_ENABLED, fieldSslEnabled);

        DBStack dbStack = underTest.convert(allocateRequest, OWNER_CRN);

        SslConfig sslConfig = dbStack.getSslConfig();
        assertThat(sslConfig).isNotNull();
        Set<String> sslCertificates = sslConfig.getSslCertificates();
        assertThat(sslCertificates).isNotNull();
        assertThat(sslCertificates).isEmpty();
        assertThat(sslConfig.getSslCertificateType()).isEqualTo(SslCertificateType.NONE);
    }

    private void setupMinimalValid(SslConfigV4Request sslConfigV4Request, CloudPlatform cloudPlatform) {
        allocateRequest.setEnvironmentCrn(ENVIRONMENT_CRN);
        allocateRequest.setTags(new HashMap<>());
        allocateRequest.setClusterCrn(CLUSTER_CRN);
        allocateRequest.setSslConfig(sslConfigV4Request);

        DetailedEnvironmentResponse environment = DetailedEnvironmentResponse.builder()
                .withCloudPlatform(cloudPlatform.name())
                .withCrn(ENVIRONMENT_CRN)
                .withLocation(LocationResponse.LocationResponseBuilder.aLocationResponse().withName(REGION).build())
                .withName(ENVIRONMENT_NAME)
                .withTag(new TagResponse())
                .build();
        when(environmentService.getByCrn(ENVIRONMENT_CRN)).thenReturn(environment);

        databaseServerRequest.setDatabaseVendor(DATABASE_VENDOR);
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndNoCerts() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AWS_CLOUD_PLATFORM.name(), REGION)).thenReturn(NO_CERTS);

        DBStack dbStack = underTest.convert(allocateRequest, OWNER_CRN);

        verifySsl(dbStack, Set.of(), null);

        verify(databaseServerSslCertificateConfig, never()).getCertByCloudPlatformAndRegionAndVersion(anyString(), anyString(), anyInt());
        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndSingleCert() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        conversionTestWhenSslEnabledAndSingleCertReturnedInternal(AWS_CLOUD_PLATFORM.name(), SINGLE_CERT);
    }

    private void conversionTestWhenSslEnabledAndSingleCertReturnedInternal(String cloudPlatform, int numOfCerts) {
        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(cloudPlatform, REGION)).thenReturn(numOfCerts);
        when(databaseServerSslCertificateConfig.getCertByCloudPlatformAndRegionAndVersion(cloudPlatform, REGION, VERSION_3)).thenReturn(sslCertificateEntryV3);

        DBStack dbStack = underTest.convert(allocateRequest, OWNER_CRN);

        verifySsl(dbStack, Set.of(CERT_PEM_V3), CLOUD_PROVIDER_IDENTIFIER_V3);

        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndSingleCertErrorNullCert() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AWS_CLOUD_PLATFORM.name(), REGION)).thenReturn(SINGLE_CERT);
        when(databaseServerSslCertificateConfig.getCertByCloudPlatformAndRegionAndVersion(AWS_CLOUD_PLATFORM.name(), REGION, VERSION_3)).thenReturn(null);

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException).hasMessage("Could not find SSL certificate version 3 for cloud platform \"AWS\"");

        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndSingleCertErrorVersionMismatch() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AWS_CLOUD_PLATFORM.name(), REGION)).thenReturn(SINGLE_CERT);
        when(databaseServerSslCertificateConfig.getCertByCloudPlatformAndRegionAndVersion(AWS_CLOUD_PLATFORM.name(), REGION, VERSION_3))
                .thenReturn(sslCertificateEntryV2);

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException).hasMessage("SSL certificate version mismatch for cloud platform \"AWS\": expected=3, actual=2");

        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndSingleCertErrorBlankCloudProviderIdentifier() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AWS_CLOUD_PLATFORM.name(), REGION)).thenReturn(SINGLE_CERT);
        SslCertificateEntry sslCertificateEntryV3Broken = new SslCertificateEntry(VERSION_3, "", CERT_PEM_V3, x509Certificate);
        when(databaseServerSslCertificateConfig.getCertByCloudPlatformAndRegionAndVersion(AWS_CLOUD_PLATFORM.name(), REGION, VERSION_3))
                .thenReturn(sslCertificateEntryV3Broken);

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException).hasMessage("Blank CloudProviderIdentifier in SSL certificate version 3 for cloud platform \"AWS\"");

        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndSingleCertErrorBlankPem() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AWS_CLOUD_PLATFORM.name(), REGION)).thenReturn(SINGLE_CERT);
        SslCertificateEntry sslCertificateEntryV3Broken = new SslCertificateEntry(VERSION_3, CLOUD_PROVIDER_IDENTIFIER_V3, "", x509Certificate);
        when(databaseServerSslCertificateConfig.getCertByCloudPlatformAndRegionAndVersion(AWS_CLOUD_PLATFORM.name(), REGION, VERSION_3))
                .thenReturn(sslCertificateEntryV3Broken);

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException).hasMessage("Blank PEM in SSL certificate version 3 for cloud platform \"AWS\"");

        verify(databaseServerSslCertificateConfig, never()).getCertsByCloudPlatformAndRegionAndVersions(anyString(), anyString(), any());
    }

    @Test
    void conversionTestWhenSslEnabledAndAzureAndSingleCert() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AZURE_CLOUD_PLATFORM);

        conversionTestWhenSslEnabledAndSingleCertReturnedInternal(AZURE_CLOUD_PLATFORM.name(), SINGLE_CERT);
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndTwoCerts() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        conversionTestWhenSslEnabledAndSingleCertReturnedInternal(AWS_CLOUD_PLATFORM.name(), TWO_CERTS);
    }

    @Test
    void conversionTestWhenSslEnabledAndAwsAndThreeCerts() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AWS_CLOUD_PLATFORM);

        conversionTestWhenSslEnabledAndSingleCertReturnedInternal(AWS_CLOUD_PLATFORM.name(), THREE_CERTS);
    }

    @Test
    void conversionTestWhenSslEnabledAndAzureAndTwoCerts() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AZURE_CLOUD_PLATFORM);

        conversionTestWhenSslEnabledAndTwoCertsReturnedInternal(AZURE_CLOUD_PLATFORM.name(), TWO_CERTS);
    }

    private void conversionTestWhenSslEnabledAndTwoCertsReturnedInternal(String cloudPlatform, int numOfCerts) {
        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(cloudPlatform, REGION)).thenReturn(numOfCerts);
        when(databaseServerSslCertificateConfig.getCertsByCloudPlatformAndRegionAndVersions(cloudPlatform, REGION, VERSION_2, VERSION_3))
                .thenReturn(Set.of(sslCertificateEntryV2, sslCertificateEntryV3));

        DBStack dbStack = underTest.convert(allocateRequest, OWNER_CRN);

        verifySsl(dbStack, Set.of(CERT_PEM_V2, CERT_PEM_V3), CLOUD_PROVIDER_IDENTIFIER_V3);

        verify(databaseServerSslCertificateConfig, never()).getCertByCloudPlatformAndRegionAndVersion(anyString(), anyString(), anyInt());
    }

    @Test
    void conversionTestWhenSslEnabledAndAzureAndTwoCertsErrorNullCert() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AZURE_CLOUD_PLATFORM);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AZURE_CLOUD_PLATFORM.name(), REGION)).thenReturn(TWO_CERTS);

        Set<SslCertificateEntry> certs = new HashSet<>();
        certs.add(sslCertificateEntryV3);
        certs.add(null);
        when(databaseServerSslCertificateConfig.getCertsByCloudPlatformAndRegionAndVersions(AZURE_CLOUD_PLATFORM.name(), REGION, VERSION_2, VERSION_3))
                .thenReturn(certs);

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException)
                .hasMessage("Could not find SSL certificate(s) when requesting versions [2, 3] for cloud platform \"AZURE\": expected 2 certificates, got 1");

        verify(databaseServerSslCertificateConfig, never()).getCertByCloudPlatformAndRegionAndVersion(anyString(), anyString(), anyInt());
    }

    @Test
    void conversionTestWhenSslEnabledAndAzureAndTwoCertsErrorFewerCerts() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AZURE_CLOUD_PLATFORM);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AZURE_CLOUD_PLATFORM.name(), REGION)).thenReturn(TWO_CERTS);
        when(databaseServerSslCertificateConfig.getCertsByCloudPlatformAndRegionAndVersions(AZURE_CLOUD_PLATFORM.name(), REGION, VERSION_2, VERSION_3))
                .thenReturn(Set.of(sslCertificateEntryV3));

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException)
                .hasMessage("Could not find SSL certificate(s) when requesting versions [2, 3] for cloud platform \"AZURE\": expected 2 certificates, got 1");

        verify(databaseServerSslCertificateConfig, never()).getCertByCloudPlatformAndRegionAndVersion(anyString(), anyString(), anyInt());
    }

    @Test
    void conversionTestWhenSslEnabledAndAzureAndTwoCertsErrorDuplicatedCertPem() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AZURE_CLOUD_PLATFORM);

        SslCertificateEntry sslCertificateEntryV2DuplicateOfV3 = new SslCertificateEntry(VERSION_2, CLOUD_PROVIDER_IDENTIFIER_V3, CERT_PEM_V3, x509Certificate);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AZURE_CLOUD_PLATFORM.name(), REGION)).thenReturn(TWO_CERTS);
        when(databaseServerSslCertificateConfig.getCertsByCloudPlatformAndRegionAndVersions(AZURE_CLOUD_PLATFORM.name(), REGION, VERSION_2, VERSION_3))
                .thenReturn(Set.of(sslCertificateEntryV2DuplicateOfV3, sslCertificateEntryV3));

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException)
                .hasMessage("Received duplicated SSL certificate PEM when requesting versions [2, 3] for cloud platform \"AZURE\"");

        verify(databaseServerSslCertificateConfig, never()).getCertByCloudPlatformAndRegionAndVersion(anyString(), anyString(), anyInt());
    }

    @Test
    void conversionTestWhenSslEnabledAndAzureAndTwoCertsErrorVersionMismatch() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AZURE_CLOUD_PLATFORM);

        SslCertificateEntry sslCertificateEntryV2Broken = new SslCertificateEntry(VERSION_1, CLOUD_PROVIDER_IDENTIFIER_V2, CERT_PEM_V2, x509Certificate);

        when(databaseServerSslCertificateConfig.getNumberOfCertsByCloudPlatformAndRegion(AZURE_CLOUD_PLATFORM.name(), REGION)).thenReturn(TWO_CERTS);
        when(databaseServerSslCertificateConfig.getCertsByCloudPlatformAndRegionAndVersions(AZURE_CLOUD_PLATFORM.name(), REGION, VERSION_2, VERSION_3))
                .thenReturn(Set.of(sslCertificateEntryV2Broken, sslCertificateEntryV3));

        IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, () -> underTest.convert(allocateRequest, OWNER_CRN));
        assertThat(illegalStateException)
                .hasMessage("Could not find SSL certificate version 2 for cloud platform \"AZURE\"");

        verify(databaseServerSslCertificateConfig, never()).getCertByCloudPlatformAndRegionAndVersion(anyString(), anyString(), anyInt());
    }

    @Test
    void conversionTestWhenSslEnabledAndAzureAndThreeCerts() {
        setupMinimalValid(createSslConfigV4Request(SslMode.ENABLED), AZURE_CLOUD_PLATFORM);

        conversionTestWhenSslEnabledAndTwoCertsReturnedInternal(AZURE_CLOUD_PLATFORM.name(), THREE_CERTS);
    }

    private void verifySsl(DBStack dbStack, Set<String> sslCertificatesExpected, String cloudProviderIdentifierExpected) {
        SslConfig sslConfig = dbStack.getSslConfig();
        assertThat(sslConfig).isNotNull();
        Set<String> sslCertificates = sslConfig.getSslCertificates();
        assertThat(sslCertificates).isNotNull();
        assertThat(sslCertificates).isEqualTo(sslCertificatesExpected);
        assertThat(sslConfig.getSslCertificateType()).isEqualTo(SslCertificateType.CLOUD_PROVIDER_OWNED);
        assertThat(sslConfig.getSslCertificateActiveVersion()).isEqualTo(MAX_VERSION);
        assertThat(sslConfig.getSslCertificateActiveCloudProviderIdentifier()).isEqualTo(cloudProviderIdentifierExpected);
    }

    private void setupAllocateRequest(boolean provideOptionalFields) {
        allocateRequest.setEnvironmentCrn(ENVIRONMENT_CRN);
        allocateRequest.setTags(Map.of("DistroXKey1", "DistroXValue1"));
        allocateRequest.setClusterCrn(CLUSTER_CRN);
        if (provideOptionalFields) {
            allocateRequest.setName("myallocation");
            AwsNetworkV4Parameters awsNetworkV4Parameters = new AwsNetworkV4Parameters();
            awsNetworkV4Parameters.setSubnetId("subnet-1,subnet-2");
            allocateRequest.getNetwork().setAws(awsNetworkV4Parameters);
            setupProviderCalculatorResponse(networkRequest, SUBNET_ID_REQUEST_PARAMETERS);
        } else {
            allocateRequest.setNetwork(null);
            allocateRequest.getDatabaseServer().setSecurityGroup(null);
        }
        allocateRequest.setSslConfig(createSslConfigV4Request(SslMode.ENABLED));

        databaseServerRequest.setInstanceType("db.m3.medium");
        databaseServerRequest.setDatabaseVendor(DATABASE_VENDOR);
        databaseServerRequest.setConnectionDriver("org.postgresql.Driver");
        databaseServerRequest.setStorageSize(50L);
        if (provideOptionalFields) {
            databaseServerRequest.setRootUserName("root");
            databaseServerRequest.setRootUserPassword("cloudera");
        }
        setupProviderCalculatorResponse(allocateRequest, ALLOCATE_REQUEST_PARAMETERS);
        setupProviderCalculatorResponse(databaseServerRequest, new HashMap<>(Map.of("dbkey", "dbvalue")));

        securityGroupRequest.setSecurityGroupIds(Set.of("sg-1234"));
    }

    private static SslConfigV4Request createSslConfigV4Request(SslMode sslMode) {
        SslConfigV4Request sslConfigV4Request = new SslConfigV4Request();
        sslConfigV4Request.setSslMode(sslMode);
        return sslConfigV4Request;
    }

    private void setupProviderCalculatorResponse(ProviderParametersBase request, Map<String, Object> response) {
        MappableBase providerCalculatorResponse = mock(MappableBase.class);
        when(providerCalculatorResponse.asMap()).thenReturn(response);
        when(providerParameterCalculator.get(request)).thenReturn(providerCalculatorResponse);
    }

}


text:
module.exports = function (inherit,StaticParent) {
  'use strict';

  function DestroyableParent(){
    StaticParent.call(this);
  }
  inherit(DestroyableParent,StaticParent);
  DestroyableParent.prototype.addChild = function(child){
    child = StaticParent.prototype.addChild.call(this,child);
    child.__parntDestroyedListener = child.attachListener('destroyed',this.removeChild.bind(this,child));
    return child;
  };
  DestroyableParent.prototype.removeChild = function(child){
    if (child.__parntDestroyedListener) {
      child.__parntDestroyedListener.destroy();
    }
    child.__parntDestroyedListener = null;
    StaticParent.prototype.removeChild.call(this,child);
  };
  return DestroyableParent;
};

redpajama_set_name: RedPajamaGithub


text:
'use strict';

var rules = require('../../../lib/defaultRules');

describe('rules', function () {

  describe('nullable', function () {
    it('should correctly disallow null and undefined values', function (done) {
      assert.isNull(rules.nullable(null, true), 'Should allow null.');
      assert.deepEqual(rules.nullable(null, false), {
        rule: 'nullable',
        actual: 'x === null',
        expected: 'x !== null && x !== undefined'
      }, 'Should disallow null');
      assert.isNull(rules.nullable(undefined, true), 'Should allow undefined.');
      assert.deepEqual(rules.nullable(undefined, false), {
        rule: 'nullable',
        actual: 'x === undefined',
        expected: 'x !== null && x !== undefined'
      }, 'Should disallow undefined.');
      done();
    });

    it('should always allow these values', function (done) {
      assert.isNull(rules.nullable(-100, false), 'Should allow -100.');
      assert.isNull(rules.nullable(-100, true), 'Should allow -100.');
      assert.isNull(rules.nullable(0, false), 'Should allow 0.');
      assert.isNull(rules.nullable(0, true), 'Should allow 0.');
      assert.isNull(rules.nullable(100, false), 'Should allow 100.');
      assert.isNull(rules.nullable(100, true), 'Should allow 100.');
      assert.isNull(rules.nullable('asdf', false), 'Should allow "asdf".');
      assert.isNull(rules.nullable('asdf', true), 'Should allow "asdf".');
      assert.isNull(rules.nullable(false, false), 'Should allow false.');
      assert.isNull(rules.nullable(true), 'Should allow false.');
      assert.isNull(rules.nullable(true, false), 'Should allow true.');
      assert.isNull(rules.nullable(true, true), 'Should allow true.');
      assert.isNull(rules.nullable(new Date(), false), 'Should allow a date.');
      assert.isNull(rules.nullable(new Date(), true), 'Should allow a date.');
      assert.isNull(rules.nullable({}, false), 'Should allow {}.');
      assert.isNull(rules.nullable({}, true), 'Should allow {}.');
      assert.isNull(rules.nullable([], false), 'Should allow [].');
      assert.isNull(rules.nullable([], true), 'Should allow [].');
      assert.isNull(rules.nullable(['stuff'], false), 'Should allow ["stuff"].');
      assert.isNull(rules.nullable(['stuff'], true), 'Should allow ["stuff"].');
      assert.isNull(rules.nullable({'stuff': 'stuff'}, false), 'Should allow {"stuff":"stuff"}.');
      assert.isNull(rules.nullable({'stuff': 'stuff'}, true), 'Should allow {"stuff":"stuff"}.');
      done();
    });
  });

  describe('max', function () {
    it('should accept numbers less than or equal to the max', function (done) {
      assert.isNull(rules.max(40, 40), 'Should allow 40 when max is 40.');
      assert.isNull(rules.max(39.9999, 40), 'Should allow 39.9999 when max is 40.');
      assert.isNull(rules.max(-39.9999, 40), 'Should allow -39.9999 when max is 40.');
      assert.isNull(rules.max(-40.0001, -40), 'Should allow -40.0001 when max is -40.');
      assert.isNull(rules.max(-100, -40), 'Should allow -100 when max is -40.');
      assert.isNull(rules.max('asdf', 40), 'Should return null for "asdf".');
      assert.isNull(rules.max(true, 40), 'Should return null for true.');
      assert.isNull(rules.max(false, 40), 'Should return null for false.');
      assert.isNull(rules.max(null, 40), 'Should return null for null.');
      assert.isNull(rules.max(undefined, 40), 'Should return null for undefined.');
      assert.isNull(rules.max(new Date(), 40), 'Should return null for a date.');
      assert.isNull(rules.max({}, 40), 'Should return null for {}.');
      assert.isNull(rules.max([], 40), 'Should return null for [].');
      assert.isNull(rules.max(['stuff'], 40), 'Should return null for ["stuff"].');
      assert.isNull(rules.max({'stuff': 'stuff'}, 40), 'Should return null for {"stuff":"stuff"}.');
      done();
    });

    it('should disallow numbers greater than the max', function (done) {
      assert.deepEqual(rules.max(40.0001, 40), {
        rule: 'max',
        actual: '40.0001 > 40',
        expected: '40.0001 <= 40'
      }, 'Should disallow 40.0001 when max is 40.');
      assert.deepEqual(rules.max(-39.9999, -40), {
        rule: 'max',
        actual: '-39.9999 > -40',
        expected: '-39.9999 <= -40'
      }, 'Should disallow -39.9999 when max is -40.');
      done();
    });
  });

  describe('min', function () {
    it('should accept numbers greater than or equal to the min', function (done) {
      assert.isNull(rules.min(40, 40), 'Should allow 40 when min is 40.');
      assert.isNull(rules.min(40.0001, 40), 'Should allow 40.0001 when min is 40.');
      assert.isNull(rules.min(-39.9999, -40), 'Should allow -39.9999 when min is -40.');
      assert.isNull(rules.min(-40, -40), 'Should allow -40 when min is -40.');
      assert.isNull(rules.min('asdf', 40), 'Should return null for "asdf".');
      assert.isNull(rules.min(true, 40), 'Should return null for true.');
      assert.isNull(rules.min(false, 40), 'Should return null for false.');
      assert.isNull(rules.min(null, 40), 'Should return null for null.');
      assert.isNull(rules.min(undefined, 40), 'Should return null for undefined.');
      assert.isNull(rules.min(new Date(), 40), 'Should return null for a date.');
      assert.isNull(rules.min({}, 40), 'Should return null for {}.');
      assert.isNull(rules.min([], 40), 'Should return null for [].');
      assert.isNull(rules.min(['stuff'], 40), 'Should return null for ["stuff"].');
      assert.isNull(rules.min({'stuff': 'stuff'}, 40), 'Should return null for {"stuff":"stuff"}.');
      done();
    });

    it('should disallow numbers less than the min', function (done) {
      assert.deepEqual(rules.min(39.9999, 40), {
        rule: 'min',
        actual: '39.9999 < 40',
        expected: '39.9999 >= 40'
      }, 'Should disallow 39.9999 when min is 40.');
      assert.deepEqual(rules.min(-40.0001, -40), {
        rule: 'min',
        actual: '-40.0001 < -40',
        expected: '-40.0001 >= -40'
      }, 'Should disallow -40.0001 when min is -40.');
      done();
    });
  });

  describe('maxLength', function () {
    it('should accept lengths less than or equal to the maxLength', function (done) {
      assert.isNull(rules.maxLength('1234567890', 10), 'Should allow "1234567890" when maxLength is 10.');
      assert.isNull(rules.maxLength('123456789', 10), 'Should allow "123456789" when maxLength is 10.');
      assert.isNull(rules.maxLength('', 0), 'Should allow "" when maxLength is 0.');
      assert.isNull(rules.maxLength(['1', '2'], 2), 'Should allow ["1", "2"] when maxLength is 2.');
      assert.isNull(rules.maxLength([], 0), 'Should allow [] when maxLength is 0.');
      assert.isNull(rules.maxLength(true, 40), 'Should return null for true.');
      assert.isNull(rules.maxLength(false, 40), 'Should return null for false.');
      assert.isNull(rules.maxLength(null, 40), 'Should return null for null.');
      assert.isNull(rules.maxLength(undefined, 40), 'Should return null for undefined.');
      assert.isNull(rules.maxLength(new Date(), 40), 'Should return null for a date.');
      assert.isNull(rules.maxLength({}, 40), 'Should return null for {}.');
      assert.isNull(rules.maxLength({'stuff': 'stuff'}, 40), 'Should return null for {"stuff":"stuff"}.');
      done();
    });

    it('should disallow lengths greater than the maxLength', function (done) {
      assert.deepEqual(rules.maxLength('1234567890', 9), {
        rule: 'maxLength',
        actual: '' + ('1234567890'.length) + ' > ' + 9,
        expected: '' + ('1234567890'.length) + ' <= ' + 9
      }, 'Should disallow "1234567890" when maxLength is 9.');
      assert.deepEqual(rules.maxLength('123456789', 1), {
        rule: 'maxLength',
        actual: '' + ('123456789'.length) + ' > ' + 1,
        expected: '' + ('123456789'.length) + ' <= ' + 1
      }, 'Should disallow "123456789" when maxLength is 1.');
      assert.deepEqual(rules.maxLength('a', 0), {
        rule: 'maxLength',
        actual: '' + ('a'.length) + ' > ' + 0,
        expected: '' + ('a'.length) + ' <= ' + 0
      }, 'Should disallow "a" when maxLength is 0.');
      assert.deepEqual(rules.maxLength(['1', '2', '3'], 2), {
        rule: 'maxLength',
        actual: '' + (['1', '2', '3'].length) + ' > ' + 2,
        expected: '' + (['1', '2', '3'].length) + ' <= ' + 2
      }, 'Should disallow ["1", "2", "3"] when maxLength is 2.');
      assert.deepEqual(rules.maxLength(['1'], 0), {
        rule: 'maxLength',
        actual: '' + (['1'].length) + ' > ' + 0,
        expected: '' + (['1'].length) + ' <= ' + 0
      }, 'Should disallow ["1"] when maxLength is 0.');
      done();
    });
  });

  describe('minLength', function () {
    it('should accept lengths greater than or equal to the minLength', function (done) {
      assert.isNull(rules.minLength('1234567890', 10), 'Should allow "1234567890" when minLength is 10.');
      assert.isNull(rules.minLength('123456789', 1), 'Should allow "123456789" when minLength is 1.');
      assert.isNull(rules.minLength('', 0), 'Should allow "" when minLength is 0.');
      assert.isNull(rules.minLength(['1', '2'], 2), 'Should allow ["1", "2"] when minLength is 2.');
      assert.isNull(rules.minLength([], 0), 'Should allow [] when minLength is 0.');
      assert.isNull(rules.minLength(true, 40), 'Should return null for true.');
      assert.isNull(rules.minLength(false, 40), 'Should return null for false.');
      assert.isNull(rules.minLength(null, 40), 'Should return null for null.');
      assert.isNull(rules.minLength(undefined, 40), 'Should return null for undefined.');
      assert.isNull(rules.minLength(new Date(), 40), 'Should return null for a date.');
      assert.isNull(rules.minLength({}, 40), 'Should return null for {}.');
      assert.isNull(rules.minLength({'stuff': 'stuff'}, 40), 'Should return null for {"stuff":"stuff"}.');
      done();
    });

    it('should disallow lengths less than the minLength', function (done) {
      assert.deepEqual(rules.minLength('1234567890', 11), {
        rule: 'minLength',
        actual: '' + ('1234567890'.length) + ' < ' + 11,
        expected: '' + ('1234567890'.length) + ' >= ' + 11
      }, 'Should disallow "1234567890" when minLength is 11.');
      assert.deepEqual(rules.minLength('', 1), {
        rule: 'minLength',
        actual: '' + (''.length) + ' < ' + 1,
        expected: '' + (''.length) + ' >= ' + 1
      }, 'Should disallow "" when minLength is 1.');
      assert.deepEqual(rules.minLength(['1', '2', '3'], 4), {
        rule: 'minLength',
        actual: '' + (['1', '2', '3'].length) + ' < ' + 4,
        expected: '' + (['1', '2', '3'].length) + ' >= ' + 4
      }, 'Should disallow ["1", "2", "3"] when minLength is 4.');
      assert.deepEqual(rules.minLength([], 1), {
        rule: 'minLength',
        actual: '' + ([].length) + ' < ' + 1,
        expected: '' + ([].length) + ' >= ' + 1
      }, 'Should disallow [] when minLength is 1.');
      done();
    });
  });
});


text:
require 'spec_helper'

describe Ruboty::Growthforecast do
  it 'has a version number' do
    expect(Ruboty::Growthforecast::VERSION).not_to be nil
  end

  it 'does something useful' do
    expect(false).to eq(true)
  end
end


text:
@interface HUAlbumsViewController : UITableViewController

@end


text:
<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: google/cloud/datafusion/v1/datafusion.proto

namespace Google\Cloud\DataFusion\V1\Instance;

use UnexpectedValueException;

/**
 * The reason for disabling the instance if the state is DISABLED.
 *
 * Protobuf type google.cloud.datafusion.v1.Instance.DisabledReason
 */
class DisabledReason
{
    /**
     * This is an unknown reason for disabling.
     *
     * Generated from protobuf enum DISABLED_REASON_UNSPECIFIED = 0;
     */
    const DISABLED_REASON_UNSPECIFIED = 0;
    /**
     * The KMS key used by the instance is either revoked or denied access to
     *
     * Generated from protobuf enum KMS_KEY_ISSUE = 1;
     */
    const KMS_KEY_ISSUE = 1;

    private static $valueToName = [
        self::DISABLED_REASON_UNSPECIFIED => 'DISABLED_REASON_UNSPECIFIED',
        self::KMS_KEY_ISSUE => 'KMS_KEY_ISSUE',
    ];

    public static function name($value)
    {
        if (!isset(self::$valueToName[$value])) {
            throw new UnexpectedValueException(sprintf(
                    'Enum %s has no name defined for value %s', __CLASS__, $value));
        }
        return self::$valueToName[$value];
    }

    public static function value($name)
    {
        $const = __CLASS__ . '::' . strtoupper($name);
        if (!defined($const)) {
            throw new UnexpectedValueException(sprintf(
                    'Enum %s has no value defined for name %s', __CLASS__, $name));
        }
        return constant($const);
    }
}


text:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">

<erlref>

    <copyright>
      <year>1996</year><year>2013</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      The contents of this file are subject to the Erlang Public License,
      Version 1.1, (the "License"); you may not use this file except in
      compliance with the License. You should have received a copy of the
      Erlang Public License along with this software. If not, it can be
      retrieved online at http://www.erlang.org/.

      Software distributed under the License is distributed on an "AS IS"
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
      the License for the specific language governing rights and limitations
      under the License.

    </legalnotice>

    <title>code</title>
    <prepared></prepared>
    <docno></docno>
    <date></date>
    <rev></rev>

  <module>code</module>
  <modulesummary>Erlang Code Server</modulesummary>
  <description>

This module contains the interface to the Erlang
      code server, which deals with the loading of compiled
      code into a running Erlang runtime system.

The runtime system can be started in either embedded or
      interactive mode. Which one is decided by the command
      line flag <c>-mode</c>.

% <input>erl -mode interactive</input>

Default mode is <c>interactive</c>.

    <list type="bulleted">
      <item>

In embedded mode, all code is loaded during system start-up
          according to the boot script. (Code can also be loaded later
          by explicitly ordering the code server to do so).

      </item>
      <item>

In interactive mode, only some code is loaded during system
          startup-up, basically the modules needed by the runtime
          system itself. Other code is dynamically loaded when first
          referenced. When a call to a function in a certain module is
          made, and the module is not loaded, the code server searches
          for and tries to load the module.

      </item>
    </list>

To prevent accidentally reloading modules affecting the Erlang
      runtime system itself, the <c>kernel</c>, <c>stdlib</c> and
      <c>compiler</c> directories are considered sticky. This
      means that the system issues a warning and rejects the request if
      a user tries to reload a module residing in any of them.
      The feature can be disabled by using the command line flag
      <c>-nostick</c>.

  </description>

    <title>Code Path</title>

In interactive mode, the code server maintains a search path --
      usually called the code path -- consisting of a list of
      directories, which it searches sequentially when trying to load a
      module.

Initially, the code path consists of the current working
      directory and all Erlang object code directories under the library
      directory <c>$OTPROOT/lib</c>, where <c>$OTPROOT</c> is
      the installation directory of Erlang/OTP, <c>code:root_dir()</c>.
      Directories can be named <c>Name[-Vsn]</c> and the code server,
      by default, chooses the directory with the highest version number
      among those which have the same <c>Name</c>. The <c>-Vsn</c>
      suffix is optional. If an <c>ebin</c> directory exists under
      <c>Name[-Vsn]</c>, it is this directory which is added to
      the code path.

The environment variable <c>ERL_LIBS</c> (defined in the operating
      system) can be used to define additional library directories that
      will be handled in the same way as the standard OTP library
      directory described above, except that directories that do not
      have an <c>ebin</c> directory will be ignored.

All application directories found in the additional directories
      will appear before the standard OTP applications, except for the
      Kernel and STDLIB applications, which will be placed before any
      additional applications. In other words, modules found in any
      of the additional library directories will override modules with
      the same name in OTP, except for modules in Kernel and
      STDLIB.

The environment variable <c>ERL_LIBS</c> (if defined) should contain
      a colon-separated (for Unix-like systems) or semicolon-separated
      (for Windows) list of additional libraries.

Example: On an Unix-like system, <c>ERL_LIBS</c> could be set to
      <c>/usr/local/jungerl:/home/some_user/my_erlang_lib</c>. (On Windows,
      use semi-colon as separator.)

    <title>Code Path Cache</title>

The code server incorporates a code path cache. The cache
      functionality is disabled by default. To activate it, start
      the emulator with the command line flag <c>-code_path_cache</c>
      or call <c>code:rehash()</c>. When the cache is created (or
      updated), the code server searches for modules in the code path
      directories. This may take some time if the the code path is long.
      After the cache creation, the time for loading modules in a large
      system (one with a large directory structure) is significantly
      reduced compared to having the cache disabled. The code server
      is able to look up the location of a module from the cache in
      constant time instead of having to search through the code path
      directories.

Application resource files (<c>.app</c> files) are also stored
      in the code path cache. This feature is used by the application
      controller (see
      <seealso marker="application">application(3)</seealso>) to load
      applications efficiently in large systems.

Note that when the code path cache is created (or updated), any
      relative directory names in the code path are converted to
      absolute.

    <title>Loading of Code From Archive Files</title>

    <warning>
The support for loading of code from archive files is
     experimental. The sole purpose of releasing it before it is ready
     is to obtain early feedback. The file format, semantics,
     interfaces etc. may be changed in a future release. The function
     <c>lib_dir/2</c> and the flag <c>-code_path_choice</c> are also
     experimental.
</warning>

In the current implementation, Erlang archives are <c>ZIP</c>
     files with <c>.ez</c> extension. Erlang archives may also be
     enclosed in <c>escript</c> files whose file extension is arbitrary.

Erlang archive files may contain entire Erlang applications or
     parts of applications. The structure in an archive file is the
     same as the directory structure for an application. If you for
     example would create an archive of <c>mnesia-4.4.7</c>, the
     archive file must be named <c>mnesia-4.4.7.ez</c> and it must
     contain a top directory with the name <c>mnesia-4.4.7</c>. If the
     version part of the name is omitted, it must also be omitted in
     the archive. That is, a <c>mnesia.ez</c> archive must contain a
     <c>mnesia</c> top directory.

An archive file for an application may for example be
     created like this:

   zip:create("mnesia-4.4.7.ez",
              ["mnesia-4.4.7"],
              [{cwd, code:lib_dir()},
               {compress, all},
               {uncompress,[".beam",".app"]}]).

Any file in the archive may be compressed, but in order to
     speed up the access of frequently read files, it may be a good
     idea to store <c>beam</c> and <c>app</c> files uncompressed in
     the archive.

Normally the top directory of an application is located either
     in the library directory <c>$OTPROOT/lib</c> or in a directory
     referred to by the environment variable <c>ERL_LIBS</c>. At
     startup when the initial code path is computed, the code server
     will also look for archive files in these directories and
     possibly add <c>ebin</c> directories in archives to the code path. The
     code path will then contain paths to directories that looks like
     <c>$OTPROOT/lib/mnesia.ez/mnesia/ebin</c> or
     <c>$OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c>.

The code server uses the module <c>erl_prim_loader</c>
     (possibly via the <c>erl_boot_server</c>) to read code files from
     archives. But the functions in <c>erl_prim_loader</c> may also be
     used by other applications to read files from archives. For
     example, the call
     <c>erl_prim_loader:list_dir( "/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/examples/bench)"</c>
     would list the contents of a directory inside an archive.
     See <seealso marker="erts:erl_prim_loader">erl_prim_loader(3)</seealso>
.

An application archive file and a regular application directory
     may coexist. This may be useful when there is a need of having
     parts of the application as regular files. A typical case is the
     <c>priv</c> directory which must reside as a regular directory in
     order to be able to dynamically link in drivers and start port
     programs. For other applications that do not have this need, the
     <c>priv</c> directory may reside in the archive and the files
     under the <c>priv</c> directory may be read via the
     <c>erl_prim_loader</c>.

At the time point when a directory is added to the code path as
     well as when the entire code path is (re)set, the code server
     will decide which subdirectories in an application that shall be
     read from the archive and which that shall be read as regular
     files. If directories are added or removed afterwards, the file
     access may fail if the code path is not updated (possibly to the
     same path as before in order to trigger the directory resolution
     update). For each directory on the second level (ebin, priv, src
     etc.) in the application archive, the code server will firstly
     choose the regular directory if it exists and secondly from the
     archive. The function
     <c>code:lib_dir/2</c> returns the path to the subdirectory. For
     example <c>code:lib_dir(megaco,ebin)</c> may return
     <c>/otp/root/lib/megaco-3.9.1.1.ez/megaco-3.9.1.1/ebin</c> while
     <c>code:lib_dir(megaco,priv)</c> may return
     <c>/otp/root/lib/megaco-3.9.1.1/priv</c>.

When an <c>escript</c> file contains an archive, there are
     neither restrictions on the name of the <c>escript</c> nor on how
     many applications that may be stored in the embedded
     archive. Single <c>beam</c> files may also reside on the top
     level in the archive. At startup, both the top directory in the
     embedded archive as well as all (second level) <c>ebin</c>
     directories in the embedded archive are added to the code path.
     See <seealso marker="erts:escript">escript(1)</seealso>

When the choice of directories in the code path is
     <c>strict</c>, the directory that ends up in the code path will
     be exactly the stated one. This means that if for example the
     directory <c>$OTPROOT/lib/mnesia-4.4.7/ebin</c> is explicitly
     added to the code path, the code server will not load files from
     <c>$OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin</c> and vice
     versa.

This behavior can be controlled via the command line flag
     <c>-code_path_choice Choice</c>. If the flag is set to <c>relaxed</c>,
     the code server will instead choose a suitable directory
     depending on the actual file structure. If there exists a regular
     application ebin directory,situation it will be chosen. But if it does
     not exist, the ebin directory in the archive is chosen if it
     exists. If neither of them exists the original directory will be
     chosen.

The command line flag <c>-code_path_choice Choice</c> does also
     affect how <c>init</c> interprets the <c>boot script</c>. The
     interpretation of the explicit code paths in the <c>boot
     script</c> may be <c>strict</c> or <c>relaxed</c>. It is
     particular useful to set the flag to <c>relaxed</c> when you want
     to elaborate with code loading from archives without editing the
     <c>boot script</c>. The default is <c>relaxed</c>. See <seealso
     marker="erts:init">init(3)</seealso>

    <title>Current and Old Code</title>

The code of a module can exists in two variants in a system:
      current code and old code. When a module is
      loaded into the system for the first time, the code of the module
      becomes 'current' and the global export table is updated
      with references to all functions exported from the module.

If then a new instance of the module is loaded (perhaps because
      of the correction of an error), then the code of the previous
      instance becomes 'old', and all export entries referring to
      the previous instance are removed. After that the new instance is
      loaded as if it was loaded for the first time, as described above,
      and becomes 'current'.

Both old and current code for a module are valid, and may even be
      evaluated concurrently. The difference is that exported functions
      in old code are unavailable. Hence there is no way to make a
      global call to an exported function in old code, but old code may
      still be evaluated because of processes lingering in it.

If a third instance of the module is loaded, the code server will
      remove (purge) the old code and any processes lingering in it will
      be terminated. Then the third instance becomes 'current' and
      the previously current code becomes 'old'.

For more information about old and current code, and how to
      make a process switch from old to current code, refer to
      <seealso marker="doc/reference_manual:code_loading">Erlang Reference Manual</seealso>.

    <title>Argument Types and Invalid Arguments</title>

Generally, module and application names are atoms, while file and directory
    names are strings. For backward compatibility reasons, some functions accept
    both strings and atoms, but a future release will probably only allow
    the arguments that are documented.

From the R12B release, functions in this module will generally fail with an
    exception if they are passed an incorrect type (for instance, an integer or a tuple
    where an atom was expected). An error tuple will be returned if type of argument
    was correct, but there was some other error (for instance, a non-existing directory
    given to <c>set_path/1</c>.

  <datatypes>
    <datatype>
      <name name="load_ret"/>
    </datatype>
    <datatype>
      <name name="load_error_rsn"/>
    </datatype>
  </datatypes>

  <funcs>
    <func>
      <name name="set_path" arity="1"/>
      <fsummary>Set the code server search path</fsummary>
      <desc>

Sets the code path to the list of directories <c><anno>Path</anno></c>.

Returns <c>true</c> if successful, or
          <c>{error, bad_directory}</c> if any <c><anno>Dir</anno></c> is not
          the name of a directory, or <c>{error, bad_path}</c> if
          the argument is invalid.

      </desc>
    </func>
    <func>
      <name name="get_path" arity="0"/>
      <fsummary>Return the code server search path</fsummary>
      <desc>

Returns the code path

      </desc>
    </func>
    <func>
      <name name="add_path" arity="1"/>
      <name name="add_pathz" arity="1"/>
      <fsummary>Add a directory to the end of the code path</fsummary>
      <type name="add_path_ret"/>
      <desc>

Adds <c><anno>Dir</anno></c> to the code path. The directory is added as
          the last directory in the new path. If <c><anno>Dir</anno></c> already
          exists in the path, it is not added.

Returns <c>true</c> if successful, or
          <c>{error, bad_directory}</c> if <c><anno>Dir</anno></c> is not the name
          of a directory.

      </desc>
    </func>
    <func>
      <name name="add_patha" arity="1"/>
      <fsummary>Add a directory to the beginning of the code path</fsummary>
      <type name="add_path_ret"/>
      <desc>

Adds <c><anno>Dir</anno></c> to the beginning of the code path. If
          <c><anno>Dir</anno></c> already exists, it is removed from the old
          position in the code path.

Returns <c>true</c> if successful, or
          <c>{error, bad_directory}</c> if <c><anno>Dir</anno></c> is not the name
          of a directory.

      </desc>
    </func>
    <func>
      <name name="add_paths" arity="1"/>
      <name name="add_pathsz" arity="1"/>
      <fsummary>Add directories to the end of the code path</fsummary>
      <desc>

Adds the directories in <c><anno>Dirs</anno></c> to the end of the code
          path. If a <c><anno>Dir</anno></c> already exists, it is not added. This
          function always returns <c>ok</c>, regardless of the validity
          of each individual <c><anno>Dir</anno></c>.

      </desc>
    </func>
    <func>
      <name name="add_pathsa" arity="1"/>
      <fsummary>Add directories to the beginning of the code path</fsummary>
      <desc>

Adds the directories in <c><anno>Dirs</anno></c> to the beginning of
          the code path. If a <c><anno>Dir</anno></c> already exists, it is removed
          from the old position in the code path. This function always
          returns <c>ok</c>, regardless of the validity of each
          individual <c><anno>Dir</anno></c>.

      </desc>
    </func>
    <func>
      <name name="del_path" arity="1"/>
      <fsummary>Delete a directory from the code path</fsummary>
      <desc>

Deletes a directory from the code path. The argument can be
          an atom <c><anno>Name</anno></c>, in which case the directory with
          the name <c>.../<anno>Name</anno>[-Vsn][/ebin]</c> is deleted from the code
          path. It is also possible to give the complete directory name
          <c><anno>Dir</anno></c> as argument.

Returns <c>true</c> if successful, or <c>false</c> if
          the directory is not found, or <c>{error, bad_name}</c> if
          the argument is invalid.

      </desc>
    </func>
    <func>
      <name name="replace_path" arity="2"/>
      <fsummary>Replace a directory with another in the code path</fsummary>
      <desc>

This function replaces an old occurrence of a directory
          named <c>.../<anno>Name</anno>[-Vsn][/ebin]</c>, in the code path, with
          <c><anno>Dir</anno></c>. If <c><anno>Name</anno></c> does not exist, it adds the new
          directory <c><anno>Dir</anno></c> last in the code path. The new directory
          must also be named <c>.../<anno>Name</anno>[-Vsn][/ebin]</c>. This function
          should be used if a new version of the directory (library) is
          added to a running system.

Returns <c>true</c> if successful, or
          <c>{error, bad_name}</c> if <c><anno>Name</anno></c> is not found, or
          <c>{error, bad_directory}</c> if <c><anno>Dir</anno></c> does not exist, or
          <c>{error, {badarg, [<anno>Name</anno>, <anno>Dir</anno>]}}</c> if <c><anno>Name</anno></c> or
          <c><anno>Dir</anno></c> is invalid.

      </desc>
    </func>
    <func>
      <name name="load_file" arity="1"/>
      <fsummary>Load a module</fsummary>
      <type name="load_ret"/>
      <desc>

Tries to load the Erlang module <c><anno>Module</anno></c>, using
          the code path. It looks for the object code file with an
          extension that corresponds to the Erlang machine used, for
          example <c><anno>Module</anno>.beam</c>. The loading fails if the module
          name found in the object code differs from the name
          <c><anno>Module</anno></c>.
          <seealso marker="#load_binary/3">load_binary/3</seealso> must
          be used to load object code with a module name that is
          different from the file name.

Returns <c>{module, <anno>Module</anno>}</c> if successful, or
          <c>{error, nofile}</c> if no object code is found, or
          <c>{error, sticky_directory}</c> if the object code resides in
          a sticky directory. Also if the loading fails, an error tuple is
          returned. See
          <seealso marker="erts:erlang#load_module/2">erlang:load_module/2</seealso>
          for possible values of <c><anno>What</anno></c>.

      </desc>
    </func>
    <func>
      <name name="load_abs" arity="1"/>
      <fsummary>Load a module, residing in a given file</fsummary>
      <type name="load_ret"/>
      <type name="loaded_filename"/>
      <type name="loaded_ret_atoms"/>
      <desc>

Does the same as <c>load_file(<anno>Module</anno>)</c>, but
          <c><anno>Filename</anno></c> is either an absolute file name, or a
          relative file name. The code path is not searched. It returns
          a value in the same way as
          <seealso marker="#load_file/1">load_file/1</seealso>. Note
          that <c><anno>Filename</anno></c> should not contain the extension (for
          example <c>".beam"</c>); <c>load_abs/1</c> adds the correct
          extension itself.

      </desc>
    </func>
    <func>
      <name name="ensure_loaded" arity="1"/>
      <fsummary>Ensure that a module is loaded</fsummary>
      <desc>

Tries to to load a module in the same way as
          <seealso marker="#load_file/1">load_file/1</seealso>,
	  unless the module is already loaded.
          In embedded mode, however, it does not load a module which is not
          already loaded, but returns <c>{error, embedded}</c> instead.

      </desc>
    </func>
    <func>
      <name name="load_binary" arity="3"/>
      <fsummary>Load object code for a module</fsummary>
      <type name="loaded_filename"/>
      <type name="loaded_ret_atoms"/>
      <desc>

This function can be used to load object code on remote
          Erlang nodes. The argument <c><anno>Binary</anno></c> must contain
	  object code for <c><anno>Module</anno></c>.
          <c><anno>Filename</anno></c> is only used by the code server to keep a
          record of from which file the object code for <c><anno>Module</anno></c>
          comes. Accordingly, <c><anno>Filename</anno></c> is not opened and read by
          the code server.

Returns <c>{module, <anno>Module</anno>}</c> if successful, or
          <c>{error, sticky_directory}</c> if the object code resides in
          a sticky directory, or <c>{error, badarg}</c> if any argument
          is invalid. Also if the loading fails, an error tuple is
          returned. See
          <seealso marker="erts:erlang#load_module/2">erlang:load_module/2</seealso>
          for possible values of <c><anno>What</anno></c>.

      </desc>
    </func>
    <func>
      <name name="delete" arity="1"/>
      <fsummary>Removes current code for a module</fsummary>
      <desc>

Removes the current code for <c><anno>Module</anno></c>, that is,
          the current code for <c><anno>Module</anno></c> is made old. This means
          that processes can continue to execute the code in the module,
          but that no external function calls can be made to it.

Returns <c>true</c> if successful, or <c>false</c> if there
          is old code for <c><anno>Module</anno></c> which must be purged first, or
          if <c><anno>Module</anno></c> is not a (loaded) module.

      </desc>
    </func>
    <func>
      <name name="purge" arity="1"/>
      <fsummary>Removes old code for a module</fsummary>
      <desc>

Purges the code for <c><anno>Module</anno></c>, that is, removes code
          marked as old. If some processes still linger in the old code,
          these processes are killed before the code is removed.

Returns <c>true</c> if successful and any process needed to
          be killed, otherwise <c>false</c>.

      </desc>
    </func>
    <func>
      <name name="soft_purge" arity="1"/>
      <fsummary>Removes old code for a module, unless no process uses it</fsummary>
      <desc>

Purges the code for <c><anno>Module</anno></c>, that is, removes code
          marked as old, but only if no processes linger in it.

Returns <c>false</c> if the module could not be purged due
          to processes lingering in old code, otherwise <c>true</c>.

      </desc>
    </func>
    <func>
      <name name="is_loaded" arity="1"/>
      <fsummary>Check if a module is loaded</fsummary>
      <type name="loaded_filename"/>
      <type name="loaded_ret_atoms"/>
      <type_desc name="loaded_filename"><c><anno>Filename</anno></c> is an absolute filename</type_desc>
      <desc>

Checks if <c><anno>Module</anno></c> is loaded. If it is,
          <c>{file, <anno>Loaded</anno>}</c> is returned, otherwise <c>false</c>.

Normally, <c><anno>Loaded</anno></c> is the absolute file name
          <c>Filename</c> from which the code was obtained. If the module
          is preloaded (see
          <seealso marker="sasl:script">script(4)</seealso>),
          <c>Loaded==preloaded</c>. If the module is Cover compiled (see
          <seealso marker="tools:cover">cover(3)</seealso>),
          <c>Loaded==cover_compiled</c>.

      </desc>
    </func>
    <func>
      <name name="all_loaded" arity="0"/>
      <fsummary>Get all loaded modules</fsummary>
      <type name="loaded_filename"/>
      <type name="loaded_ret_atoms"/>
      <type_desc name="loaded_filename"><c><anno>Filename</anno></c> is an absolute filename</type_desc>
      <desc>

Returns a list of tuples <c>{<anno>Module</anno>, <anno>Loaded</anno>}</c> for all
          loaded modules. <c><anno>Loaded</anno></c> is normally the absolute file
          name, as described for
          <seealso marker="#is_loaded/1">is_loaded/1</seealso>.

      </desc>
    </func>
    <func>
      <name name="which" arity="1"/>
      <fsummary>The object code file of a module</fsummary>
      <type name="loaded_ret_atoms"/>
      <desc>

If the module is not loaded, this function searches the code
          path for the first file which contains object code for
          <c><anno>Module</anno></c> and returns the absolute file name. If
          the module is loaded, it returns the name of the file which
          contained the loaded object code. If the module is pre-loaded,
          <c>preloaded</c> is returned. If the module is Cover compiled,
          <c>cover_compiled</c> is returned. <c>non_existing</c> is
          returned if the module cannot be found.

      </desc>
    </func>
    <func>
      <name name="get_object_code" arity="1"/>
      <fsummary>Get the object code for a module</fsummary>
      <desc>

Searches the code path for the object code of the module
          <c><anno>Module</anno></c>. It returns <c>{<anno>Module</anno>, <anno>Binary</anno>, <anno>Filename</anno>}</c>
          if successful, and <c>error</c> if not. <c><anno>Binary</anno></c> is a
          binary data object which contains the object code for
          the module. This can be useful if code is to be loaded on a
          remote node in a distributed system. For example, loading
          module <c><anno>Module</anno></c> on a node <c>Node</c> is done as
          follows:

...
{_Module, Binary, Filename} = code:get_object_code(Module),
rpc:call(Node, code, load_binary, [Module, Filename, Binary]),
...
      </desc>
    </func>
    <func>
      <name name="root_dir" arity="0"/>
      <fsummary>Root directory of Erlang/OTP</fsummary>
      <desc>

Returns the root directory of Erlang/OTP, which is
          the directory where it is installed.

> <input>code:root_dir().</input>
"/usr/local/otp"

      </desc>
    </func>
    <func>
      <name name="lib_dir" arity="0"/>
      <fsummary>Library directory of Erlang/OTP</fsummary>
      <desc>

Returns the library directory, <c>$OTPROOT/lib</c>, where
          <c>$OTPROOT</c> is the root directory of Erlang/OTP.

> <input>code:lib_dir().</input>
"/usr/local/otp/lib"

      </desc>
    </func>
    <func>
      <name name="lib_dir" arity="1"/>
      <fsummary>Library directory for an application</fsummary>
      <desc>

This function is mainly intended for finding out the path
          for the "library directory", the top directory, for an
          application <c><anno>Name</anno></c> located under <c>$OTPROOT/lib</c> or
          on a directory referred to via the <c>ERL_LIBS</c>
          environment variable.

If there is a regular directory called <c><anno>Name</anno></c> or
          <c><anno>Name</anno>-Vsn</c> in the code path with an <c>ebin</c>
          subdirectory, the path to this directory is returned (not
          the <c>ebin</c> directory). If the directory refers to a
          directory in an archive, the archive name is stripped away
          before the path is returned.  For example, if the directory
          <c>/usr/local/otp/lib/mnesia-4.2.2.ez/mnesia-4.2.2/ebin</c>
          is in the path, <c>/usr/local/otp/lib/mnesia-4.2.2/ebin</c>
          will be returned. This means that the library directory for
          an application is the same, regardless of whether the
          application resides in an archive or not.

> <input>code:lib_dir(mnesia).</input>
"/usr/local/otp/lib/mnesia-4.2.2"

Returns <c>{error, bad_name}</c> if <c><anno>Name</anno></c>
	 is not the name of an application under <c>$OTPROOT/lib</c> or
	 on a directory referred to via the <c>ERL_LIBS</c>
         environment variable. Fails with an exception if <c>Name</c>
         has the wrong type.

	<warning>
For backward compatibility, <c><anno>Name</anno></c> is also allowed to
	be a string. That will probably change in a future release.
</warning>
      </desc>
    </func>
    <func>
      <name name="lib_dir" arity="2"/>
      <fsummary>subdirectory for an application</fsummary>
      <desc>

Returns the path to a subdirectory directly under the top
         directory of an application. Normally the subdirectories
         resides under the top directory for the application, but when
         applications at least partly resides in an archive the
         situation is different. Some of the subdirectories may reside
         as regular directories while other resides in an archive
         file. It is not checked if this directory really exists.

> <input>code:lib_dir(megaco, priv).</input>
"/usr/local/otp/lib/megaco-3.9.1.1/priv"

Fails with an exception if <c><anno>Name</anno></c> or <c><anno>SubDir</anno></c> has
        the wrong type.

      </desc>
    </func>
    <func>
      <name name="compiler_dir" arity="0"/>
      <fsummary>Library directory for the compiler</fsummary>
      <desc>

Returns the compiler library directory. Equivalent to
          <c>code:lib_dir(compiler)</c>.

      </desc>
    </func>
    <func>
      <name name="priv_dir" arity="1"/>
      <fsummary>Priv directory for an application</fsummary>
      <desc>

Returns the path to the <c>priv</c> directory in an
         application. Equivalent to <c>code:lib_dir(<anno>Name</anno>, priv).</c>.

	<warning>
For backward compatibility, <c><anno>Name</anno></c> is also allowed to
	be a string. That will probably change in a future release.
</warning>
      </desc>
    </func>
    <func>
      <name name="objfile_extension" arity="0"/>
      <fsummary>Object code file extension</fsummary>
      <desc>

Returns the object code file extension that corresponds to
          the Erlang machine used, namely <c>".beam"</c>.

      </desc>
    </func>
    <func>
      <name name="stick_dir" arity="1"/>
      <fsummary>Mark a directory as sticky</fsummary>
      <desc>

This function marks <c><anno>Dir</anno></c> as sticky.

Returns <c>ok</c> if successful or <c>error</c> if not.

      </desc>
    </func>
    <func>
      <name name="unstick_dir" arity="1"/>
      <fsummary>Remove a sticky directory mark</fsummary>
      <desc>

This function unsticks a directory which has been marked as
          sticky.

Returns <c>ok</c> if successful or <c>error</c> if not.

      </desc>
    </func>
    <func>
      <name name="is_sticky" arity="1"/>
      <fsummary>Test whether a module is sticky</fsummary>
      <desc>

This function returns <c>true</c> if <c><anno>Module</anno></c> is the
	name of a module that has been loaded from a sticky directory
	(or in other words: an attempt to reload the module will fail),
	or <c>false</c> if <c><anno>Module</anno></c> is not a loaded module or is
	not sticky.

      </desc>
    </func>
    <func>
      <name name="rehash" arity="0"/>
      <fsummary>Rehash or create code path cache</fsummary>
      <desc>

This function creates or rehashes the code path cache.

      </desc>
    </func>
    <func>
      <name name="where_is_file" arity="1"/>
      <fsummary>Full name of a file located in the code path</fsummary>
      <desc>

Searches the code path for <c><anno>Filename</anno></c>, a file of
          arbitrary type. If found, the full name is returned.
          <c>non_existing</c> is returned if the file cannot be found.
          The function can be useful, for example, to locate
          application resource files. If the code path cache is used,
          the code server will efficiently read the full name from
          the cache, provided that <c><anno>Filename</anno></c> is an object code
          file or an <c>.app</c> file.

      </desc>
    </func>
    <func>
      <name name="clash" arity="0"/>
      <fsummary>Search for modules with identical names.</fsummary>
      <desc>

Searches the entire code space for module names with
          identical names and writes a report to <c>stdout</c>.

      </desc>
    </func>
    <func>
      <name name="is_module_native" arity="1"/>
      <fsummary>Test whether a module has native code</fsummary>
      <desc>

This function returns <c>true</c> if <c><anno>Module</anno></c> is
	name of a loaded module that has native code loaded, and
	<c>false</c> if <c><anno>Module</anno></c> is loaded but does not have
	native. If <c><anno>Module</anno></c> is not loaded, this function returns
	<c>undefined</c>.

      </desc>
    </func>

    <func>
      <name name="get_mode" arity="0"/>
      <fsummary>The code_server's mode.</fsummary>
      <desc>

This function returns an atom describing the code_server's mode:
        <c>interactive</c> or <c>embedded</c>.

This information is useful when an external entity (for example,
        an IDE) provides additional code for a running node. If in interactive
        mode, it only needs to add to the code path. If in embedded mode,
        the code has to be loaded with <c>load_binary/3</c>

      </desc>
    </func>
  </funcs>
</erlref>


text:
set -e

source ./install-basic-programs.sh

source ./install-npm.sh

source ./install-git.sh

source ./install-postman.sh

source ./install-aws-cli.sh

source ./install-terminator.sh

source ./install-mellow-player.sh

source ./configure-www-directory.sh

source ./configure-basic-bash-aliases.sh

# show the current git branch in linux terminal (https://gist.github.com/andrewslince/9164071)

# install nvm (https://github.com/nvm-sh/nvm#installing-and-updating)

# install google chrome (https://www.google.com/intl/pt-BR/chrome/)

# install docker (https://docs.docker.com/engine/install/ubuntu/)

# install docker compose (https://docs.docker.com/compose/install/)

# install vscode (https://code.visualstudio.com/Download)

# install vscode extensions

exit 0


text:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Bhaptics.Tact.Unity;

public class BhapticsRotateExample : MonoBehaviour
{
    public VestHapticClip vestHapticClip;
    [Space]
    public Text angleXText;
    public Text offsetYText;

    private float angleX = 0f, offsetY = 0f;

    public void PlayWithRotate()
    {
        if (vestHapticClip != null)
        {
            vestHapticClip.Play(vestHapticClip.Intensity, vestHapticClip.Duration, angleX, offsetY);
        }
    }

    public void Stop()
    {
        if (vestHapticClip != null)
        {
            vestHapticClip.Stop();
        }
    }

    public void OnAngleXChanged(Slider slider)
    {
        if (slider != null)
        {
            angleX = slider.value * 360f;
            angleXText.text = Mathf.RoundToInt(angleX).ToString();
        }
    }

    public void OnOffsetYChanged(Slider slider)
    {
        if (slider != null)
        {
            offsetY = slider.value - 0.5f;
            offsetYText.text = (Mathf.RoundToInt(offsetY * 100f) / 100f).ToString();
        }
    }
}


text:
package com.spring.sharepoint.interceptor.test.service;

import java.lang.reflect.Method;
import java.util.Map;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import com.spring.sharepoint.interceptor.test.dataprovider.SharepointInterceptorDataProvider;

public class SharepointInterceptorTest extends SharepointInterceptorDataProvider {

	@BeforeMethod( alwaysRun = true )
	public void beforeMethod( Method m )
	{
		System.out.println( "****************** Starting test: " + m.getName() + "*************************" );
	}

	@AfterMethod( alwaysRun = true )
	public void afterMethod( Method m )
	{
		System.out.println( "****************** Finished test: " + m.getName() + "*************************" );
		System.out.println();
	}

	//--------------- Test Cases ---------------------------

	@Test( dataProvider = "SharepointInterceptor", groups = { "SharepointInterceptor" } )
	public void testSharepointInterceptor(String url) {

		try {
			HttpHeaders headers = new HttpHeaders();
			HttpEntity<String> entity = new HttpEntity<String>( "", headers );

			@SuppressWarnings("rawtypes")
			ResponseEntity<Map> result = restTemplate.exchange( url, HttpMethod.POST, entity, Map.class );

			System.out.println(result.getBody());
		} catch (Exception e) {
			e.printStackTrace();
			Assert.fail(e.getMessage());
		}

	}

}


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <title>FCC News</title>
    <link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'>
    <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.9/css/weather-icons.css'>
    <link rel="stylesheet" href="css/style.css">


text:
require '../lib/twitpic'

twitpic = TwitPic::Client.new

# This part is optional and only required if you are calling
# write enabled methods against the TwitPic API, which we are here.
twitpic.configure do |conf|
  conf.api_key = "your api key"
  conf.consumer_key = "app consumer key"
  conf.consumer_secret = "app consumer secret"
  conf.oauth_token = "user oauth token"
  conf.oauth_secret = "user oauth secret"
end

media = twitpic.upload("/path/to/file.jpg", "Uploading from Ruby!")

puts media.to_s


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Anal. Mus. nac. Hist. nat. B. Aires 31: 400 (1922)

#### Original name
Meliola furcata var. coperniciae Speg.

### Remarks
null


text:
/* eslint-env node */

"use strict";

var fs    = require("fs-extra"),
    path  = require("path"),
    spawn = require("child_process").spawn;

var Errors = {
    NPM_INSTALL_FAILED: "NPM_INSTALL_FAILED"
};

/**
 * Private function to run "npm install --production" command in the extension directory.
 *
 * @param {string} installDirectory Directory to remove
 * @param {array} npmOptions can contain additional options like `--production` or `--proxy http://127.0.0.1:8888`
 * @param {function} callback NodeJS style callback to call after finish
 */
function _performNpmInstall(installDirectory, npmOptions, callback) {
    var npmPath = path.resolve(path.dirname(require.resolve("npm")), "..", "bin", "npm-cli.js");
    var args = [npmPath, "install"].concat(npmOptions);

    console.log("running npm " + args.slice(1).join(" ") + " in " + installDirectory);

    var child = spawn(process.execPath, args, { cwd: installDirectory });

    child.on("error", function (err) {
        return callback(err);
    });

    var stdout = [];
    child.stdout.addListener("data", function (buffer) {
        stdout.push(buffer);
    });

    var stderr = [];
    child.stderr.addListener("data", function (buffer) {
        stderr.push(buffer);
    });

    var exitCode = 0;
    child.addListener("exit", function (code) {
        exitCode = code;
    });

    child.addListener("close", function () {
        stderr = Buffer.concat(stderr).toString();
        stdout = Buffer.concat(stdout).toString();
        if (exitCode > 0) {
            console.error("npm-stderr: " + stderr);
            return callback(new Error(stderr));
        }
        if (stderr) {
            console.warn("npm-stderr: " + stderr);
        }
        console.log("npm-stdout: " + stdout);
        return callback();
    });

    child.stdin.end();
}

/**
 * Checks package.json of the extracted extension for npm dependencies
 * and runs npm install when required.
 * @param {Object} validationResult return value of the validation procedure
 * @param {Function} callback function to be called after the end of validation procedure
 */
function performNpmInstallIfRequired(npmOptions, validationResult, callback) {

    function finish() {
        callback(null, validationResult);
    }

    var installDirectory = path.join(validationResult.extractDir, validationResult.commonPrefix);
    var packageJson;

    try {
        packageJson = fs.readJsonSync(path.join(installDirectory, "package.json"));
    } catch (e) {
        packageJson = null;
    }

    if (!packageJson || !packageJson.dependencies || !Object.keys(packageJson.dependencies).length) {
        return finish();
    }

    _performNpmInstall(installDirectory, npmOptions, function (err) {
        if (err) {
            validationResult.errors.push([Errors.NPM_INSTALL_FAILED, err.toString()]);
        }
        finish();
    });
}

exports.performNpmInstallIfRequired = performNpmInstallIfRequired;


text:
console.log("x");
console.log("x");
console.log("x");
console.log("x");
console.log("x");