Package ch.entwine.weblounge.test.harness.content

Source Code of ch.entwine.weblounge.test.harness.content.CacheTest

/*
*  Weblounge: Web Content Management System
*  Copyright (c) 2003 - 2011 The Weblounge Team
*  http://entwinemedia.com/weblounge
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program; if not, write to the Free Software Foundation
*  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

package ch.entwine.weblounge.test.harness.content;

import static junit.framework.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import ch.entwine.weblounge.common.content.page.Page;
import ch.entwine.weblounge.common.impl.content.page.PageReader;
import ch.entwine.weblounge.common.impl.language.LanguageUtils;
import ch.entwine.weblounge.common.impl.testing.IntegrationTestBase;
import ch.entwine.weblounge.common.impl.util.TestUtils;
import ch.entwine.weblounge.common.language.Language;
import ch.entwine.weblounge.common.url.UrlUtils;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import javax.servlet.http.HttpServletResponse;

/**
* Integration test for the response cache.
*/
public class CacheTest extends IntegrationTestBase {

  /** The logger */
  private static final Logger logger = LoggerFactory.getLogger(CacheTest.class);

  /** The paths to test */
  private static final String contentTestPage = "/test/pagecontent";

  /** The paths to test */
  private static final String modificationTestPage = "/test/modificationDate";

  /** The id of the page that is hosting the modification date pagelet */
  private static final String modificationTestPageId = "4bb19980-8f98-4873-a813-000000000015";

  /** The paths to host page */
  private static final String hostPage = "/test/host";

  /** The id of the page that is linked to by the host page */
  private static final String linkedPageId = "4bb19980-8f98-4873-a813-a00000000002";

  /** The request language */
  private static final Language language = LanguageUtils.getLanguage(Locale.GERMAN);

  /**
   * Creates a new instance of the <code>HTML</code> page test.
   */
  public CacheTest() {
    super("Response Cache Test", WEBLOUNGE_CONTENT_TEST_GROUP);
  }

  /**
   * {@inheritDoc}
   *
   * @see ch.entwine.weblounge.testing.kernel.IntegrationTest#execute(java.lang.String)
   */
  @Override
  public void execute(String serverUrl) throws Exception {
    logger.info("Testing if response cache is activated");

    // Test if the cache is active
    logger.info("Sending request to determine cache status to {}", serverUrl);
    HttpGet request = new HttpGet(serverUrl);
    request.addHeader("X-Cache-Debug", "yes");
    String[][] params = new String[][] { {} };

    // Send and the request and examine the response twice to make sure to get
    // a cached response is available
    boolean cacheIsActive = false;
    for (int i = 0; i < 2; i++) {
      HttpClient httpClient = new DefaultHttpClient();
      try {
        HttpResponse response = TestUtils.request(httpClient, request, params);
        cacheIsActive = response.getHeaders("X-Cache-Key").length > 0;
      } finally {
        httpClient.getConnectionManager().shutdown();
      }
    }

    if (!cacheIsActive) {
      logger.warn("Response cache is not available and won't be tested");
      return;
    }

    logger.warn("Response cache is active");
    testCacheHeaders(serverUrl);
    testInheritedModifcation(serverUrl);
    testPageletModifcationDate(serverUrl);
  }

  /**
   * Test if the cache is returning proper header to enable caching on the
   * client side, such as <code>Last-Modified</code>, <code>Expires</code> or
   * <code>ETag</code>.
   *
   * @param serverUrl
   *          the server url
   * @throws Exception
   *           if the test fails
   */
  private void testCacheHeaders(String serverUrl) throws Exception {
    logger.info("Preparing test of response caching");

    DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
    df.setTimeZone(TimeZone.getTimeZone("GMT"));

    // Prepare the request
    logger.info("Testing response cache");

    String requestUrl = UrlUtils.concat(serverUrl, contentTestPage, language.getIdentifier());

    logger.info("Sending request to the {} version of {}", language.getLocale().getDisplayName(), requestUrl);
    HttpGet request = new HttpGet(requestUrl);
    request.addHeader("X-Cache-Debug", "yes");
    String[][] params = new String[][] { { "language", language.getIdentifier() } };

    // Send and the request and examine the response. The first request might
    // not come out of the cache
    logger.debug("Sending request to {}", request.getURI());
    HttpClient httpClient = new DefaultHttpClient();
    try {
      HttpResponse response = TestUtils.request(httpClient, request, params);
      int statusCode = response.getStatusLine().getStatusCode();
      boolean okOrNotModified = statusCode == HttpServletResponse.SC_OK || statusCode == HttpServletResponse.SC_NOT_MODIFIED;
      assertTrue(okOrNotModified);

      // Get the ETag header
      assertNotNull(response.getHeaders("ETag"));
      assertEquals(1, response.getHeaders("ETag").length);
      String eTag = response.getHeaders("ETag")[0].getValue();

      // Get the Expires header
      assertNotNull(response.getHeaders("Expires"));
      assertEquals(1, response.getHeaders("Expires").length);
      Date expires = df.parse(response.getHeaders("Expires")[0].getValue());

      // Prepare the second request
      response.getEntity().consumeContent();
      httpClient.getConnectionManager().shutdown();

      // Give the cache time to persist the entry
      Thread.sleep(1000);

      httpClient = new DefaultHttpClient();

      request.setHeader("If-None-Match", eTag);
      request.setHeader("If-Modified-Since", df.format(System.currentTimeMillis()));

      response = TestUtils.request(httpClient, request, params);
      assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response.getStatusLine().getStatusCode());

      // Get the Expires header
      assertNotNull(response.getHeaders("Expires"));
      assertEquals(1, response.getHeaders("Expires").length);

      // We are explicitly not checking for equality with the previously
      // received value, since on first request, that value is not yet correct

      // Get the ETag header
      assertNotNull(response.getHeaders("ETag"));
      assertEquals(0, response.getHeaders("ETag").length);

      // Test the Cache header
      assertNotNull(response.getHeaders("X-Cache-Key"));
      assertEquals(1, response.getHeaders("X-Cache-Key").length);

      // Test the expires header
      Date newExpires = df.parse(response.getHeaders("Expires")[0].getValue());
      assertTrue(expires.before(newExpires) || expires.equals(newExpires));

    } finally {
      httpClient.getConnectionManager().shutdown();
    }
  }

  /**
   * Tests if the modification date matches that of the most recent element on a
   * page rather than the page's modification date.
   *
   * @param serverUrl
   *          the server url
   * @throws Exception
   *           if the test fails
   */
  private void testInheritedModifcation(String serverUrl) throws Exception {
    logger.info("Preparing test of cache headers influenced by inherited updated content");

    DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
    df.setTimeZone(TimeZone.getTimeZone("GMT"));

    // Prepare the request
    logger.info("Gathering original modification date");

    String requestUrl = UrlUtils.concat(serverUrl, hostPage, language.getIdentifier());

    logger.info("Sending request to {}", requestUrl);
    HttpGet request = new HttpGet(requestUrl);
    request.addHeader("X-Cache-Debug", "yes");
    String[][] params = new String[][] { {} };

    // Send and the request and examine the response. Keep the modification
    // date.
    HttpClient httpClient = new DefaultHttpClient();
    try {
      HttpResponse response = TestUtils.request(httpClient, request, params);

      int statusCode = response.getStatusLine().getStatusCode();
      boolean okOrNotModified = statusCode == HttpServletResponse.SC_OK || statusCode == HttpServletResponse.SC_NOT_MODIFIED;
      assertTrue(okOrNotModified);

      // Get the ETag header
      assertNotNull(response.getHeaders("ETag"));
      assertEquals(1, response.getHeaders("ETag").length);
      String hostOrignalETag = response.getHeaders("ETag")[0].getValue();

      // Get the Modified header
      assertNotNull(response.getHeaders("Last-Modified"));
      assertEquals(1, response.getHeaders("Last-Modified").length);
      Date hostModified = df.parse(response.getHeaders("Last-Modified")[0].getValue());
      response.getEntity().consumeContent();
      httpClient.getConnectionManager().shutdown();

      logger.info("Updating linked page");
      update(serverUrl, linkedPageId);

      // Give the cache time to persist the entry
      Thread.sleep(1000);

      httpClient = new DefaultHttpClient();

      // Test using ETag and modified header
      request.setHeader("If-None-Match", hostOrignalETag);
      request.setHeader("If-Modified-Since", df.format(hostModified));

      response = TestUtils.request(httpClient, request, params);
      assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());

      // Get the Expires header
      assertNotNull(response.getHeaders("Expires"));
      assertEquals(1, response.getHeaders("Expires").length);
      // We are explicitly not checking for equality with the previously
      // received value, since on first request, that value is not yet correct

      // Get the ETag header and make sure it has been updated
      assertNotNull(response.getHeaders("ETag"));
      assertEquals(1, response.getHeaders("ETag").length);
      assertFalse(hostOrignalETag.equals(response.getHeaders("ETag")[0].getValue()));

      // Test the modified header and make sure it has been updated
      assertNotNull(response.getHeaders("Last-Modified"));
      assertEquals(1, response.getHeaders("Last-Modified").length);
      Date newModified = df.parse(response.getHeaders("Last-Modified")[0].getValue());
      assertTrue(hostModified.before(newModified));

    } finally {
      httpClient.getConnectionManager().shutdown();
    }
  }

  /**
   * Tests if the modification date of a page can properly be adjusted by a
   * pagelet that is using the <code>&lt;modified&gt;</code> tag.
   *
   * @param serverUrl
   *          the server url
   * @throws Exception
   *           if the test fails
   */
  private void testPageletModifcationDate(String serverUrl) throws Exception {
    logger.info("Preparing test of cache headers influenced by the 'modified' tag");

    // Load the page's modification date

    String requestUrl = UrlUtils.concat(serverUrl, "system/weblounge/pages", modificationTestPageId);
    HttpGet getPageRequest = new HttpGet(requestUrl);
    HttpClient httpClient = new DefaultHttpClient();
    Page page = null;
    logger.info("Requesting the page's modification date at {}", requestUrl);
    try {
      HttpResponse response = TestUtils.request(httpClient, getPageRequest, null);
      assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
      PageReader reader = new PageReader();
      page = reader.read(response.getEntity().getContent(), site);
    } finally {
      httpClient.getConnectionManager().shutdown();
    }

    DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
    df.setTimeZone(TimeZone.getTimeZone("GMT"));

    // Regularly load the page

    requestUrl = UrlUtils.concat(serverUrl, modificationTestPage);

    logger.info("Sending request to {}", requestUrl);
    HttpGet request = new HttpGet(requestUrl);
    request.addHeader("X-Cache-Debug", "yes");
    String[][] params = new String[][] { {} };

    // Send and the request and examine the response. Keep the modification
    // date.
    httpClient = new DefaultHttpClient();
    try {
      HttpResponse response = TestUtils.request(httpClient, request, params);

      int statusCode = response.getStatusLine().getStatusCode();
      boolean okOrNotModified = statusCode == HttpServletResponse.SC_OK || statusCode == HttpServletResponse.SC_NOT_MODIFIED;
      assertTrue(okOrNotModified);

      // Get the Modified header
      assertNotNull(response.getHeaders("Last-Modified"));
      assertEquals(1, response.getHeaders("Last-Modified").length);
      Date hostModified = df.parse(response.getHeaders("Last-Modified")[0].getValue());
      response.getEntity().consumeContent();

      // Make sure the page is advertised as being more recent than the page's
      // modification date
      assertTrue(hostModified.after(page.getModificationDate()));

    } finally {
      httpClient.getConnectionManager().shutdown();
    }
  }

  /**
   * Updates the page with the given identifier.
   *
   * @param serverUrl
   *          the server url
   * @param id
   *          the page identifier
   * @throws Exception
   *           if updating the page fails
   */
  private void update(String serverUrl, String id) throws Exception {
    String requestUrl = UrlUtils.concat(serverUrl, "system/weblounge/pages");

    // Lock the page
    HttpPut lockPageRequest = new HttpPut(UrlUtils.concat(requestUrl, id, "lock"));
    HttpClient httpClient = new DefaultHttpClient();
    logger.info("Locking the page at {}", requestUrl);
    try {
      HttpResponse response = TestUtils.request(httpClient, lockPageRequest, null);
      assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
    } finally {
      httpClient.getConnectionManager().shutdown();
    }

    // Publish it
    HttpPut publishPageRequest = new HttpPut(UrlUtils.concat(requestUrl, id, "publish"));
    httpClient = new DefaultHttpClient();
    String[][] params = new String[][] { { "modified", "true" } };
    logger.info("Publishing the page at {}", requestUrl);
    try {
      HttpResponse response = TestUtils.request(httpClient, publishPageRequest, params);
      assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
    } finally {
      httpClient.getConnectionManager().shutdown();
    }

    // Unlock the page
    HttpDelete unlockRequest = new HttpDelete(UrlUtils.concat(requestUrl, id, "lock"));
    httpClient = new DefaultHttpClient();
    logger.info("Unlocking the page at {}", requestUrl);
    try {
      HttpResponse response = TestUtils.request(httpClient, unlockRequest, null);
      assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
    } finally {
      httpClient.getConnectionManager().shutdown();
    }

  }

}
TOP

Related Classes of ch.entwine.weblounge.test.harness.content.CacheTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.