use of com.github.ambry.account.Account in project ambry by linkedin.
the class HelixAccountServiceTest method testConflictingSnapshotVersionUpdate.
/**
* Test updating an account with a conflicting expected snapshot version.
*/
@Test
public void testConflictingSnapshotVersionUpdate() throws Exception {
accountService = mockHelixAccountServiceFactory.getAccountService();
// write two accounts (1, "a") and (2, "b")
writeAccountsForConflictTest();
Account expectedAccount = accountService.getAccountById((short) 1);
int currentSnapshotVersion = expectedAccount.getSnapshotVersion();
for (int snapshotVersionOffset : new int[] { -2, -1, 1 }) {
int snapshotVersionToUse = currentSnapshotVersion + snapshotVersionOffset;
Collection<Account> conflictAccounts = Collections.singleton(new AccountBuilder((short) 1, "c", AccountStatus.INACTIVE).snapshotVersion(snapshotVersionToUse).build());
assertUpdateAccountsFails(conflictAccounts, AccountServiceErrorCode.ResourceConflict, accountService);
assertEquals("Wrong account number in HelixAccountService", 2, accountService.getAllAccounts().size());
Account account = accountService.getAccountById((short) 1);
assertEquals("Account should not have been updated", expectedAccount, account);
assertEquals("Snapshot version should not have been updated", currentSnapshotVersion, account.getSnapshotVersion());
}
Collection<Account> validAccounts = Collections.singleton(new AccountBuilder((short) 1, "c", AccountStatus.INACTIVE).snapshotVersion(currentSnapshotVersion).build());
updateAccountsAndAssertAccountExistence(validAccounts, 2, true);
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class HelixAccountServiceTest method testReadConflictAccountDataFromHelixPropertyStoreCase1.
/**
* Tests reading conflicting {@link Account} metadata from {@link HelixPropertyStore}. Two {@link Account}s have
* different accountIds but the same accountNames. This is a BAD record that should impact fetching or updating
* {@link Account}s.
* @throws Exception Any unexpected exception.
*/
@Test
public void testReadConflictAccountDataFromHelixPropertyStoreCase1() throws Exception {
List<Account> conflictAccounts = new ArrayList<>();
Account account1 = new AccountBuilder((short) 1, "a", AccountStatus.INACTIVE).build();
Account account2 = new AccountBuilder((short) 2, "a", AccountStatus.INACTIVE).build();
conflictAccounts.add(account1);
conflictAccounts.add(account2);
readAndUpdateBadRecord(conflictAccounts);
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class HelixAccountServiceTest method testUpdateDisabled.
/**
* Tests disabling account updates. By setting the {@link HelixAccountServiceConfig#UPDATE_DISABLED} to be true, all the
* account update request should be rejected.
*/
@Test
public void testUpdateDisabled() throws Exception {
helixConfigProps.setProperty(HelixAccountServiceConfig.UPDATE_DISABLED, "true");
vHelixConfigProps = new VerifiableProperties(helixConfigProps);
storeConfig = new HelixPropertyStoreConfig(vHelixConfigProps);
String updaterThreadPrefix = UUID.randomUUID().toString();
MockHelixAccountServiceFactory mockHelixAccountServiceFactory = new MockHelixAccountServiceFactory(vHelixConfigProps, new MetricRegistry(), notifier, updaterThreadPrefix, mockRouter);
accountService = mockHelixAccountServiceFactory.getAccountService();
// add a new account
Account newAccountWithoutContainer = new AccountBuilder(refAccountId, refAccountName, refAccountStatus).build();
List<Account> accountsToUpdate = Collections.singletonList(newAccountWithoutContainer);
try {
accountService.updateAccounts(accountsToUpdate);
fail("Update accounts should be disabled");
} catch (AccountServiceException e) {
assertEquals("Mismatch in error code", AccountServiceErrorCode.UpdateDisabled, e.getErrorCode());
}
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class HelixAccountServiceTest method testSelectInactiveContainer.
/**
* Tests select INACTIVE {@link Container}s from DELETE_IN_PROGRESS {@link Container}s.
*/
@Test
public void testSelectInactiveContainer() throws Exception {
// generates store stats
int accountCount = 1;
int containerCount = 3;
StatsSnapshot statsSnapshot = generateStoreStats(accountCount, containerCount, random, StatsReportType.ACCOUNT_REPORT);
// a set that records the account ids that have already been taken.
Set<Short> accountIdSet = new HashSet<>();
// generate a single reference account and container that can be referenced by refAccount and refContainer respectively.
refAccountId = Utils.getRandomShort(random);
accountIdSet.add(refAccountId);
generateRefAccounts(idToRefAccountMap, idToRefContainerMap, accountIdSet, 2, 3);
accountService = mockHelixAccountServiceFactory.getAccountService();
accountService.updateAccounts(idToRefAccountMap.values());
assertAccountsInAccountService(idToRefAccountMap.values(), 2, accountService);
Set<Container> expectContainerSet = new HashSet<>();
List<Account> accountsToUpdate = new ArrayList<>();
int accountId = 0;
for (Account account : accountService.getAllAccounts()) {
AccountBuilder accountBuilder = new AccountBuilder((short) accountId, "A[" + accountId + "]", AccountStatus.ACTIVE);
int containerId = 0;
for (Container container : account.getAllContainers()) {
ContainerBuilder containerBuilder = new ContainerBuilder((short) containerId, "C[" + containerId + "]", ContainerStatus.DELETE_IN_PROGRESS, container.getDescription() + "--extra", (short) accountId);
accountBuilder.addOrUpdateContainer(containerBuilder.build());
containerId++;
}
accountsToUpdate.add(accountBuilder.build());
if (accountId == 1) {
expectContainerSet.addAll(accountsToUpdate.get(accountId).getAllContainers());
}
accountId++;
}
updateAccountsAndAssertAccountExistence(accountsToUpdate, 4, true);
Set<Container> inactiveContainerSet = AccountUtils.selectInactiveContainerCandidates(statsSnapshot, accountService.getContainersByStatus(ContainerStatus.DELETE_IN_PROGRESS));
assertEquals("Mismatch in container Set after detect", expectContainerSet, inactiveContainerSet);
((HelixAccountService) accountService).markContainersInactive(inactiveContainerSet);
Account testAccount0 = accountService.getAccountById((short) 0);
for (Container container : testAccount0.getAllContainers()) {
assertEquals("Based on the stats report, container has not been compacted yet", ContainerStatus.DELETE_IN_PROGRESS, container.getStatus());
}
Account testAccount1 = accountService.getAccountById((short) 1);
for (Container container : testAccount1.getAllContainers()) {
assertEquals("Based on the stats report, inactive container status needs to be set as INACTIVE", ContainerStatus.INACTIVE, container.getStatus());
}
}
use of com.github.ambry.account.Account in project ambry by linkedin.
the class HelixAccountServiceTest method generateRefAccountsForDeprecationTest.
/**
* Randomly generates a collection of {@link Account}s, which do not have the same id or name with needed container status.
* @param idToRefAccountMap A map from id to {@link Account} to populate with the generated {@link Account}s.
* @param idToRefContainerMap A map from name to {@link Account} to populate with the generated {@link Account}s.
* @param accountIdSet A set of ids that could not be used to generate {@link Account}s.
* @param accountCount The number of {@link Account}s to generate.
* @param timestamp timestamp for delete trigger time.
*/
static void generateRefAccountsForDeprecationTest(Map<Short, Account> idToRefAccountMap, Map<Short, Map<Short, Container>> idToRefContainerMap, Set<Short> accountIdSet, int accountCount, long timestamp) {
idToRefAccountMap.clear();
idToRefContainerMap.clear();
for (int i = 0; i < accountCount; i++) {
short accountId = Utils.getRandomShort(random);
if (!accountIdSet.add(accountId)) {
i--;
continue;
}
String accountName = UUID.randomUUID().toString();
Account.AccountStatus accountStatus = random.nextBoolean() ? Account.AccountStatus.ACTIVE : Account.AccountStatus.INACTIVE;
Map<Short, Container> idToContainers = new HashMap<>();
List<Container> containers = new ArrayList<>();
List<ContainerBuilder> containerBuilders = AccountTestUtils.generateContainerBuilders(4, accountId);
containerBuilders.get(0).setStatus(Container.ContainerStatus.ACTIVE);
containerBuilders.get(1).setStatus(Container.ContainerStatus.INACTIVE);
containerBuilders.get(2).setStatus(Container.ContainerStatus.DELETE_IN_PROGRESS);
containerBuilders.get(2).setDeleteTriggerTime(timestamp);
containerBuilders.get(3).setStatus(Container.ContainerStatus.DELETE_IN_PROGRESS);
containerBuilders.get(3).setDeleteTriggerTime(timestamp + 10000);
containers.addAll(containerBuilders.stream().map(containerBuilder -> containerBuilder.build()).collect(Collectors.toList()));
idToContainers = containers.stream().collect(Collectors.toMap(Container::getId, Function.identity()));
Account account = new AccountBuilder(accountId, accountName, accountStatus).containers(containers).build();
assertEquals("Wrong number of generated containers for the account", 4, account.getAllContainers().size());
idToRefAccountMap.put(accountId, account);
idToRefContainerMap.put(accountId, idToContainers);
}
assertEquals("Wrong number of generated accounts", accountCount, idToRefAccountMap.size());
}
Aggregations