Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TestUtils.java
Go to the documentation of this file.
1 // Copyright (c) 2012 Cloudera, Inc. All rights reserved.
2 
3 package com.cloudera.impala.testutil;
4 import java.text.SimpleDateFormat;
5 import java.util.ArrayList;
6 import java.util.Calendar;
7 import java.util.Collections;
8 import java.util.Scanner;
9 import java.util.Map;
10 import java.io.StringWriter;
11 import java.io.StringReader;
12 
13 import javax.json.Json;
14 import javax.json.stream.JsonGenerator;
15 import javax.json.JsonReader;
16 import javax.json.JsonObject;
17 import javax.json.JsonWriter;
18 import javax.json.JsonWriterFactory;
19 
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22 
24 import com.cloudera.impala.thrift.TClientRequest;
25 import com.cloudera.impala.thrift.TNetworkAddress;
26 import com.cloudera.impala.thrift.TQueryCtx;
27 import com.cloudera.impala.thrift.TQueryOptions;
28 import com.cloudera.impala.thrift.TSessionState;
29 import com.cloudera.impala.thrift.TSessionType;
30 import com.cloudera.impala.thrift.TUniqueId;
31 
32 import com.google.common.collect.Maps;
33 
34 public class TestUtils {
35  private final static Logger LOG = LoggerFactory.getLogger(TestUtils.class);
36  private final static String[] expectedFilePrefix_ = { "hdfs:", "file: " };
37  private final static String[] ignoreContentAfter_ = { "HOST:", "LOCATIONS:" };
38  // Special prefix that designates an expected value specified as a regex rather
39  // than a literal
40  private final static String regexAgainstActual_ = "regex:";
41 
42  // Our partition file paths are returned in the format of:
43  // hdfs://<host>:<port>/<table>/year=2009/month=4/-47469796--667104359_25784_data.0
44  // Everything after the month=4 can vary run to run so we want to filter this out
45  // when comparing expected vs actual results. We also want to filter out the
46  // host/port because that could vary run to run as well.
47  private final static String HDFS_FILE_PATH_FILTER = "-*\\d+--\\d+_\\d+.*$";
48  private final static String HDFS_HOST_PORT_FILTER = "//\\w+:\\d+/";
49 
61  public static String compareOutput(
62  ArrayList<String> actual, ArrayList<String> expected, boolean orderMatters) {
63  if (!orderMatters) {
64  Collections.sort(actual);
65  Collections.sort(expected);
66  }
67  int mismatch = -1; // line in actual w/ mismatch
68  int maxLen = Math.min(actual.size(), expected.size());
69  for (int i = 0; i < maxLen; ++i) {
70  String expectedStr = expected.get(i).trim();
71  String actualStr = actual.get(i);
72  // Look for special prefixes in containsPrefixes.
73  boolean containsPrefix = false;
74  for (int prefixIdx = 0; prefixIdx < expectedFilePrefix_.length; ++prefixIdx) {
75  containsPrefix = expectedStr.contains(expectedFilePrefix_[prefixIdx]);
76  if (containsPrefix) {
77  expectedStr = expectedStr.replaceFirst(expectedFilePrefix_[prefixIdx], "");
78  actualStr = actualStr.replaceFirst(expectedFilePrefix_[prefixIdx], "");
79  expectedStr = applyHdfsFilePathFilter(expectedStr);
80  actualStr = applyHdfsFilePathFilter(actualStr);
81  break;
82  }
83  }
84 
85  boolean ignoreAfter = false;
86  for (int j = 0; j < ignoreContentAfter_.length; ++j) {
87  ignoreAfter |= expectedStr.startsWith(ignoreContentAfter_[j]);
88  }
89 
90  if (expectedStr.startsWith(regexAgainstActual_)) {
91  // Get regex to check against by removing prefix.
92  String regex = expectedStr.replace(regexAgainstActual_, "").trim();
93  if (!actualStr.matches(regex)) {
94  mismatch = i;
95  break;
96  }
97  // Accept actualStr.
98  continue;
99  }
100 
101  // do a whitespace-insensitive comparison
102  Scanner e = new Scanner(expectedStr);
103  Scanner a = new Scanner(actualStr);
104  while (a.hasNext() && e.hasNext()) {
105  if (containsPrefix) {
106  if (!a.next().contains(e.next())) {
107  mismatch = i;
108  break;
109  }
110  } else {
111  if (!a.next().equals(e.next())) {
112  mismatch = i;
113  break;
114  }
115  }
116  }
117  if (mismatch != -1) {
118  break;
119  }
120 
121  if (ignoreAfter) {
122  if (e.hasNext() && !a.hasNext()) {
123  mismatch = i;
124  break;
125  }
126  } else if (a.hasNext() != e.hasNext()) {
127  mismatch = i;
128  break;
129  }
130  }
131  if (mismatch == -1 && actual.size() < expected.size()) {
132  // actual is a prefix of expected
133  StringBuilder output =
134  new StringBuilder("actual result is missing lines:\n");
135  for (int i = 0; i < actual.size(); ++i) {
136  output.append(actual.get(i)).append("\n");
137  }
138  output.append("missing:\n");
139  for (int i = actual.size(); i < expected.size(); ++i) {
140  output.append(expected.get(i)).append("\n");
141  }
142  return output.toString();
143  }
144 
145  if (mismatch != -1) {
146  // print actual and expected, highlighting mismatch
147  StringBuilder output =
148  new StringBuilder("actual result doesn't match expected result:\n");
149  for (int i = 0; i <= mismatch; ++i) {
150  output.append(actual.get(i)).append("\n");
151  }
152  // underline mismatched line with "^^^..."
153  for (int i = 0; i < actual.get(mismatch).length(); ++i) {
154  output.append('^');
155  }
156  output.append("\n");
157  for (int i = mismatch + 1; i < actual.size(); ++i) {
158  output.append(actual.get(i)).append("\n");
159  }
160  output.append("\nexpected:\n");
161  for (String str : expected) {
162  output.append(str).append("\n");
163  }
164  return output.toString();
165  }
166 
167  if (actual.size() > expected.size()) {
168  // print actual and expected
169  StringBuilder output =
170  new StringBuilder("actual result contains extra output:\n");
171  for (String str : actual) {
172  output.append(str).append("\n");
173  }
174  output.append("\nexpected:\n");
175  for (String str : expected) {
176  output.append(str).append("\n");
177  }
178  return output.toString();
179  }
180 
181  return "";
182  }
183 
188  private static String applyHdfsFilePathFilter(String hdfsPath) {
189  hdfsPath = hdfsPath.replaceAll(HDFS_HOST_PORT_FILTER, " ");
190  return hdfsPath.replaceAll(HDFS_FILE_PATH_FILTER, "");
191  }
192 
193 
197  public static TQueryCtx createQueryContext() {
198  return createQueryContext(Catalog.DEFAULT_DB, System.getProperty("user.name"));
199  }
200 
204  public static TQueryCtx createQueryContext(String defaultDb, String user) {
205  TQueryCtx queryCtx = new TQueryCtx();
206  queryCtx.setRequest(new TClientRequest("FeTests", new TQueryOptions()));
207  queryCtx.setQuery_id(new TUniqueId());
208  queryCtx.setSession(new TSessionState(new TUniqueId(), TSessionType.BEESWAX,
209  defaultDb, user, new TNetworkAddress("localhost", 0)));
210  SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSSSS");
211  queryCtx.setNow_string(formatter.format(Calendar.getInstance().getTime()));
212  queryCtx.setPid(1000);
213  return queryCtx;
214  }
215 
219  public static String prettyPrintJson(String json) {
220  StringWriter sw = new StringWriter();
221  JsonWriter jsonWriter = null;
222  try {
223  JsonReader jr = Json.createReader(new StringReader(json));
224  JsonObject jobj = jr.readObject();
225  Map<String, Object> properties = Maps.newHashMap();
226  properties.put(JsonGenerator.PRETTY_PRINTING, true);
227  JsonWriterFactory writerFactory = Json.createWriterFactory(properties);
228  jsonWriter = writerFactory.createWriter(sw);
229  jsonWriter.writeObject(jobj);
230  } catch (Exception e) {
231  LOG.error(String.format("Error pretty printing JSON string %s: %s", json,
232  e.getMessage()));
233  return "";
234  } finally {
235  if (jsonWriter != null) jsonWriter.close();
236  }
237  return sw.toString();
238  }
239 }
static final String[] ignoreContentAfter_
Definition: TestUtils.java:37
static final String HDFS_FILE_PATH_FILTER
Definition: TestUtils.java:47
static String applyHdfsFilePathFilter(String hdfsPath)
Definition: TestUtils.java:188
static final String regexAgainstActual_
Definition: TestUtils.java:40
static TQueryCtx createQueryContext(String defaultDb, String user)
Definition: TestUtils.java:204
static final String HDFS_HOST_PORT_FILTER
Definition: TestUtils.java:48
static String compareOutput(ArrayList< String > actual, ArrayList< String > expected, boolean orderMatters)
Definition: TestUtils.java:61
static final String[] expectedFilePrefix_
Definition: TestUtils.java:36
static String prettyPrintJson(String json)
Definition: TestUtils.java:219
static final String DEFAULT_DB
Definition: Catalog.java:58