diff --git a/bubble-server/pom.xml b/bubble-server/pom.xml
index 7b71c17a..6bfd9282 100644
--- a/bubble-server/pom.xml
+++ b/bubble-server/pom.xml
@@ -349,6 +349,30 @@ For commercial use, please contact jonathan@kyuss.org
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M4
+
+ 1
+ false
+ -Xmx1024m -XX:MaxPermSize=256m
+
+ bubble.test.DbInit
+ bubble.test.AuthTest
+ bubble.test.PaymentTest
+ bubble.test.RecurringBillingTest
+ bubble.test.DriverTest
+ bubble.test.ProxyTest
+ bubble.test.TrafficAnalyticsTest
+ bubble.test.BackupTest
+ bubble.test.NetworkTest
+
+
+
+
diff --git a/bubble-server/src/main/java/bubble/cloud/payment/stripe/StripePaymentDriver.java b/bubble-server/src/main/java/bubble/cloud/payment/stripe/StripePaymentDriver.java
index 917ab00d..8a3cdb2f 100644
--- a/bubble-server/src/main/java/bubble/cloud/payment/stripe/StripePaymentDriver.java
+++ b/bubble-server/src/main/java/bubble/cloud/payment/stripe/StripePaymentDriver.java
@@ -35,7 +35,8 @@ public class StripePaymentDriver extends PaymentDriverBase setupDone = new AtomicReference<>(null);
@Override public void postSetup() {
+ final String apiKey = getCredentials().getParam(PARAM_SECRET_API_KEY);
+ if (empty(apiKey)) die("postSetup: "+PARAM_SECRET_API_KEY+" not found in credentials");
if (setupDone.get() == null) {
synchronized (setupDone) {
if (setupDone.get() == null) {
- final String apiKey = getCredentials().getParam(PARAM_SECRET_API_KEY);
- if (empty(apiKey)) die("postSetup: "+PARAM_SECRET_API_KEY+" not found in credentials");
+ if (setupDone.get() != null && !setupDone.get().equals(apiKey)) {
+ die("postSetup: cannot re-initialize with another API key (only one "+ SIMPLE_NAME +" is supported)");
+ }
Stripe.apiKey = apiKey;
- setupDone.set(cloud.getUuid());
+ setupDone.set(apiKey);
} else {
log.info("postSetup: already set up");
}
@@ -65,8 +69,8 @@ public class StripePaymentDriver extends PaymentDriverBase implements SqlViewSearc
private static final AtomicBoolean activated = new AtomicBoolean(false);
@Transactional(Transactional.TxType.REQUIRES_NEW)
public boolean activated() {
- if (activated.get()) return true;
+ if (activated.get() && !configuration.testMode()) return true;
final boolean accountsExist = countAll() > 0;
if (accountsExist) activated.set(true);
return accountsExist;
diff --git a/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java b/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java
index c390890a..26e40dac 100644
--- a/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java
+++ b/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java
@@ -13,6 +13,7 @@ import bubble.model.cloud.CloudService;
import bubble.notify.payment.PaymentValidationResult;
import bubble.server.BubbleConfiguration;
import bubble.service.bill.RefundService;
+import bubble.service.cloud.NetworkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -35,6 +36,7 @@ public class AccountPlanDAO extends AccountOwnedEntityDAO {
@Autowired private BillDAO billDAO;
@Autowired private CloudServiceDAO cloudDAO;
@Autowired private BubbleNetworkDAO networkDAO;
+ @Autowired private NetworkService networkService;
@Autowired private RefundService refundService;
@Autowired private BubbleConfiguration configuration;
@@ -128,7 +130,7 @@ public class AccountPlanDAO extends AccountOwnedEntityDAO {
final BubbleNetwork network = networkDAO.findByUuid(accountPlan.getNetwork());
if (network != null && network.getState() != BubbleNetworkState.stopped) {
- throw invalidEx("err.accountPlan.stopNetworkBeforeDeleting");
+ networkService.stopNetwork(network);
}
update(accountPlan.setDeleted(now()).setEnabled(false));
if (accountPlan.getNetwork() == null && accountPlan.getDeletedNetwork() != null) {
diff --git a/bubble-server/src/main/java/bubble/model/cloud/BubbleFootprint.java b/bubble-server/src/main/java/bubble/model/cloud/BubbleFootprint.java
index c379bc5c..c53a6807 100644
--- a/bubble-server/src/main/java/bubble/model/cloud/BubbleFootprint.java
+++ b/bubble-server/src/main/java/bubble/model/cloud/BubbleFootprint.java
@@ -25,6 +25,7 @@ import java.util.function.Function;
import static bubble.ApiConstants.EP_FOOTPRINTS;
import static org.cobbzilla.util.daemon.ZillaRuntime.bool;
+import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.json.JsonUtil.json;
import static org.cobbzilla.util.reflect.ReflectionUtil.copy;
import static org.cobbzilla.wizard.model.crypto.EncryptedTypes.ENCRYPTED_STRING;
@@ -48,7 +49,9 @@ public class BubbleFootprint extends IdentifiableBase implements AccountTemplate
public static final String DEFAULT_FOOTPRINT = "Worldwide";
- public static final BubbleFootprint DEFAULT_FOOTPRINT_OBJECT = new BubbleFootprint()
+ public static final BubbleFootprint DEFAULT_FOOTPRINT_OBJECT = new BubbleFootprint() {
+ @Override public void setUuid(String uuid) { die("cannot set uuid on DEFAULT_FOOTPRINT_OBJECT"); }
+ }
.setName(DEFAULT_FOOTPRINT)
.setDescription("No restrictions, run anywhere")
.setTemplate(true);
diff --git a/bubble-server/src/main/java/bubble/model/cloud/CloudService.java b/bubble-server/src/main/java/bubble/model/cloud/CloudService.java
index f38a8f77..c75b52d9 100644
--- a/bubble-server/src/main/java/bubble/model/cloud/CloudService.java
+++ b/bubble-server/src/main/java/bubble/model/cloud/CloudService.java
@@ -223,14 +223,15 @@ public class CloudService extends IdentifiableBaseParentEntity implements Accoun
}
private static final Map driverCache = new ExpirationMap<>();
+ public static void flushDriverCache() { driverCache.clear(); }
public static void clearDriverCache (String uuid) { driverCache.remove(uuid); }
public T wireAndSetup (BubbleConfiguration configuration) {
// note: CloudServiceDAO calls clearDriverCache when driver config is updated,
// then the updated class/config/credentials will be used.
- if (!hasUuid()) {
- // this is a test before creation, just try to wire it up, but do not cache the result
+ if (!hasUuid() || configuration.testMode()) {
+ // this is a test before creation (or we are in test mode), just wire it up, but do not cache the result
return _wireAndSetup(configuration);
}
return (T) driverCache.computeIfAbsent(getUuid(), k -> _wireAndSetup(configuration));
diff --git a/bubble-server/src/main/java/bubble/notify/payment/NotificationHandler_payment_driver_validate.java b/bubble-server/src/main/java/bubble/notify/payment/NotificationHandler_payment_driver_validate.java
index 58f4a306..cc391d3b 100644
--- a/bubble-server/src/main/java/bubble/notify/payment/NotificationHandler_payment_driver_validate.java
+++ b/bubble-server/src/main/java/bubble/notify/payment/NotificationHandler_payment_driver_validate.java
@@ -6,12 +6,14 @@ import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.CloudService;
import bubble.model.cloud.notify.ReceivedNotification;
import bubble.notify.DelegatedNotificationHandlerBase;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import static bubble.model.cloud.notify.NotificationType.payment_driver_response;
import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.json.JsonUtil.json;
+@Slf4j
public class NotificationHandler_payment_driver_validate extends DelegatedNotificationHandlerBase {
@Autowired protected BubbleNodeDAO nodeDAO;
diff --git a/bubble-server/src/main/java/bubble/notify/storage/NotificationHandler_storage_driver.java b/bubble-server/src/main/java/bubble/notify/storage/NotificationHandler_storage_driver.java
index d1312edb..efba1fa1 100644
--- a/bubble-server/src/main/java/bubble/notify/storage/NotificationHandler_storage_driver.java
+++ b/bubble-server/src/main/java/bubble/notify/storage/NotificationHandler_storage_driver.java
@@ -7,11 +7,13 @@ import bubble.model.cloud.CloudService;
import bubble.model.cloud.notify.ReceivedNotification;
import bubble.notify.DelegatedNotificationHandlerBase;
import bubble.service.cloud.StorageStreamService;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.json.JsonUtil.json;
+@Slf4j
public abstract class NotificationHandler_storage_driver extends DelegatedNotificationHandlerBase {
@Autowired protected BubbleNodeDAO nodeDAO;
@@ -22,8 +24,9 @@ public abstract class NotificationHandler_storage_driver extends DelegatedNotifi
final BubbleNode sender = nodeDAO.findByUuid(n.getFromNode());
if (sender == null) die("handleNotification: sender not found: "+n.getFromNode());
+ final BubbleNode thisNode = configuration.getThisNode();
final StorageDriverNotification notification = json(n.getPayloadJson(), StorageDriverNotification.class);
- final CloudService storage = cloudDAO.findByAccountAndId(configuration.getThisNode().getAccount(), notification.getStorageService());
+ final CloudService storage = cloudDAO.findByAccountAndId(thisNode.getAccount(), notification.getStorageService());
if (storage == null) die("handleNotification: storage not found: "+notification.getStorageService());
handleNotification(n, sender, notification, storage);
}
diff --git a/bubble-server/src/main/java/bubble/resources/account/AccountsResource.java b/bubble-server/src/main/java/bubble/resources/account/AccountsResource.java
index ca1ba0ef..1ef2d5ae 100644
--- a/bubble-server/src/main/java/bubble/resources/account/AccountsResource.java
+++ b/bubble-server/src/main/java/bubble/resources/account/AccountsResource.java
@@ -189,7 +189,7 @@ public class AccountsResource {
log.info("setContact: contact is new, sending verify message");
messageDAO.sendVerifyRequest(getRemoteHost(req), c.account, contact);
}
- return ok(added.mask());
+ return ok(existing != null ? added.mask() : added);
}
@POST @Path("/{id}"+EP_POLICY+EP_CONTACTS+"/verify")
diff --git a/bubble-server/src/main/java/bubble/service/boot/ActivationService.java b/bubble-server/src/main/java/bubble/service/boot/ActivationService.java
index c3859a53..95cd7445 100644
--- a/bubble-server/src/main/java/bubble/service/boot/ActivationService.java
+++ b/bubble-server/src/main/java/bubble/service/boot/ActivationService.java
@@ -161,7 +161,7 @@ public class ActivationService {
BubbleFootprint footprint = footprintDAO.findByAccountAndId(account.getUuid(), DEFAULT_FOOTPRINT);
if (footprint == null) {
- footprint = footprintDAO.create(DEFAULT_FOOTPRINT_OBJECT.setAccount(account.getUuid()));
+ footprint = footprintDAO.create(new BubbleFootprint(DEFAULT_FOOTPRINT_OBJECT).setAccount(account.getUuid()));
}
final BubbleNetwork network = createRootNetwork(new BubbleNetwork()
diff --git a/bubble-server/src/main/java/bubble/service/notify/NotificationInboxProcessor.java b/bubble-server/src/main/java/bubble/service/notify/NotificationInboxProcessor.java
index 2940891b..c48844af 100644
--- a/bubble-server/src/main/java/bubble/service/notify/NotificationInboxProcessor.java
+++ b/bubble-server/src/main/java/bubble/service/notify/NotificationInboxProcessor.java
@@ -1,5 +1,6 @@
package bubble.service.notify;
+import bubble.dao.cloud.BubbleNodeDAO;
import bubble.dao.cloud.notify.ReceivedNotificationDAO;
import bubble.model.cloud.notify.NotificationProcessingStatus;
import bubble.model.cloud.notify.ReceivedNotification;
@@ -49,6 +50,10 @@ public class NotificationInboxProcessor implements Runnable {
return;
}
}
+ if (configuration.getBean(BubbleNodeDAO.class).findByUuid(n.getFromNode()) == null) {
+ log.warn("processNotification: fromNode does not exist: "+n.getFromNode());
+ return;
+ }
handler.handleNotification(n);
}
diff --git a/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties b/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties
index e48cfa6e..261295a1 100644
--- a/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties
+++ b/bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties
@@ -341,7 +341,6 @@ err.accountPlan.callerCountryDisallowed=Your country is not currently supported
err.accountPlan.disabled=Account plan is not enabled
err.accountPlan.notFound=Account plan not found
err.accountPlan.noVerifiedContacts=Cannot proceed, no account contact information has yet been verified
-err.accountPlan.stopNetworkBeforeDeleting=You must stop the bubble first, the delete the plan
err.admin.cannotRemoveAdminStatusFromSelf=You cannot remove admin status from your own account
err.allowedCountriesJson.length=Allowed countries list is too long
err.approval.invalid=Approval cannot proceed
diff --git a/bubble-server/src/main/resources/models/defaults/bubblePlan.json b/bubble-server/src/main/resources/models/defaults/bubblePlan.json
index 874b640d..91115fa8 100644
--- a/bubble-server/src/main/resources/models/defaults/bubblePlan.json
+++ b/bubble-server/src/main/resources/models/defaults/bubblePlan.json
@@ -1,6 +1,6 @@
[{
"name": "bubble",
- "chargeName": "BubbleStd",
+ "chargeName": "BubbleVPN",
"computeSizeType": "small",
"nodesIncluded": 1,
"additionalPerNodePrice": 0,
@@ -11,7 +11,7 @@
"additionalBandwidthPerGbPrice": 0
}, {
"name": "bubble_plus",
- "chargeName": "BubblePlus",
+ "chargeName": "BubbleVPN-Plus",
"computeSizeType": "medium",
"nodesIncluded": 1,
"additionalPerNodePrice": 0,
diff --git a/bubble-server/src/test/java/bubble/mock/MockStripePaymentDriver.java b/bubble-server/src/test/java/bubble/mock/MockStripePaymentDriver.java
index 4e658336..5d92b6cc 100644
--- a/bubble-server/src/test/java/bubble/mock/MockStripePaymentDriver.java
+++ b/bubble-server/src/test/java/bubble/mock/MockStripePaymentDriver.java
@@ -5,6 +5,7 @@ import bubble.model.bill.AccountPaymentMethod;
import bubble.model.bill.AccountPlan;
import bubble.model.bill.Bill;
import bubble.model.bill.BubblePlan;
+import com.stripe.Stripe;
import java.util.concurrent.atomic.AtomicReference;
@@ -15,6 +16,10 @@ public class MockStripePaymentDriver extends StripePaymentDriver {
public static final AtomicReference error = new AtomicReference<>(null);
public static void setError(String err) { error.set(err); }
+ @Override public void postSetup() {
+ Stripe.apiKey = getCredentials().getParam(PARAM_SECRET_API_KEY);;
+ }
+
@Override public boolean authorize(BubblePlan plan, String accountPlanUuid, AccountPaymentMethod paymentMethod) {
final String err = error.get();
if (err != null && (err.equals("authorize") || err.equals("all"))) {
diff --git a/bubble-server/src/test/java/bubble/test/ActivatedBubbleModelTestBase.java b/bubble-server/src/test/java/bubble/test/ActivatedBubbleModelTestBase.java
index 93f82325..dd1e0498 100644
--- a/bubble-server/src/test/java/bubble/test/ActivatedBubbleModelTestBase.java
+++ b/bubble-server/src/test/java/bubble/test/ActivatedBubbleModelTestBase.java
@@ -31,10 +31,8 @@ import java.util.stream.Collectors;
import static bubble.ApiConstants.*;
import static bubble.model.account.Account.ROOT_USERNAME;
-import static bubble.service.boot.StandardSelfNodeService.THIS_NODE_FILE;
import static org.cobbzilla.util.daemon.ZillaRuntime.*;
import static org.cobbzilla.util.handlebars.HandlebarsUtil.applyReflectively;
-import static org.cobbzilla.util.io.FileUtil.abs;
import static org.cobbzilla.util.io.StreamUtil.stream2string;
import static org.cobbzilla.util.json.JsonUtil.FULL_MAPPER_ALLOW_COMMENTS;
import static org.cobbzilla.util.json.JsonUtil.json;
@@ -50,22 +48,10 @@ public abstract class ActivatedBubbleModelTestBase extends BubbleModelTestBase {
protected Account admin;
- private boolean hasExistingDb = false;
-
@Override public boolean doTruncateDb() { return false; }
@Override public void beforeStart(RestServer server) {
- // if server hbm2ddl mode is validate, do not delete node file
final BubbleConfiguration configuration = server.getConfiguration();
- if (configuration.dbExists()) {
- hasExistingDb = true;
- log.info("beforeStart: not deleting "+abs(THIS_NODE_FILE)+" because DB exists");
- } else {
- // start fresh
- if (THIS_NODE_FILE.exists() && !THIS_NODE_FILE.delete()) {
- die("beforeStart: error deleting " + abs(THIS_NODE_FILE));
- }
- }
// set default domain
final Map env = configuration.getEnvironment();
@@ -94,7 +80,7 @@ public abstract class ActivatedBubbleModelTestBase extends BubbleModelTestBase {
server.getConfiguration().getEntityClassesReverse();
// Activate the system
-
+ resetBubbleServer();
try {
final BubbleConfiguration configuration = server.getConfiguration();
final Map ctx = configuration.getEnvCtx();
diff --git a/bubble-server/src/test/java/bubble/test/BubbleApiRunnerListener.java b/bubble-server/src/test/java/bubble/test/BubbleApiRunnerListener.java
index c80399c1..5fb7806c 100644
--- a/bubble-server/src/test/java/bubble/test/BubbleApiRunnerListener.java
+++ b/bubble-server/src/test/java/bubble/test/BubbleApiRunnerListener.java
@@ -14,7 +14,6 @@ import bubble.service.bill.BillingService;
import com.github.jknack.handlebars.Handlebars;
import com.stripe.model.Token;
import lombok.extern.slf4j.Slf4j;
-import org.cobbzilla.util.string.StringUtil;
import org.cobbzilla.wizard.client.script.SimpleApiRunnerListener;
import java.util.HashMap;
@@ -23,6 +22,7 @@ import java.util.Map;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.cobbzilla.util.daemon.ZillaRuntime.*;
+import static org.cobbzilla.util.string.StringUtil.splitAndTrim;
import static org.cobbzilla.util.system.Sleep.sleep;
import static org.cobbzilla.util.time.TimeUtil.parseDuration;
@@ -35,7 +35,7 @@ public class BubbleApiRunnerListener extends SimpleApiRunnerListener {
public static final String STRIPE_TOKENIZE_CARD = "stripe_tokenize_card";
public static final String CTX_STRIPE_TOKEN = "stripeToken";
- public static final long DEFAULT_BILLING_SLEEP = SECONDS.toMillis(10);
+ public static final long DEFAULT_BILLING_SLEEP = SECONDS.toMillis(30);
private BubbleConfiguration configuration;
@@ -49,7 +49,7 @@ public class BubbleApiRunnerListener extends SimpleApiRunnerListener {
@Override public void beforeScript(String before, Map ctx) throws Exception {
if (before == null) return;
if (before.startsWith(FAST_FORWARD_AND_BILL)) {
- final List parts = StringUtil.splitAndTrim(before.substring(FAST_FORWARD_AND_BILL.length()), " ");
+ final List parts = splitAndTrim(before.substring(FAST_FORWARD_AND_BILL.length()), " ");
final long delta = parseDuration(parts.get(0));
final long sleepTime = parts.size() > 1 ? parseDuration(parts.get(1)) : DEFAULT_BILLING_SLEEP;
incrementSystemTimeOffset(delta);
diff --git a/bubble-server/src/test/java/bubble/test/BubbleCoreSuite.java b/bubble-server/src/test/java/bubble/test/BubbleCoreSuite.java
deleted file mode 100644
index 5b94bdd9..00000000
--- a/bubble-server/src/test/java/bubble/test/BubbleCoreSuite.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package bubble.test;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-
-@RunWith(Suite.class)
-@Suite.SuiteClasses({
- DbInit.class,
- AuthTest.class,
- PaymentTest.class,
- S3StorageTest.class,
- DriverTest.class,
- ProxyTest.class,
- TrafficAnalyticsTest.class,
- BackupTest.class,
- NetworkTest.class,
- NetworkKeysTest.class
-})
-public class BubbleCoreSuite {}
diff --git a/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java b/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java
index bab38af8..8e64c3b5 100644
--- a/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java
+++ b/bubble-server/src/test/java/bubble/test/BubbleModelTestBase.java
@@ -2,11 +2,18 @@ package bubble.test;
import bubble.cloud.email.mock.MockEmailDriver;
import bubble.cloud.sms.mock.MockSmsDriver;
+import bubble.dao.account.AccountDAO;
+import bubble.dao.account.AccountPolicyDAO;
+import bubble.model.account.Account;
+import bubble.model.account.AccountPolicy;
+import bubble.model.cloud.BubbleNode;
+import bubble.model.cloud.CloudService;
import bubble.server.BubbleConfiguration;
import bubble.server.BubbleServer;
import bubble.server.listener.NodeInitializerListener;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
+import org.cobbzilla.wizard.cache.redis.RedisService;
import org.cobbzilla.wizard.client.ApiClientBase;
import org.cobbzilla.wizard.client.script.ApiRunner;
import org.cobbzilla.wizard.client.script.ApiRunnerListener;
@@ -14,6 +21,8 @@ import org.cobbzilla.wizard.server.RestServer;
import org.cobbzilla.wizard.server.RestServerLifecycleListener;
import org.cobbzilla.wizard.server.config.factory.StreamConfigurationSource;
import org.cobbzilla.wizardtest.resources.ApiModelTestBase;
+import org.junit.AfterClass;
+import org.junit.Before;
import java.io.File;
import java.util.ArrayList;
@@ -21,9 +30,14 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
+import static bubble.service.boot.StandardSelfNodeService.SELF_NODE_JSON;
+import static bubble.service.boot.StandardSelfNodeService.THIS_NODE_FILE;
import static bubble.test.BubbleTestBase.ENV_EXPORT_FILE;
import static bubble.test.HandlebarsTestHelpers.registerTestHelpers;
import static java.util.Arrays.asList;
+import static org.cobbzilla.util.daemon.ZillaRuntime.die;
+import static org.cobbzilla.util.daemon.ZillaRuntime.shortError;
+import static org.cobbzilla.util.io.FileUtil.abs;
import static org.cobbzilla.util.system.CommandShell.loadShellExportsOrDie;
@Slf4j
@@ -33,16 +47,59 @@ public abstract class BubbleModelTestBase extends ApiModelTestBase server) {
- server.getConfiguration().setBackupsEnabled(backupsEnabled());
- super.beforeStart(server);
+ @Before public void resetBubbleServer() {
+ server = (BubbleServer) getServer();
+ try {
+ final BubbleNode thisNode = server.getConfiguration().getThisNode();
+ log.info("resetBubbleServer: set server (thisNode=" + (thisNode == null ? null : thisNode.id()) + ")");
+ } catch (Exception e) {
+ log.warn("resetBubbleServer: "+shortError(e));
+ }
+ final BubbleConfiguration configuration = getConfiguration();
+ final AccountDAO accountDAO = configuration.getBean(AccountDAO.class);
+ final AccountPolicyDAO policyDAO = configuration.getBean(AccountPolicyDAO.class);
+ CloudService.flushDriverCache();
+
+ configuration.getBean(RedisService.class).flush();
+ final Account root = accountDAO.getFirstAdmin();
+ if (root != null) {
+ final AccountPolicy rootPolicy = policyDAO.findSingleByAccount(root.getUuid());
+ policyDAO.delete(rootPolicy.getUuid());
+ policyDAO.create(new AccountPolicy().setAccount(root.getUuid()));
+ }
+ }
+
+ @AfterClass public static void resetSelfJson () {
+ if (server != null) server.stopServer();
+ final File selfJson = new File(SELF_NODE_JSON);
+ if (selfJson.exists()) {
+ if (!selfJson.delete()) die("resetSelfJson: error deleting "+abs(SELF_NODE_JSON));
+ }
}
public boolean backupsEnabled() { return false; }
+ @Override public void beforeStart(RestServer server) {
+ final BubbleConfiguration configuration = server.getConfiguration();
+ configuration.setBackupsEnabled(backupsEnabled());
+ if (configuration.dbExists()) {
+ hasExistingDb = true;
+ log.info("beforeStart: not deleting "+abs(THIS_NODE_FILE)+" because DB exists");
+ } else {
+ // start fresh
+ if (THIS_NODE_FILE.exists() && !THIS_NODE_FILE.delete()) {
+ die("beforeStart: error deleting " + abs(THIS_NODE_FILE));
+ }
+ }
+ super.beforeStart(server);
+ }
+
@Getter(lazy=true) private final ApiClientBase _api = new TestBubbleApiClient(getConfiguration());
@Override public ApiClientBase getApi() { return get_api(); }
diff --git a/bubble-server/src/test/java/bubble/test/NetworkKeysTest.java b/bubble-server/src/test/java/bubble/test/NetworkKeysTest.java
deleted file mode 100644
index 5b1db03e..00000000
--- a/bubble-server/src/test/java/bubble/test/NetworkKeysTest.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package bubble.test;
-
-import org.junit.Test;
-
-public class NetworkKeysTest extends NetworkTestBase {
-
- @Test public void testGetNetworkKeys() throws Exception { modelTest("network/network_keys"); }
-
-}
diff --git a/bubble-server/src/test/java/bubble/test/NetworkTest.java b/bubble-server/src/test/java/bubble/test/NetworkTest.java
index ea9b1fc3..9cd3091b 100644
--- a/bubble-server/src/test/java/bubble/test/NetworkTest.java
+++ b/bubble-server/src/test/java/bubble/test/NetworkTest.java
@@ -8,5 +8,7 @@ public class NetworkTest extends NetworkTestBase {
@Test public void testRegions () throws Exception { modelTest("network/network_regions"); }
@Test public void testUpgradeRole () throws Exception { modelTest("network/upgrade_role"); }
+ @Test public void testGetNetworkKeys() throws Exception { modelTest("network/network_keys"); }
+
}
diff --git a/bubble-server/src/test/java/bubble/test/PaymentTest.java b/bubble-server/src/test/java/bubble/test/PaymentTest.java
index ecbbfce5..a2e45e05 100644
--- a/bubble-server/src/test/java/bubble/test/PaymentTest.java
+++ b/bubble-server/src/test/java/bubble/test/PaymentTest.java
@@ -1,30 +1,10 @@
package bubble.test;
-import bubble.server.BubbleConfiguration;
-import bubble.service.bill.BillingService;
-import bubble.service.bill.StandardRefundService;
import lombok.extern.slf4j.Slf4j;
-import org.cobbzilla.wizard.server.RestServer;
import org.junit.Test;
@Slf4j
-public class PaymentTest extends ActivatedBubbleModelTestBase {
-
- @Override protected String getManifest() { return "manifest-test"; }
-
- @Override public void beforeStart(RestServer server) {
- final BubbleConfiguration configuration = server.getConfiguration();
- configuration.setSpringContextPath("classpath:/spring-mock-network.xml");
- configuration.getStaticAssets().setLocalOverride(null);
- super.beforeStart(server);
- }
-
- @Override public void onStart(RestServer server) {
- final BubbleConfiguration configuration = server.getConfiguration();
- configuration.getBean(StandardRefundService.class).start(); // ensure RefundService is always started
- configuration.getBean(BillingService.class).start(); // ensure BillingService is always started
- super.onStart(server);
- }
+public class PaymentTest extends PaymentTestBase {
@Test public void testFreePayment () throws Exception { modelTest("payment/pay_free"); }
@Test public void testCodePayment () throws Exception { modelTest("payment/pay_code"); }
@@ -34,6 +14,4 @@ public class PaymentTest extends ActivatedBubbleModelTestBase {
modelTest("payment/pay_credit_refund_and_restart");
}
- @Test public void testRecurringBilling () throws Exception { modelTest("payment/recurring_billing"); }
-
}
diff --git a/bubble-server/src/test/java/bubble/test/PaymentTestBase.java b/bubble-server/src/test/java/bubble/test/PaymentTestBase.java
new file mode 100644
index 00000000..c2e61340
--- /dev/null
+++ b/bubble-server/src/test/java/bubble/test/PaymentTestBase.java
@@ -0,0 +1,26 @@
+package bubble.test;
+
+import bubble.server.BubbleConfiguration;
+import bubble.service.bill.BillingService;
+import bubble.service.bill.StandardRefundService;
+import org.cobbzilla.wizard.server.RestServer;
+
+public class PaymentTestBase extends ActivatedBubbleModelTestBase {
+
+ @Override protected String getManifest() { return "manifest-test"; }
+
+ @Override public void beforeStart(RestServer server) {
+ final BubbleConfiguration configuration = server.getConfiguration();
+ configuration.setSpringContextPath("classpath:/spring-mock-network.xml");
+ configuration.getStaticAssets().setLocalOverride(null);
+ super.beforeStart(server);
+ }
+
+ @Override public void onStart(RestServer server) {
+ final BubbleConfiguration configuration = server.getConfiguration();
+ configuration.getBean(StandardRefundService.class).start(); // ensure RefundService is always started
+ configuration.getBean(BillingService.class).start(); // ensure BillingService is always started
+ super.onStart(server);
+ }
+
+}
diff --git a/bubble-server/src/test/java/bubble/test/RecurringBillingTest.java b/bubble-server/src/test/java/bubble/test/RecurringBillingTest.java
new file mode 100644
index 00000000..26d174f9
--- /dev/null
+++ b/bubble-server/src/test/java/bubble/test/RecurringBillingTest.java
@@ -0,0 +1,9 @@
+package bubble.test;
+
+import org.junit.Test;
+
+public class RecurringBillingTest extends PaymentTestBase {
+
+ @Test public void testRecurringBilling () throws Exception { modelTest("payment/recurring_billing"); }
+
+}
diff --git a/bubble-server/src/test/java/bubble/test/dev/NewBlankDevServerTest.java b/bubble-server/src/test/java/bubble/test/dev/NewBlankDevServerTest.java
index 9c11b72d..f005a1d8 100644
--- a/bubble-server/src/test/java/bubble/test/dev/NewBlankDevServerTest.java
+++ b/bubble-server/src/test/java/bubble/test/dev/NewBlankDevServerTest.java
@@ -8,6 +8,7 @@ import org.cobbzilla.wizard.server.RestServer;
import org.junit.Test;
import static java.util.concurrent.TimeUnit.DAYS;
+import static org.cobbzilla.util.string.StringUtil.safeParseInt;
import static org.cobbzilla.util.system.Sleep.sleep;
@Slf4j
@@ -17,6 +18,13 @@ public class NewBlankDevServerTest extends BubbleModelTestBase {
@Override protected boolean useMocks() { return false; }
@Override protected boolean createSqlIndexes () { return true; }
+ @Override public void beforeStart(RestServer server) {
+ final BubbleConfiguration configuration = server.getConfiguration();
+ final Integer port = safeParseInt(configuration.getEnvironment().get("BUBBLE_SERVER_PORT"));
+ configuration.getHttp().setPort(port);
+ super.beforeStart(server);
+ }
+
@Override public void onStart(RestServer server) {
getConfiguration().getBean(EntityConfigsResource.class).getAllowPublic().set(true);
super.onStart(server);
diff --git a/bubble-server/src/test/java/bubble/test/GoDaddyDnsTest.java b/bubble-server/src/test/java/bubble/test/live/GoDaddyDnsTest.java
similarity index 73%
rename from bubble-server/src/test/java/bubble/test/GoDaddyDnsTest.java
rename to bubble-server/src/test/java/bubble/test/live/GoDaddyDnsTest.java
index 342ae045..9e282672 100644
--- a/bubble-server/src/test/java/bubble/test/GoDaddyDnsTest.java
+++ b/bubble-server/src/test/java/bubble/test/live/GoDaddyDnsTest.java
@@ -1,5 +1,6 @@
-package bubble.test;
+package bubble.test.live;
+import bubble.test.NetworkTestBase;
import org.junit.Test;
public class GoDaddyDnsTest extends NetworkTestBase {
diff --git a/bubble-server/src/test/java/bubble/test/Route53DnsTest.java b/bubble-server/src/test/java/bubble/test/live/Route53DnsTest.java
similarity index 93%
rename from bubble-server/src/test/java/bubble/test/Route53DnsTest.java
rename to bubble-server/src/test/java/bubble/test/live/Route53DnsTest.java
index bc30998b..55017f03 100644
--- a/bubble-server/src/test/java/bubble/test/Route53DnsTest.java
+++ b/bubble-server/src/test/java/bubble/test/live/Route53DnsTest.java
@@ -1,9 +1,10 @@
-package bubble.test;
+package bubble.test.live;
import bubble.cloud.CloudServiceDriver;
import bubble.cloud.dns.route53.Route53DnsDriver;
import bubble.model.cloud.BubbleDomain;
import bubble.model.cloud.CloudService;
+import bubble.test.NetworkTestBase;
import org.junit.Test;
import java.util.Arrays;
diff --git a/bubble-server/src/test/java/bubble/test/S3StorageTest.java b/bubble-server/src/test/java/bubble/test/live/S3StorageTest.java
similarity index 99%
rename from bubble-server/src/test/java/bubble/test/S3StorageTest.java
rename to bubble-server/src/test/java/bubble/test/live/S3StorageTest.java
index 18e721a5..9b60352f 100644
--- a/bubble-server/src/test/java/bubble/test/S3StorageTest.java
+++ b/bubble-server/src/test/java/bubble/test/live/S3StorageTest.java
@@ -1,4 +1,4 @@
-package bubble.test;
+package bubble.test.live;
import bubble.cloud.CloudServiceType;
import bubble.cloud.storage.s3.S3StorageConfig;
@@ -7,6 +7,7 @@ import bubble.model.cloud.CloudService;
import bubble.model.cloud.RekeyRequest;
import bubble.model.cloud.StorageMetadata;
import bubble.notify.storage.StorageListing;
+import bubble.test.NetworkTestBase;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.http.HttpHeaders;
diff --git a/bubble-server/src/test/resources/models/tests/auth/multifactor_auth.json b/bubble-server/src/test/resources/models/tests/auth/multifactor_auth.json
index 7c373dae..6c2e6355 100644
--- a/bubble-server/src/test/resources/models/tests/auth/multifactor_auth.json
+++ b/bubble-server/src/test/resources/models/tests/auth/multifactor_auth.json
@@ -107,7 +107,6 @@
"response": {
"check": [
{"condition": "json.getType().name() == 'email'"},
- {"condition": "json.getInfo() == 'user-multifactor_auth@example.com'"},
{"condition": "json.getAuthFactor().name() == 'required'"}
]
}
@@ -540,8 +539,7 @@
},
"response": {
"check": [
- {"condition": "json.getAuthFactor().name() == 'sufficient'"},
- {"condition": "json.getInfo() == 'foo@example.com'"}
+ {"condition": "json.getAuthFactor().name() == 'sufficient'"}
]
}
},
@@ -711,8 +709,8 @@
"check": [
{"condition": "json.getAccountContacts() != null"},
{"condition": "json.getAccountContacts().length == 2"},
- {"condition": "!json.getAccountContacts()[0].getInfo() != 'bar@example.com'"},
- {"condition": "!json.getAccountContacts()[1].getInfo() != 'bar@example.com'"}
+ {"condition": "!json.getAccountContacts()[0].getInfo().startsWith('bar')"},
+ {"condition": "!json.getAccountContacts()[1].getInfo().startsWith('bar')"}
]
}
}
diff --git a/bubble-server/src/test/resources/models/tests/payment/pay_credit_refund_and_restart.json b/bubble-server/src/test/resources/models/tests/payment/pay_credit_refund_and_restart.json
index beeb1dbe..03e6c11d 100644
--- a/bubble-server/src/test/resources/models/tests/payment/pay_credit_refund_and_restart.json
+++ b/bubble-server/src/test/resources/models/tests/payment/pay_credit_refund_and_restart.json
@@ -177,26 +177,6 @@
}
},
- {
- "comment": "try to delete plan, must stop network first",
- "request": {
- "method": "delete",
- "uri": "me/plans/{{accountPlan.uuid}}"
- },
- "response": {
- "status": 422,
- "check": [{"condition": "json.has('err.accountPlan.stopNetworkBeforeDeleting')"}]
- }
- },
-
- {
- "comment": "delete network",
- "request": {
- "method": "delete",
- "uri": "me/networks/{{accountPlan.network}}"
- }
- },
-
{
"comment": "delete plan",
"request": {
diff --git a/bubble-server/src/test/resources/test-bubble-config.yml b/bubble-server/src/test/resources/test-bubble-config.yml
index 42e00c5e..664c6779 100644
--- a/bubble-server/src/test/resources/test-bubble-config.yml
+++ b/bubble-server/src/test/resources/test-bubble-config.yml
@@ -41,7 +41,7 @@ staticAssets:
STRIPE_PUBLIC_API_KEY: {{STRIPE_PUBLIC_API_KEY}}
http:
- port: {{#exists BUBBLE_SERVER_PORT}}{{BUBBLE_SERVER_PORT}}{{else}}8090{{/exists}}
+ port: 0
baseUri: /api
jersey:
diff --git a/utils/cobbzilla-wizard b/utils/cobbzilla-wizard
index 8f3c566b..f4062af3 160000
--- a/utils/cobbzilla-wizard
+++ b/utils/cobbzilla-wizard
@@ -1 +1 @@
-Subproject commit 8f3c566b05bdced05af7f69d4cdf63f672f8fc61
+Subproject commit f4062af3bc423f88705fc90bebc4fbab15096e83