Skip to content

Commit 2fef9bf

Browse files
committed
Merge pull request #76 from aozarov/temp
Replacing gcd.sh as a local resource with a remote version
2 parents 8881beb + 8352ecd commit 2fef9bf

File tree

2 files changed

+86
-15
lines changed

2 files changed

+86
-15
lines changed

gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java

Lines changed: 86 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,33 @@
2020

2121
import com.google.common.base.Strings;
2222

23+
import java.io.BufferedInputStream;
2324
import java.io.BufferedOutputStream;
2425
import java.io.BufferedReader;
2526
import java.io.File;
27+
import java.io.FileInputStream;
2628
import java.io.FileOutputStream;
2729
import java.io.FileReader;
2830
import java.io.FileWriter;
2931
import java.io.IOException;
3032
import java.io.InputStream;
3133
import java.io.InputStreamReader;
3234
import java.io.OutputStream;
35+
import java.math.BigInteger;
3336
import java.net.HttpURLConnection;
37+
import java.net.MalformedURLException;
3438
import java.net.URL;
39+
import java.nio.channels.Channels;
40+
import java.nio.channels.ReadableByteChannel;
3541
import java.nio.file.FileVisitResult;
3642
import java.nio.file.Files;
3743
import java.nio.file.Path;
3844
import java.nio.file.Paths;
3945
import java.nio.file.SimpleFileVisitor;
4046
import java.nio.file.attribute.BasicFileAttributes;
47+
import java.security.MessageDigest;
48+
import java.security.NoSuchAlgorithmException;
49+
import java.util.Locale;
4150
import java.util.zip.ZipEntry;
4251
import java.util.zip.ZipInputStream;
4352

@@ -52,8 +61,18 @@ public class LocalGcdHelper {
5261

5362
public static final String DEFAULT_PROJECT_ID = "projectid1";
5463
public static final int PORT = 8080;
55-
private static final String GCD = "gcd-head";
56-
private static final String GCD_LOC = '/' + GCD + ".zip";
64+
private static final String GCD = "gcd-v1beta2-rev1-2.1.2b";
65+
private static final String GCD_FILENAME = GCD + ".zip";
66+
private static final String MD5_CHECKSUM = "d84384cdfa8658e1204f4f8be51300e8";
67+
private static final URL GCD_URL;
68+
69+
static {
70+
try {
71+
GCD_URL = new URL("http://storage.googleapis.com/gcd/tools/" + GCD_FILENAME);
72+
} catch (MalformedURLException e) {
73+
throw new RuntimeException(e);
74+
}
75+
}
5776

5877
private static class ProcessStreamReader extends Thread {
5978

@@ -101,13 +120,32 @@ public LocalGcdHelper(String projectId) {
101120
this.projectId = projectId;
102121
}
103122

123+
/**
124+
* Starts the local datastore for the specific project.
125+
*
126+
* This will unzip the gcd tool, create the project and start it.
127+
* All content is written to a temporary directory that will be deleted when
128+
* {@link #stop()} is called or when the program terminates) to make sure that no left-over
129+
* data from prior runs is used.
130+
*/
104131
public void start() throws IOException, InterruptedException {
132+
// send a quick request in case we have a hanging process from a previous run
105133
sendQuitRequest();
134+
// Each run is associated with its own folder that is deleted once test completes.
106135
gcdPath = Files.createTempDirectory("gcd");
107136
File gcdFolder = gcdPath.toFile();
108137
gcdFolder.deleteOnExit();
109138

110-
try (ZipInputStream zipIn = new ZipInputStream(getClass().getResourceAsStream(GCD_LOC))) {
139+
// check if we already have a local copy of the gcd utility and download it if not.
140+
File gcdZipFile = new File(System.getProperty("java.io.tmpdir"), GCD_FILENAME);
141+
if (!gcdZipFile.exists() || !MD5_CHECKSUM.equals(md5(gcdZipFile))) {
142+
ReadableByteChannel rbc = Channels.newChannel(GCD_URL.openStream());
143+
FileOutputStream fos = new FileOutputStream(gcdZipFile);
144+
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
145+
fos.close();
146+
}
147+
// unzip the gcd
148+
try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(gcdZipFile))) {
111149
ZipEntry entry = zipIn.getNextEntry();
112150
while (entry != null) {
113151
File filePath = new File(gcdFolder, entry.getName());
@@ -120,27 +158,60 @@ public void start() throws IOException, InterruptedException {
120158
entry = zipIn.getNextEntry();
121159
}
122160
}
123-
161+
// cleanup any possible data for the same project
124162
File datasetFolder = new File(gcdFolder, GCD + '/' + projectId);
125163
deleteRecurse(datasetFolder.toPath());
126164

127-
// TODO: if System.getProperty("os.name").startsWith("Windows") use cmd.exe /c and gcd.cmd
128-
Process temp = new ProcessBuilder()
129-
.redirectErrorStream(true)
130-
.directory(new File(gcdFolder, GCD))
131-
.redirectOutput(new File("/dev/null"))
132-
.command("bash", "gcd.sh", "create", "-d", projectId, projectId)
133-
.start();
165+
// create the datastore for the project
166+
ProcessBuilder processBuilder = new ProcessBuilder()
167+
.redirectError(ProcessBuilder.Redirect.INHERIT)
168+
.directory(new File(gcdFolder, GCD));
169+
if (isWindows()) {
170+
processBuilder.command("cmd", "/C", "gcd.cmd", "create", "-p", projectId, projectId);
171+
processBuilder.redirectOutput(new File("NULL:"));
172+
} else {
173+
processBuilder.redirectOutput(new File("/dev/null"));
174+
processBuilder.command("bash", "gcd.sh", "create", "-p", projectId, projectId);
175+
}
176+
177+
Process temp = processBuilder.start();
134178
temp.waitFor();
135179

136-
temp = new ProcessBuilder()
180+
// start the datastore for the project
181+
processBuilder = new ProcessBuilder()
137182
.directory(new File(gcdFolder, GCD))
138-
.redirectErrorStream(true)
139-
.command("bash", "gcd.sh", "start", "--testing", "--allow_remote_shutdown", projectId)
140-
.start();
183+
.redirectErrorStream(true);
184+
if (isWindows()) {
185+
processBuilder.command("cmd", "/C", "gcd.cmd", "start", "--testing",
186+
"--allow_remote_shutdown", projectId);
187+
} else {
188+
processBuilder.command("bash", "gcd.sh", "start", "--testing", "--allow_remote_shutdown",
189+
projectId);
190+
}
191+
temp = processBuilder.start();
141192
processReader = ProcessStreamReader.start(temp, "Dev App Server is now running");
142193
}
143194

195+
private static String md5(File gcdZipFile) throws IOException {
196+
try {
197+
MessageDigest md5 = MessageDigest.getInstance("MD5");
198+
try (InputStream is = new BufferedInputStream(new FileInputStream(gcdZipFile))) {
199+
byte[] bytes = new byte[4 * 1024 * 1024];
200+
int len;
201+
while ((len = is.read(bytes)) >= 0) {
202+
md5.update(bytes, 0, len);
203+
}
204+
}
205+
return String.format("%032x",new BigInteger(1, md5.digest()));
206+
} catch (NoSuchAlgorithmException e) {
207+
throw new IOException(e);
208+
}
209+
}
210+
211+
private static boolean isWindows() {
212+
return System.getProperty("os.name").toLowerCase(Locale.ENGLISH).indexOf("windows") > -1;
213+
}
214+
144215
private static void extractFile(ZipInputStream zipIn, File filePath) throws IOException {
145216
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) {
146217
byte[] bytesIn = new byte[1024];
Binary file not shown.

0 commit comments

Comments
 (0)