View Javadoc

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   * A very basic server implementation.
17   * <p>
18   * It is not used for anything, but sometimes useful to reproduce
19   * bugs.
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 }