blob: 596afc73efd0506ef8d4c9139b3ab43392025a0a [file] [log] [blame]
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.googlesource.gerrit.plugins.its.base.workflow;
import static org.easymock.EasyMock.expect;
import com.google.common.collect.Lists;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.server.config.SitePath;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
import org.eclipse.jgit.util.FileUtils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
public class RuleBaseTest extends LoggingMockingTestCase {
private Injector injector;
private Path sitePath;
private Rule.Factory ruleFactory;
private Condition.Factory conditionFactory;
private ActionRequest.Factory actionRequestFactory;
private boolean cleanupSitePath;
private enum RuleBaseKind {
GLOBAL,
ITS,
FAULTY
}
public void testWarnNonExistingRuleBase() {
replayMocks();
createRuleBase();
assertLogMessageContains("Neither global");
}
public void testEmptyRuleBase() throws IOException {
injectRuleBase("");
replayMocks();
createRuleBase();
}
public void testSimpleRuleBase() throws IOException {
injectRuleBase("[rule \"rule1\"]\n" +
"\tconditionA = value1\n" +
"\taction = action1");
Rule rule1 = createMock(Rule.class);
expect(ruleFactory.create("rule1")).andReturn(rule1);
Condition condition1 = createMock(Condition.class);
expect(conditionFactory.create("conditionA", "value1")).andReturn(condition1);
rule1.addCondition(condition1);
ActionRequest actionRequest1 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
rule1.addActionRequest(actionRequest1);
replayMocks();
createRuleBase();
}
public void testBasicRuleBase() throws IOException {
injectRuleBase("[rule \"rule1\"]\n" +
"\tconditionA = value1,value2\n" +
"\tconditionA = value3,value of 4\n" +
"\tconditionB = value5\n" +
"\taction = action1\n" +
"\taction = action2 param\n" +
"\n" +
"[ruleXZ \"nonrule\"]\n" +
"\tconditionA = value1\n" +
"\taction = action2\n" +
"[rule \"rule2\"]\n" +
"\tconditionC = value6\n" +
"\taction = action3");
Rule rule1 = createMock(Rule.class);
expect(ruleFactory.create("rule1")).andReturn(rule1);
Condition condition1 = createMock(Condition.class);
expect(conditionFactory.create("conditionA", "value1,value2")).
andReturn(condition1);
rule1.addCondition(condition1);
Condition condition2 = createMock(Condition.class);
expect(conditionFactory.create("conditionA", "value3,value of 4")).
andReturn(condition2);
rule1.addCondition(condition2);
Condition condition3 = createMock(Condition.class);
expect(conditionFactory.create("conditionB", "value5")).
andReturn(condition3);
rule1.addCondition(condition3);
ActionRequest actionRequest1 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
rule1.addActionRequest(actionRequest1);
ActionRequest actionRequest2 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action2 param")).andReturn(actionRequest2);
rule1.addActionRequest(actionRequest2);
Rule rule2 = createMock(Rule.class);
expect(ruleFactory.create("rule2")).andReturn(rule2);
Condition condition4 = createMock(Condition.class);
expect(conditionFactory.create("conditionC", "value6")).
andReturn(condition4);
rule2.addCondition(condition4);
ActionRequest actionRequest3 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action3")).andReturn(actionRequest3);
rule2.addActionRequest(actionRequest3);
replayMocks();
createRuleBase();
}
public void testActionRequestsForSimple() throws IOException {
injectRuleBase("[rule \"rule1\"]\n" +
"\taction = action1");
Rule rule1 = createMock(Rule.class);
expect(ruleFactory.create("rule1")).andReturn(rule1);
ActionRequest actionRequest1 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
rule1.addActionRequest(actionRequest1);
Collection<Property> properties = Collections.emptySet();
List<ActionRequest> rule1Match = Lists.newArrayListWithCapacity(1);
rule1Match.add(actionRequest1);
expect(rule1.actionRequestsFor(properties)).andReturn(rule1Match);
replayMocks();
RuleBase ruleBase = createRuleBase();
Collection<ActionRequest> actual = ruleBase.actionRequestsFor(properties);
List<ActionRequest> expected = Lists.newArrayListWithCapacity(3);
expected.add(actionRequest1);
assertEquals("Matched actionRequests do not match", expected, actual);
}
public void testActionRequestsForExtended() throws IOException {
injectRuleBase("[rule \"rule1\"]\n" +
"\taction = action1\n" +
"\taction = action2\n" +
"\n" +
"[rule \"rule2\"]\n" +
"\taction = action3");
Rule rule1 = createMock(Rule.class);
expect(ruleFactory.create("rule1")).andReturn(rule1);
ActionRequest actionRequest1 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
rule1.addActionRequest(actionRequest1);
ActionRequest actionRequest2 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action2")).andReturn(actionRequest2);
rule1.addActionRequest(actionRequest2);
Rule rule2 = createMock(Rule.class);
expect(ruleFactory.create("rule2")).andReturn(rule2);
ActionRequest actionRequest3 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action3")).andReturn(actionRequest3);
rule2.addActionRequest(actionRequest3);
Collection<Property> properties = Lists.newArrayListWithCapacity(1);
Property property1 = createMock(Property.class);
properties.add(property1);
List<ActionRequest> rule1Match = Lists.newArrayListWithCapacity(2);
rule1Match.add(actionRequest1);
rule1Match.add(actionRequest2);
expect(rule1.actionRequestsFor(properties)).andReturn(rule1Match);
List<ActionRequest> rule2Match = Lists.newArrayListWithCapacity(1);
rule2Match.add(actionRequest3);
expect(rule2.actionRequestsFor(properties)).andReturn(rule2Match);
replayMocks();
RuleBase ruleBase = createRuleBase();
Collection<ActionRequest> actual = ruleBase.actionRequestsFor(properties);
List<ActionRequest> expected = Lists.newArrayListWithCapacity(3);
expected.add(actionRequest1);
expected.add(actionRequest2);
expected.add(actionRequest3);
assertEquals("Matched actionRequests do not match", expected, actual);
}
public void testWarnExistingFaultyNameRuleBaseFile() throws IOException {
injectRuleBase("", RuleBaseKind.FAULTY);
replayMocks();
createRuleBase();
assertLogMessageContains("Please migrate"); // Migration warning for old name
assertLogMessageContains("Neither global"); // For rule file at at usual places
}
public void testSimpleFaultyNameRuleBase() throws IOException {
injectRuleBase("[rule \"rule1\"]\n" +
"\tconditionA = value1\n" +
"\taction = action1", RuleBaseKind.FAULTY);
Rule rule1 = createMock(Rule.class);
expect(ruleFactory.create("rule1")).andReturn(rule1);
Condition condition1 = createMock(Condition.class);
expect(conditionFactory.create("conditionA", "value1")).andReturn(condition1);
rule1.addCondition(condition1);
ActionRequest actionRequest1 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
rule1.addActionRequest(actionRequest1);
replayMocks();
createRuleBase();
assertLogMessageContains("Please migrate"); // Migration warning for old name
assertLogMessageContains("Neither global"); // For rule file at at usual places
}
public void testSimpleItsRuleBase() throws IOException {
injectRuleBase("[rule \"rule1\"]\n" +
"\tconditionA = value1\n" +
"\taction = action1", RuleBaseKind.ITS);
Rule rule1 = createMock(Rule.class);
expect(ruleFactory.create("rule1")).andReturn(rule1);
Condition condition1 = createMock(Condition.class);
expect(conditionFactory.create("conditionA", "value1")).andReturn(condition1);
rule1.addCondition(condition1);
ActionRequest actionRequest1 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
rule1.addActionRequest(actionRequest1);
replayMocks();
createRuleBase();
}
public void testAllRuleBaseFilesAreLoaded() throws IOException {
injectRuleBase("[rule \"rule1\"]\n" +
"\taction = action1", RuleBaseKind.FAULTY);
injectRuleBase("[rule \"rule2\"]\n" +
"\taction = action2", RuleBaseKind.GLOBAL);
injectRuleBase("[rule \"rule3\"]\n" +
"\taction = action3", RuleBaseKind.ITS);
Collection<Property> properties = Collections.emptySet();
Rule rule1 = createMock(Rule.class);
expect(ruleFactory.create("rule1")).andReturn(rule1);
ActionRequest actionRequest1 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
rule1.addActionRequest(actionRequest1);
List<ActionRequest> rule1Match = Lists.newArrayListWithCapacity(1);
rule1Match.add(actionRequest1);
expect(rule1.actionRequestsFor(properties)).andReturn(rule1Match);
Rule rule2 = createMock(Rule.class);
expect(ruleFactory.create("rule2")).andReturn(rule2);
ActionRequest actionRequest2 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action2")).andReturn(actionRequest2);
rule2.addActionRequest(actionRequest2);
List<ActionRequest> rule2Match = Lists.newArrayListWithCapacity(1);
rule2Match.add(actionRequest2);
expect(rule2.actionRequestsFor(properties)).andReturn(rule2Match);
Rule rule3 = createMock(Rule.class);
expect(ruleFactory.create("rule3")).andReturn(rule3);
ActionRequest actionRequest3 = createMock(ActionRequest.class);
expect(actionRequestFactory.create("action3")).andReturn(actionRequest3);
rule3.addActionRequest(actionRequest3);
List<ActionRequest> rule3Match = Lists.newArrayListWithCapacity(1);
rule3Match.add(actionRequest3);
expect(rule3.actionRequestsFor(properties)).andReturn(rule3Match);
replayMocks();
RuleBase ruleBase = createRuleBase();
Collection<ActionRequest> actual = ruleBase.actionRequestsFor(properties);
List<ActionRequest> expected = Lists.newArrayListWithCapacity(3);
expected.add(actionRequest1);
expected.add(actionRequest2);
expected.add(actionRequest3);
assertEquals("Matched actionRequests do not match", expected, actual);
assertLogMessageContains("Please migrate"); // Migration warning for old name
}
private RuleBase createRuleBase() {
return injector.getInstance(RuleBase.class);
}
private void injectRuleBase(String rules) throws IOException {
injectRuleBase(rules, RuleBaseKind.GLOBAL);
}
private void injectRuleBase(String rules, RuleBaseKind ruleBaseKind) throws IOException {
String baseName = "";
switch (ruleBaseKind) {
case GLOBAL:
baseName = "actions";
break;
case ITS:
baseName = "actions-ItsTestName";
break;
case FAULTY:
baseName = "action";
break;
default:
fail("Unknown ruleBaseKind");
}
File ruleBaseFile = new File(sitePath.toFile(),
"etc" + File.separatorChar + "its" + File.separator +
baseName + ".config");
File ruleBaseParentFile = ruleBaseFile.getParentFile();
if (!ruleBaseParentFile.exists()) {
assertTrue("Failed to create parent (" + ruleBaseParentFile + ") for " +
"rule base", ruleBaseParentFile.mkdirs());
}
try (FileWriter unbufferedWriter = new FileWriter(ruleBaseFile);
BufferedWriter writer = new BufferedWriter(unbufferedWriter)) {
writer.write(rules);
}
}
@Override
public void setUp() throws Exception {
super.setUp();
cleanupSitePath = false;
injector = Guice.createInjector(new TestModule());
}
@Override
public void tearDown() throws Exception {
if (cleanupSitePath) {
if (Files.exists(sitePath)) {
FileUtils.delete(sitePath.toFile(), FileUtils.RECURSIVE);
}
}
super.tearDown();
}
private Path randomTargetPath() {
return Paths.get("target", "random-name-" + UUID.randomUUID().toString());
}
private class TestModule extends FactoryModule {
@Override
protected void configure() {
bind(String.class).annotatedWith(PluginName.class)
.toInstance("ItsTestName");
sitePath = randomTargetPath();
assertFalse("sitePath already (" + sitePath + ") already exists",
Files.exists(sitePath));
cleanupSitePath = true;
bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
ruleFactory = createMock(Rule.Factory.class);
bind(Rule.Factory.class).toInstance(ruleFactory);
conditionFactory = createMock(Condition.Factory.class);
bind(Condition.Factory.class).toInstance(conditionFactory);
actionRequestFactory = createMock(ActionRequest.Factory.class);
bind(ActionRequest.Factory.class).toInstance(actionRequestFactory);
}
}
}