Package com.google.jstestdriver

Source Code of com.google.jstestdriver.FileUploader

/*
* Copyright 2010 Google 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.google.jstestdriver;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.google.jstestdriver.JsonCommand.CommandType;
import com.google.jstestdriver.Response.ResponseType;
import com.google.jstestdriver.browser.BrowserFileSet;
import com.google.jstestdriver.hooks.FileInfoScheme;
import com.google.jstestdriver.model.HandlerPathPrefix;
import com.google.jstestdriver.model.JstdTestCase;
import com.google.jstestdriver.model.JstdTestCaseDelta;
import com.google.jstestdriver.servlet.fileset.BrowserFileCheck;
import com.google.jstestdriver.servlet.fileset.DeltaUpload;
import com.google.jstestdriver.servlet.fileset.TestCaseUpload;
import com.google.jstestdriver.util.StopWatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Handles the uploading of files.
*
* @author corysmith@google.com (Cory Smith)
*/
public class FileUploader {
  public static final int CHUNK_SIZE = 50;

  private final StopWatch stopWatch;
  private final Gson gson = new Gson();
  private final Server server;
  private final String baseUrl;
  private final FileLoader fileLoader;
  private final JsTestDriverFileFilter filter;
  private final Set<FileInfoScheme> schemes;

  private static final Logger logger = LoggerFactory.getLogger(FileUploader.class);

  private final HandlerPathPrefix prefix;

  @Inject
  public FileUploader(StopWatch stopWatch, Server server,
      @Named("server") String baseUrl, FileLoader fileLoader,
      JsTestDriverFileFilter filter,
      Set<FileInfoScheme> schemes,
      @Named("serverHandlerPrefix") HandlerPathPrefix prefix) {
    this.stopWatch = stopWatch;
    this.server = server;
    this.baseUrl = baseUrl;
    this.fileLoader = fileLoader;
    this.filter = filter;
    this.schemes = schemes;
    this.prefix = prefix;
  }

  /** Uploads the changed files to the server and the browser. */
  public void uploadFileSet(String browserId, Collection<JstdTestCase> testCases, ResponseStream stream) {

    stopWatch.start("determineServerFileSet(%s)", browserId);
    final Collection<JstdTestCaseDelta> deltas = determineServerFileSet(testCases);
    stopWatch.stop("determineServerFileSet(%s)", browserId);

    logger.debug("Deltas: {}", deltas);
    stopWatch.start("upload to server %s", browserId);
    uploadToServer(deltas);
    stopWatch.stop("upload to server %s", browserId);
    for (JstdTestCase testCase : testCases) {
      stopWatch.start("determineBrowserFileSet(%s)", browserId);
      final List<FileInfo> browserFilesToUpdate = determineBrowserFileSet(browserId, testCase, stream);
      stopWatch.stop("determineBrowserFileSet(%s)", browserId);

      stopWatch.start("uploadToTheBrowser(%s)", browserId);
      uploadToTheBrowser(browserId, stream, browserFilesToUpdate, CHUNK_SIZE);
      stopWatch.stop("uploadToTheBrowser(%s)", browserId);
    }
  }
 

  /**
   * Uploads the {@link JstdTestCase}s to the server, and retrieves a list
   * of {@link JstdTestCaseDelta}s of the files that are different.
   */
  public Collection<JstdTestCaseDelta> determineServerFileSet(Collection<JstdTestCase> testCases) {
    Map<String, String> fileSetParams = new LinkedHashMap<String, String>();
    fileSetParams.put("data", gson.toJson(testCases));
    fileSetParams.put("action", TestCaseUpload.ACTION);
    String postResult = server.post(baseUrl + "/fileSet", fileSetParams);
    return gson.fromJson(postResult, new TypeToken<Collection<JstdTestCaseDelta>>() {}.getType());
  }

  /** Determines what files have been changed as compared to the server. */
  public List<FileInfo> determineBrowserFileSet(String browserId, JstdTestCase testCase,
      ResponseStream stream) {

    BrowserFileSet browserFileSet = getBrowserFileSet(browserId, testCase);

    stopWatch.start("resolving browser upload %s", browserId);
    try {
      logger.debug("Updating files {}", browserFileSet.getFilesToUpload());
      // need a linked hashset here to avoid adding a file more than once.
      final Set<FileInfo> finalFilesToUpload = new LinkedHashSet<FileInfo>();
      // reset if there are extra files in the browser
      if (browserFileSet.shouldReset() || !browserFileSet.getExtraFiles().isEmpty()) {
        reset(browserId, stream, testCase);
        browserFileSet = getBrowserFileSet(browserId, testCase);
        logger.info("second fileset {}", browserFileSet);
      }
      for (FileInfo file : browserFileSet.getFilesToUpload()) {
        finalFilesToUpload.addAll(determineInBrowserDependencies(file, testCase.getServable()));
      }
      return Lists.newArrayList(finalFilesToUpload);
    } finally {
      stopWatch.stop("resolving browser upload %s", browserId);
    }
  }

  private BrowserFileSet getBrowserFileSet(String browserId, JstdTestCase testCase) {
    stopWatch.start("get upload set %s", browserId);
    Map<String, String> fileSetParams = new LinkedHashMap<String, String>();

    fileSetParams.put("id", browserId);
    fileSetParams.put("data", gson.toJson(testCase));
    fileSetParams.put("action", BrowserFileCheck.ACTION);
    //logger.info("FileParams: {}", fileSetParams);
    String postResult = server.post(baseUrl + "/fileSet", fileSetParams);
    if (postResult.length() < 0) {
      return new BrowserFileSet(Collections.<FileInfo>emptyList(), Collections.<FileInfo>emptyList(), false);
    }
    BrowserFileSet browserFileSet = gson.fromJson(postResult, BrowserFileSet.class);
    stopWatch.stop("get upload set %s", browserId);
    return browserFileSet;
  }


  /** Uploads files to the browser. */
  public void uploadToTheBrowser(String browserId, ResponseStream stream,
      List<FileInfo> loadedFiles, int chunkSize) {
    List<FileSource> filesSrc = Lists.newLinkedList(filterFilesToLoad(loadedFiles));
    int numberOfFilesToLoad = filesSrc.size();
    logger.info("Files toupload {}",
        Lists.transform(Lists.newArrayList(loadedFiles), new Function<FileInfo, String>() {
          @Override
          public String apply(FileInfo in) {
            return "\n" + in.getDisplayPath();
          }
        }));
    for (int i = 0; i < numberOfFilesToLoad; i += chunkSize) {

      int chunkEndIndex = Math.min(i + chunkSize, numberOfFilesToLoad);
      List<String> loadParameters = new LinkedList<String>();
      List<FileSource> filesToLoad = filesSrc.subList(i, chunkEndIndex);
      loadParameters.add(gson.toJson(filesToLoad));
      loadParameters.add("false");
      JsonCommand cmd = new JsonCommand(CommandType.LOADTEST, loadParameters);
      Map<String, String> loadFileParams = new LinkedHashMap<String, String>();

      loadFileParams.put("id", browserId);
      loadFileParams.put("data", gson.toJson(cmd));
      if (logger.isDebugEnabled()) {
        logger.debug("Sending LOADTEST to {} for {}", browserId,
            Lists.transform(filesToLoad, new Function<FileSource, String>() {
              @Override
              public String apply(FileSource in) {
                return "\n" + in.getFileSrc();
              }
            }));
      }
      server.post(baseUrl + "/cmd", loadFileParams);
      while (true) {
        String jsonResponse = server.fetch(baseUrl + "/cmd?id=" + browserId);
        StreamMessage message = gson.fromJson(jsonResponse, StreamMessage.class);
        Response response = message.getResponse();
        logger.trace("LOADTEST response for {}", response);
        stream.stream(response);
        if (message.isLast()) {
          logger.debug("Finished LOADTEST on {} with {}", browserId, response.getResponseType());
          break;
        }
      }
    }
  }

  public void uploadToServer(final Collection<JstdTestCaseDelta> deltas) {
    if (deltas.isEmpty()) {
      return;
    }
    List<JstdTestCaseDelta> loadedDeltas = Lists.newArrayListWithCapacity(deltas.size());
    for (JstdTestCaseDelta delta : deltas) {
      loadedDeltas.add(delta.loadFiles(fileLoader));
    }
    for (List<JstdTestCaseDelta> partition : Lists.partition(loadedDeltas, 50)) {
      Map<String, String> uploadFileParams = new LinkedHashMap<String, String>();
      uploadFileParams.put("action", DeltaUpload.ACTION);
      uploadFileParams.put("data", gson.toJson(partition));
      server.post(baseUrl + "/fileSet", uploadFileParams);
    }
  }

  private void reset(String browserId, ResponseStream stream, JstdTestCase testCase) {
    stopWatch.start("reset %s", browserId);
    JsonCommand cmd = new JsonCommand(CommandType.RESET,
        Lists.newArrayList("preload", testCase.getId()));
    Map<String, String> resetParams = new LinkedHashMap<String, String>();

    logger.debug("reset browser {}  testcase {}", browserId, testCase.getId());
    resetParams.put("id", browserId);
    resetParams.put("data", gson.toJson(cmd));
    server.post(baseUrl + "/cmd", resetParams);

    logger.trace("starting reset for {}", browserId);
    Response response;
    StreamMessage message;
    do {
      String jsonResponse = server.fetch(baseUrl + "/cmd?id=" + browserId);
      message = gson.fromJson(jsonResponse, StreamMessage.class);
      response = message.getResponse();
      stream.stream(response);
    } while(!(ResponseType.RESET_RESULT.equals(response.getResponseType()) && message.isLast()));
    logger.trace("finished reset for {}", browserId);
    stopWatch.stop("reset %s", browserId);
  }

  /**
   * Determines what files must be reloaded in the browser, based on this file
   * being updated.
   */
  private Collection<FileInfo> determineInBrowserDependencies(FileInfo file, List<FileInfo> files) {
    LinkedHashSet<FileInfo> deps = Sets.newLinkedHashSet();
    for (FileInfo dep : filter.resolveFilesDeps(file, files)) {
      deps.add(dep);
    }
    return deps;
  }

  private List<FileSource> filterFilesToLoad(Collection<FileInfo> fileInfos) {
    List<FileSource> filteredFileSources = new LinkedList<FileSource>();

    for (FileInfo fileInfo : fileInfos) {
      if (!fileInfo.isServeOnly()) {
        filteredFileSources.add(fileInfo.toFileSource(prefix, schemes));
      }
    }
    return filteredFileSources;
  }
}
TOP

Related Classes of com.google.jstestdriver.FileUploader

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.