<commit_before>package jetbrains.buildServer.clouds.vmware;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import jetbrains.buildServer.BaseTestCase;
import jetbrains.buildServer.clouds.*;
import jetbrains.buildServer.clouds.base.stubs.DummyCloudManagerBase;
import jetbrains.buildServer.clouds.server.impl.CloudManagerBase;
import jetbrains.buildServer.clouds.server.impl.profile.CloudProfileDataImpl;
import jetbrains.buildServer.clouds.server.impl.profile.CloudProfileImpl;
import jetbrains.buildServer.clouds.vmware.stubs.FakeApiConnector;
import jetbrains.buildServer.clouds.vmware.tasks.VmwareUpdateTaskManager;
import jetbrains.buildServer.clouds.vmware.web.VMWareWebConstants;
import jetbrains.buildServer.serverSide.InvalidProperty;
import org.jetbrains.annotations.NotNull;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import static jetbrains.buildServer.clouds.vmware.VmwareCloudIntegrationTest.PROFILE_ID;
import static jetbrains.buildServer.clouds.vmware.VmwareCloudIntegrationTest.TEST_SERVER_UUID;

/**
 * Created by Sergey.Pak on 6/9/2016.
 */
@Test
public class VmwarePropertiesProcessorTest extends BaseTestCase {
  private VmwarePropertiesProcessor myProcessor;
  private Map<String, String> myProperties;
  private Collection<CloudProfile> myProfiles;
  private Map<String, CloudClientEx> myClients;

  @BeforeMethod
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    final CloudManagerBase cloudManager = new DummyCloudManagerBase(){
      @NotNull
      @Override
      public Collection<CloudProfile> listProfiles() {
        return myProfiles;
      }

      @NotNull
      @Override
      public CloudClientEx getClient(@NotNull final String profileId) {
        return myClients.get(profileId);
      }
    };
    myProcessor = new VmwarePropertiesProcessor(cloudManager);
    myProfiles = new ArrayList<>();
    myClients = new HashMap<>();

    myProperties = new HashMap<>();
    myProperties.put(VMWareWebConstants.USERNAME, "un");
    myProperties.put(VMWareWebConstants.SECURE_PASSWORD, "pw");
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:9099");
  }

  public void check_base_properties(){
    check_no_errors();
    myProperties.remove(VMWareWebConstants.USERNAME);
    expect_error(VMWareWebConstants.USERNAME, "Value should be set");
    myProperties.put(VMWareWebConstants.USERNAME, "un");
    myProperties.remove(VMWareWebConstants.SECURE_PASSWORD);
    expect_error(VMWareWebConstants.SECURE_PASSWORD, "Value should be set");
    myProperties.put(VMWareWebConstants.SECURE_PASSWORD, "pw");
    myProperties.remove(VMWareWebConstants.SERVER_URL);
    expect_error(VMWareWebConstants.SERVER_URL, "Value should be set");

  }

  public void check_profile_instance_limit(){
    myProperties.put(VMWareWebConstants.PROFILE_INSTANCE_LIMIT, "2");
    check_no_errors();
    myProperties.put(VMWareWebConstants.PROFILE_INSTANCE_LIMIT, "0");
    expect_error("vmware_profile_instance_limit", "Must be a positive integer or empty");

    myProperties.put(VMWareWebConstants.PROFILE_INSTANCE_LIMIT, "aaaa");
    expect_error("vmware_profile_instance_limit", "Must be a positive integer or empty");
  }

  public void check_same_source_ids_new_profile() throws IOException {
    final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
    profileData.setCloudCode(VmwareConstants.TYPE);
    profileData.setName("Vmware profile");
    CloudClientParameters cloudClientParameters = new CloudClientParameters();
    cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
    cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{sourceVmName:'image1', behaviour:'START_STOP'}," +
                                                                                 "{sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                                 "customizationSpec:'someCustomization'}," +
                                                                                 "{sourceVmName:'image_template', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                                 "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
    profileData.setParameters(cloudClientParameters);
    final String profileId = "vmw-1";
    myProfiles.add(new CloudProfileImpl(profileId, profileData));
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                              "customizationSpec:'someCustomization'}]");

    myClients.put(profileId, createClient(cloudClientParameters));

    expect_error("source_images_json", "The cloud profile 'Vmware profile' already contains an image named 'IMAGE2'. Select a different VM or change the custom name.");
  }

  public void check_same_source_ids_edit_profile() throws IOException {
    {
      final String profileId = "vmw-1";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image1',sourceVmName:'image1', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template',sourceVmName:'image_template', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }
    {
      final String profileId = "vmw-2";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile 2");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image3',sourceVmName:'image3', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image4',sourceVmName:'image4',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template2',sourceVmName:'image_template2', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }

    myProperties.put(CloudConstants.PROFILE_ID, "vmw-2");
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                              "customizationSpec:'someCustomization'}]");

    expect_error("source_images_json", "The cloud profile 'Vmware profile' already contains an image named 'IMAGE2'. Select a different VM or change the custom name.");

    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image3',sourceVmName:'image2',nickname:'image3',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                     "customizationSpec:'someCustomization'}]");

    check_no_errors();
  }

  public void check_same_source_same_server_url() throws IOException {
    {
      final String profileId = "vmw-1";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8081");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image1',sourceVmName:'image1', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template',sourceVmName:'image_template', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }
    {
      final String profileId = "vmw-2";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile 2");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8082");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image3',sourceVmName:'image3', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image4',sourceVmName:'image4',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template2',sourceVmName:'image_template2', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:8081");
    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                     "customizationSpec:'someCustomization'}]");<commit_msg>TW-45019 - Cloud profiles on project level - WIP<commit_after>package jetbrains.buildServer.clouds.vmware;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import jetbrains.buildServer.BaseTestCase;
import jetbrains.buildServer.clouds.*;
import jetbrains.buildServer.clouds.base.stubs.DummyCloudManagerBase;
import jetbrains.buildServer.clouds.server.impl.CloudManagerBase;
import jetbrains.buildServer.clouds.server.impl.profile.CloudProfileDataImpl;
import jetbrains.buildServer.clouds.server.impl.profile.CloudProfileImpl;
import jetbrains.buildServer.clouds.vmware.stubs.FakeApiConnector;
import jetbrains.buildServer.clouds.vmware.tasks.VmwareUpdateTaskManager;
import jetbrains.buildServer.clouds.vmware.web.VMWareWebConstants;
import jetbrains.buildServer.serverSide.InvalidProperty;
import org.jetbrains.annotations.NotNull;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import static jetbrains.buildServer.clouds.vmware.VmwareCloudIntegrationTest.PROFILE_ID;
import static jetbrains.buildServer.clouds.vmware.VmwareCloudIntegrationTest.TEST_SERVER_UUID;

/**
 * Created by Sergey.Pak on 6/9/2016.
 */
@Test
public class VmwarePropertiesProcessorTest extends BaseTestCase {
  private VmwarePropertiesProcessor myProcessor;
  private Map<String, String> myProperties;
  private Collection<CloudProfile> myProfiles;
  private Map<String, CloudClientEx> myClients;
  private static final String PROJECT_ID = "MyProjectId";

  @BeforeMethod
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    final CloudManagerBase cloudManager = new DummyCloudManagerBase(){
      @NotNull
      @Override
      public Collection<CloudProfile> listProfiles() {
        return myProfiles;
      }

      @NotNull
      @Override
      public CloudClientEx getClient(@NotNull final String profileId) {
        return myClients.get(profileId);
      }
    };
    myProcessor = new VmwarePropertiesProcessor(cloudManager);
    myProfiles = new ArrayList<>();
    myClients = new HashMap<>();

    myProperties = new HashMap<>();
    myProperties.put(VMWareWebConstants.USERNAME, "un");
    myProperties.put(VMWareWebConstants.SECURE_PASSWORD, "pw");
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:9099");
  }

  public void check_base_properties(){
    check_no_errors();
    myProperties.remove(VMWareWebConstants.USERNAME);
    expect_error(VMWareWebConstants.USERNAME, "Value should be set");
    myProperties.put(VMWareWebConstants.USERNAME, "un");
    myProperties.remove(VMWareWebConstants.SECURE_PASSWORD);
    expect_error(VMWareWebConstants.SECURE_PASSWORD, "Value should be set");
    myProperties.put(VMWareWebConstants.SECURE_PASSWORD, "pw");
    myProperties.remove(VMWareWebConstants.SERVER_URL);
    expect_error(VMWareWebConstants.SERVER_URL, "Value should be set");

  }

  public void check_profile_instance_limit(){
    myProperties.put(VMWareWebConstants.PROFILE_INSTANCE_LIMIT, "2");
    check_no_errors();
    myProperties.put(VMWareWebConstants.PROFILE_INSTANCE_LIMIT, "0");
    expect_error("vmware_profile_instance_limit", "Must be a positive integer or empty");

    myProperties.put(VMWareWebConstants.PROFILE_INSTANCE_LIMIT, "aaaa");
    expect_error("vmware_profile_instance_limit", "Must be a positive integer or empty");
  }

  public void check_same_source_ids_new_profile() throws IOException {
    final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
    profileData.setCloudCode(VmwareConstants.TYPE);
    profileData.setName("Vmware profile");
    CloudClientParameters cloudClientParameters = new CloudClientParameters();
    cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
    cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{sourceVmName:'image1', behaviour:'START_STOP'}," +
                                                                                 "{sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                                 "customizationSpec:'someCustomization'}," +
                                                                                 "{sourceVmName:'image_template', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                                 "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
    profileData.setParameters(cloudClientParameters);
    final String profileId = "vmw-1";
    myProfiles.add(new CloudProfileImpl(PROJECT_ID, profileId, profileData));
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                              "customizationSpec:'someCustomization'}]");

    myClients.put(profileId, createClient(cloudClientParameters));

    expect_error("source_images_json", "The cloud profile 'Vmware profile' already contains an image named 'IMAGE2'. Select a different VM or change the custom name.");
  }

  public void check_same_source_ids_edit_profile() throws IOException {
    {
      final String profileId = "vmw-1";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image1',sourceVmName:'image1', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template',sourceVmName:'image_template', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(PROJECT_ID, profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }
    {
      final String profileId = "vmw-2";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile 2");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image3',sourceVmName:'image3', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image4',sourceVmName:'image4',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template2',sourceVmName:'image_template2', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(PROJECT_ID, profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }

    myProperties.put(CloudConstants.PROFILE_ID, "vmw-2");
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:8080");
    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                              "customizationSpec:'someCustomization'}]");

    expect_error("source_images_json", "The cloud profile 'Vmware profile' already contains an image named 'IMAGE2'. Select a different VM or change the custom name.");

    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image3',sourceVmName:'image2',nickname:'image3',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                     "customizationSpec:'someCustomization'}]");

    check_no_errors();
  }

  public void check_same_source_same_server_url() throws IOException {
    {
      final String profileId = "vmw-1";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8081");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image1',sourceVmName:'image1', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template',sourceVmName:'image_template', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(PROJECT_ID, profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }
    {
      final String profileId = "vmw-2";
      final CloudProfileDataImpl profileData = new CloudProfileDataImpl();
      profileData.setCloudCode(VmwareConstants.TYPE);
      profileData.setName("Vmware profile 2");
      CloudClientParameters cloudClientParameters = new CloudClientParameters();
      cloudClientParameters.setParameter(VMWareWebConstants.SERVER_URL, "http://localhost:8082");
      cloudClientParameters.setCloudImages(CloudImageParameters.collectionFromJson("[{'source-id':'image3',sourceVmName:'image3', behaviour:'START_STOP'}," +
                                                                              "{'source-id':'image4',sourceVmName:'image4',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                                                                              "customizationSpec:'someCustomization'}," +
                                                                              "{'source-id':'image_template2',sourceVmName:'image_template2', snapshot:'" + VmwareConstants.CURRENT_STATE +
                                                                              "',folder:'cf',pool:'rp',maxInstances:3,behaviour:'FRESH_CLONE', customizationSpec: 'linux'}]"));
      profileData.setParameters(cloudClientParameters);
      myProfiles.add(new CloudProfileImpl(PROJECT_ID, profileId, profileData));
      myClients.put(profileId, createClient(cloudClientParameters));
    }
    myProperties.put(VMWareWebConstants.SERVER_URL, "http://localhost:8081");
    myProperties.put(CloudImageParameters.SOURCE_IMAGES_JSON,
                     "[{'source-id':'image2',sourceVmName:'image2',snapshot:'snap*',folder:'cf',pool:'rp',maxInstances:3,behaviour:'ON_DEMAND_CLONE', " +
                     "customizationSpec:'someCustomization'}]");
{'fraction_non_alphanumeric': 0.11233922039098454, 'fraction_numerical': 0.007984895567006255, 'mean_word_length': 3.045830681094844, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 128, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2282934', 'n_tokens_mistral': 6610, 'n_tokens_neox': 6447, 'n_words': 858}