Skip to content

Commit

Permalink
cleanup obsolete frozen rules
Browse files Browse the repository at this point in the history
Signed-off-by: Masoud Kiaeeha <6916434+maxxkia@users.noreply.github.com>

Resolves TNG#1264
  • Loading branch information
maxxkia committed Jan 19, 2025
1 parent 73dfe66 commit 39fe12b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
import java.nio.file.Files;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.google.common.base.Splitter;
import com.tngtech.archunit.PublicAPI;
Expand Down Expand Up @@ -110,6 +112,7 @@ public void initialize(Properties properties) {
log.trace("Initializing {} at {}", TextFileBasedViolationStore.class.getSimpleName(), storedRulesFile.getAbsolutePath());
storedRules = new FileSyncedProperties(storedRulesFile);
checkInitialization(storedRules.initializationSuccessful(), "Cannot create rule store at %s", storedRulesFile.getAbsolutePath());
cleanupObsoleteRules();
}

private File getStoredRulesFile() {
Expand All @@ -132,6 +135,18 @@ private void checkInitialization(boolean initializationSuccessful, String messag
}
}

private void cleanupObsoleteRules() {
Set<String> obsoleteStoredRules = storedRules.keySet().stream()
.filter(ruleDescription -> !new File(storeFolder, storedRules.getProperty(ruleDescription)).exists())
.collect(Collectors.toSet());
if (!obsoleteStoredRules.isEmpty() && !storeUpdateAllowed) {
throw new StoreUpdateFailedException(String.format(
"Failed to remove %d obsolete stored rule(s). Updating frozen violations is disabled (enable by configuration %s.%s=true)",
obsoleteStoredRules.size(), ViolationStoreFactory.FREEZE_STORE_PROPERTY_NAME, ALLOW_STORE_UPDATE_PROPERTY_NAME));
}
obsoleteStoredRules.forEach(storedRules::removeProperty);
}

@Override
public boolean contains(ArchRule rule) {
return storedRules.containsKey(rule.getDescription());
Expand Down Expand Up @@ -255,6 +270,15 @@ void setProperty(String propertyName, String value) {
syncFileSystem();
}

void removeProperty(String propertyName) {
loadedProperties.remove(ensureUnixLineBreaks(propertyName));
syncFileSystem();
}

Set<String> keySet() {
return loadedProperties.stringPropertyNames();
}

private void syncFileSystem() {
try (FileOutputStream outputStream = new FileOutputStream(propertiesFile)) {
loadedProperties.store(outputStream, "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
import com.tngtech.archunit.lang.ArchRule;
import org.assertj.core.api.ThrowableAssert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -38,6 +39,38 @@ public void setUp() throws Exception {
"default.allowStoreCreation", String.valueOf(true)));
}

@Test
public void throws_exception_when_there_are_obsolete_entries_in_storedRules_files() throws Exception {
// given
store.save(defaultRule(), ImmutableList.of("first violation", "second violation"));
Properties properties = readProperties(new File(configuredFolder, "stored.rules"));
File ruleViolationsFile = new File(configuredFolder, properties.getProperty(defaultRule().getDescription()));
assertThat(ruleViolationsFile.delete()).isTrue();

// when && then
ThrowableAssert.ThrowingCallable storeInitialization = () -> store.initialize(propertiesOf(
"default.path", configuredFolder.getAbsolutePath(),
"default.allowStoreUpdate", String.valueOf(false)));
assertThatThrownBy(storeInitialization)
.isInstanceOf(StoreUpdateFailedException.class)
.hasMessage("Failed to remove 1 obsolete stored rule(s). Updating frozen violations is disabled (enable by configuration freeze.store.default.allowStoreUpdate=true)");
}

@Test
public void deletes_obsolete_entries_from_storedRules_files() throws Exception {
// given
store.save(defaultRule(), ImmutableList.of("first violation", "second violation"));
Properties properties = readProperties(new File(configuredFolder, "stored.rules"));
File ruleViolationsFile = new File(configuredFolder, properties.getProperty(defaultRule().getDescription()));
assertThat(ruleViolationsFile.delete()).isTrue();

// when
store.initialize(propertiesOf("default.path", configuredFolder.getAbsolutePath()));

// then
assertThat(store.contains(defaultRule())).isFalse();
}

@Test
public void reports_unknown_rule_as_unstored() {
assertThat(store.contains(defaultRule())).as("store contains random rule").isFalse();
Expand Down

0 comments on commit 39fe12b

Please sign in to comment.