@Test
  public void testAddAndGetDatasetVersion() throws Exception {
    Account testAccount = makeTestAccountWithContainer();
    Container testContainer = new ArrayList<>(testAccount.getAllContainers()).get(0);
    Map<String, String> userTags = new HashMap<>();
    List<Long> versions = new ArrayList<>();
    userTags.put("userTag", "tagValue");
    long datasetTtl = 3600L;
    Dataset dataset = new DatasetBuilder(testAccount.getName(), testContainer.getName(), DATASET_NAME).setVersionSchema(
        Dataset.VersionSchema.MONOTONIC).setRetentionTimeInSeconds(datasetTtl).setUserTags(userTags).build();

    // Add a dataset to db
    mySqlAccountStore.addDataset(testAccount.getId(), testContainer.getId(), dataset);

    // Add a valid dataset version
    long versionNumber = 1;
    String version = String.valueOf(versionNumber);
    versions.add(versionNumber);
    long creationTimeInMs = System.currentTimeMillis();
    DatasetVersionRecord expectedDatasetVersionRecord =
        new DatasetVersionRecord(testAccount.getId(), testContainer.getId(), DATASET_NAME, version,
            Utils.addSecondsToEpochTime(creationTimeInMs, datasetTtl), null);
    DatasetVersionRecord datasetVersionRecordFromMysql =
        mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
            testContainer.getName(), DATASET_NAME, version, -1, creationTimeInMs, false, DatasetVersionState.READY);
    assertEquals("Mismatch in dataset", expectedDatasetVersionRecord, datasetVersionRecordFromMysql);

    // Get the dataset version
    datasetVersionRecordFromMysql =
        mySqlAccountStore.getDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
            testContainer.getName(), DATASET_NAME, version);
    assertEquals("Mismatch in dataset version read from db", expectedDatasetVersionRecord,
        datasetVersionRecordFromMysql);

    // Enable datasetVersionTtlEnable and add a valid dataset version with ttl and get from DB, should use the dataset
    // version level ttl.
    versionNumber = 2;
    version = String.valueOf(versionNumber);
    versions.add(versionNumber);
    creationTimeInMs = System.currentTimeMillis();
    long datasetVersionTtl = 360L;
    boolean datasetVersionTtlEnable = true;
    expectedDatasetVersionRecord =
        new DatasetVersionRecord(testAccount.getId(), testContainer.getId(), DATASET_NAME, version,
            Utils.addSecondsToEpochTime(creationTimeInMs, datasetVersionTtl), null);
    mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
        testContainer.getName(), DATASET_NAME, version, datasetVersionTtl, creationTimeInMs, datasetVersionTtlEnable,
        DatasetVersionState.READY);
    datasetVersionRecordFromMysql =
        mySqlAccountStore.getDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
            testContainer.getName(), DATASET_NAME, version);
    assertEquals("Mismatch in dataset version read from db", expectedDatasetVersionRecord,
        datasetVersionRecordFromMysql);

    // Disable datasetVersionTtlEnable and add a valid dataset version with ttl and get from DB, should use the dataset
    // level ttl.
    versionNumber = 3;
    datasetVersionTtlEnable = false;
    version = String.valueOf(versionNumber);
    versions.add(versionNumber);
    expectedDatasetVersionRecord =
        new DatasetVersionRecord(testAccount.getId(), testContainer.getId(), DATASET_NAME, version,
            Utils.addSecondsToEpochTime(creationTimeInMs, datasetTtl), null);
    mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
        testContainer.getName(), DATASET_NAME, version, datasetVersionTtl, creationTimeInMs, datasetVersionTtlEnable,
        DatasetVersionState.READY);
    datasetVersionRecordFromMysql =
        mySqlAccountStore.getDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
            testContainer.getName(), DATASET_NAME, version);
    assertEquals("Mismatch in dataset version read from db", expectedDatasetVersionRecord,
        datasetVersionRecordFromMysql);

    // Add a permanent dataset version, it should inherit from dataset level ttl.
    versionNumber = 4;
    version = String.valueOf(versionNumber);
    versions.add(versionNumber);
    creationTimeInMs = System.currentTimeMillis();
    mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
        testContainer.getName(), DATASET_NAME, version, -1, creationTimeInMs, false, DatasetVersionState.READY);
    DatasetVersionRecord datasetVersionRecordWithTtl =
        mySqlAccountStore.getDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
            testContainer.getName(), DATASET_NAME, version);
    assertEquals("Mismatch in dataset expirationTimeMs", (long) dataset.getRetentionTimeInSeconds(),
        TimeUnit.MILLISECONDS.toSeconds(datasetVersionRecordWithTtl.getExpirationTimeMs() - creationTimeInMs));

    //Test semantic version.
    dataset =
        new DatasetBuilder(testAccount.getName(), testContainer.getName(), DATASET_NAME_WITH_SEMANTIC).setVersionSchema(
            Dataset.VersionSchema.SEMANTIC).setRetentionTimeInSeconds((long) -1).setUserTags(userTags).build();
    // Add a dataset to db
    mySqlAccountStore.addDataset(testAccount.getId(), testContainer.getId(), dataset);
    version = "1.2.4";
    mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
        testContainer.getName(), DATASET_NAME_WITH_SEMANTIC, version, -1, System.currentTimeMillis(), false,
        DatasetVersionState.READY);
    DatasetVersionRecord datasetVersionRecordWithSemanticVersion =
        mySqlAccountStore.getDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
            testContainer.getName(), DATASET_NAME_WITH_SEMANTIC, version);
    assertEquals("Mismatch in dataset version", version, datasetVersionRecordWithSemanticVersion.getVersion());

    // Add dataset version for non-existing dataset.
    try {
      mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
          testContainer.getName(), "NonExistingDataset", version, -1, System.currentTimeMillis(), false,
          DatasetVersionState.READY);
      fail("Add dataset version should fail without dataset");
    } catch (AccountServiceException e) {
      assertEquals("Unexpected ErrorCode", AccountServiceErrorCode.NotFound, e.getErrorCode());
    }

    //add same dataset version, should fail
    try {
      mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
          testContainer.getName(), DATASET_NAME_WITH_SEMANTIC, version, -1, 0, false, DatasetVersionState.READY);
      fail("Should fail due to dataset version already exist");
    } catch (AccountServiceException e) {
      assertEquals("Unexpected error code", AccountServiceErrorCode.ResourceConflict, e.getErrorCode());
    }

    //Delete dataset version
    mySqlAccountStore.deleteDatasetVersion(testAccount.getId(), testContainer.getId(), DATASET_NAME_WITH_SEMANTIC,
        version);

    //add dataset version again, should succeed.
    mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
        testContainer.getName(), DATASET_NAME_WITH_SEMANTIC, version, -1, System.currentTimeMillis(), false,
        DatasetVersionState.READY);

    //get the new added dataset version, should not fail.
    mySqlAccountStore.getDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
        testContainer.getName(), DATASET_NAME_WITH_SEMANTIC, version);

    // Add dataset version which didn't follow the semantic format.
    version = "1.2";
    try {
      mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
          testContainer.getName(), DATASET_NAME_WITH_SEMANTIC, version, -1, System.currentTimeMillis(), false,
          DatasetVersionState.READY);
      fail("Add dataset version should fail with wrong format of semantic version");
    } catch (IllegalArgumentException e) {
      // do nothing
    }

    //delete the dataset, and can't add or get any dataset version.
    mySqlAccountStore.deleteDataset(testAccount.getId(), testContainer.getId(), DATASET_NAME);
    version = "1";
    try {
      mySqlAccountStore.addDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
          testContainer.getName(), DATASET_NAME, version, -1, System.currentTimeMillis(), false,
          DatasetVersionState.READY);
      fail("Should fail due to the dataset already gone");
    } catch (AccountServiceException e) {
      assertEquals("Unexpected error code", AccountServiceErrorCode.Deleted, e.getErrorCode());
    }

    try {
      mySqlAccountStore.getDatasetVersion(testAccount.getId(), testContainer.getId(), testAccount.getName(),
          testContainer.getName(), DATASET_NAME, version);
      fail("Should fail due to the dataset already gone");
    } catch (AccountServiceException e) {
      assertEquals("Unexpected error code", AccountServiceErrorCode.Deleted, e.getErrorCode());
    }

    List<DatasetVersionRecord> datasetVersionRecords =
        mySqlAccountStore.getAllValidVersionForDatasetDeletion(testAccount.getId(), testContainer.getId(),
            DATASET_NAME);
    assertEquals("Mismatch on number of valid dataset versions", 4, datasetVersionRecords.size());

    mySqlAccountStore.deleteDatasetVersion(testAccount.getId(), testContainer.getId(), DATASET_NAME, "1");

    datasetVersionRecords =
        mySqlAccountStore.getAllValidVersionForDatasetDeletion(testAccount.getId(), testContainer.getId(),
            DATASET_NAME);
    assertEquals("Mismatch on number of valid dataset versions", 3, datasetVersionRecords.size());

    datasetVersionRecords =
        mySqlAccountStore.getAllValidVersionForDatasetDeletion(testAccount.getId(), testContainer.getId(),
            DATASET_NAME_WITH_SEMANTIC);
    assertEquals("Mismatch on number of valid dataset versions", 1, datasetVersionRecords.size());
    assertEquals("Mismatch on valid dataset versions", "1.2.4", datasetVersionRecords.get(0).getVersion());
  }
Test add and get dataset version with different input.
ambry-account/src/integration-test/java/com/github/ambry/account/MySqlAccountServiceIntegrationTest.java