kris/fix_backup_restore_test
до master
4 роки тому
@@ -122,7 +122,6 @@ public class ApiConstants { | |||
public static final String DOMAINS_ENDPOINT = "/domains"; | |||
public static final String PLANS_ENDPOINT = "/plans"; | |||
public static final String FOOTPRINTS_ENDPOINT = "/footprints"; | |||
public static final String BACKUPS_ENDPOINT = "/backups"; | |||
public static final String EP_CLEAN_BACKUPS = "/clean"; | |||
public static final String PAYMENT_METHODS_ENDPOINT = "/paymentMethods"; | |||
@@ -20,7 +20,7 @@ import javax.persistence.*; | |||
import javax.validation.constraints.Pattern; | |||
import javax.validation.constraints.Size; | |||
import static bubble.ApiConstants.BACKUPS_ENDPOINT; | |||
import static bubble.ApiConstants.EP_BACKUPS; | |||
import static bubble.ApiConstants.ERROR_MAXLEN; | |||
import static bubble.service.backup.BackupService.BR_STATE_LOCK_TIMEOUT; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | |||
@@ -29,7 +29,7 @@ import static org.cobbzilla.wizard.model.crypto.EncryptedTypes.ENCRYPTED_STRING; | |||
import static org.cobbzilla.wizard.model.crypto.EncryptedTypes.ENC_PAD; | |||
@ECType(root=true, name="backup") @ECTypeCreate(method="DISABLED") | |||
@ECTypeURIs(baseURI=BACKUPS_ENDPOINT, listFields={"network", "label", "path"}) | |||
@ECTypeURIs(baseURI=EP_BACKUPS, listFields={"network", "label", "path"}) | |||
@Entity @NoArgsConstructor @Accessors(chain=true) | |||
@ECIndexes({ @ECIndex(unique=true, of={"network", "path"}) }) | |||
public class BubbleBackup extends IdentifiableBase implements HasAccount { | |||
@@ -8,6 +8,7 @@ import org.junit.Test; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.die; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | |||
import static org.cobbzilla.util.http.URIUtil.hostToDomain; | |||
public class BackupRestoreTest extends LiveTestBase { | |||
@@ -15,10 +16,14 @@ public class BackupRestoreTest extends LiveTestBase { | |||
final String fqdn = System.getenv("BUBBLE_BACKUP_RESTORE_SAGE"); | |||
return empty(fqdn) ? die("getTestSageFqdn: BUBBLE_BACKUP_RESTORE_SAGE env var not defined") : fqdn; | |||
} | |||
// If not default, remember to set `TEST_SAGE_ROOT_PASS` properly also. | |||
@Override protected boolean shouldStopSage() { return false; } | |||
@Override public boolean backupsEnabled() { return true; } | |||
@Override public String getDefaultDomain() { return hostToDomain(getTestSageFqdn()); } | |||
@Test public void testBackupAndRestore () throws Exception { modelTest("live/backup_and_restore"); } | |||
} |
@@ -11,8 +11,10 @@ import org.junit.After; | |||
import org.junit.AfterClass; | |||
import org.junit.Before; | |||
import java.util.AbstractMap; | |||
import java.util.concurrent.atomic.AtomicReference; | |||
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; | |||
import static org.junit.Assert.fail; | |||
@Slf4j | |||
@@ -21,27 +23,34 @@ public class LiveTestBase extends NetworkTestBase { | |||
@Override protected boolean useMocks() { return false; } | |||
protected String getTestSageFqdn() { return System.getenv("TEST_SAGE_FQDN"); } | |||
protected String getTestSageRootPass() { | |||
final var envRootPass = System.getenv("TEST_SAGE_ROOT_PASS"); | |||
return (!empty(envRootPass)) ? envRootPass : ROOT_PASSWORD; | |||
} | |||
protected boolean shouldStopSage() { return true; } | |||
private static final AtomicReference<String> sageFqdn = new AtomicReference<>(); | |||
private static final AtomicReference<AbstractMap.SimpleEntry<String, String>> sageFqdnAndRootPass = | |||
new AtomicReference<>(); | |||
private static final AtomicReference<LiveTestBase> testInstance = new AtomicReference<>(); | |||
@Before public void startSage () throws Exception { | |||
synchronized (sageFqdn) { | |||
if (sageFqdn.get() == null) { | |||
final String envSage = getTestSageFqdn(); | |||
synchronized (sageFqdnAndRootPass) { | |||
if (sageFqdnAndRootPass.get() == null) { | |||
final var envSage = getTestSageFqdn(); | |||
final var rootPass = getTestSageRootPass(); | |||
if (envSage != null) { | |||
sageFqdn.set(envSage); | |||
sageFqdnAndRootPass.set(new AbstractMap.SimpleEntry<>(envSage, rootPass)); | |||
} else { | |||
modelTest("live/fork_sage"); | |||
final NewNodeNotification newNetwork = (NewNodeNotification) getApiRunner().getContext().get("newNetwork"); | |||
final var newNetwork = (NewNodeNotification) getApiRunner().getContext().get("newNetwork"); | |||
if (newNetwork == null) fail("newNetwork not found in context after fork"); | |||
if (newNetwork.getFqdn() == null) fail("newNetwork.fqdn was null after fork"); | |||
sageFqdn.set(newNetwork.getFqdn()); | |||
sageFqdnAndRootPass.set(new AbstractMap.SimpleEntry<>(newNetwork.getFqdn(), rootPass)); | |||
} | |||
} | |||
} | |||
getApiRunner().getContext().put("sageFqdn", sageFqdn.get()); | |||
getApiRunner().getContext().put("sageFqdn", sageFqdnAndRootPass.get().getKey()); | |||
getApiRunner().getContext().put("sageRootPass", sageFqdnAndRootPass.get().getValue()); | |||
} | |||
@After public void saveTestInstance() throws Exception { testInstance.set(this); } | |||
@@ -49,10 +58,10 @@ public class LiveTestBase extends NetworkTestBase { | |||
@AfterClass public static void stopSage () throws Exception { | |||
final LiveTestBase liveTest = testInstance.get(); | |||
if (liveTest == null) { | |||
log.warn("testInstance was never set, cannot stop sage: "+sageFqdn.get()); | |||
log.warn("testInstance was never set, cannot stop sage: " + sageFqdnAndRootPass.get()); | |||
} else { | |||
if (liveTest.shouldStopSage()) { | |||
final String fqdn = sageFqdn.get(); | |||
final var fqdn = sageFqdnAndRootPass.get().getKey(); | |||
if (fqdn == null) { | |||
log.warn("stopSage: sage FQDN never got set"); | |||
} else { | |||
@@ -31,7 +31,7 @@ | |||
{ | |||
"comment": "add <<contactType>> contact for user <<username>>", | |||
"unless": "existingContact.getInfo() == '<<contactInfo>>'", | |||
"unless": "existingContact.getUuid() != null", | |||
"request": { | |||
"session": "<<userSession>>", | |||
"uri": "users/<<username>>/policy/contacts", | |||
@@ -47,7 +47,7 @@ | |||
{ | |||
"comment": "resend verification message for <<contactType>>/<<contactInfo>> for user <<username>>", | |||
"onlyIf": "existingContact.getInfo() == '<<contactInfo>>'", | |||
"onlyIf": "existingContact.getUuid() != null", | |||
"request": { | |||
"session": "<<userSession>>", | |||
"uri": "users/<<username>>/policy/contacts/verify", | |||
@@ -22,7 +22,8 @@ | |||
"region": "New Jersey", | |||
"bubbleConnectionVar": "bubbleConnection", | |||
"bubbleUserSessionVar": "bubbleUserSession", | |||
"bubbleUserVar": "bubbleUserAccount" | |||
"bubbleUserVar": "bubbleUserAccount", | |||
"sendMetrics": null | |||
} | |||
}, | |||
@@ -94,8 +95,47 @@ | |||
}, | |||
{ | |||
"comment": "add email contact for the new user, if not already present", | |||
"include": "add_approved_contact", | |||
"params": { | |||
"username": "<<username>>", | |||
"userSession": "<<userSessionVar>>", | |||
"userConnection": "<<sageConnectionVar>>", | |||
"rootSession": "rootSession", | |||
"rootConnection": "<<sageConnectionVar>>", | |||
"contactInfo": "<<email>>", | |||
"contactLookup": "<<email>>", | |||
"authFactor": "not_required" | |||
} | |||
}, | |||
{ | |||
"comment": "list all payment methods", | |||
"request": { "uri": "me/paymentMethods?all=true" }, | |||
"response": { "store": "paymentMethods" } | |||
}, | |||
{ | |||
"comment": "add payment method for the user", | |||
"onlyIf": "len(paymentMethods) == 0", | |||
"before": "stripe_tokenize_card", | |||
"request": { | |||
"uri": "me/paymentMethods", | |||
"method": "put", | |||
"entity": { "paymentMethodType": "credit", "paymentInfo": "{{stripeToken}}" } | |||
} | |||
}, | |||
{ | |||
"comment": "list all payment methods again after creating one", | |||
"onlyIf": "len(paymentMethods) == 0", | |||
"request": { "uri": "me/paymentMethods?all=true" }, | |||
"response": { "store": "paymentMethods", "check": [{ "condition": "len(json) == 1" }] } | |||
}, | |||
{ | |||
"comment": "add plan, using the first found payment method for the new bubble", | |||
"before": "sleep 24s", | |||
"comment": "add plan", | |||
"request": { | |||
"uri": "me/plans", | |||
"method": "put", | |||
@@ -105,12 +145,12 @@ | |||
"locale": "<<locale>>", | |||
"timezone": "<<timezone>>", | |||
"plan": "<<plan>>", | |||
"footprint": "<<footprint>>" | |||
"footprint": "<<footprint>>", | |||
"sendMetrics": <<sendMetrics>>, | |||
"paymentMethodObject": { "uuid": "{{ paymentMethods.[0].uuid }}" } | |||
} | |||
}, | |||
"response": { | |||
"store": "plan" | |||
} | |||
"response": { "store": "plan" } | |||
}, | |||
{ | |||
@@ -125,8 +165,8 @@ | |||
}, | |||
{ | |||
"before": "await_url me/networks/<<network>>/dns/find?type=A&name=.<<network>>.<<domain>> 40m 10s await_json.length > 0", | |||
"comment": "list DNS for the network, should now see a DNS A record for new instance", | |||
"before": "await_url me/networks/<<network>>/dns/find?type=A&name=.<<network>>.<<domain>> 40m 10s await_json.length > 0", | |||
"request": { | |||
"uri": "me/networks/<<network>>/dns/find?type=A&name=.<<network>>.<<domain>>" | |||
}, | |||
@@ -139,8 +179,8 @@ | |||
}, | |||
{ | |||
"before": "await_url .bubble 40m 20s", | |||
"comment": "call API of deployed node, ensure it is running", | |||
"before": "await_url .bubble 40m 20s", | |||
"connection": { | |||
"name": "<<bubbleConnectionVar>>", | |||
"baseUri": "https://{{<<networkVar>>.host}}.<<network>>.<<domain>>:{{serverConfig.nginxPort}}/api" | |||
@@ -10,7 +10,7 @@ | |||
"uri": "auth/login", | |||
"entity": { | |||
"username": "root", | |||
"password": "password1!" | |||
"password": "{{sageRootPass}}" | |||
} | |||
}, | |||
"response": { | |||
@@ -20,19 +20,8 @@ | |||
} | |||
}, | |||
{ | |||
"comment": "load root account policy", | |||
"request": { | |||
"uri": "users/root/policy" | |||
}, | |||
"response": { | |||
"store": "rootPolicy" | |||
} | |||
}, | |||
{ | |||
"comment": "add root@example.com as email contact for root user, if not already present", | |||
"onlyIf": "!rootPolicy.hasContact('root@example.com')", | |||
"include": "add_approved_contact", | |||
"params": { | |||
"username": "root", | |||
@@ -51,6 +40,7 @@ | |||
"include": "new_bubble", | |||
"params": { | |||
"sageFqdn": "{{sageFqdn}}", | |||
"rootPassword": "{{sageRootPass}}", | |||
"username": "bubble-user", | |||
"password": "password1!", | |||
"userSessionVar": "userSession", | |||
@@ -58,13 +48,14 @@ | |||
"email": "bubble-user@example.com", | |||
"plan": "bubble", | |||
"networkVar": "bubbleNetwork", | |||
"bubbleConnectionVar": "bubbleConnection" | |||
"bubbleConnectionVar": "bubbleConnection", | |||
"sendMetrics": true | |||
} | |||
}, | |||
{ | |||
"before": "await_url .bubble 40m 20s", | |||
"comment": "add file to storage", | |||
"before": "await_url .bubble 40m 20s", | |||
"connection": { "name": "bubbleConnection" }, | |||
"request": { | |||
"session": "bubbleUserSession", | |||
@@ -23,7 +23,7 @@ | |||
"uri": "auth/login", | |||
"entity": { | |||
"name": "root", | |||
"password": "password1!" | |||
"password": "{{sageRootPass}}" | |||
} | |||
}, | |||
"response": { | |||