/src/test/java/com/couchbase/mock/JMembaseTest.java
Java | 391 lines | 307 code | 55 blank | 29 comment | 17 complexity | c8dd34ca3ef15a5b360f03439859ebff MD5 | raw file
- /*
- * Copyright 2017 Couchbase, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.couchbase.mock;
- import com.couchbase.mock.client.FailoverRequest;
- import com.couchbase.mock.client.HiccupRequest;
- import com.couchbase.mock.client.MockClient;
- import com.couchbase.mock.client.MockRequest;
- import com.couchbase.mock.client.MockResponse;
- import com.couchbase.mock.client.RespawnRequest;
- import com.couchbase.mock.harakiri.HarakiriMonitor;
- import com.couchbase.mock.util.Base64;
- import com.couchbase.mock.util.ReaderUtils;
- import com.google.gson.Gson;
- import com.google.gson.JsonObject;
- import junit.framework.TestCase;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import java.net.HttpURLConnection;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.net.URL;
- import java.net.UnknownHostException;
- import java.util.List;
- import java.util.Map;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import static com.couchbase.mock.http.HttpAssert.assertResponseNotFound;
- import static com.couchbase.mock.http.HttpAssert.assertResponseOK;
- import static com.couchbase.mock.http.HttpAssert.assertResponseUnauthorized;
- /**
- * Basic testing of JMembase
- *
- * @author Trond Norbye
- */
- public class JMembaseTest extends TestCase {
- public JMembaseTest(String testName) {
- super(testName);
- }
- private CouchbaseMock instance;
- static private final int port = 28091;
- static private final int numNodes;
- static private final int numVBuckets;
- static {
- final String platform = System.getProperty("os.name");
- if (platform.equals("Mac OS X") || platform.equals("Linux")) {
- numNodes = 4;
- numVBuckets = 16;
- } else {
- numNodes = 100;
- numVBuckets = 1024;
- }
- }
- private boolean serverNotReady(int port) {
- Socket socket = null;
- try {
- socket = new Socket("localhost", port);
- return false;
- } catch (UnknownHostException ex) {
- } catch (IOException ex) {
- } finally {
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException e) {
- }
- }
- }
- return true;
- }
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- instance = new CouchbaseMock(null, port, numNodes, numVBuckets, "default:,protected:secret");
- instance.start();
- do {
- Thread.sleep(100);
- } while (serverNotReady(port));
- }
- @Override
- protected void tearDown() throws Exception {
- instance.stop();
- super.tearDown();
- }
- public void testHandleHttpRequest() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/protected");
- assertResponseOK(url, "protected", "secret");
- }
- public void testHandleHttpRequestWithTrailingSlash() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/protected/");
- assertResponseOK(url, "protected", "secret");
- }
- public void testAdministratorCouldAccessProtectedBuckets() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/protected");
- assertResponseOK(url, "Administrator", "password");
- }
- public void testDefaultBucketShouldBeAccessibleForEveryone() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/default");
- assertResponseOK(url);
- }
- public void testProtectedBucketsShouldBeFilteredOutFromList() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets");
- HttpURLConnection conn;
- try {
- conn = (HttpURLConnection) url.openConnection();
- assertNotNull(conn);
- assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
- StringBuilder sb = new StringBuilder();
- BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- String line;
- while ((line = in.readLine()) != null) {
- sb.append(line);
- }
- List json = JsonUtils.decodeAsList(sb.toString());
- assertEquals(1, json.size());
- Map<String,Object> bucket = (Map<String,Object>)json.get(0);
- assertEquals("default", bucket.get("name"));
- } catch (Exception ex) {
- fail(ex.getMessage());
- }
- }
- public void testHandleHttpRequestNetwork() throws IOException {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- pw.print("GET /pools/default/buckets/default HTTP/1.1\r\n");
- pw.print("Authorization: Basic " + Base64.encode("Administrator:password") + "\r\n");
- pw.print("\r\n");
- pw.flush();
- Socket s = new Socket("localhost", port);
- OutputStream out = s.getOutputStream();
- out.write(sw.toString().getBytes());
- out.flush();
- BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
- int content_length = 0;
- String header;
- while ((header = in.readLine()).length() > 0) {
- String[] tokens = header.split(": ");
- if (tokens[0].equals("Content-Length")) {
- content_length = Integer.parseInt(tokens[1]);
- }
- }
- char[] body = new char[content_length];
- assertEquals(content_length, in.read(body));
- s.close();
- }
- public void testHandleHttpRequestMissingAuth() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/protected");
- assertResponseUnauthorized(url);
- }
- @SuppressWarnings("SpellCheckingInspection")
- public void testHandleHttpRequestIncorrectCred() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/protected");
- assertResponseUnauthorized(url, "Bubba", "TheHut");
- }
- @SuppressWarnings("SpellCheckingInspection")
- public void testHandleHttpRequestIllegalCred() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/default");
- assertResponseUnauthorized(url, "", "TheHut");
- }
- public void testHandleHttpRequestUnkownFile() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/");
- assertResponseNotFound(url, "Administrator", "password");
- }
- // @SuppressWarnings("UnusedAssignment")
- // public void testHarakiriMonitorInvalidHost() throws IOException {
- // try {
- // HarakiriMonitor m = new HarakiriMonitor("ItWouldSuckIfYouHadAHostNamedThis", 0, false, instance.getDispatcher());
- // fail("I was not expecting to be able to connect to: \"ItWouldSuckIfYouHadAHostNamedThis:0\"");
- // } catch (Throwable t) {
- // }
- // }
- @SuppressWarnings("UnusedAssignment")
- public void testHarakiriMonitorInvalidPort() throws IOException {
- try {
- HarakiriMonitor m = new HarakiriMonitor(instance.getDispatcher());
- m.connect(null, 0);
- fail("I was not expecting to be able to connect to port 0");
- } catch (Throwable t) {
- }
- }
- public void testHarakiriMonitor() throws IOException {
- ServerSocket server = new ServerSocket(0);
- HarakiriMonitor m;
- m = new HarakiriMonitor(instance.getDispatcher());
- m.connect(null, server.getLocalPort());
- Thread t = new Thread(m);
- t.start();
- server.close();
- while (t.isAlive()) {
- try {
- t.join();
- } catch (InterruptedException ex) {
- Logger.getLogger(JMembaseTest.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
- private String readConfig(InputStream stream) throws IOException {
- int bb, lf = 0;
- StringBuilder cfg = new StringBuilder();
- do {
- bb = stream.read();
- if (bb == '\n') {
- lf++;
- } else {
- lf = 0;
- cfg.append(bb);
- }
- } while (lf < 4);
- return cfg.toString();
- }
- private static String readInput(InputStream cin) throws IOException {
- byte[] inputBuffer = new byte[4096];
- int nr;
- StringBuilder sb = new StringBuilder();
- while ((nr = cin.read(inputBuffer)) > 0) {
- String s = new String(inputBuffer, 0, nr);
- sb.append(s);
- if (nr < inputBuffer.length) {
- break;
- }
- }
- return sb.toString();
- }
- private boolean readResponse(InputStream in) throws IOException {
- String json = readInput(in);
- try {
- JsonObject response = (new Gson()).fromJson(json, JsonObject.class);
- return response.get("status").getAsString().toLowerCase().equals("ok");
- } catch (Throwable ex) {
- System.err.println("Invalid response received from the server: [" + json + "]");
- return false;
- }
- }
- @SuppressWarnings("SpellCheckingInspection")
- public void testConfigStreaming() throws IOException {
- MockClient mock = new MockClient(new InetSocketAddress("localhost", 0));
- instance.startHarakiriMonitor("localhost:" + mock.getPort(), false);
- mock.negotiate();
- Bucket bucket = instance.getBuckets().get("protected");
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/bucketsStreaming/protected");
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.addRequestProperty("Authorization", "Basic " + Base64.encode("protected:secret"));
- InputStream stream = conn.getInputStream();
- String currCfg, nextCfg;
- currCfg = readConfig(stream);
- assertEquals(numNodes, bucket.activeServers().size());
- assertTrue(mock.request(new FailoverRequest(1, "protected")).isOk());
- nextCfg = readConfig(stream);
- assertNotSame(currCfg, nextCfg);
- assertEquals(numNodes - 1, bucket.activeServers().size());
- currCfg = nextCfg;
- assertTrue(mock.request(new RespawnRequest(1, "protected")).isOk());
- nextCfg = readConfig(stream);
- assertNotSame(currCfg, nextCfg);
- assertEquals(numNodes, bucket.activeServers().size());
- assertTrue(mock.request(new HiccupRequest(10000, 20)).isOk());
- assertTrue(mock.request(new FailoverRequest(1)).isOk());
- assertTrue(mock.request(new RespawnRequest(1)).isOk());
- mock.shutdown();
- instance.getMonitor().stop();
- }
- public void testIllegalMockCommand() throws IOException {
- ServerSocket server = new ServerSocket(0);
- instance.startHarakiriMonitor("localhost:" + server.getLocalPort(), false);
- Socket client = server.accept();
- InputStream input = client.getInputStream();
- OutputStream output = client.getOutputStream();
- readInput(input);
- output.write("Yo, this should fail!\n".getBytes());
- assertFalse(readResponse(input));
- }
- public void testUnknownMockCommand() throws IOException {
- MockClient mock = new MockClient(new InetSocketAddress("localhost", 0));
- instance.startHarakiriMonitor("localhost:" + mock.getPort(), false);
- mock.negotiate();
- MockRequest request = MockRequest.build("foo");
- MockResponse resp = mock.request(request);
- assertFalse(resp.isOk());
- assertNotNull(resp.getErrorMessage());
- }
- public void testRestFlush() throws IOException {
- URL url = new URL("http://localhost:" + instance.getHttpPort() + "/pools/default/buckets/default/controller/doFlush");
- HttpURLConnection conn;
- try {
- conn = (HttpURLConnection) url.openConnection();
- assertNotNull(conn);
- assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
- } catch (Exception ex) {
- fail(ex.getMessage());
- }
- }
- final static String DDOC = "{"
- + " \"_id\": \"_design/beer\","
- + " \"language\": \"javascript\","
- + " \"views\": {"
- + " \"all\": {"
- + " \"map\": \"function(doc){ emit(doc.id, null); }\""
- + " }"
- + " }"
- + "}";
- public void testDesignManagement() throws Exception {
- URL url = new URL("http://localhost:"+instance.getHttpPort()+"/default/_design/beer");
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setDoOutput(true);
- conn.setRequestMethod("PUT");
- conn.setRequestProperty("Content-Type", "application/json");
- OutputStreamWriter osw = new OutputStreamWriter(conn.getOutputStream());
- osw.write(DDOC);
- osw.flush();
- osw.close();
- conn.getInputStream().close();
- // Get it back
- conn = (HttpURLConnection) url.openConnection();
- String s = ReaderUtils.fromStream(conn.getInputStream());
- assertEquals(s, DDOC);
- }
- }