From 229ce21573395f7691532623e11654ea90029398 Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Mon, 13 Jan 2020 20:03:31 -0500 Subject: [PATCH] update tests so jenkins can run them easier --- bubble-server/pom.xml | 24 +++++++ .../payment/stripe/StripePaymentDriver.java | 22 ++++--- .../java/bubble/dao/account/AccountDAO.java | 2 +- .../java/bubble/dao/bill/AccountPlanDAO.java | 4 +- .../bubble/model/cloud/BubbleFootprint.java | 5 +- .../java/bubble/model/cloud/CloudService.java | 5 +- ...cationHandler_payment_driver_validate.java | 2 + .../NotificationHandler_storage_driver.java | 5 +- .../resources/account/AccountsResource.java | 2 +- .../service/boot/ActivationService.java | 2 +- .../notify/NotificationInboxProcessor.java | 5 ++ .../post_auth/ResourceMessages.properties | 1 - .../resources/models/defaults/bubblePlan.json | 4 +- .../bubble/mock/MockStripePaymentDriver.java | 5 ++ .../test/ActivatedBubbleModelTestBase.java | 16 +---- .../bubble/test/BubbleApiRunnerListener.java | 6 +- .../java/bubble/test/BubbleCoreSuite.java | 19 ------ .../java/bubble/test/BubbleModelTestBase.java | 63 ++++++++++++++++++- .../java/bubble/test/NetworkKeysTest.java | 9 --- .../test/java/bubble/test/NetworkTest.java | 2 + .../test/java/bubble/test/PaymentTest.java | 24 +------ .../java/bubble/test/PaymentTestBase.java | 26 ++++++++ .../bubble/test/RecurringBillingTest.java | 9 +++ .../test/dev/NewBlankDevServerTest.java | 8 +++ .../test/{ => live}/GoDaddyDnsTest.java | 3 +- .../test/{ => live}/Route53DnsTest.java | 3 +- .../bubble/test/{ => live}/S3StorageTest.java | 3 +- .../models/tests/auth/multifactor_auth.json | 8 +-- .../pay_credit_refund_and_restart.json | 20 ------ .../src/test/resources/test-bubble-config.yml | 2 +- utils/cobbzilla-wizard | 2 +- 31 files changed, 189 insertions(+), 122 deletions(-) delete mode 100644 bubble-server/src/test/java/bubble/test/BubbleCoreSuite.java delete mode 100644 bubble-server/src/test/java/bubble/test/NetworkKeysTest.java create mode 100644 bubble-server/src/test/java/bubble/test/PaymentTestBase.java create mode 100644 bubble-server/src/test/java/bubble/test/RecurringBillingTest.java rename bubble-server/src/test/java/bubble/test/{ => live}/GoDaddyDnsTest.java (73%) rename bubble-server/src/test/java/bubble/test/{ => live}/Route53DnsTest.java (93%) rename bubble-server/src/test/java/bubble/test/{ => live}/S3StorageTest.java (99%) 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