1 package com.aragost.javahg.test;
2
3 import java.io.BufferedReader;
4 import java.io.ByteArrayOutputStream;
5 import java.io.File;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.InputStreamReader;
10 import java.io.OutputStream;
11
12 import com.aragost.javahg.internals.Utils;
13 import com.google.common.io.Files;
14
15
16
17
18
19
20
21 public class SimpleTestServer {
22
23 private File directory;
24
25 private String hgBin = "hg";
26
27 private InputStream input;
28 private InputStream error;
29 private OutputStream output;
30
31 private Thread errorReaderThread = new Thread() {
32 public void run() {
33 BufferedReader reader = new BufferedReader(new InputStreamReader(SimpleTestServer.this.error));
34 String line;
35 try {
36 while ((line = reader.readLine()) != null) {
37 System.err.println("error: " + line);
38 }
39 } catch (IOException e) {
40 e.printStackTrace();
41 }
42 };
43 };
44
45 public SimpleTestServer(File directory) {
46 this.directory = directory;
47 }
48
49 public void start() throws IOException {
50 ProcessBuilder processBuilder = new ProcessBuilder(this.hgBin, "serve", "--cmdserve", "pipe", "--config",
51 "ui.interactive=true");
52 processBuilder.directory(this.directory);
53 Process process = processBuilder.start();
54
55 this.input = process.getInputStream();
56 this.error = process.getErrorStream();
57 this.output = process.getOutputStream();
58 this.errorReaderThread.start();
59 readChannel();
60 int length = readLength();
61 byte[] bytes = new byte[length];
62 int n = this.input.read(bytes);
63 if (n != length) {
64 throw new RuntimeException("Wrong number of bytes read");
65 }
66 System.out.println(new String(bytes));
67 }
68
69 public void stop() throws IOException {
70 this.input.close();
71 this.error.close();
72 this.output.close();
73 }
74
75 private void processInput() throws IOException {
76 while (true) {
77 int channel = readChannel();
78 if (channel == -1) {
79 return;
80 }
81 int length = readLength();
82 switch (channel) {
83 case 'o':
84 case 'e':
85 System.out.print("" + (char) channel + length + ":");
86 byte[] bytes = new byte[length];
87 int n = this.input.read(bytes);
88 if (n != length) {
89 throw new RuntimeException("Wrong number of bytes read");
90 }
91 System.out.println(new String(bytes));
92 break;
93 case 'r':
94 int rc = readLength();
95 System.out.println("rc=" + rc);
96 return;
97 default:
98 throw new RuntimeException("Unsupported channel: " + channel);
99 }
100 }
101 }
102
103 private int readLength() throws IOException {
104 return Utils.readBigEndian(this.input);
105 }
106
107 private int readChannel() throws IOException {
108 return this.input.read();
109 }
110
111 public void run(String... args) throws IOException {
112 ByteArrayOutputStream baos = new ByteArrayOutputStream();
113 baos.write(args[0].getBytes());
114 for (int i = 1; i < args.length; i++) {
115 baos.write(0);
116 baos.write(args[i].getBytes());
117 }
118 this.output.write("runcommand\n".getBytes());
119 Utils.writeBigEndian(baos.size(), this.output);
120 this.output.write(baos.toByteArray());
121 this.output.flush();
122 processInput();
123 }
124
125 public static void main(String[] args) throws IOException {
126 File dir = Files.createTempDir();
127 Runtime.getRuntime().exec("hg init " + dir.getAbsolutePath());
128 SimpleTestServer s = new SimpleTestServer(dir);
129 s.start();
130
131 File file = new File(dir, "a");
132 FileOutputStream out = new FileOutputStream(file);
133 out.write("a".getBytes());
134 out.close();
135
136 s.run("add", "--debug");
137 s.run("commit", "--debug", "-mm");
138
139 out = new FileOutputStream(file);
140 out.write("b".getBytes());
141 out.close();
142
143 s.run("add", "--debug");
144 s.run("commit", "--debug", "-mm");
145 s.run("rollback");
146 s.run("log", "--rev", "0", "--debug", "--template", "{node}");
147 s.run("status");
148 s.run("add", "--debug");
149 s.run("commit", "-mm");
150
151 s.stop();
152 }
153 }