Skip to content

Commit

Permalink
[#3210] improve(web): add checking table properties to the web e2e te…
Browse files Browse the repository at this point in the history
…st (#3400)

### What changes were proposed in this pull request?

add checking table properties to the web e2e test

<img width="647" alt="image"
src="https://github.com/datastrato/gravitino/assets/17310559/012fcd91-ab31-46a0-8e87-3c5d66ffd21f">

<img width="655" alt="image"
src="https://github.com/datastrato/gravitino/assets/17310559/c226551b-24e2-4c5e-88aa-24c2cfb10c2f">



### Why are the changes needed?

Fix: #3210

### Does this PR introduce _any_ user-facing change?

N/A

### How was this patch tested?

IT

Co-authored-by: CHEYNE <contact@ch3yne.com>
  • Loading branch information
jerryshao and ch3yne committed May 17, 2024
1 parent 09caf0a commit 2944fa4
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package com.datastrato.gravitino.integration.test.web.ui;

import static com.datastrato.gravitino.rel.expressions.transforms.Transforms.identity;

import com.datastrato.gravitino.Catalog;
import com.datastrato.gravitino.NameIdentifier;
import com.datastrato.gravitino.client.GravitinoAdminClient;
Expand All @@ -17,6 +19,14 @@
import com.datastrato.gravitino.integration.test.web.ui.pages.MetalakePage;
import com.datastrato.gravitino.integration.test.web.ui.utils.AbstractWebIT;
import com.datastrato.gravitino.rel.Column;
import com.datastrato.gravitino.rel.expressions.NamedReference;
import com.datastrato.gravitino.rel.expressions.distributions.Distribution;
import com.datastrato.gravitino.rel.expressions.distributions.Distributions;
import com.datastrato.gravitino.rel.expressions.sorts.NullOrdering;
import com.datastrato.gravitino.rel.expressions.sorts.SortDirection;
import com.datastrato.gravitino.rel.expressions.sorts.SortOrder;
import com.datastrato.gravitino.rel.expressions.sorts.SortOrders;
import com.datastrato.gravitino.rel.expressions.transforms.Transform;
import com.datastrato.gravitino.rel.types.Types;
import com.google.common.collect.Maps;
import java.util.Arrays;
Expand All @@ -30,6 +40,7 @@
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.openqa.selenium.By;

@Tag("gravitino-docker-it")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
Expand Down Expand Up @@ -83,6 +94,9 @@ public class CatalogsPageTest extends AbstractWebIT {
private static final String COMMON_JDBC_USER = "trino";
private static final String COMMON_JDBC_PWD = "ds123";

public static final String DISTRIBUTION = "distribution";
public static final String SORT_ORDERS = "sortOrders";

private static String defaultBaseLocation;

@BeforeAll
Expand Down Expand Up @@ -124,23 +138,40 @@ void createSchema(String metalakeName, String catalogName, String schemaName) {
* @param catalogName The name of the Catalog where the table will be created.
* @param schemaName The name of the Schema where the table will be created.
* @param tableName The name of the Table to be created.
* @param colName The name of the Column to be created in the Table.
*/
void createTableAndColumn(
String metalakeName,
String catalogName,
String schemaName,
String tableName,
String colName) {
void createHiveTableAndColumn(
String metalakeName, String catalogName, String schemaName, String tableName) {
Map<String, String> properties = Maps.newHashMap();
Column column = Column.of(colName, Types.IntegerType.get(), "column comment");
Column col1 = Column.of(COLUMN_NAME, Types.ByteType.get(), "col1 comment");
Column col2 = Column.of(COLUMN_NAME_2, Types.ByteType.get(), "col2 comment");
Column[] columns = new Column[] {col1, col2};
Distribution distribution = createDistribution();
SortOrder[] sortOrders = createSortOrder();
Transform[] partitions = new Transform[] {identity(col2.name())};

catalog
.asTableCatalog()
.createTable(
NameIdentifier.of(metalakeName, catalogName, schemaName, tableName),
new Column[] {column},
columns,
"comment",
properties);
properties,
partitions,
distribution,
sortOrders);
}

private Distribution createDistribution() {
return Distributions.hash(10, NamedReference.field(COLUMN_NAME));
}

private SortOrder[] createSortOrder() {
return new SortOrders.SortImpl[] {
SortOrders.of(
NamedReference.field(COLUMN_NAME), SortDirection.DESCENDING, NullOrdering.NULLS_FIRST),
SortOrders.of(
NamedReference.field(COLUMN_NAME_2), SortDirection.DESCENDING, NullOrdering.NULLS_FIRST)
};
}

/**
Expand Down Expand Up @@ -392,8 +423,7 @@ public void testRefreshCatalogPage() {
@Order(12)
public void testClickSchemaLink() {
// create table
createTableAndColumn(
METALAKE_NAME, MODIFIED_HIVE_CATALOG_NAME, SCHEMA_NAME, TABLE_NAME, COLUMN_NAME);
createHiveTableAndColumn(METALAKE_NAME, MODIFIED_HIVE_CATALOG_NAME, SCHEMA_NAME, TABLE_NAME);
catalogsPage.clickSchemaLink(
METALAKE_NAME, MODIFIED_HIVE_CATALOG_NAME, CATALOG_TYPE_RELATIONAL, SCHEMA_NAME);
Assertions.assertTrue(catalogsPage.verifyShowTableTitle(SCHEMA_TABLE_TITLE));
Expand Down Expand Up @@ -439,6 +469,18 @@ public void testClickTableLink() {

@Test
@Order(15)
public void testShowTablePropertiesTooltip() {
mouseMoveTo(By.xpath("//*[@data-refer='col-icon-" + DISTRIBUTION + "-" + COLUMN_NAME + "']"));
Assertions.assertTrue(catalogsPage.verifyTableProperties(DISTRIBUTION, COLUMN_NAME));
mouseMoveTo(By.xpath("//*[@data-refer='col-icon-" + SORT_ORDERS + "-" + COLUMN_NAME_2 + "']"));
Assertions.assertTrue(catalogsPage.verifyTableProperties(SORT_ORDERS, COLUMN_NAME_2));
mouseMoveTo(By.xpath("//*[@data-refer='overview-tip-" + SORT_ORDERS + "']"));
Assertions.assertTrue(
catalogsPage.verifyTablePropertiesOverview(Arrays.asList(COLUMN_NAME, COLUMN_NAME_2)));
}

@Test
@Order(16)
public void testRefreshTablePage() {
driver.navigate().refresh();
Assertions.assertEquals(driver.getTitle(), WEB_TITLE);
Expand All @@ -459,7 +501,7 @@ public void testRefreshTablePage() {
}

@Test
@Order(16)
@Order(17)
public void testRelationalHiveCatalogTreeNode() throws InterruptedException {
String hiveNode =
String.format(
Expand Down Expand Up @@ -490,10 +532,9 @@ public void testRelationalHiveCatalogTreeNode() throws InterruptedException {
}

@Test
@Order(17)
@Order(18)
public void testTreeNodeRefresh() throws InterruptedException {
createTableAndColumn(
METALAKE_NAME, MODIFIED_HIVE_CATALOG_NAME, SCHEMA_NAME, TABLE_NAME_2, COLUMN_NAME_2);
createHiveTableAndColumn(METALAKE_NAME, MODIFIED_HIVE_CATALOG_NAME, SCHEMA_NAME, TABLE_NAME_2);
String hiveNode =
String.format(
"{{%s}}{{%s}}{{%s}}",
Expand All @@ -519,7 +560,7 @@ public void testTreeNodeRefresh() throws InterruptedException {
}

@Test
@Order(18)
@Order(19)
public void testOtherRelationaCatalogTreeNode() throws InterruptedException {
String icebergNode =
String.format(
Expand All @@ -539,7 +580,7 @@ public void testOtherRelationaCatalogTreeNode() throws InterruptedException {
}

@Test
@Order(19)
@Order(20)
public void testSelectMetalake() throws InterruptedException {
catalogsPage.metalakeSelectChange(METALAKE_SELECT_NAME);
Assertions.assertTrue(catalogsPage.verifyEmptyTableData());
Expand All @@ -549,7 +590,7 @@ public void testSelectMetalake() throws InterruptedException {
}

@Test
@Order(20)
@Order(21)
public void testFilesetCatalogTreeNode() throws InterruptedException {
// 1. create schema and fileset of fileset catalog
createSchema(METALAKE_NAME, FILESET_CATALOG_NAME, SCHEMA_NAME_FILESET);
Expand Down Expand Up @@ -611,7 +652,7 @@ public void testFilesetCatalogTreeNode() throws InterruptedException {
}

@Test
@Order(21)
@Order(22)
public void testBackHomePage() throws InterruptedException {
clickAndWait(catalogsPage.backHomeBtn);
Assertions.assertTrue(catalogsPage.verifyBackHomePage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

package com.datastrato.gravitino.integration.test.web.ui.pages;

import static com.datastrato.gravitino.integration.test.web.ui.CatalogsPageTest.DISTRIBUTION;
import static com.datastrato.gravitino.integration.test.web.ui.CatalogsPageTest.SORT_ORDERS;

import com.datastrato.gravitino.integration.test.web.ui.utils.AbstractWebIT;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -548,6 +551,61 @@ public boolean verifyTableColumns() {
}
}

public boolean verifyTableProperties(String type, String colName) {
try {
String xpath = "";
String formattedColName = "";
if (type.equals(DISTRIBUTION)) {
xpath = "//*[@data-refer='tip-" + DISTRIBUTION + "-item-" + colName + "']";
formattedColName = "hash[10](" + colName + ")";
} else if (type.equals(SORT_ORDERS)) {
xpath = "//*[@data-refer='tip-" + SORT_ORDERS + "-item-" + colName + "']";
formattedColName = colName + " desc nulls_last";
}
List<WebElement> tooltipItems = driver.findElements(By.xpath(xpath));
new WebDriverWait(driver, MAX_TIMEOUT)
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath)));
List<String> texts = new ArrayList<>();
for (WebElement text : tooltipItems) {
texts.add(text.getText());
}
if (!texts.contains(formattedColName)) {
LOG.error("Tooltip item {} does not match, expected '{}'", colName, texts);
return false;
}
return true;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
return false;
}
}

public boolean verifyTablePropertiesOverview(List<String> cols) {
try {
WebElement columnsText =
driver.findElement(By.xpath("//*[@data-refer='overview-sortOrders-items']"));
boolean isMatchText = columnsText.getText().contains(",");
List<WebElement> tooltipCols =
driver.findElements(By.xpath("//*[@data-refer='overview-tip-sortOrders-items']"));
List<String> texts = new ArrayList<>();
for (WebElement text : tooltipCols) {
texts.add(text.getText());
}
List<String> colsTexts = new ArrayList<>();
for (String col : cols) {
colsTexts.add(col + " desc nulls_last");
}
if (!isMatchText || !texts.containsAll(colsTexts)) {
LOG.error("Overview tooltip {} does not match, expected '{}'", colsTexts, texts);
return false;
}
return true;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
return false;
}
}

public boolean verifyBackHomePage() {
try {
WebDriverWait wait = new WebDriverWait(driver, MAX_TIMEOUT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ protected boolean waitShowText(final String text, final Object locator) {
}
}

protected void mouseMoveTo(final Object locator) {
Actions action = new Actions(driver);
action.moveToElement(locatorElement(locator)).perform();
}

protected WebElement pollingWait(final By locator, final long maxTimeout) {
Wait<WebDriver> wait =
new FluentWait<>(driver)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ const TabsContent = () => {
color='white'
className={fonts.className}
sx={{ display: 'flex', flexDirection: 'column' }}
data-refer={`overview-tip-${item.type}-items`}
>
{item.type === 'sortOrders'
? it.text
Expand Down Expand Up @@ -213,7 +214,7 @@ const TabsContent = () => {
</>
}
>
<ListItem sx={{ maxWidth: 140, py: 0 }}>
<ListItem sx={{ maxWidth: 140, py: 0 }} data-refer={`overview-tip-${item.type}`}>
<ListItemText
sx={{ m: 0 }}
primary={
Expand Down Expand Up @@ -248,6 +249,7 @@ const TabsContent = () => {
whiteSpace: 'nowrap',
textOverflow: 'ellipsis'
}}
data-refer={`overview-${item.type}-items`}
>
{item.items.map((it, idx) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const TableView = () => {
color='white'
className={fonts.className}
sx={{ display: 'flex', flexDirection: 'column' }}
data-refer={`tip-${type}-item-${name}`}
>
{it.text || it.fields}
</Typography>
Expand All @@ -139,7 +140,7 @@ const TableView = () => {
</>
}
>
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box sx={{ display: 'flex', alignItems: 'center' }} data-refer={`col-icon-${type}-${name}`}>
<Icon icon={icon} />
</Box>
</CustomTooltip>
Expand Down

0 comments on commit 2944fa4

Please sign in to comment.