Java tutorial
/* * This file is provided to you 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.basho.riak.client.http.util; import static com.basho.riak.client.util.CharsetUtils.utf8StringToBytes; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.codec.binary.Base64; import org.apache.http.client.HttpClient; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.params.AllClientPNames; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.PoolingClientConnectionManager; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import com.basho.riak.client.http.RiakClient; import com.basho.riak.client.http.RiakConfig; import com.basho.riak.client.http.RiakLink; import com.basho.riak.client.http.RiakObject; import com.basho.riak.client.http.util.ClientUtils; public class TestClientUtils { @Mock RiakClient mockRiakClient; RiakConfig config = new RiakConfig(); @Test public void newHttpClient_uses_configs_http_client_if_exists() { MockitoAnnotations.initMocks(this); HttpClient httpClient = new DefaultHttpClient(); config.setHttpClient(httpClient); assertSame(httpClient, ClientUtils.newHttpClient(config)); } @Test public void newHttpClient_sets_max_total_connections() { final int maxConnections = 11; config.setMaxConnections(maxConnections); HttpClient httpClient = ClientUtils.newHttpClient(config); assertEquals(maxConnections, ((PoolingClientConnectionManager) httpClient.getConnectionManager()).getMaxTotal()); } @Test public void newHttpClient_sets_connection_timeout() { final int timeout = 11; config.setTimeout(timeout); HttpClient httpClient = ClientUtils.newHttpClient(config); assertEquals(timeout, httpClient.getParams().getIntParameter(AllClientPNames.CONNECTION_TIMEOUT, 1)); assertEquals(timeout, httpClient.getParams().getIntParameter(AllClientPNames.SO_TIMEOUT, 1)); } @Test public void newHttpClient_sets_retry_handler() { final HttpRequestRetryHandler handler = mock(HttpRequestRetryHandler.class); config.setRetryHandler(handler); HttpClient httpClient = ClientUtils.newHttpClient(config); assertSame(handler, ((DefaultHttpClient) httpClient).getHttpRequestRetryHandler()); } @Test public void makeURI_url_encodes_bucket() { String url = ClientUtils.makeURI(config, "/"); assertTrue("Expected bucket to be encoded as %2F in URL" + url, url.endsWith("/%2F")); } @Test public void makeURI_url_encodes_key() { String url = ClientUtils.makeURI(config, "b", "/"); assertTrue("Expected key to be encoded as %2F in URL: " + url, url.endsWith("/b/%2F")); } @Test public void makeURI_prepends_slash_to_extra_if_extra_is_a_path_component() { String url = ClientUtils.makeURI(config, "b", "k", "path_component"); assertTrue("Expected a slash before path_component in URL: " + url, url.endsWith("/path_component")); } @Test public void getPathFromURL_masks_full_url() { String path = ClientUtils.getPathFromUrl("http://host.com:10000/path/to/object"); assertEquals("/path/to/object", path); } @Test public void getPathFromURL_masks_portless_url() { String path = ClientUtils.getPathFromUrl("http://host.com/path/to/object"); assertEquals("/path/to/object", path); } @Test public void getPathFromURL_masks_schemeless_url() { String path = ClientUtils.getPathFromUrl("host.com:10000/path/to/object"); assertEquals("/path/to/object", path); } @Test public void getPathFromURL_returns_path_in_path_only_url() { String path = ClientUtils.getPathFromUrl("/path/to/object"); assertEquals("/path/to/object", path); } @Test public void getPathFromURL_handles_empty_url() { String path = ClientUtils.getPathFromUrl(""); assertEquals("", path); } @Test public void getPathFromURL_handles_null() { String path = ClientUtils.getPathFromUrl(null); assertNull(path); } @Test public void unquote_string_removes_surrounding_quotes() { String s = ClientUtils.unquoteString("\"string\""); assertFalse("Starting quote should be removed", s.startsWith("\"")); assertFalse("Trailing quote should be removed", s.endsWith("\"")); } @Test public void unquote_string_unescapes_blackslash_escaped_chars() { String s = ClientUtils.unquoteString("\"\\\\\\a\\n\""); assertEquals("\\an", s); } @Test public void unquote_string_handles_trailing_blackslash() { String s = ClientUtils.unquoteString("\"\\\\\\a\\n\\\""); assertEquals("\\an\\", s); } @Test public void unquote_string_handles_unquoted_string() { String s = ClientUtils.unquoteString("\\\\\\a\\n"); assertEquals("\\an", s); } @Test public void json_opt_string_handles_any_type_and_nulls_without_throwing() throws JSONException { // optString() is used by jsonObjectAsMap and jsonArrayAsList with the // assumption that // it won't throw. Just making sure... JSONObject jsonObject = new JSONObject(); JSONArray jsonArray = new JSONArray(); assertEquals("", jsonObject.optString("k")); assertEquals("", jsonArray.optString(0)); jsonObject.put("k", new JSONArray()); jsonArray.put(0, new JSONArray()); assertEquals("[]", jsonObject.optString("k")); assertEquals("[]", jsonArray.optString(0)); jsonObject.put("k", new JSONObject()); jsonArray.put(0, new JSONObject()); assertEquals("{}", jsonObject.optString("k")); assertEquals("{}", jsonArray.optString(0)); jsonObject.put("k", 12); jsonArray.put(0, 12); assertEquals("12", jsonObject.optString("k")); assertEquals("12", jsonArray.optString(0)); jsonObject.put("k", true); jsonArray.put(0, true); assertEquals("true", jsonObject.optString("k")); assertEquals("true", jsonArray.optString(0)); } @Test public void json_object_as_map_puts_all_fields_using_opt_string() throws JSONException { JSONObject json = spy(new JSONObject().put("k1", "v1").put("k2", "v2").put("k3", "v3")); Map<String, String> map = ClientUtils.jsonObjectAsMap(json); verify(json).optString("k1"); verify(json).optString("k2"); verify(json).optString("k3"); assertEquals("v1", map.get("k1")); assertEquals("v2", map.get("k2")); assertEquals("v3", map.get("k3")); } @Test public void json_array_as_list_adds_all_elements_using_opt_string() { JSONArray json = spy(new JSONArray().put("v1").put("v2").put("v3")); List<String> list = ClientUtils.jsonArrayAsList(json); verify(json).optString(0); verify(json).optString(1); verify(json).optString(2); assertEquals("v1", list.get(0)); assertEquals("v2", list.get(1)); assertEquals("v3", list.get(2)); } @Test public void parses_null_or_empty_link_header() { Collection<RiakLink> links; links = ClientUtils.parseLinkHeader(null); assertNotNull(links); assertTrue(links.isEmpty()); ClientUtils.parseLinkHeader(""); assertNotNull(links); assertTrue(links.isEmpty()); } @Test public void parses_links_from_header() { // Rely on LinkHeader tests to verify that link parsing actually works // for other cases (single link, multiple links, malformed, etc) List<RiakLink> links = ClientUtils.parseLinkHeader("</link/1>; riaktag=t, </link/2>; riaktag=\"abc\""); assertEquals(2, links.size()); assertEquals(new RiakLink("link", "1", "t"), links.get(0)); assertEquals(new RiakLink("link", "2", "abc"), links.get(1)); } @Test public void parse_usermeta_handles_null_or_empty_header_set() { Map<String, String> usermeta; usermeta = ClientUtils.parseUsermeta(null); assertNotNull(usermeta); assertTrue(usermeta.isEmpty()); usermeta = ClientUtils.parseUsermeta(new HashMap<String, String>()); assertNotNull(usermeta); assertTrue(usermeta.isEmpty()); } @Test public void parse_usermeta_returns_correct_headers() { @SuppressWarnings("serial") Map<String, String> usermeta = new HashMap<String, String>() { { put("h1", "v1"); put("h2", "v2"); put("X-Riak-Meta-Test", "v"); } }; usermeta = ClientUtils.parseUsermeta(usermeta); assertEquals(1, usermeta.size()); assertEquals("v", usermeta.get("Test")); } @Test public void parse_usermeta_is_case_insensitive() { @SuppressWarnings("serial") Map<String, String> usermeta = new HashMap<String, String>() { { put("X-Riak-Meta-Test", "v"); put("x-riak-meta-Test2", "v2"); } }; usermeta = ClientUtils.parseUsermeta(usermeta); assertEquals(2, usermeta.size()); assertEquals("v", usermeta.get("Test")); assertEquals("v2", usermeta.get("Test2")); } @Test public void parse_multipart_handles_null_params() { List<RiakObject> objects = ClientUtils.parseMultipart(null, null, null, null, null); assertNotNull(objects); } @Test public void parse_multipart_returns_correct_riak_and_bucket_and_key() { Map<String, String> headers = new HashMap<String, String>(); headers.put("content-type", "multipart/mixed; boundary=boundary"); headers.put("x-riak-vclock", "vclock"); String body = "\r\n--boundary\r\n" + "\r\n" + "--boundary--"; List<RiakObject> objects = ClientUtils.parseMultipart(mockRiakClient, "b", "k", headers, utf8StringToBytes(body)); assertEquals(1, objects.size()); assertSame(mockRiakClient, objects.get(0).getRiakClient()); assertEquals("b", objects.get(0).getBucket()); assertEquals("k", objects.get(0).getKey()); } @Test public void parse_multipart_returns_all_header_metadata_for_object() { Map<String, String> headers = new HashMap<String, String>(); headers.put("content-type", "multipart/mixed; boundary=boundary"); headers.put("x-riak-vclock", "vclock"); String body = "\r\n--boundary\r\n" + "Content-Type: text/plain\r\n" + "Last-Modified: lastmod\r\n" + "Link: </riak/b/l>; riaktag=t\r\n" + "ETag: vtag\r\n" + "X-Riak-Meta-Test: value\r\n" + "\r\n" + "--boundary--"; List<RiakObject> objects = ClientUtils.parseMultipart(mockRiakClient, "b", "k", headers, utf8StringToBytes(body)); assertEquals(1, objects.get(0).numLinks()); assertTrue(objects.get(0).hasLink(new RiakLink("b", "l", "t"))); assertEquals(1, objects.get(0).numUsermetaItems()); assertEquals("value", objects.get(0).getUsermetaItem("test")); assertEquals("text/plain", objects.get(0).getContentType()); assertEquals("vclock", objects.get(0).getVclock()); assertEquals("lastmod", objects.get(0).getLastmod()); assertEquals("vtag", objects.get(0).getVtag()); } @Test public void parse_multipart_returns_value() { Map<String, String> headers = new HashMap<String, String>(); headers.put("content-type", "multipart/mixed; boundary=boundary"); headers.put("x-riak-vclock", "vclock"); String body = "\r\n--boundary\r\n" + "\r\n" + "foo\r\n" + "--boundary--"; List<RiakObject> objects = ClientUtils.parseMultipart(mockRiakClient, "b", "k", headers, utf8StringToBytes(body)); assertEquals("foo", objects.get(0).getValue()); } // Rely on Multipart tests to verify that multipart parsing actually works @Test public void join_handles_null_array() { assertNull(ClientUtils.join(null, null)); } @Test public void join_handles_empty_array() { assertNull(ClientUtils.join(new String[0], null)); } @Test public void join_handles_one_element_array() { assertEquals("x", ClientUtils.join(new String[] { "x" }, ",")); } @Test public void join_handles_one_multielement_array() { assertEquals("x,y,z", ClientUtils.join(new String[] { "x", "y", "z" }, ",")); } @Test public void join_handles_one_multicharacter_delimiter() { assertEquals("x//y//z", ClientUtils.join(new String[] { "x", "y", "z" }, "//")); } @Test(expected = IllegalArgumentException.class) public void encode_client_id_throws_on_null() { ClientUtils.encodeClientId((byte[]) null); } @Test(expected = IllegalArgumentException.class) public void encode_client_id_throws_on_too_short_input() { ClientUtils.encodeClientId("id"); } @Test public void encode_client_id_encodes_first_4_bytes() { String id = "clientid"; String encoded = ClientUtils.encodeClientId(id); byte[] decoded; try { decoded = Base64.decodeBase64(encoded.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("UTF-8 support required in JVM"); } assertEquals(4, decoded.length); assertEquals(id.getBytes()[0], decoded[0]); assertEquals(id.getBytes()[1], decoded[1]); assertEquals(id.getBytes()[2], decoded[2]); assertEquals(id.getBytes()[3], decoded[3]); } @Test public void random_client_id_returns_4_encoded_bytes() { String encoded = ClientUtils.randomClientId(); byte[] decoded; try { decoded = Base64.decodeBase64(encoded.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("UTF-8 support required in JVM"); } assertEquals(4, decoded.length); } @Test public void random_client_id_returns_different_ids() { String id1 = ClientUtils.randomClientId(); String id2 = ClientUtils.randomClientId(); assertNotNull(id1); assertNotNull(id2); assertFalse(id1.equals(id2)); } }