This is an automated email from the ASF dual-hosted git repository.

tarmstrong pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/impala.git


The following commit(s) were added to refs/heads/2.x by this push:
     new 2106127  IMPALA-7144: Re-enable TestDescribeTableResults
2106127 is described below

commit 21061277241a02fff3fbc8b2fe0b2d81bb290645
Author: Fredy Wijaya <fwij...@cloudera.com>
AuthorDate: Thu Jun 7 16:08:38 2018 -0500

    IMPALA-7144: Re-enable TestDescribeTableResults
    
    This patch makes the TestDescribeTableResults more robust by only
    comparing the information that the authorization cares about instead
    of comparing all output in DESCRIBE. This change will avoid any unnecessary
    changes to AuthorizationTest if HMS updates the DESCRIBE output.
    
    The test is also updated to support standalone execution without relying
    on other tests be executed first since it can cause the test to be flaky
    especially if the tests in AuthorizationTest are executed in parallel.
    
    Testing:
    - Ran all FE tests
    
    Change-Id: I3aeaecf5b6d906a66d338e165a6d506e3964563f
    Reviewed-on: http://gerrit.cloudera.org:8080/10643
    Reviewed-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com>
    Tested-by: Impala Public Jenkins <impala-public-jenk...@cloudera.com>
    Reviewed-on: http://gerrit.cloudera.org:8080/12331
    Reviewed-by: Fredy Wijaya <fwij...@cloudera.com>
---
 .../apache/impala/analysis/AuthorizationTest.java  | 346 +++++++++++----------
 1 file changed, 175 insertions(+), 171 deletions(-)

diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java 
b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
index 4d7e4d6..f482140 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
@@ -27,6 +27,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.UUID;
 
 import org.apache.hadoop.conf.Configuration;
@@ -40,7 +41,6 @@ import org.apache.impala.catalog.AuthorizationException;
 import org.apache.impala.catalog.Db;
 import org.apache.impala.catalog.ImpaladCatalog;
 import org.apache.impala.catalog.ScalarFunction;
-import org.apache.impala.catalog.ScalarType;
 import org.apache.impala.catalog.Type;
 import org.apache.impala.common.AnalysisException;
 import org.apache.impala.common.FrontendTestBase;
@@ -1807,189 +1807,193 @@ public class AuthorizationTest extends 
FrontendTestBase {
         "User '%s' does not have privileges to access: 
functional.allcomplextypes");
   }
 
-  // Expected output of DESCRIBE for a functional table.
-  private static final List<String> EXPECTED_DESCRIBE_ALLTYPESSMALL =
-      Lists.newArrayList(
-      "id","int","",
-      "int_col","int", "",
-      "year","int", ""
-      );
+  private static class DescribeResult {
+    // List of column names.
+    private final List<String> columns_;
+    // The value of the describe result's location field.
+    private final String location_;
 
-  // Expected output of DESCRIBE for a functional table.
-  private static final List<String> EXPECTED_DESCRIBE_ALLTYPESAGG =
-      Lists.newArrayList(
-      "id","int","",
-      "bool_col","boolean","",
-      "tinyint_col","tinyint","",
-      "smallint_col","smallint", "",
-      "int_col","int", "",
-      "bigint_col","bigint", "",
-      "float_col","float", "",
-      "double_col","double", "",
-      "date_string_col","string", "",
-      "string_col","string", "",
-      "timestamp_col","timestamp", "",
-      "year","int", "",
-      "month","int", "",
-      "day","int", ""
-      );
+    public DescribeResult(List<String> columns, String location) {
+      this.columns_ = columns;
+      this.location_ = location;
+    }
 
-  // Expected output of DESCRIBE for a functional table.
-  // "*" is used when the output is variable such as time or user.
-  private static final List<String> EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG =
-      Lists.newArrayList(
-      "# col_name","data_type","comment",
-      "","NULL","NULL",
-      "id","int","NULL",
-      "bool_col","boolean","NULL",
-      "tinyint_col","tinyint","NULL",
-      "smallint_col","smallint","NULL",
-      "int_col","int","NULL",
-      "bigint_col","bigint","NULL",
-      "float_col","float","NULL",
-      "double_col","double","NULL",
-      "date_string_col","string","NULL",
-      "string_col","string","NULL",
-      "timestamp_col","timestamp","NULL",
-      "","NULL","NULL",
-      "# Partition Information","NULL","NULL",
-      "# col_name","data_type","comment",
-      "","NULL","NULL",
-      "year","int","NULL",
-      "month","int","NULL",
-      "day","int","NULL",
-      "","NULL","NULL",
-      "# Detailed Table Information","NULL","NULL",
-      "Database:","functional","NULL",
-      "OwnerType:","USER","NULL",
-      "Owner:","*","NULL",
-      "CreateTime:","*","NULL",
-      "LastAccessTime:","UNKNOWN","NULL",
-      "Protect Mode:","None","NULL",
-      "Retention:","0","NULL",
-      "Location:","hdfs://localhost:20500/test-warehouse/alltypesagg","NULL",
-      "Table Type:","EXTERNAL_TABLE","NULL",
-      "Table Parameters:","NULL","NULL",
-      "","DO_NOT_UPDATE_STATS","true",
-      "","EXTERNAL","TRUE",
-      "","STATS_GENERATED_VIA_STATS_TASK","true",
-      "","impala.lastComputeStatsTime","*",
-      "","numRows","11000",
-      "","totalSize","834279",
-      "","transient_lastDdlTime","*",
-      "","NULL","NULL",
-      "# Storage Information","NULL","NULL",
-      "SerDe 
Library:","org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe","NULL",
-      "InputFormat:","org.apache.hadoop.mapred.TextInputFormat","NULL",
-      
"OutputFormat:","org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat","NULL",
-      "Compressed:","No","NULL",
-      "Num Buckets:","0","NULL",
-      "Bucket Columns:","[]","NULL",
-      "Sort Columns:","[]","NULL",
-      "Storage Desc Params:","NULL","NULL",
-      "","escape.delim","\\\\",
-      "","field.delim",",",
-      "","serialization.format",","
-      );
+    public DescribeResult(List<String> columns) {
+      this(columns, null);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+      DescribeResult that = (DescribeResult) o;
+      return Objects.equals(columns_, that.columns_) &&
+          Objects.equals(location_, that.location_);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(columns_, location_);
+    }
+
+    @Override
+    public String toString() {
+      return "DescribeResult{" +
+          "columns=" + columns_ +
+          ", location='" + location_ + '\'' +
+          '}';
+    }
+  }
 
-  // Expected output of DESCRIBE for a functional table.
-  // "*" is used when the output is variable such as time or user.
-  private static final List<String> EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL =
-      Lists.newArrayList(
-      "# col_name","data_type","comment",
-      "","NULL","NULL",
-      "id","int","NULL",
-      "int_col","int","NULL",
-      "","NULL","NULL",
-      "# Partition Information","NULL","NULL",
-      "# col_name","data_type","comment",
-      "","NULL","NULL",
-      "year","int","NULL",
-      "","NULL","NULL",
-      "# Detailed Table Information","NULL","NULL",
-      "Database:","functional","NULL",
-      "OwnerType:","USER","NULL",
-      "Owner:","*","NULL",
-      "CreateTime:","*","NULL",
-      "LastAccessTime:","UNKNOWN","NULL",
-      "Protect Mode:","None","NULL",
-      "Retention:","0","NULL",
-      "Table Type:","EXTERNAL_TABLE","NULL",
-      "Table Parameters:","NULL","NULL",
-      "","DO_NOT_UPDATE_STATS","true",
-      "","EXTERNAL","TRUE",
-      "","STATS_GENERATED_VIA_STATS_TASK","true",
-      "","impala.lastComputeStatsTime","*",
-      "","numRows","100",
-      "","totalSize","6472",
-      "","transient_lastDdlTime","*",
-      "","NULL","NULL",
-      "# Storage Information","NULL","NULL",
-      "SerDe 
Library:","org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe","NULL",
-      "InputFormat:","org.apache.hadoop.mapred.TextInputFormat","NULL",
-      
"OutputFormat:","org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat","NULL",
-      "Compressed:","No","NULL",
-      "Num Buckets:","0","NULL",
-      "Bucket Columns:","[]","NULL",
-      "Sort Columns:","[]","NULL",
-      "Storage Desc Params:","NULL","NULL",
-      "","escape.delim","\\\\",
-      "","field.delim",",",
-      "","serialization.format",","
+  // Expected output of DESCRIBE for functional.alltypessmall.
+  private static final DescribeResult EXPECTED_DESCRIBE_ALLTYPESSMALL =
+      new DescribeResult(Lists.newArrayList(
+          "id",
+          "int_col",
+          "year"
+      ));
+
+  // Expected output of DESCRIBE for functional.alltypesagg.
+  private static final DescribeResult EXPECTED_DESCRIBE_ALLTYPESAGG =
+      new DescribeResult(Lists.newArrayList(
+          "id",
+          "bool_col",
+          "tinyint_col",
+          "smallint_col",
+          "int_col",
+          "bigint_col",
+          "float_col",
+          "double_col",
+          "date_string_col",
+          "string_col",
+          "timestamp_col",
+          "year",
+          "month",
+          "day"
+      ));
+
+  // Expected output of DESCRIBE for functional.alltypesagg.
+  private static final DescribeResult EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG =
+      new DescribeResult(Lists.newArrayList(
+          "id",
+          "bool_col",
+          "tinyint_col",
+          "smallint_col",
+          "int_col",
+          "bigint_col",
+          "float_col",
+          "double_col",
+          "date_string_col",
+          "string_col",
+          "timestamp_col",
+          "year",
+          "month",
+          "day"),
+          "hdfs://localhost:20500/test-warehouse/alltypesagg"
       );
 
+  // Expected output of DESCRIBE for functional.alltypessmall.
+  private static final DescribeResult EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL 
=
+      new DescribeResult(Lists.newArrayList(
+          "id",
+          "int_col",
+          "year"
+      ));
+
   @Test
   public void TestDescribeTableResults() throws ImpalaException {
-    // Verify MINIMAL describe contains all columns
-    TDescribeResult result = fe_.describeTable(new 
TTableName("functional","alltypesagg"),
-        TDescribeOutputStyle.MINIMAL, USER);
-    Assert.assertEquals(EXPECTED_DESCRIBE_ALLTYPESAGG, 
resultToStringList(result));
-
-    // Verify EXTENDED output contains all columns and data
-    result = fe_.describeTable(new TTableName("functional","alltypesagg"),
-        TDescribeOutputStyle.EXTENDED, USER);
-    verifyOutputWithOptionalData(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG,
-        resultToStringList(result));
-
-    // Verify FORMATTED output contains all columns and data
-    result = fe_.describeTable(new TTableName("functional","alltypesagg"),
-        TDescribeOutputStyle.FORMATTED, USER);
-    verifyOutputWithOptionalData(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG,
-        resultToStringList(result));
+    // Running these statements force the tables to be loaded into the 
catalog, which
+    // allows running this test independently of other tests.
+    AuthzOk("describe functional.alltypesagg");
+    AuthzOk("describe functional.alltypessmall");
+
+    // Verify MINIMAL describe contains all columns.
+    TDescribeOutputStyle style = TDescribeOutputStyle.MINIMAL;
+    TDescribeResult result = fe_.describeTable(new TTableName("functional",
+        "alltypesagg"), style, USER);
+    assertEquals(EXPECTED_DESCRIBE_ALLTYPESAGG, toDescribeResult(result, 
style));
 
     // Verify MINIMAL describe on restricted table shows limited columns.
-    result = fe_.describeTable(new TTableName("functional","alltypessmall"),
-        TDescribeOutputStyle.MINIMAL, USER);
-    Assert.assertEquals(EXPECTED_DESCRIBE_ALLTYPESSMALL,
-        resultToStringList(result));
-
-    // Verify FORMATTED output contains all columns and data
-    result = fe_.describeTable(new TTableName("functional","alltypessmall"),
-        TDescribeOutputStyle.FORMATTED, USER);
-    verifyOutputWithOptionalData(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL,
-        resultToStringList(result));
-  }
-
-  // Compares two arrays but skips an expected value that contains '*' since 
we need to
-  // compare output but some values change based on builds, environments, etc.
-  private void verifyOutputWithOptionalData(List<String> expected, 
List<String> actual) {
-    Assert.assertEquals(expected.size(), actual.size());
-    for (int idx = 0; idx < expected.size(); idx++) {
-      if (!expected.get(idx).equals("*")) {
-        Assert.assertEquals(expected.get(idx), actual.get(idx));
-      }
+    style = TDescribeOutputStyle.MINIMAL;
+    result = fe_.describeTable(new TTableName("functional", "alltypessmall"), 
style,
+        USER);
+    assertEquals(EXPECTED_DESCRIBE_ALLTYPESSMALL, toDescribeResult(result, 
style));
+
+    for (TDescribeOutputStyle s : new TDescribeOutputStyle[]{
+        TDescribeOutputStyle.EXTENDED, TDescribeOutputStyle.FORMATTED}) {
+      // Verify FORMATTED/EXTENDED output contains all columns and metadata.
+      result = fe_.describeTable(new TTableName("functional", "alltypesagg"), 
s, USER);
+      assertEquals(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESAGG, 
toDescribeResult(result, s));
+
+      // Verify FORMATTED output contains all columns and metadata.
+      result = fe_.describeTable(new TTableName("functional", 
"alltypessmall"), s, USER);
+      assertEquals(EXPECTED_DESCRIBE_EXTENDED_ALLTYPESSMALL, 
toDescribeResult(result, s));
     }
   }
 
-  // Convert TDescribeResult to ArrayList of strings.
-  private static List<String> resultToStringList(TDescribeResult result) {
-    List<String> strarr = new ArrayList<String>();
-    for (TResultRow row: result.getResults()) {
-      for (TColumnValue col: row.getColVals()) {
-        strarr.add(col.getString_val() == null ? "NULL": 
col.getString_val().trim());
-      }
+  private static DescribeResult toDescribeResult(TDescribeResult result,
+      TDescribeOutputStyle style) {
+    List<String> columns = new ArrayList<>();
+    String location = null;
+    List<TResultRow> rows = result.getResults();
+    switch (style) {
+      case MINIMAL:
+        // Example output:
+        // [[bool_col,boolean,]
+        //  [month,int,]]
+        for (TResultRow row : rows) {
+          columns.add(row.getColVals().get(0).getString_val().trim());
+        }
+        break;
+      case EXTENDED:
+      case FORMATTED:
+        // Example output:
+        // [[name,type,comment],
+        //  [#col_name,data_type,comment],
+        //  [,,],
+        //  [bool_col,boolean,],
+        //  [tinyint_col,tinyint,],
+        //  [,,],
+        //  [#PartitionInformation,,],
+        //  [#col_name,data_type,comment],
+        //  [,,],
+        //  [year,int,],
+        //  [month,int,],
+        //  [,,],
+        //  [#DetailedTableInformation,,],
+        //  [Database:,functional,],
+        //  [Location:,hdfs://localhost:20500/test-warehouse/alltypes,],
+        //  [,,]
+        //  [#StorageInformation,,]
+        //  [SerDeLibrary:,org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe,]
+        //  [InputFormat:,org.apache.hadoop.mapred.TextInputFormat,]]
+        int rowIdx = 0;
+        while (rowIdx < rows.size()) {
+          List<TColumnValue> cols = rows.get(rowIdx).getColVals();
+          if (cols.get(0).getString_val().startsWith("Location")) {
+            Preconditions.checkState(location == null);
+            location = cols.get(1).getString_val().trim();
+          } else if (cols.get(0).getString_val().startsWith("# col_name")) {
+            // To get the column names, we need to ignore the first empty line 
and stop
+            // until we see another empty line.
+            rowIdx += 2; // Skips over the first empty line.
+            Preconditions.checkElementIndex(rowIdx, rows.size());
+            cols = rows.get(rowIdx).getColVals();
+            // Stop when we see the next empty line.
+            while (!cols.get(0).getString_val().trim().isEmpty()) {
+              columns.add(cols.get(0).getString_val().trim());
+              rowIdx++;
+              Preconditions.checkElementIndex(rowIdx, rows.size());
+              cols = rows.get(rowIdx).getColVals();
+            }
+          }
+          rowIdx++;
+        }
+        break;
+      default:
+        throw new IllegalArgumentException("Invalid describe output style: " + 
style);
     }
-    return strarr;
+    return new DescribeResult(columns, location);
   }
 
   @Test

Reply via email to