-
Notifications
You must be signed in to change notification settings - Fork 3
Add integration tests for table store #239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jnmt
wants to merge
3
commits into
fix-null-condition-handling
Choose a base branch
from
add-integration-tests-for-table-store
base: fix-null-condition-handling
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,324
−0
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../schema-loader/ledger-schema.json |
163 changes: 163 additions & 0 deletions
163
common-test/src/main/java/com/scalar/dl/ledger/LedgerEndToEndTestBase.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
package com.scalar.dl.ledger; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import com.google.inject.Guice; | ||
import com.google.inject.Injector; | ||
import com.scalar.db.api.DistributedStorage; | ||
import com.scalar.db.api.DistributedStorageAdmin; | ||
import com.scalar.db.config.DatabaseConfig; | ||
import com.scalar.db.exception.storage.ExecutionException; | ||
import com.scalar.db.schemaloader.SchemaLoader; | ||
import com.scalar.db.schemaloader.SchemaLoaderException; | ||
import com.scalar.db.service.StorageFactory; | ||
import com.scalar.db.storage.dynamo.DynamoAdmin; | ||
import com.scalar.db.storage.dynamo.DynamoConfig; | ||
import com.scalar.dl.client.config.ClientConfig; | ||
import com.scalar.dl.ledger.config.LedgerConfig; | ||
import com.scalar.dl.ledger.server.AdminService; | ||
import com.scalar.dl.ledger.server.BaseServer; | ||
import com.scalar.dl.ledger.server.LedgerPrivilegedService; | ||
import com.scalar.dl.ledger.server.LedgerServerModule; | ||
import java.io.IOException; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Properties; | ||
import org.junit.jupiter.api.AfterAll; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.BeforeAll; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.TestInstance; | ||
|
||
@TestInstance(TestInstance.Lifecycle.PER_CLASS) | ||
public abstract class LedgerEndToEndTestBase { | ||
private static final String SCALAR_NAMESPACE = "scalar"; | ||
private static final String ASSET_TABLE = "asset"; | ||
private static final String ASSET_METADATA_TABLE = "asset_metadata"; | ||
private static final String LEDGER_SCHEMA_PATH = "/../schema-loader/ledger-schema.json"; | ||
|
||
private static final String JDBC_TRANSACTION_MANAGER = "jdbc"; | ||
private static final String PROP_STORAGE = "scalardb.storage"; | ||
private static final String PROP_CONTACT_POINTS = "scalardb.contact_points"; | ||
private static final String PROP_USERNAME = "scalardb.username"; | ||
private static final String PROP_PASSWORD = "scalardb.password"; | ||
private static final String PROP_TRANSACTION_MANAGER = "scalardb.transaction_manager"; | ||
private static final String PROP_DYNAMO_ENDPOINT_OVERRIDE = "scalardb.dynamo.endpoint_override"; | ||
private static final String DEFAULT_STORAGE = "jdbc"; | ||
private static final String DEFAULT_CONTACT_POINTS = "jdbc:mysql://localhost/"; | ||
private static final String DEFAULT_USERNAME = "root"; | ||
private static final String DEFAULT_PASSWORD = "mysql"; | ||
private static final String DEFAULT_TRANSACTION_MANAGER = "consensus-commit"; | ||
private static final String DEFAULT_DYNAMO_ENDPOINT_OVERRIDE = "http://localhost:8000"; | ||
|
||
private static final String SOME_PRIVATE_KEY = | ||
"-----BEGIN EC PRIVATE KEY-----\n" | ||
+ "MHcCAQEEIF4SjQxTArRcZaROSFjlBP2rR8fAKtL8y+kmGiSlM5hEoAoGCCqGSM49\n" | ||
+ "AwEHoUQDQgAEY0i/iAFxIBS3etbjoSC1/aUKQV66+wiawL4bZqklu86ObIc7wrif\n" | ||
+ "HExPmVhKFSklOyZqGoOiVZA0zf0LZeFaPA==\n" | ||
+ "-----END EC PRIVATE KEY-----"; | ||
public static final String SOME_CERTIFICATE = | ||
"-----BEGIN CERTIFICATE-----\n" | ||
+ "MIICQTCCAeagAwIBAgIUEKARigcZQ3sLEXdlEtjYissVx0cwCgYIKoZIzj0EAwIw\n" | ||
+ "QTELMAkGA1UEBhMCSlAxDjAMBgNVBAgTBVRva3lvMQ4wDAYDVQQHEwVUb2t5bzES\n" | ||
+ "MBAGA1UEChMJU2FtcGxlIENBMB4XDTE4MDYyMTAyMTUwMFoXDTE5MDYyMTAyMTUw\n" | ||
+ "MFowRTELMAkGA1UEBhMCSlAxDjAMBgNVBAgTBVRva3lvMQ4wDAYDVQQHEwVUb2t5\n" | ||
+ "bzEWMBQGA1UEChMNU2FtcGxlIENsaWVudDBZMBMGByqGSM49AgEGCCqGSM49AwEH\n" | ||
+ "A0IABGNIv4gBcSAUt3rW46Egtf2lCkFeuvsImsC+G2apJbvOjmyHO8K4nxxMT5lY\n" | ||
+ "ShUpJTsmahqDolWQNM39C2XhWjyjgbcwgbQwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud\n" | ||
+ "JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQW\n" | ||
+ "BBTpBQl/JxB7yr77uMVT9mMicPeVJTAfBgNVHSMEGDAWgBQrJo3N3/0j3oPS6F6m\n" | ||
+ "wunHe8xLpzA1BgNVHREELjAsghJjbGllbnQuZXhhbXBsZS5jb22CFnd3dy5jbGll\n" | ||
+ "bnQuZXhhbXBsZS5jb20wCgYIKoZIzj0EAwIDSQAwRgIhAJPtXSzuncDJXnM+7us8\n" | ||
+ "46MEVjGHJy70bRY1My23RkxbAiEA5oFgTKMvls8e4UpnmUgFNP+FH8a5bF4tUPaV\n" | ||
+ "BQiBbgk=\n" | ||
+ "-----END CERTIFICATE-----"; | ||
private static final int SOME_KEY_VERSION = 1; | ||
|
||
private BaseServer ledgerServer; | ||
private Properties props; | ||
private Map<String, String> creationOptions = new HashMap<>(); | ||
private Path ledgerSchemaPath; | ||
private DistributedStorage storage; | ||
private DistributedStorageAdmin storageAdmin; | ||
|
||
@BeforeAll | ||
public void setUpBeforeClass() throws Exception { | ||
props = createLedgerProperties(); | ||
StorageFactory factory = StorageFactory.create(props); | ||
storage = factory.getStorage(); | ||
storageAdmin = factory.getStorageAdmin(); | ||
ledgerSchemaPath = Paths.get(System.getProperty("user.dir") + LEDGER_SCHEMA_PATH); | ||
SchemaLoader.load(props, ledgerSchemaPath, creationOptions, true); | ||
createServer(new LedgerConfig(props)); | ||
} | ||
|
||
@AfterAll | ||
public void tearDownAfterClass() throws SchemaLoaderException, InterruptedException { | ||
ledgerServer.stop(); | ||
storage.close(); | ||
storageAdmin.close(); | ||
SchemaLoader.unload(props, ledgerSchemaPath, true); | ||
} | ||
|
||
@BeforeEach | ||
public void setUp() {} | ||
|
||
@AfterEach | ||
public void tearDown() throws ExecutionException { | ||
storageAdmin.truncateTable(SCALAR_NAMESPACE, ASSET_TABLE); | ||
storageAdmin.truncateTable(SCALAR_NAMESPACE, ASSET_METADATA_TABLE); | ||
} | ||
|
||
private Properties createLedgerProperties() { | ||
String storage = System.getProperty(PROP_STORAGE, DEFAULT_STORAGE); | ||
String contactPoints = System.getProperty(PROP_CONTACT_POINTS, DEFAULT_CONTACT_POINTS); | ||
String username = System.getProperty(PROP_USERNAME, DEFAULT_USERNAME); | ||
String password = System.getProperty(PROP_PASSWORD, DEFAULT_PASSWORD); | ||
String transactionManager = | ||
System.getProperty(PROP_TRANSACTION_MANAGER, DEFAULT_TRANSACTION_MANAGER); | ||
String endpointOverride = | ||
System.getProperty(PROP_DYNAMO_ENDPOINT_OVERRIDE, DEFAULT_DYNAMO_ENDPOINT_OVERRIDE); | ||
|
||
Properties props = new Properties(); | ||
props.put(DatabaseConfig.STORAGE, storage); | ||
props.put(DatabaseConfig.CONTACT_POINTS, contactPoints); | ||
props.put(DatabaseConfig.USERNAME, username); | ||
props.put(DatabaseConfig.PASSWORD, password); | ||
props.put(DatabaseConfig.TRANSACTION_MANAGER, transactionManager); | ||
if (transactionManager.equals(JDBC_TRANSACTION_MANAGER)) { | ||
props.put(LedgerConfig.TX_STATE_MANAGEMENT_ENABLED, "true"); | ||
} | ||
props.put(LedgerConfig.PROOF_ENABLED, "true"); | ||
props.put(LedgerConfig.PROOF_PRIVATE_KEY_PEM, SOME_PRIVATE_KEY); | ||
|
||
if (storage.equals(DynamoConfig.STORAGE_NAME)) { | ||
props.put(DynamoConfig.ENDPOINT_OVERRIDE, endpointOverride); | ||
props.put( | ||
DynamoConfig.TABLE_METADATA_NAMESPACE, DatabaseConfig.DEFAULT_SYSTEM_NAMESPACE_NAME); | ||
creationOptions = | ||
ImmutableMap.of(DynamoAdmin.NO_SCALING, "true", DynamoAdmin.NO_BACKUP, "true"); | ||
} | ||
|
||
return props; | ||
} | ||
|
||
private void createServer(LedgerConfig config) throws IOException, InterruptedException { | ||
Injector injector = Guice.createInjector(new LedgerServerModule(config)); | ||
ledgerServer = new BaseServer(injector, config); | ||
|
||
ledgerServer.start(com.scalar.dl.ledger.server.LedgerService.class); | ||
ledgerServer.startPrivileged(LedgerPrivilegedService.class); | ||
ledgerServer.startAdmin(AdminService.class); | ||
} | ||
|
||
protected ClientConfig createClientConfig(String entity) throws IOException { | ||
Properties props = new Properties(); | ||
props.put(ClientConfig.ENTITY_ID, entity); | ||
props.put(ClientConfig.DS_CERT_VERSION, String.valueOf(SOME_KEY_VERSION)); | ||
props.put(ClientConfig.DS_CERT_PEM, SOME_CERTIFICATE); | ||
props.put(ClientConfig.DS_PRIVATE_KEY_PEM, SOME_PRIVATE_KEY); | ||
return new ClientConfig(props); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way
ledgerSchemaPath
is constructed is brittle. It relies onuser.dir
pointing to a specific directory relative to the schema file, which might not always be the case depending on how the tests are executed (e.g., from an IDE with a different working directory). This can lead toFileNotFoundException
and flaky tests.A more robust approach would be to place the schema file in the test resources and load it using the class loader. This would make the test setup independent of the execution environment.
For example, if
ledger-schema.json
is insrc/main/resources
of thecommon-test
module, you could load it like this:Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be better for some cases, but we only use it in the tests in this repo, and it's a symlink shared in the
schema-loader
directory. So, I prefer to leave it as is.