killbill-aplcache
Changes
invoice/pom.xml 6(+5 -1)
invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java 105(+93 -12)
pom.xml 6(+6 -0)
Details
diff --git a/beatrix/src/test/resources/Catalog-Entitlement-Testplan.txt b/beatrix/src/test/resources/Catalog-Entitlement-Testplan.txt
new file mode 100644
index 0000000..84c496b
--- /dev/null
+++ b/beatrix/src/test/resources/Catalog-Entitlement-Testplan.txt
@@ -0,0 +1,97 @@
+NOTES
+=====
+
+Events: Create, change, cancel, migrate
+Validate: BillingEvents, SubscriptionTransition
+Rules:
+ Cancellation
+ Action Policy: When to cancel (Immediate/End-of-term)
+ Creation
+ Alignment: How to align phases in a bundle
+ Change plan behavior
+ Action Policy: When to change plan (Immediate/End-of-term)
+ Alignment: How to align phases
+ Pricelist: Which pricelist to pick when moving between plans
+ Billing alignment
+ Subscription BCD, Bundle BCD, Account BCD
+Phases - timing
+Prices - multi-currency, fixed vs recurring prices
+Pricelists - particularly pricelist change rules
+Catalog changes new subscriptions / existing subscriptions
+Price change
+
+TESTS
+=====
+
+BASEPLAN TESTS
+ * Create a single phase recurring plan
+ - check for creation event (timing?)
+ - check for no termination event
+ - check pricing (different currencies)
+ - check BDC (subscription, account, timezone)
+ * Create a single phase fixed length plan
+ - check for creation event (timing - different request dates)
+ - check for termination event (timing - different lengths?)
+ - check price (fixed vs recurring)
+ * Create a two phase event use a fixed price and a recurring price
+ - check for phase change (timing)
+ - check prices change
+ * Create a multi-phase plan
+ - check for phase events
+ - check price changes
+ * Create multiple base plans in a single bundle - should fail
+
+ * Change base plan once
+ - check plan change policy (immediate, eot)
+ - check alignments of new plan with old
+ - check move between pricelists
+ - check that phases progress successfully after change
+ - check obsolete events are removed
+ * Change base plan multiple times
+ - check that alignment occurs correctly
+ - check phases progress correctly
+ - check obsolete events are removed
+
+ * Cancellation of a single phase plan
+ - check creation and timing of termination event
+ * Cancellation of a multi-phase plan
+ - check creation of termination event
+ - check removal of events beyond termination event
+ * Change a cancelled base plan - should fail
+
+ * Migration to a single phase plan
+ - check migration event occurs when it should
+ * Migration to a multi-phase plan
+ - check migration event occurs when it should
+ - check migration into different phase
+ - check alignment of phases can be correctly controlled
+ * Migration to a fixed duration plan
+ - check migration event occurs when it should
+ - check termination event occurs when it should
+
+
+
+STANDALONE TEST
+ * Create multiple plans in a single bundle
+ - check plans can be created
+ - check cannot add a base plan
+ - check BCD at subscription bundle level
+
+
+PRICE CHANGE TEST
+ * Price change on a single phase base plan
+ - check new subscriptions get price after effective date
+ - check changed subscriptions get price after effective date
+ - check existing subscriptions ONLY get it after ESED
+ - check that if ESED is missing existing subs are grandfathered for ever
+ * Price change on a multi-phase subscription
+ - check price change applies correctly to correct phases
+ * Multiple price changes
+ - check multiple price changes with overlapping dates
+
+
+ADD-ON TESTS
+ * Add-on creation alignment
+ * Add-on cancel with base plan
+
+
\ No newline at end of file
invoice/pom.xml 6(+5 -1)
diff --git a/invoice/pom.xml b/invoice/pom.xml
index 1001e68..3cc522b 100644
--- a/invoice/pom.xml
+++ b/invoice/pom.xml
@@ -103,7 +103,11 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>com.jayway.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
</build>
diff --git a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
index c9f5aa9..6036652 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/notification/TestNextBillingDateNotifier.java
@@ -16,50 +16,131 @@
package com.ning.billing.invoice.notification;
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.MINUTES;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+
+import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
import org.skife.config.ConfigurationObjectFactory;
+import org.skife.jdbi.v2.DBI;
+import org.skife.jdbi.v2.Transaction;
+import org.skife.jdbi.v2.TransactionStatus;
+import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import com.google.common.eventbus.Subscribe;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Stage;
-import com.ning.billing.config.CatalogConfig;
import com.ning.billing.config.InvoiceConfig;
+import com.ning.billing.dbi.MysqlTestingHelper;
import com.ning.billing.lifecycle.KillbillService.ServiceException;
import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.clock.DefaultClock;
+import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.eventbus.Bus;
import com.ning.billing.util.eventbus.MemoryEventBus;
import com.ning.billing.util.notificationq.DefaultNotificationQueueService;
+import com.ning.billing.util.notificationq.DummySqlTest;
import com.ning.billing.util.notificationq.NotificationQueueService;
+import com.ning.billing.util.notificationq.dao.NotificationSqlDao;
public class TestNextBillingDateNotifier {
private Clock clock;
- private NextBillingDateNotifier notifier;
+ private DefaultNextBillingDateNotifier notifier;
+ private DummySqlTest dao;
+ private Bus eventBus;
+ private MysqlTestingHelper helper;
@BeforeClass(groups={"setup"})
- public void setup() throws ServiceException {
+ public void setup() throws ServiceException, IOException, ClassNotFoundException, SQLException {
//TestApiBase.loadSystemPropertiesFromClasspath("/entitlement.properties");
- final Injector g = Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
+ final Injector g = Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
protected void configure() {
- bind(Clock.class).to(DefaultClock.class).asEagerSingleton();
- bind(NextBillingDateNotifier.class).to(DefaultNextBillingDateNotifier.class).asEagerSingleton();
+ bind(Clock.class).to(ClockMock.class).asEagerSingleton();
bind(Bus.class).to(MemoryEventBus.class).asEagerSingleton();
bind(NotificationQueueService.class).to(DefaultNotificationQueueService.class).asEagerSingleton();
final InvoiceConfig config = new ConfigurationObjectFactory(System.getProperties()).build(InvoiceConfig.class);
- bind(InvoiceConfig.class).toInstance(config);
+ bind(InvoiceConfig.class).toInstance(config);
+ final MysqlTestingHelper helper = new MysqlTestingHelper();
+ bind(MysqlTestingHelper.class).toInstance(helper);
+ DBI dbi = helper.getDBI();
+ bind(DBI.class).toInstance(dbi);
+
}
});
- notifier = g.getInstance(NextBillingDateNotifier.class);
clock = g.getInstance(Clock.class);
-
+ DBI dbi = g.getInstance(DBI.class);
+ dao = dbi.onDemand(DummySqlTest.class);
+ eventBus = g.getInstance(Bus.class);
+ helper = g.getInstance(MysqlTestingHelper.class);
+ notifier = new DefaultNextBillingDateNotifier(g.getInstance(NotificationQueueService.class), eventBus, g.getInstance(InvoiceConfig.class));
+ startMysql();
}
- @Test(enabled=false, groups="fast")
- public void test() {
+ private void startMysql() throws IOException, ClassNotFoundException, SQLException {
+ final String ddl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+ final String testDdl = IOUtils.toString(NotificationSqlDao.class.getResourceAsStream("/com/ning/billing/util/ddl_test.sql"));
+ helper.startMysql();
+ helper.initDb(ddl);
+ helper.initDb(testDdl);
+ }
+
+ public static class NextBillingEventListener {
+ private int eventCount=0;
+
+ public int getEventCount() {
+ return eventCount;
+ }
+
+ @Subscribe
+ public synchronized void processEvent(NextBillingDateEvent event) {
+ eventCount++;
+ //log.debug("Got event {} {}", event.name, event.value);
+ }
+ }
+
+ @Test(enabled=true, groups="slow")
+ public void test() throws Exception {
+ final UUID subscriptionId = new UUID(0L,1L);
+ final DateTime now = new DateTime();
+ final DateTime readyTime = now.plusMillis(2000);
+
+ final NextBillingEventListener listener = new NextBillingEventListener();
+ eventBus.start();
+ notifier.initialize();
+ notifier.start();
+ eventBus.register(listener);
+ dao.inTransaction(new Transaction<Void, DummySqlTest>() {
+ @Override
+ public Void inTransaction(DummySqlTest transactional,
+ TransactionStatus status) throws Exception {
+
+ notifier.insertNextBillingNotification(transactional, subscriptionId, readyTime);
+ return null;
+ }
+ });
+
+ // Move time in the future after the notification effectiveDate
+ ((ClockMock) clock).setDeltaFromReality(3000);
+
+
+ await().atMost(1, MINUTES).until(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return listener.getEventCount() == 1;
+ }
+ });
+
+ Assert.assertEquals(listener.getEventCount(), 1);
}
}
pom.xml 6(+6 -0)
diff --git a/pom.xml b/pom.xml
index 8c8fbb3..28f48db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -234,6 +234,12 @@
<version>6.0</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.jayway.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <version>1.3.3</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
<build>
diff --git a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
index 8058561..207a78c 100644
--- a/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
+++ b/util/src/test/java/com/ning/billing/util/notificationq/TestNotificationQueue.java
@@ -150,18 +150,7 @@ public class TestNotificationQueue {
((ClockMock) clock).setDeltaFromReality(3000);
// Notification should have kicked but give it at least a sec' for thread scheduling
- int nbTry = 1;
- boolean success = false;
- do {
- synchronized(expectedNotifications) {
- if (expectedNotifications.get(notificationKey.toString())) {
- success = true;
- break;
- }
- expectedNotifications.wait(1000);
- }
- } while (nbTry-- > 0);
- assertEquals(success, true);
+
}
@Test