/* Copyright 2012, UCAR/Unidata.
See the LICENSE file for more information.
*/
package ucar.unidata.util.test;
import ucar.httpservices.HTTPFactory;
import ucar.httpservices.HTTPMethod;
import ucar.nc2.NetcdfFile;
import ucar.nc2.dataset.NetcdfDataset;
import java.io.*;
import java.nio.charset.Charset;
import java.util.EnumSet;
import java.util.Set;
public class UnitTestCommon
{
//////////////////////////////////////////////////
// Static Constants
static public final boolean DEBUG = false;
static public final Charset UTF8 = Charset.forName("UTF-8");
// Look for these to verify we have found the thredds root
static final String[] DEFAULTSUBDIRS = new String[]{"httpservices", "cdm", "tds", "opendap", "dap4"};
static public org.slf4j.Logger log;
// NetcdfDataset enhancement to use: need only coord systems
static final Set<NetcdfDataset.Enhance> ENHANCEMENT = EnumSet.of(NetcdfDataset.Enhance.CoordSystems);
//////////////////////////////////////////////////
// Static methods
// Walk around the directory structure to locate
// the path to the thredds root (which may not
// be names "thredds").
// Same as code in UnitTestCommon, but for
// some reason, Intellij will not let me import it.
static String
locateThreddsRoot()
{
// Walk up the user.dir path looking for a node that has
// all the directories in SUBROOTS.
String path = System.getProperty("user.dir");
// clean up the path
path = path.replace('\\', '/'); // only use forward slash
assert (path != null);
if(path.endsWith("/")) path = path.substring(0, path.length() - 1);
File prefix = new File(path);
for(; prefix != null; prefix = prefix.getParentFile()) {//walk up the tree
int found = 0;
String[] subdirs = prefix.list();
for(String dirname : subdirs) {
for(String want : DEFAULTSUBDIRS) {
if(dirname.equals(want)) {
found++;
break;
}
}
}
if(found == DEFAULTSUBDIRS.length) try {// Assume this is it
String root = prefix.getCanonicalPath();
// clean up the root path
root = root.replace('\\', '/'); // only use forward slash
return root;
} catch (IOException ioe) {
}
}
return null;
}
static protected String
rebuildpath(String[] pieces, int last)
{
StringBuilder buf = new StringBuilder();
for(int i = 0; i <= last; i++) {
buf.append("/");
buf.append(pieces[i]);
}
return buf.toString();
}
static public void
clearDir(File dir, boolean clearsubdirs)
{
// wipe out the dir contents
if(!dir.exists()) return;
for(File f : dir.listFiles()) {
if(f.isDirectory()) {
if(clearsubdirs) {
clearDir(f, true); // clear subdirs
f.delete();
}
} else
f.delete();
}
}
//////////////////////////////////////////////////
// Instance variables
// System properties
protected boolean prop_ascii = true;
protected boolean prop_diff = true;
protected boolean prop_baseline = false;
protected boolean prop_visual = false;
protected boolean prop_debug = DEBUG;
protected boolean prop_generate = true;
protected String prop_controls = null;
protected String title = "Testing";
protected String name = "testcommon";
protected String threddsroot = null;
protected String dtsServer = null;
protected String threddsServer = null;
//////////////////////////////////////////////////
// Constructor(s)
public UnitTestCommon()
{
this("UnitTest");
}
public UnitTestCommon(String name)
{
this.name = name;
setSystemProperties();
initPaths();
}
protected void
initPaths()
{
// Compute the root path
this.threddsroot = locateThreddsRoot();
// Compute server names
this.dtsServer = TestDir.dap2TestServer;
if(DEBUG) {
System.err.println("UnitTestCommon: dtsServer=" + dtsServer);
}
this.threddsServer = TestDir.remoteTestServer;
if(DEBUG) {
System.err.println("UnitTestCommon: threddsServer=" + threddsServer);
}
}
/**
* Try to get the system properties
*/
protected void setSystemProperties()
{
if(System.getProperty("nodiff") != null)
prop_diff = false;
if(System.getProperty("baseline") != null)
prop_baseline = true;
if(System.getProperty("nogenerate") != null)
prop_generate = false;
if(System.getProperty("debug") != null)
prop_debug = true;
if(System.getProperty("visual") != null)
prop_visual = true;
if(System.getProperty("ascii") != null)
prop_ascii = true;
if(System.getProperty("utf8") != null)
prop_ascii = false;
if(prop_baseline && prop_diff)
prop_diff = false;
prop_controls = System.getProperty("controls", "");
}
//////////////////////////////////////////////////
// Accessor
public void setTitle(String title)
{
this.title = title;
}
public String getTitle()
{
return this.title;
}
public String getThreddsroot()
{
return this.threddsroot;
}
public String getName()
{
return this.name;
}
//////////////////////////////////////////////////
// Instance Utilities
public void
visual(String header, String captured)
{
visual(header, captured, '-');
}
public void
visual(String header, String captured, char marker)
{
if(!captured.endsWith("\n"))
captured = captured + "\n";
// Dump the output for visual comparison
System.out.println("Testing " + getName() + ": " + header + ":");
StringBuilder sep = new StringBuilder();
for(int i = 0; i < 10; i++) {
sep.append(marker);
}
System.out.println(sep.toString());
System.out.print(captured);
System.out.println(sep.toString());
}
static public String compare(String tag, String baseline, String s)
{
try {
// Diff the two print results
Diff diff = new Diff(tag);
StringWriter sw = new StringWriter();
boolean pass = !diff.doDiff(baseline, s, sw);
return (pass ? null : sw.toString());
} catch (Exception e) {
System.err.println("UnitTest: Diff failure: " + e);
return null;
}
}
protected String
findServer(String servlet, String svcname, String schema)
throws Exception
{
if(servlet.startsWith("/"))
servlet = servlet.substring(1);
String svc = "http://" + svcname + "/" + servlet;
if(!checkServer(svc))
throw new Exception("Server not reachable:" + svc);
// Since we will be accessing it thru NetcdfDataset, we need to change the schema.
return schema + "://" + svcname + "/" + servlet;
}
protected boolean
checkServer(String candidate)
{
if(candidate == null) return false;
// ping to see if we get a response
System.err.print("Checking for sourceurl: " + candidate);
try {
try (HTTPMethod method = HTTPFactory.Get(candidate)) {
method.execute();
String s = method.getResponseAsString();
System.err.println(" ; found");
return true;
}
} catch (IOException ie) {
System.err.println(" ; fail");
return false;
} finally {
// requires httpclient4 HTTPSession.setRetryCount(savecount);
}
}
//////////////////////////////////////////////////
// Static utilities
// Copy result into the a specified dir
static public void
writefile(String path, String content)
throws IOException
{
File f = new File(path);
if(f.exists()) f.delete();
FileWriter out = new FileWriter(f);
out.write(content);
out.close();
}
// Copy result into the a specified dir
static public void
writefile(String path, byte[] content)
throws IOException
{
File f = new File(path);
if(f.exists()) f.delete();
FileOutputStream out = new FileOutputStream(f);
out.write(content);
out.close();
}
static public String
readfile(String filename)
throws IOException
{
StringBuilder buf = new StringBuilder();
File xx = new File(filename);
if(!xx.canRead()) {
int x = 0;
}
FileReader file = new FileReader(filename);
BufferedReader rdr = new BufferedReader(file);
String line;
while((line = rdr.readLine()) != null) {
if(line.startsWith("#")) continue;
buf.append(line + "\n");
}
return buf.toString();
}
static public byte[]
readbinaryfile(String filename)
throws IOException
{
FileInputStream stream = new FileInputStream(filename);
byte[] result = readbinaryfile(stream);
stream.close();
return result;
}
static public byte[]
readbinaryfile(InputStream stream)
throws IOException
{
// Extract the stream into a bytebuffer
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
byte[] tmp = new byte[1 << 16];
for(; ; ) {
int cnt;
cnt = stream.read(tmp);
if(cnt <= 0) break;
bytes.write(tmp, 0, cnt);
}
return bytes.toByteArray();
}
// Properly access a dataset
static public NetcdfDataset openDataset(String url)
throws IOException
{
return NetcdfDataset.acquireDataset(null, url, ENHANCEMENT, -1, null, null);
}
// Fix up a filename reference in a string
static public String shortenFileName(String text, String filename)
{
// In order to achieve diff consistentcy, we need to
// modify the output to change "netcdf .../file.nc {...}"
// to "netcdf file.nc {...}"
String fixed = filename.replace('\\', '/');
String shortname = filename;
if(fixed.lastIndexOf('/') >= 0)
shortname = filename.substring(fixed.lastIndexOf('/') + 1, filename.length());
text = text.replaceAll(filename, shortname);
return text;
}
static public void
tag(String t)
{
System.err.println(t);
System.err.flush();
}
static protected String
ncdumpmetadata(NetcdfFile ncfile)
throws Exception
{
StringWriter sw = new StringWriter();
// Print the meta-databuffer using these args to NcdumpW
try {
if(!ucar.nc2.NCdumpW.print(ncfile, "-unsigned", sw, null))
throw new Exception("NcdumpW failed");
} catch (IOException ioe) {
throw new Exception("NcdumpW failed", ioe);
}
sw.close();
return sw.toString();
}
static protected String
ncdumpdata(NetcdfFile ncfile)
throws Exception
{
StringWriter sw = new StringWriter();
// Dump the databuffer
sw = new StringWriter();
try {
if(!ucar.nc2.NCdumpW.print(ncfile, "-vall -unsigned", sw, null))
throw new Exception("NCdumpW failed");
} catch (IOException ioe) {
ioe.printStackTrace();
throw new Exception("NCdumpW failed", ioe);
}
sw.close();
return sw.toString();
}
}