<commit_before>/*******************************************************************************
*  Code contributed to the webinos project
*
* 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.
*
* Copyright 2011-2012 Paddy Byers
*
******************************************************************************/

this.WidgetManager = (function() {
	var path = require('path');

	var MODE_INSTALL = 0,
	    MODE_UPDATE  = 1;

	var callPrepareListener = function(listener, processingResult) {
		if(listener) {
			if(typeof(listener) == 'function')
				listener(processingResult);
			else if(listener.onPrepareComplete)
				listener.onPrepareComplete(processingResult);
		}
	};

	function PendingInstall(processor, resource, processingResult, widgetConfig, listener) {
		this.processor = processor;
		this.resource = resource;
		this.processingResult = processingResult;
		this.widgetConfig = widgetConfig;
		this.listener = listener;
		this.pendingAsyncCount = 0;
	}

	PendingInstall.prototype.onStatusChange = function(status) {
		if(status >= 0) {
			/* a terminal state */
			var complete = (--this.pendingAsyncCount == 0);
			if(complete) {
				processor.postAsync(this);
				callPrepareListener(this.listener, this.processingResult);
			}
		}
	};

	/* public constructor */
	function WidgetManager(storage) {
		this.storage = storage;
		this.cachedConfigs = new CacheMap();
		this.pendingInstalls = {};
	}

	/* public static variables */
	WidgetManager.MODE_INSTALL = MODE_INSTALL;
	WidgetManager.MODE_UPDATE = MODE_UPDATE;

	/*
	 * Permanently remove the specified widget from the widgetmanager
	 */
	WidgetManager.prototype.uninstall = function(installId) {
		try {
			this.cachedConfigs.remove(installId);
			this.storage.deleteItem(installId);
		} catch (e) {}
	};

	/*
	 * List all currently installed and enabled widgets
	 */
	WidgetManager.prototype.getInstalledWidgets = function() {
		var result;
		try {
			result = this.storage.listItems();
		} catch (e) {}
		return result;
	};

	/*
	 * Get the directory into which the widget content has been extracted
	 * @param installId the installId of the widget
	 * @return fully qualified path to the widget's content directory
	 */
	WidgetManager.prototype.getWidgetDir = function(installId) {
		var result;
		try {
			result = this.storage.getWidgetDir(installId);
		} catch (e) {}
		return result;
	};

	/*
	 * Get the configuration for the named widget
	 * @param installId the installId of the widget
	 * @return the WidgetConfig
	 */
	WidgetManager.prototype.getWidgetConfig = function(installId) {
		var result = this.cachedConfigs.get(installId);
		if(!result) {
			try {
				result = WidgetPersistence.readWidgetMetadata(this.storage, installId);
				if(result)
					this.cachedConfigs.put(installId, result);
			} catch(e){}
		}
		if(result)
			result.installId = installId;
		return result;
	};

	/*
	 * Prepare a widget resource for installation
	 * This processes the widget resource and performs digsig validation,
	 * assigns an installID and places the widget in a disabled state.
	 * It is expected that with the processing results, the user will
	 * be prompted, and then either completeInstall or abortInstall will
	 * be called to complete the operation.
	 *
	 * This method is asynchronous - all asynchronous dependencies of widget
	 * processing are scheduled, and the supplied listener is called when all
	 * are complete.
	 *
	 * @param resourcePath - fully qualified path to the widget resource file
	 * @param constraints  - the constraints to be used for the processing
	 * @param listener     - the listener to be notified when processing is complete
	 * @return the IProcessingResult with the results
	 */
	WidgetManager.prototype.prepareInstall = function(resource, constraints, listener) {
		/* perform the widget processing */
		if(!path.existsSync(resource)) throw new Error("Widget resource file does not exist");
		var processor = new WidgetProcessor(resource, constraints);
		var that = this;
		var storage = this.storage;

		var onProcess = function(processingResult) {
			if(processingResult.status != WidgetConfig.STATUS_OK) {
				callPrepareListener(listener, processingResult);
				return;
			}

			/* basic processing was successful, so determine status of any existing
			 * version of this widget */
			var existingConfig, existingValidation;
			var installId = processingResult.widgetConfig.installId;
			if(storage.containsItem(installId)) {
				/* generate comparison */
				existingConfig = that.getWidgetConfig(installId);
				if(existingConfig) {
					existingValidation = WidgetPersistence.readWidgetPolicy(storage, installId);
					var comparisonResult = processor.compareTo(existingConfig, existingValidation, storage.hasUserdata(installId));
					if(comparisonResult.getError()) {
						callPrepareListener(listener, processingResult);
						return;
					}
				}
			}

			/* allocate space in the storage if necessary */
			storage.createItem(installId);

			/* extract icon */
			var widgetConfig = processingResult.widgetConfig;
			if(widgetConfig.prefIcon)
				WidgetPersistence.extractFile(that.storage.getWidgetDir(installId), processingResult.widgetResource, processingResult.localisedFileMapping, widgetConfig.prefIcon);

			/* if all OK, this pending install is ready for async dependencies */
			var pendingInstall = new PendingInstall(processor, processor.getWidgetResource(), processingResult, widgetConfig, listener);
			that.pendingInstalls[installId] = pendingInstall;

			/* process pending async dependencies, if any */
			var hasAsync = false;
			if(constraints && constraints.processAsyncDependencies) {
				var dependencies = processor.asyncDependencies;
				if(dependencies) {
					for(var i in dependencies) {
						dependencies[i].resolve(storage, installId, pendingInstall);
						pendingInstall.pendingAsyncCount++;
						hasAsync = true;
					}
				}
			}

			/* if nothing pending, complete now */
			if(!hasAsync) {
				/* complete now */
				that.postAsync(pendingInstall);
				callPrepareListener(listener, processingResult);
			}
		};

		processor.process(false, onProcess);
	};

	/*
	 * Finish widget processing and enable the installed widget
	 * @param installId the widget installId
	 * @param preserveUserdata true if existing userdata is preserved
	 * @return the status
	 */
	WidgetManager.prototype.completeInstall = function(installId, preserveUserdata) {
		try {
			var pendingInstall = this.pendingInstalls[installId];
			if(pendingInstall) {
				/* finalise the installation processing */
				var processingResult = pendingInstall.processingResult;
				WidgetPersistence.writeWidgetMetadata(this.storage, installId, pendingInstall.widgetConfig);

				WidgetPersistence.extractWidget(this.storage, installId, pendingInstall.resource, processingResult.localisedFileMapping);
				this.storage.setItemEnabled(installId, true, preserveUserdata);
				this.cachedConfigs.put(installId, pendingInstall.widgetConfig);
				delete this.pendingInstalls[installId];
				pendingInstall.processor.dispose();
			}
			return WidgetConfig.STATUS_OK;
		} catch(e) {
			Logger.logAction(Logger.LOG_ERROR, "WidgetManager.completeInstall()", e);
			return WidgetConfig.STATUS_IO_ERROR;
		}
	};

	/*
	 * Abort the pending installation of the widget
	 * @param installId the widget installId
	 * @return the status
	 */
	WidgetManager.prototype.abortInstall = function(installId) {
		try {
			var pendingInstall = pendingInstalls[installId];
			if(pendingInstall) {
				delete this.pendingInstalls[installId];
				this.storage.deleteItem(installId);
				pendingInstall.processingResult.dispose();
			}
			return WidgetConfig.STATUS_OK;
		} catch(e) {
			return WidgetConfig.STATUS_IO_ERROR;
		}
	};

	/*
	 * Re-perform widget processing to adjust for changes in the processing constraints.
	 * This will react to the following changes in constraints:
	 * - locales;
	 * - security policy;
	 * The widget might remain enabled but with changes to configuration, or it may become
	 * disabled, or it may become re-enabled.
	 * @param installId the installId
	 * @param constraints the new constraints
	 * @return the status
	 */
	WidgetManager.prototype.reinstall = function(installId, constraints) {
		this.storage.setItemEnabled(installId, false, false);

		/* redo only the required parts of re-processing */
		var wgtFile = this.storage.getMetaFile(installId, WidgetStorage.WGT_FILE);
		var processor = new WidgetProcessor(wgtFile, constraints);
		var processingResult = processor.process(true);
		var status = processingResult.status;
		if(status != WidgetConfig.STATUS_OK )
			return status;

		var widgetConfig = processingResult.widgetConfig;
		WidgetPersistence.writeWidgetMetadata(storage, installId, widgetConfig);
		var res = new ZipWidgetResource(wgtFile);
		WidgetPersistence.extractWidget(storage, installId, res, processingResult.localisedFileMapping);
		this.storage.setItemEnabled(installId, true, true);
		this.cachedConfigs.put(installId, widgetConfig);
		processingResult.dispose();
		return WidgetConfig.STATUS_OK;
	};

	var processFeatureRequests = function(processor, securityContext, features) {
		/*
		 * ASSERTION (BONDI A&S)
		 *
		 * The WRT MUST take the following device capability mediation actions prior
		 * to launching widgets, as specified in [BONDI A&S]:
		 * AS-0390: The WRT MUST resolve all dependencies of Features referenced statically
		 *          at install time, or at instantiation time for Widget Resources that are
		 *          instantiated without prior installation.
		 * AS-0430: As part of the resolution of each statically referenced Feature, the WRT
		 *          MUST evaluate an access control Query that determines whether or not the
		 *          Widget is authorised to access the requested Feature. If the evaluated
		 *          Decision of that Query is Deny, and the dependency is marked as required,
		 *          the WRT MUST abort installation and it MUST not be possible to instantiate
		 *          that Widget.
		 * AS-0440: If permission is not granted for that Widget to access that Feature, and
		 *          the dependency is marked as optional, the WRT MUST continue installation.
		 *          The WRT MUST fail access to any associated JavaScript API at runtime if
		 *          the dependency remains unsatisfied at the time the Widget is instantiated.
		 */
		for(var i in features) {
			var feature = features[i];
			if(securityContext) {
				var access = new FeatureAccess(securityContext, feature);
				access.getAccess();
				access.dispose();
				if(access.maxEffect == SecurityContext.EFFECT_DENY) {
					if(feature.required) {
						// the widget cannot be installed
						Logger.logAction('AS-0440', 'unable to install widget because of denied required feature (' + feature.name + ')');
						processor.setError(new Artifact(WidgetConfig.STATUS_DENIED, Artifact.CODE_DENIED_FEATURE, 'AS-0440', [feature]));
						processor.setStatus(WidgetConfig.STATUS_DENIED);
						break;
					}
					Logger.logAction('AS-0440', 'continue installation with denied nonrequired feature (' + feature.name + ')');
				}
			}
		}
	};

	var processAccessRequests = function(processor, securityContext, accessRequests) {
		/*
		 * Process the requested accesses, and eliminate those that are unconditionally denied
		 */
		var filteredRequests = [];
		for(var i in accessRequests) {
			var accessRequest = accessReauests[i];
			if(securityContext) {
				var access = new NetworkAccess(securityContext, accessRequest);
				access.getAccess();
				if(access.xhrEffect == SecurityContext.EFFECT_DENY && access.domEffect == SecurityContext.EFFECT_DENY)
					continue;
				accessRequest.xhrEffect = access.xhrEffect;
				accessRequest.domEffect = access.domEffect;
			}
			filteredRequests.push(accessRequest);
		}
		return filteredRequests;
	};

	WidgetManager.prototype.postAsync = function(pendingInstall) {
		/* save policy attributes and run security queries */
		var widgetConfig = pendingInstall.widgetConfig;
		var installId = widgetConfig.installId;
		var processingResult = pendingInstall.processingResult;
		var processor = pendingInstall.processor;
		var securityContext;
		try {
			WidgetPersistence.writeWidgetPolicy(this.storage, installId, widgetConfig, processingResult.validationResult);
			var attrFile = this.storage.getMetaFile(installId, WidgetStorage.POLICY_FILE);
			securityContext;// = Security.createContext(installId, attrFile);
			processFeatureRequests(processor, securityContext, widgetConfig.featureList);
			widgetConfig.accessRequestList = processAccessRequests(processor, securityContext, widgetConfig.accessRequestList);
		} catch (e) {
			Logger.logAction("postAsync.exception", e);
			processor.setError(
				new Artifact(WidgetConfig.STATUS_IO_ERROR,
					0,
					"postAsync.exception",
					null));
		} finally {
			if(securityContext)
				securityContext.dispose();
		}
	};

	return WidgetManager;
})();
<commit_msg>Catch exceptions thrown in prepareInstall()<commit_after>/*******************************************************************************
*  Code contributed to the webinos project
*
* 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.
*
* Copyright 2011-2012 Paddy Byers
*
******************************************************************************/

this.WidgetManager = (function() {
	var path = require('path');

	var MODE_INSTALL = 0,
	    MODE_UPDATE  = 1;

	var callPrepareListener = function(listener, processingResult) {
		if(listener) {
			if(typeof(listener) == 'function')
				listener(processingResult);
			else if(listener.onPrepareComplete)
				listener.onPrepareComplete(processingResult);
		}
	};

	function PendingInstall(processor, resource, processingResult, widgetConfig, listener) {
		this.processor = processor;
		this.resource = resource;
		this.processingResult = processingResult;
		this.widgetConfig = widgetConfig;
		this.listener = listener;
		this.pendingAsyncCount = 0;
	}

	PendingInstall.prototype.onStatusChange = function(status) {
		if(status >= 0) {
			/* a terminal state */
			var complete = (--this.pendingAsyncCount == 0);
			if(complete) {
				processor.postAsync(this);
				callPrepareListener(this.listener, this.processingResult);
			}
		}
	};

	/* public constructor */
	function WidgetManager(storage) {
		this.storage = storage;
		this.cachedConfigs = new CacheMap();
		this.pendingInstalls = {};
	}

	/* public static variables */
	WidgetManager.MODE_INSTALL = MODE_INSTALL;
	WidgetManager.MODE_UPDATE = MODE_UPDATE;

	/*
	 * Permanently remove the specified widget from the widgetmanager
	 */
	WidgetManager.prototype.uninstall = function(installId) {
		try {
			this.cachedConfigs.remove(installId);
			this.storage.deleteItem(installId);
		} catch (e) {}
	};

	/*
	 * List all currently installed and enabled widgets
	 */
	WidgetManager.prototype.getInstalledWidgets = function() {
		var result;
		try {
			result = this.storage.listItems();
		} catch (e) {}
		return result;
	};

	/*
	 * Get the directory into which the widget content has been extracted
	 * @param installId the installId of the widget
	 * @return fully qualified path to the widget's content directory
	 */
	WidgetManager.prototype.getWidgetDir = function(installId) {
		var result;
		try {
			result = this.storage.getWidgetDir(installId);
		} catch (e) {}
		return result;
	};

	/*
	 * Get the configuration for the named widget
	 * @param installId the installId of the widget
	 * @return the WidgetConfig
	 */
	WidgetManager.prototype.getWidgetConfig = function(installId) {
		var result = this.cachedConfigs.get(installId);
		if(!result) {
			try {
				result = WidgetPersistence.readWidgetMetadata(this.storage, installId);
				if(result)
					this.cachedConfigs.put(installId, result);
			} catch(e){}
		}
		if(result)
			result.installId = installId;
		return result;
	};

	/*
	 * Prepare a widget resource for installation
	 * This processes the widget resource and performs digsig validation,
	 * assigns an installID and places the widget in a disabled state.
	 * It is expected that with the processing results, the user will
	 * be prompted, and then either completeInstall or abortInstall will
	 * be called to complete the operation.
	 *
	 * This method is asynchronous - all asynchronous dependencies of widget
	 * processing are scheduled, and the supplied listener is called when all
	 * are complete.
	 *
	 * @param resourcePath - fully qualified path to the widget resource file
	 * @param constraints  - the constraints to be used for the processing
	 * @param listener     - the listener to be notified when processing is complete
	 * @return the IProcessingResult with the results
	 */
	WidgetManager.prototype.prepareInstall = function(resource, constraints, listener) {
		try {
			/* perform the widget processing */
			if(!path.existsSync(resource)) throw new Error("Widget resource file does not exist");
			var processor = new WidgetProcessor(resource, constraints);
			var that = this;
			var storage = this.storage;

			var onProcess = function(processingResult) {
				if(processingResult.status != WidgetConfig.STATUS_OK) {
					callPrepareListener(listener, processingResult);
				}

				/* basic processing was successful, so determine status of any existing
				 * version of this widget */
				var existingConfig, existingValidation;
				var installId = processingResult.widgetConfig.installId;
				if(storage.containsItem(installId)) {
					/* generate comparison */
					existingConfig = that.getWidgetConfig(installId);
					if(existingConfig) {
						existingValidation = WidgetPersistence.readWidgetPolicy(storage, installId);
						var comparisonResult = processor.compareTo(existingConfig, existingValidation, storage.hasUserdata(installId));
						if(comparisonResult.getError()) {
							callPrepareListener(listener, processingResult);
						}
					}
				}

				/* allocate space in the storage if necessary */
				storage.createItem(installId);

				/* extract icon */
				var widgetConfig = processingResult.widgetConfig;
				if(widgetConfig.prefIcon)
					WidgetPersistence.extractFile(that.storage.getWidgetDir(installId), processingResult.widgetResource, processingResult.localisedFileMapping, widgetConfig.prefIcon);

				/* if all OK, this pending install is ready for async dependencies */
				var pendingInstall = new PendingInstall(processor, processor.getWidgetResource(), processingResult, widgetConfig, listener);
				that.pendingInstalls[installId] = pendingInstall;

				/* process pending async dependencies, if any */
				var hasAsync = false;
				if(constraints && constraints.processAsyncDependencies) {
					var dependencies = processor.asyncDependencies;
					if(dependencies) {
						for(var i in dependencies) {
							dependencies[i].resolve(storage, installId, pendingInstall);
							pendingInstall.pendingAsyncCount++;
							hasAsync = true;
						}
					}
				}

				/* if nothing pending, complete now */
				if(!hasAsync) {
					/* complete now */
					that.postAsync(pendingInstall);
					callPrepareListener(listener, processingResult);
				}
			};

			processor.process(false, onProcess);
			return WidgetConfig.STATUS_OK;
		} catch(e) {
			Logger.logAction(Logger.LOG_ERROR, "WidgetManager.prepareInstall() exception", e.stack);
			var processingResult = new ProcessingResult();
			e.status = WidgetConfig.STATUS_IO_ERROR;
			processingResult.setError(e);
			callPrepareListener(processingResult, listener);
			return e.status;
		}
	};

	/*
	 * Finish widget processing and enable the installed widget
	 * @param installId the widget installId
	 * @param preserveUserdata true if existing userdata is preserved
	 * @return the status
	 */
	WidgetManager.prototype.completeInstall = function(installId, preserveUserdata) {
		try {
			var pendingInstall = this.pendingInstalls[installId];
			if(pendingInstall) {
				/* finalise the installation processing */
				var processingResult = pendingInstall.processingResult;
				WidgetPersistence.writeWidgetMetadata(this.storage, installId, pendingInstall.widgetConfig);

				WidgetPersistence.extractWidget(this.storage, installId, pendingInstall.resource, processingResult.localisedFileMapping);
				this.storage.setItemEnabled(installId, true, preserveUserdata);
				this.cachedConfigs.put(installId, pendingInstall.widgetConfig);
				delete this.pendingInstalls[installId];
				pendingInstall.processor.dispose();
			}
			return WidgetConfig.STATUS_OK;
		} catch(e) {
			Logger.logAction(Logger.LOG_ERROR, "WidgetManager.completeInstall()", e);
			return WidgetConfig.STATUS_IO_ERROR;
		}
	};

	/*
	 * Abort the pending installation of the widget
	 * @param installId the widget installId
	 * @return the status
	 */
	WidgetManager.prototype.abortInstall = function(installId) {
		try {
			var pendingInstall = pendingInstalls[installId];
			if(pendingInstall) {
				delete this.pendingInstalls[installId];
				this.storage.deleteItem(installId);
				pendingInstall.processingResult.dispose();
			}
			return WidgetConfig.STATUS_OK;
		} catch(e) {
			return WidgetConfig.STATUS_IO_ERROR;
		}
	};

	/*
	 * Re-perform widget processing to adjust for changes in the processing constraints.
	 * This will react to the following changes in constraints:
	 * - locales;
	 * - security policy;
	 * The widget might remain enabled but with changes to configuration, or it may become
	 * disabled, or it may become re-enabled.
	 * @param installId the installId
	 * @param constraints the new constraints
	 * @return the status
	 */
	WidgetManager.prototype.reinstall = function(installId, constraints) {
		this.storage.setItemEnabled(installId, false, false);

		/* redo only the required parts of re-processing */
		var wgtFile = this.storage.getMetaFile(installId, WidgetStorage.WGT_FILE);
		var processor = new WidgetProcessor(wgtFile, constraints);
		var processingResult = processor.process(true);
		var status = processingResult.status;
		if(status != WidgetConfig.STATUS_OK )
			return status;

		var widgetConfig = processingResult.widgetConfig;
		WidgetPersistence.writeWidgetMetadata(storage, installId, widgetConfig);
		var res = new ZipWidgetResource(wgtFile);
		WidgetPersistence.extractWidget(storage, installId, res, processingResult.localisedFileMapping);
		this.storage.setItemEnabled(installId, true, true);
		this.cachedConfigs.put(installId, widgetConfig);
		processingResult.dispose();
		return WidgetConfig.STATUS_OK;
	};

	var processFeatureRequests = function(processor, securityContext, features) {
		/*
		 * ASSERTION (BONDI A&S)
		 *
		 * The WRT MUST take the following device capability mediation actions prior
		 * to launching widgets, as specified in [BONDI A&S]:
		 * AS-0390: The WRT MUST resolve all dependencies of Features referenced statically
		 *          at install time, or at instantiation time for Widget Resources that are
		 *          instantiated without prior installation.
		 * AS-0430: As part of the resolution of each statically referenced Feature, the WRT
		 *          MUST evaluate an access control Query that determines whether or not the
		 *          Widget is authorised to access the requested Feature. If the evaluated
		 *          Decision of that Query is Deny, and the dependency is marked as required,
		 *          the WRT MUST abort installation and it MUST not be possible to instantiate
		 *          that Widget.
		 * AS-0440: If permission is not granted for that Widget to access that Feature, and
		 *          the dependency is marked as optional, the WRT MUST continue installation.
		 *          The WRT MUST fail access to any associated JavaScript API at runtime if
		 *          the dependency remains unsatisfied at the time the Widget is instantiated.
		 */
		for(var i in features) {
			var feature = features[i];
			if(securityContext) {
				var access = new FeatureAccess(securityContext, feature);
				access.getAccess();
				access.dispose();
				if(access.maxEffect == SecurityContext.EFFECT_DENY) {
					if(feature.required) {
						// the widget cannot be installed
						Logger.logAction('AS-0440', 'unable to install widget because of denied required feature (' + feature.name + ')');
						processor.setError(new Artifact(WidgetConfig.STATUS_DENIED, Artifact.CODE_DENIED_FEATURE, 'AS-0440', [feature]));
						processor.setStatus(WidgetConfig.STATUS_DENIED);
						break;
					}
					Logger.logAction('AS-0440', 'continue installation with denied nonrequired feature (' + feature.name + ')');
				}
			}
		}
	};

	var processAccessRequests = function(processor, securityContext, accessRequests) {
		/*
		 * Process the requested accesses, and eliminate those that are unconditionally denied
		 */
		var filteredRequests = [];
		for(var i in accessRequests) {
			var accessRequest = accessReauests[i];
			if(securityContext) {
				var access = new NetworkAccess(securityContext, accessRequest);
				access.getAccess();
				if(access.xhrEffect == SecurityContext.EFFECT_DENY && access.domEffect == SecurityContext.EFFECT_DENY)
					continue;
				accessRequest.xhrEffect = access.xhrEffect;
				accessRequest.domEffect = access.domEffect;
			}
			filteredRequests.push(accessRequest);
		}
		return filteredRequests;
	};

	WidgetManager.prototype.postAsync = function(pendingInstall) {
		/* save policy attributes and run security queries */
		var widgetConfig = pendingInstall.widgetConfig;
		var installId = widgetConfig.installId;
		var processingResult = pendingInstall.processingResult;
		var processor = pendingInstall.processor;
		var securityContext;
		try {
			WidgetPersistence.writeWidgetPolicy(this.storage, installId, widgetConfig, processingResult.validationResult);
			var attrFile = this.storage.getMetaFile(installId, WidgetStorage.POLICY_FILE);
			securityContext;// = Security.createContext(installId, attrFile);
			processFeatureRequests(processor, securityContext, widgetConfig.featureList);
			widgetConfig.accessRequestList = processAccessRequests(processor, securityContext, widgetConfig.accessRequestList);
		} catch (e) {
			Logger.logAction("postAsync.exception", e);
			processor.setError(
				new Artifact(WidgetConfig.STATUS_IO_ERROR,
					0,
					"postAsync.exception",
					null));
		} finally {
			if(securityContext)
				securityContext.dispose();
		}
	};

	return WidgetManager;
})();
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

base.requireStylesheet('cc.raster_task_slice_view');
base.require('cc.tile');
base.require('cc.tile_view');
base.require('cc.layer_tree_host_impl_view');
base.require('tracing.analysis.slice_view');
base.require('ui.info_bar');

base.exportTo('cc', function() {

  /**
   * @constructor
   */
  var RasterTaskSliceView = ui.define(
      'raster-task-slice-view', tracing.analysis.SliceView);

  RasterTaskSliceView.prototype = {
    __proto__: tracing.analysis.SliceView.prototype,

    decorate: function() {
      this.classList.add('raster-task-slice-view');
      this.layerTreeView_ = new cc.LayerTreeHostImplSnapshotView();
      this.infoBar_ = new ui.InfoBar();
      this.appendChild(this.infoBar_);
      this.appendChild(this.layerTreeView_);
    },

    updateContents: function() {
      this.infoBar_.visible = false;

      if (!this.slice.args.metadata) {
        this.infoBar_.visible = true;
        this.infoBar_.message = 'No metadata on this raster task.';
        this.layerTreeView_.style.display = 'none';
        return;
      }
      var tile = this.slice.args.metadata.tile_id;
      if (!tile) {
        this.infoBar_.visible = true;
        this.infoBar_.message = 'No tile on this raster task.';
        this.layerTreeView_.style.display = 'none';
        return;
      }
      if (!(tile instanceof cc.TileSnapshot)) {
        this.infoBar_.visible = true;
        this.infoBar_.message = 'This raster task didn\'t get fully traced.';
        this.layerTreeView_.style.display = 'none';
        return;
      }
      this.layerTreeView_.style.display = '';

      var containingSnapshot = tile.containingSnapshot;
      this.layerTreeView_.objectSnapshot = containingSnapshot;
      this.layerTreeView_.selection = new cc.RasterTaskSelection(this.slice);
    }
  };

  tracing.analysis.SliceView.register(
      'TileManager::RunRasterTask', RasterTaskSliceView);
  tracing.analysis.SliceView.register(
      'TileManager::RunAnalyzeTask', RasterTaskSliceView);

  return {
    RasterTaskSliceView: RasterTaskSliceView
  };

});
<commit_msg>Recognize newer form raster tasks<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

base.requireStylesheet('cc.raster_task_slice_view');
base.require('cc.tile');
base.require('cc.tile_view');
base.require('cc.layer_tree_host_impl_view');
base.require('tracing.analysis.slice_view');
base.require('ui.info_bar');

base.exportTo('cc', function() {

  /**
   * @constructor
   */
  var RasterTaskSliceView = ui.define(
      'raster-task-slice-view', tracing.analysis.SliceView);

  RasterTaskSliceView.prototype = {
    __proto__: tracing.analysis.SliceView.prototype,

    decorate: function() {
      this.classList.add('raster-task-slice-view');
      this.layerTreeView_ = new cc.LayerTreeHostImplSnapshotView();
      this.infoBar_ = new ui.InfoBar();
      this.appendChild(this.infoBar_);
      this.appendChild(this.layerTreeView_);
    },

    updateContents: function() {
      this.infoBar_.visible = false;

      if (!this.slice.args.metadata) {
        this.infoBar_.visible = true;
        this.infoBar_.message = 'No metadata on this raster task.';
        this.layerTreeView_.style.display = 'none';
        return;
      }
      var tile = this.slice.args.metadata.tile_id;
      if (!tile) {
        this.infoBar_.visible = true;
        this.infoBar_.message = 'No tile on this raster task.';
        this.layerTreeView_.style.display = 'none';
        return;
      }
      if (!(tile instanceof cc.TileSnapshot)) {
        this.infoBar_.visible = true;
        this.infoBar_.message = 'This raster task didn\'t get fully traced.';
        this.layerTreeView_.style.display = 'none';
        return;
      }
      this.layerTreeView_.style.display = '';

      var containingSnapshot = tile.containingSnapshot;
      this.layerTreeView_.objectSnapshot = containingSnapshot;
      this.layerTreeView_.selection = new cc.RasterTaskSelection(this.slice);
    }
  };

  tracing.analysis.SliceView.register(
      'TileManager::RunRasterTask', RasterTaskSliceView);
  tracing.analysis.SliceView.register(
      'RasterWorkerPoolTaskImpl::RunRasterOnThread', RasterTaskSliceView);

  tracing.analysis.SliceView.register(
      'TileManager::RunAnalyzeTask', RasterTaskSliceView);
  tracing.analysis.SliceView.register(
      'RasterWorkerPoolTaskImpl::RunAnalysisOnThread', RasterTaskSliceView);

  return {
    RasterTaskSliceView: RasterTaskSliceView
  };

});
<|endoftext|>


<commit_before>module.exports = {

    run: function(grunt) {
        var pathModule = require("path");

        var modulesPackageConfig = grunt.file.readJSON('package.json');

        //Construct and validate the arguments
        var args = {
            platform: grunt.option("platform"),
            modulesPath: grunt.option("modulesPath"),
            tnsPath: grunt.option("tnsPath"),
            emulatorProcessIdentifier: grunt.option("emuPId"),
            emuAvdName: grunt.option("avd"),
            outFile: grunt.option("logFilePath"),
            runtimePath: grunt.option("runtimePath"),
            runtimeVersion: grunt.option("runtimeVersion"),
            showEmu: grunt.option("showEmu"),
            runAppOnly: grunt.option("runAppOnly"),
            pathToApp: grunt.option("pathToApp")
        };

        (function validateInput(){
            if (!(/^(Android|iOS)$/).test(args.platform)) {
                throw new Error("Invalid target platform specified! Use --platform=Android|iOS");
            }

            if (args.platform === "Android") {
                if (!args.emulatorProcessIdentifier) {
                    throw new Error("Please, specify an identifier of the emulator process so that it can be stopped (--emuPId=...). Too many emulators started might cause machine overload");
                }
                if (!args.emuAvdName) {
                    throw new Error("Please, specify the name of the AVD to start (--avd=...).");
                }
            }

            if (args.runAppOnly && !args.pathToApp) {
                throw new Error("runAppOnly called, but no path to application specified. Please, add the path via the (--pathToApp=...) parameter.");
            }
        }());

        var localCfg = {
            tnsPath: args.tnsPath || "tns",
            emulatorProcessIdentifier: args.emulatorProcessIdentifier,
            modulesPath: args.modulesPath || "./bin/dist/tns-core-modules-" + modulesPackageConfig.version + ".tgz",
            emuAvdName: args.emuAvdName,
            outFile: args.outFile || "./TestRunResult.txt",
            frameworkArgument: args.runtimePath ? " --frameworkPath=" + args.runtimePath : "",
            runtimeVersionArgument: args.runtimeVersion ? "@" + args.runtimeVersion : "",
            showEmu: args.showEmu || false,
            runAppOnly: args.runAppOnly || false,

            workingDir:".testsapprun",
            testsAppName:"TestsApp",
            applicationDir: pathModule.join(".testsapprun", "TestsApp"),
            appDir: pathModule.join(".testsapprun", "TestsApp", "app"),
            pathToApk: "./platforms/android/build/outputs/apk/TestsApp-debug.apk",
            pathToApp: "./platforms/ios/build/emulator/TestsApp.app",
            deployedAppName:"org.nativescript.TestsApp",
            mainActivityName:"com.tns.NativeScriptActivity",
            pathToCompiledTests: "bin/dist/apps/tests",
            simulatorSysLog: pathModule.join(process.env.HOME, "Library/Logs/CoreSimulator", args.emuAvdName, "/system.log"),
            platform: args.platform
        }

        if (localCfg.runAppOnly) {
            localCfg.pathToApp = localCfg.pathToApk = args.pathToApp;
            localCfg.applicationDir = "./";
        }

        grunt.initConfig({
            clean: {
                workingDir: {
                    src: localCfg.workingDir
                },
                originalAppDir: {
                    src: [
                            localCfg.appDir + "/*",
                            "!" + pathModule.join(localCfg.appDir, "App_Resources") + ""
                         ]
                },
                modules: {
                    src: pathModule.join(localCfg.applicationDir, "node_modules", "tns-core-modules")
                },
                tempExtractedModules: {
                    src: pathModule.join(localCfg.applicationDir, "node_modules", "package")
                },
                simulatorLog: {
                    src: localCfg.simulatorSysLog,
                    options: {
                        force: true
                    }
                }
            },
            mkdir: {
                workingDir: {
                    options: {
                        create: [localCfg.workingDir],
                        mode: 0700
                    }
                }
            },
            copy: {
                testsAppToRunDir: {
                    src: "**/*.*",
                    dest: localCfg.appDir,
                    cwd: localCfg.pathToCompiledTests,
                    expand: true
                },
                modulesToDir: {
                    expand: true,
                    src:  "**/*.*",
                    cwd: pathModule.join(localCfg.applicationDir, "node_modules", "package"),
                    dest: pathModule.join(localCfg.applicationDir, "node_modules", "tns-core-modules")
                },
                addAndroidPermissions: {
                    src: "AndroidManifest.xml",
                    dest: localCfg.applicationDir + "/app/App_Resources/Android/",
                    cwd: localCfg.applicationDir + "/app/App_Resources/Android",
                    expand: true,
                    options: {
                        process: function(content, srcPath) {
                            var newContent = content;

                            var internetPermissionFinder = /((\s*)<uses-permission[^>]*android\.permission\.INTERNET[^>]*>)/;

                            if (!/uses-permission[^>]*android\.permission\.ACCESS_NETWORK_STATE/.test(content)) {
                                newContent = newContent.replace(internetPermissionFinder, "$1$2<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>");
                            }
                            if (!/uses-permission[^>]*android\.permission\.ACCESS_FINE_LOCATION/.test(content)) {
                                newContent = newContent.replace(internetPermissionFinder, "$1$2<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>");
                            }
                            return newContent;
                        }
                    }
                },
                addiOSPermissions: {
                    src: localCfg.testsAppName + "-Info.plist",
                    dest: pathModule.join(localCfg.applicationDir,"/platforms/ios/", localCfg.testsAppName) + "/",
                    cwd: pathModule.join(localCfg.applicationDir,"/platforms/ios/", localCfg.testsAppName),
                    expand: true,
                    options: {
                        process: function(content, srcPath) {
                            var newContent = content;

                            var lastDictLocator = /(<\/dict>\s*<\/plist>)$/gm;

                            if (!/NSAppTransportSecurity/.test(content)) {
                                newContent = newContent.replace(lastDictLocator, "<key>NSAppTransportSecurity</key>\n$1");
                            }
                            if (!/NSAllowsArbitraryLoads/.test(content)) {
                                newContent = newContent.replace(lastDictLocator, "<dict>\n<key>NSAllowsArbitraryLoads</key>\n<true/>\n</dict>\n$1");
                            }
                            return newContent;
                        }
                    }
                },
                simulatorLog: {
                    src: localCfg.simulatorSysLog,
                    dest: localCfg.outFile
                }
            },
            exec: {
                killAndroidEmulator: {
                    cmd: "pkill '" + localCfg.emulatorProcessIdentifier + "'",
                    exitCode: [0, 1]
                },
                killiOSEmulator: {
                    cmd: "pkill Simulator",
                    exitCode: [0, 1]
                },
                createApp: {
                    cmd: localCfg.tnsPath + " create " + localCfg.testsAppName,
                    cwd: localCfg.workingDir
                },
                restartAdb: {
                    cmd: "adb kill-server && adb start-server"
                },
                uninstallExistingAndroidApp: {
                    cmd: "adb uninstall " + localCfg.deployedAppName
                },
                installNewAndroidApp: {
                    cmd: "adb install " + localCfg.pathToApk,
                    cwd: localCfg.applicationDir
                },
                startAndroidEmulator: {
                    cmd: "emulator -avd " + localCfg.emuAvdName + " -no-audio " + (args.showEmu ? "" : "-no-window") + "&"
                },
                startAndroidApp: {
                    cmd: "adb shell am start -n " + localCfg.deployedAppName + "/" + localCfg.mainActivityName
                },
                uninstallExistingiOSApp: {
                    cmd: "xcrun simctl uninstall " + localCfg.emuAvdName + " org.nativescript." + localCfg.testsAppName,
                    cwd: localCfg.applicationDir
                },
                installNewiOSApp: {
                    cmd: "xcrun simctl install " + localCfg.emuAvdName + " " + localCfg.pathToApp,
                    cwd: localCfg.applicationDir
                },
                startiOSApp: {
                    cmd: "xcrun simctl launch " + localCfg.emuAvdName + " org.nativescript." + localCfg.testsAppName
                }
            },
            untar: {
                modules: {
                    src: localCfg.modulesPath,
                    dest: pathModule.join(localCfg.applicationDir, "node_modules")
                }
            },
            shell: {
                collectAndroidLog: {
                    command: "./expect.exp " + "'adb logcat' " + localCfg.outFile,
                    options: {
                        execOptions: {
                            maxBuffer: Infinity
                        }
                    }
                },
                waitiOSLogCompletion: {
                    command: "./expect.exp " + "'tail -f " + localCfg.simulatorSysLog + "' " + localCfg.outFile,
                    options: {
                        execOptions: {
                            maxBuffer: Infinity
                        }
                    }
                },
                startiOSSimulator: {
                    command: "xcrun instruments -w " + localCfg.emuAvdName,
                    options: {
                        failOnError: false
                    },
                },
                buildApp: {
                    command: "tns build " + localCfg.platform.toLowerCase(),
                    options: {
                        execOptions: {
                            maxBuffer: Infinity,
                            cwd: localCfg.applicationDir
                        }
                    }
                },
                addPlatform: {
                    command: "tns platform add " + localCfg.platform.toLowerCase() + localCfg.runtimeVersionArgument + " " + localCfg.frameworkArgument,
                    options: {
                        execOptions: {
                            maxBuffer: Infinity,
                            cwd: localCfg.applicationDir
                        }
                    }
                },
            }
        });

        grunt.loadNpmTasks("grunt-shell");
        grunt.loadNpmTasks("grunt-exec");
        grunt.loadNpmTasks("grunt-mkdir");
        grunt.loadNpmTasks("grunt-contrib-clean");
        grunt.loadNpmTasks("grunt-contrib-copy");
        grunt.loadNpmTasks("grunt-untar");

        var getPlatformSpecificTask = function(templatedTaskName) {
            return templatedTaskName.replace(/\{platform\}/, localCfg.platform);
        }

        grunt.registerTask("startEmulatorAndroid", [
            getPlatformSpecificTask("exec:startAndroidEmulator"),
        ]);

        grunt.registerTask("startEmulatoriOS", [
            getPlatformSpecificTask("shell:startiOSSimulator"),
        ]);

        grunt.registerTask("collectLogAndroid", [
            "shell:collectAndroidLog"
        ]);

        grunt.registerTask("collectLogiOS", [
            "shell:waitiOSLogCompletion",
            "copy:simulatorLog"
        ]);

        grunt.registerTask("doPreUninstallAppAndroid", [
            "exec:restartAdb"
        ]);

        grunt.registerTask("doPreUninstallAppiOS", [
            "clean:simulatorLog"
        ]);

        grunt.registerTask("cleanup", [
//            getPlatformSpecificTask("exec:kill{platform}Emulator"),
            "clean:workingDir"
        ]);

        grunt.registerTask("buildOnly", [
            "exec:createApp",
            "clean:originalAppDir",
            "copy:testsAppToRunDir",
            "clean:modules",
            "untar:modules",
            "copy:modulesToDir",
            "clean:tempExtractedModules",

            "shell:addPlatform",
            getPlatformSpecificTask("copy:add{platform}Permissions"),
            "shell:buildApp",
        ]);

        grunt.registerTask("buildTestsApp", [
            "cleanup",
            "mkdir:workingDir",
            "buildOnly"

        ]);
        grunt.registerTask("buildOnlyTestsApp", ["buildTestsApp"]);

        grunt.registerTask("runOnly", [
//            getPlatformSpecificTask("doPreUninstallApp{platform}"),

            getPlatformSpecificTask("exec:uninstallExisting{platform}App"),
            getPlatformSpecificTask("exec:installNew{platform}App"),
            getPlatformSpecificTask("exec:start{platform}App"),
            getPlatformSpecificTask("collectLog{platform}"),
        ]);

        grunt.registerTask("runApp", [
//            "cleanup",
//            getPlatformSpecificTask("startEmulator{platform}"),
            "runOnly",
            "cleanup"

        ]);

        grunt.registerTask("runOnlyTestsApp", ["runApp"]);

        var tasksToExecute = ["runApp"];
        if (!localCfg.runAppOnly) {
            tasksToExecute = [
                "cleanup",
                "mkdir:workingDir",
                getPlatformSpecificTask("startEmulator{platform}"),
                "buildOnly",
                "runOnly",
                "cleanup"
            ];
        }

        grunt.registerTask("testsapp", tasksToExecute);
    }
}
<commit_msg>Reduced adb log level to root out the problem<commit_after>module.exports = {

    run: function(grunt) {
        var pathModule = require("path");

        var modulesPackageConfig = grunt.file.readJSON('package.json');

        //Construct and validate the arguments
        var args = {
            platform: grunt.option("platform"),
            modulesPath: grunt.option("modulesPath"),
            tnsPath: grunt.option("tnsPath"),
            emulatorProcessIdentifier: grunt.option("emuPId"),
            emuAvdName: grunt.option("avd"),
            outFile: grunt.option("logFilePath"),
            runtimePath: grunt.option("runtimePath"),
            runtimeVersion: grunt.option("runtimeVersion"),
            showEmu: grunt.option("showEmu"),
            runAppOnly: grunt.option("runAppOnly"),
            pathToApp: grunt.option("pathToApp")
        };

        (function validateInput(){
            if (!(/^(Android|iOS)$/).test(args.platform)) {
                throw new Error("Invalid target platform specified! Use --platform=Android|iOS");
            }

            if (args.platform === "Android") {
                if (!args.emulatorProcessIdentifier) {
                    throw new Error("Please, specify an identifier of the emulator process so that it can be stopped (--emuPId=...). Too many emulators started might cause machine overload");
                }
                if (!args.emuAvdName) {
                    throw new Error("Please, specify the name of the AVD to start (--avd=...).");
                }
            }

            if (args.runAppOnly && !args.pathToApp) {
                throw new Error("runAppOnly called, but no path to application specified. Please, add the path via the (--pathToApp=...) parameter.");
            }
        }());

        var localCfg = {
            tnsPath: args.tnsPath || "tns",
            emulatorProcessIdentifier: args.emulatorProcessIdentifier,
            modulesPath: args.modulesPath || "./bin/dist/tns-core-modules-" + modulesPackageConfig.version + ".tgz",
            emuAvdName: args.emuAvdName,
            outFile: args.outFile || "./TestRunResult.txt",
            frameworkArgument: args.runtimePath ? " --frameworkPath=" + args.runtimePath : "",
            runtimeVersionArgument: args.runtimeVersion ? "@" + args.runtimeVersion : "",
            showEmu: args.showEmu || false,
            runAppOnly: args.runAppOnly || false,

            workingDir:".testsapprun",
            testsAppName:"TestsApp",
            applicationDir: pathModule.join(".testsapprun", "TestsApp"),
            appDir: pathModule.join(".testsapprun", "TestsApp", "app"),
            pathToApk: "./platforms/android/build/outputs/apk/TestsApp-debug.apk",
            pathToApp: "./platforms/ios/build/emulator/TestsApp.app",
            deployedAppName:"org.nativescript.TestsApp",
            mainActivityName:"com.tns.NativeScriptActivity",
            pathToCompiledTests: "bin/dist/apps/tests",
            simulatorSysLog: pathModule.join(process.env.HOME, "Library/Logs/CoreSimulator", args.emuAvdName, "/system.log"),
            platform: args.platform
        }

        if (localCfg.runAppOnly) {
            localCfg.pathToApp = localCfg.pathToApk = args.pathToApp;
            localCfg.applicationDir = "./";
        }

        grunt.initConfig({
            clean: {
                workingDir: {
                    src: localCfg.workingDir
                },
                originalAppDir: {
                    src: [
                            localCfg.appDir + "/*",
                            "!" + pathModule.join(localCfg.appDir, "App_Resources") + ""
                         ]
                },
                modules: {
                    src: pathModule.join(localCfg.applicationDir, "node_modules", "tns-core-modules")
                },
                tempExtractedModules: {
                    src: pathModule.join(localCfg.applicationDir, "node_modules", "package")
                },
                simulatorLog: {
                    src: localCfg.simulatorSysLog,
                    options: {
                        force: true
                    }
                }
            },
            mkdir: {
                workingDir: {
                    options: {
                        create: [localCfg.workingDir],
                        mode: 0700
                    }
                }
            },
            copy: {
                testsAppToRunDir: {
                    src: "**/*.*",
                    dest: localCfg.appDir,
                    cwd: localCfg.pathToCompiledTests,
                    expand: true
                },
                modulesToDir: {
                    expand: true,
                    src:  "**/*.*",
                    cwd: pathModule.join(localCfg.applicationDir, "node_modules", "package"),
                    dest: pathModule.join(localCfg.applicationDir, "node_modules", "tns-core-modules")
                },
                addAndroidPermissions: {
                    src: "AndroidManifest.xml",
                    dest: localCfg.applicationDir + "/app/App_Resources/Android/",
                    cwd: localCfg.applicationDir + "/app/App_Resources/Android",
                    expand: true,
                    options: {
                        process: function(content, srcPath) {
                            var newContent = content;

                            var internetPermissionFinder = /((\s*)<uses-permission[^>]*android\.permission\.INTERNET[^>]*>)/;

                            if (!/uses-permission[^>]*android\.permission\.ACCESS_NETWORK_STATE/.test(content)) {
                                newContent = newContent.replace(internetPermissionFinder, "$1$2<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>");
                            }
                            if (!/uses-permission[^>]*android\.permission\.ACCESS_FINE_LOCATION/.test(content)) {
                                newContent = newContent.replace(internetPermissionFinder, "$1$2<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>");
                            }
                            return newContent;
                        }
                    }
                },
                addiOSPermissions: {
                    src: localCfg.testsAppName + "-Info.plist",
                    dest: pathModule.join(localCfg.applicationDir,"/platforms/ios/", localCfg.testsAppName) + "/",
                    cwd: pathModule.join(localCfg.applicationDir,"/platforms/ios/", localCfg.testsAppName),
                    expand: true,
                    options: {
                        process: function(content, srcPath) {
                            var newContent = content;

                            var lastDictLocator = /(<\/dict>\s*<\/plist>)$/gm;

                            if (!/NSAppTransportSecurity/.test(content)) {
                                newContent = newContent.replace(lastDictLocator, "<key>NSAppTransportSecurity</key>\n$1");
                            }
                            if (!/NSAllowsArbitraryLoads/.test(content)) {
                                newContent = newContent.replace(lastDictLocator, "<dict>\n<key>NSAllowsArbitraryLoads</key>\n<true/>\n</dict>\n$1");
                            }
                            return newContent;
                        }
                    }
                },
                simulatorLog: {
                    src: localCfg.simulatorSysLog,
                    dest: localCfg.outFile
                }
            },
            exec: {
                killAndroidEmulator: {
                    cmd: "pkill '" + localCfg.emulatorProcessIdentifier + "'",
                    exitCode: [0, 1]
                },
                killiOSEmulator: {
                    cmd: "pkill Simulator",
                    exitCode: [0, 1]
                },
                createApp: {
                    cmd: localCfg.tnsPath + " create " + localCfg.testsAppName,
                    cwd: localCfg.workingDir
                },
                restartAdb: {
                    cmd: "adb kill-server && adb start-server"
                },
                uninstallExistingAndroidApp: {
                    cmd: "adb uninstall " + localCfg.deployedAppName
                },
                installNewAndroidApp: {
                    cmd: "adb install " + localCfg.pathToApk,
                    cwd: localCfg.applicationDir
                },
                startAndroidEmulator: {
                    cmd: "emulator -avd " + localCfg.emuAvdName + " -no-audio " + (args.showEmu ? "" : "-no-window") + "&"
                },
                startAndroidApp: {
                    cmd: "adb shell am start -n " + localCfg.deployedAppName + "/" + localCfg.mainActivityName
                },
                uninstallExistingiOSApp: {
                    cmd: "xcrun simctl uninstall " + localCfg.emuAvdName + " org.nativescript." + localCfg.testsAppName,
                    cwd: localCfg.applicationDir
                },
                installNewiOSApp: {
                    cmd: "xcrun simctl install " + localCfg.emuAvdName + " " + localCfg.pathToApp,
                    cwd: localCfg.applicationDir
                },
                startiOSApp: {
                    cmd: "xcrun simctl launch " + localCfg.emuAvdName + " org.nativescript." + localCfg.testsAppName
                }
            },
            untar: {
                modules: {
                    src: localCfg.modulesPath,
                    dest: pathModule.join(localCfg.applicationDir, "node_modules")
                }
            },
            shell: {
                collectAndroidLog: {
                    command: "./expect.exp " + "'adb logcat *:D' " + localCfg.outFile,
                    options: {
                        execOptions: {
                            maxBuffer: Infinity
                        }
                    }
                },
                waitiOSLogCompletion: {
                    command: "./expect.exp " + "'tail -f " + localCfg.simulatorSysLog + "' " + localCfg.outFile,
                    options: {
                        execOptions: {
                            maxBuffer: Infinity
                        }
                    }
                },
                startiOSSimulator: {
                    command: "xcrun instruments -w " + localCfg.emuAvdName,
                    options: {
                        failOnError: false
                    },
                },
                buildApp: {
                    command: "tns build " + localCfg.platform.toLowerCase(),
                    options: {
                        execOptions: {
                            maxBuffer: Infinity,
                            cwd: localCfg.applicationDir
                        }
                    }
                },
                addPlatform: {
                    command: "tns platform add " + localCfg.platform.toLowerCase() + localCfg.runtimeVersionArgument + " " + localCfg.frameworkArgument,
                    options: {
                        execOptions: {
                            maxBuffer: Infinity,
                            cwd: localCfg.applicationDir
                        }
                    }
                },
            }
        });

        grunt.loadNpmTasks("grunt-shell");
        grunt.loadNpmTasks("grunt-exec");
        grunt.loadNpmTasks("grunt-mkdir");
        grunt.loadNpmTasks("grunt-contrib-clean");
        grunt.loadNpmTasks("grunt-contrib-copy");
        grunt.loadNpmTasks("grunt-untar");

        var getPlatformSpecificTask = function(templatedTaskName) {
            return templatedTaskName.replace(/\{platform\}/, localCfg.platform);
        }

        grunt.registerTask("startEmulatorAndroid", [
            getPlatformSpecificTask("exec:startAndroidEmulator"),
        ]);

        grunt.registerTask("startEmulatoriOS", [
            getPlatformSpecificTask("shell:startiOSSimulator"),
        ]);

        grunt.registerTask("collectLogAndroid", [
            "shell:collectAndroidLog"
        ]);

        grunt.registerTask("collectLogiOS", [
            "shell:waitiOSLogCompletion",
            "copy:simulatorLog"
        ]);

        grunt.registerTask("doPreUninstallAppAndroid", [
            "exec:restartAdb"
        ]);

        grunt.registerTask("doPreUninstallAppiOS", [
            "clean:simulatorLog"
        ]);

        grunt.registerTask("cleanup", [
//            getPlatformSpecificTask("exec:kill{platform}Emulator"),
            "clean:workingDir"
        ]);

        grunt.registerTask("buildOnly", [
            "exec:createApp",
            "clean:originalAppDir",
            "copy:testsAppToRunDir",
            "clean:modules",
            "untar:modules",
            "copy:modulesToDir",
            "clean:tempExtractedModules",

            "shell:addPlatform",
            getPlatformSpecificTask("copy:add{platform}Permissions"),
            "shell:buildApp",
        ]);

        grunt.registerTask("buildTestsApp", [
            "cleanup",
            "mkdir:workingDir",
            "buildOnly"

        ]);
        grunt.registerTask("buildOnlyTestsApp", ["buildTestsApp"]);

        grunt.registerTask("runOnly", [
//            getPlatformSpecificTask("doPreUninstallApp{platform}"),

            getPlatformSpecificTask("exec:uninstallExisting{platform}App"),
            getPlatformSpecificTask("exec:installNew{platform}App"),
            getPlatformSpecificTask("exec:start{platform}App"),
            getPlatformSpecificTask("collectLog{platform}"),
        ]);

        grunt.registerTask("runApp", [
//            "cleanup",
//            getPlatformSpecificTask("startEmulator{platform}"),
            "runOnly",
            "cleanup"

        ]);

        grunt.registerTask("runOnlyTestsApp", ["runApp"]);

        var tasksToExecute = ["runApp"];
        if (!localCfg.runAppOnly) {
            tasksToExecute = [
                "cleanup",
                "mkdir:workingDir",
                getPlatformSpecificTask("startEmulator{platform}"),
                "buildOnly",
                "runOnly",
                "cleanup"
            ];
        }

        grunt.registerTask("testsapp", tasksToExecute);
    }
}
<|endoftext|>


<commit_before>import { alias } from '@ember/object/computed';
import { computed } from '@ember/object';
import DS from 'ember-data';
import { fragment } from 'ember-data-model-fragments/attributes';
import fieldToAttrs, { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import { memberAction } from 'ember-api-actions';

import apiPath from 'vault/utils/api-path';
import attachCapabilities from 'vault/lib/attach-capabilities';

const { attr, hasMany } = DS;

let Model = DS.Model.extend({
  authConfigs: hasMany('auth-config', { polymorphic: true, inverse: 'backend', async: false }),
  path: attr('string'),
  accessor: attr('string'),
  name: attr('string'),
  type: attr('string'),
  // namespaces introduced types with a `ns_` prefix for built-in engines
  // so we need to strip that to normalize the type
  methodType: computed('type', function() {
    return this.get('type').replace(/^ns_/, '');
  }),
  description: attr('string', {
    editType: 'textarea',
  }),
  config: fragment('mount-config', { defaultValue: {} }),
  local: attr('boolean', {
    helpText:
      'When Replication is enabled, a local mount will not be replicated across clusters. This can only be specified at mount time.',
  }),
  sealWrap: attr('boolean', {
    helpText:
      'When enabled - if a seal supporting seal wrapping is specified in the configuration, all critical security parameters (CSPs) in this backend will be seal wrapped. (For K/V mounts, all values will be seal wrapped.) This can only be specified at mount time.',
  }),

  // used when the `auth` prefix is important,
  // currently only when setting perf mount filtering
  apiPath: computed('path', function() {
    return `auth/${this.get('path')}`;
  }),
  localDisplay: computed('local', function() {
    return this.get('local') ? 'local' : 'replicated';
  }),

  tuneAttrs: computed(function() {
    return expandAttributeMeta(this, [
      'description',
      'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
    ]);
  }),

  //sys/mounts/auth/[auth-path]/tune.
  tune: memberAction({
    path: 'tune',
    type: 'post',
    urlType: 'updateRecord',
  }),

  formFields: computed(function() {
    return [
      'type',
      'path',
      'description',
      'accessor',
      'local',
      'sealWrap',
      'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
    ];
  }),

  formFieldGroups: computed(function() {
    return [
      { default: ['path'] },
      {
        'Method Options': [
          'description',
          'config.listingVisibility',
          'local',
          'sealWrap',
          'config.{defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
        ],
      },
    ];
  }),

  attrs: computed('formFields', function() {
    return expandAttributeMeta(this, this.get('formFields'));
  }),

  fieldGroups: computed('formFieldGroups', function() {
    return fieldToAttrs(this, this.get('formFieldGroups'));
  }),
  canDisable: alias('deletePath.canDelete'),
  canEdit: alias('configPath.canUpdate'),
});

export default attachCapabilities(Model, {
  deltePath: apiPath`sys/auth/${'id'}`,
  configPath: function(context) {
    if (context.type === 'aws') {
      return apiPath`auth/${'id'}/config/client`;
    } else {
      return apiPath`auth/${'id'}/config`;
    }
  },
});
<commit_msg>fix typo (#7394)<commit_after>import { alias } from '@ember/object/computed';
import { computed } from '@ember/object';
import DS from 'ember-data';
import { fragment } from 'ember-data-model-fragments/attributes';
import fieldToAttrs, { expandAttributeMeta } from 'vault/utils/field-to-attrs';
import { memberAction } from 'ember-api-actions';

import apiPath from 'vault/utils/api-path';
import attachCapabilities from 'vault/lib/attach-capabilities';

const { attr, hasMany } = DS;

let Model = DS.Model.extend({
  authConfigs: hasMany('auth-config', { polymorphic: true, inverse: 'backend', async: false }),
  path: attr('string'),
  accessor: attr('string'),
  name: attr('string'),
  type: attr('string'),
  // namespaces introduced types with a `ns_` prefix for built-in engines
  // so we need to strip that to normalize the type
  methodType: computed('type', function() {
    return this.get('type').replace(/^ns_/, '');
  }),
  description: attr('string', {
    editType: 'textarea',
  }),
  config: fragment('mount-config', { defaultValue: {} }),
  local: attr('boolean', {
    helpText:
      'When Replication is enabled, a local mount will not be replicated across clusters. This can only be specified at mount time.',
  }),
  sealWrap: attr('boolean', {
    helpText:
      'When enabled - if a seal supporting seal wrapping is specified in the configuration, all critical security parameters (CSPs) in this backend will be seal wrapped. (For K/V mounts, all values will be seal wrapped.) This can only be specified at mount time.',
  }),

  // used when the `auth` prefix is important,
  // currently only when setting perf mount filtering
  apiPath: computed('path', function() {
    return `auth/${this.get('path')}`;
  }),
  localDisplay: computed('local', function() {
    return this.get('local') ? 'local' : 'replicated';
  }),

  tuneAttrs: computed(function() {
    return expandAttributeMeta(this, [
      'description',
      'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
    ]);
  }),

  //sys/mounts/auth/[auth-path]/tune.
  tune: memberAction({
    path: 'tune',
    type: 'post',
    urlType: 'updateRecord',
  }),

  formFields: computed(function() {
    return [
      'type',
      'path',
      'description',
      'accessor',
      'local',
      'sealWrap',
      'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
    ];
  }),

  formFieldGroups: computed(function() {
    return [
      { default: ['path'] },
      {
        'Method Options': [
          'description',
          'config.listingVisibility',
          'local',
          'sealWrap',
          'config.{defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
        ],
      },
    ];
  }),

  attrs: computed('formFields', function() {
    return expandAttributeMeta(this, this.get('formFields'));
  }),

  fieldGroups: computed('formFieldGroups', function() {
    return fieldToAttrs(this, this.get('formFieldGroups'));
  }),
  canDisable: alias('deletePath.canDelete'),
  canEdit: alias('configPath.canUpdate'),
});

export default attachCapabilities(Model, {
  deletePath: apiPath`sys/auth/${'id'}`,
  configPath: function(context) {
    if (context.type === 'aws') {
      return apiPath`auth/${'id'}/config/client`;
    } else {
      return apiPath`auth/${'id'}/config`;
    }
  },
});
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2014-2021 Camptocamp SA
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const path = require('path');
const fs = require('fs');
const puppeteer = require('puppeteer');
const parse = require('url-parse');

const arg = process.argv[2];
if (!arg) {
  throw new Error('Please provide a HTML file as the first argument');
}
const screenshot = !arg.startsWith('http');
const screenshotPath = screenshot ? `${arg}.png` : undefined;
const page_url = screenshot ? `http://localhost:3001/${arg}` : arg;

function fileMock(name, contentType) {
  return {
    status: 200,
    headers: {
      'content-type': contentType,
    },
    body: (() => {
      try {
        return fs.readFileSync(path.resolve(__dirname, name));
      } catch (e) {
        // Ignore
        return undefined;
      }
    })(),
  };
}

const OSMImage = fileMock('osm.png', 'image/png');
const ASITVDCapabilities = fileMock('asitvd.capabilities.xml', 'text/xml');
let browser;

process.on('unhandledRejection', async (error) => {
  console.log(`UnhandledRejection: ${error.message}.`);
  await browser.close();
  process.exit(2);
});

const requestsURL = new Set();
const start = new Date();
let timeout = undefined;
function loaded(page, browser) {
  if (timeout !== undefined) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(async () => {
    if (requestsURL.size) {
      if (new Date() - start > 60000) {
        console.log(`The page take more than 60s. to load (${(new Date() - start) / 1000}).`);
        console.log('Pending requests:');
        requestsURL.forEach((request) => console.log(request));
        await browser.close();
        process.exit(2);
      } else {
        timeout = undefined;
        loaded(page, browser);
      }
    } else {
      console.log(`Check finished in ${(new Date() - start) / 1000} seconds`);
      if (screenshot) {
        timeout = setTimeout(async () => {
          page
            .screenshot({
              path: screenshotPath,
            })
            .then(
              async () => {
                console.log(`Screenshot saved at: ${screenshotPath}`);
                await browser.close();
              },
              async (e) => {
                console.log(`Screenshot error: ${e}`);
                await browser.close();
                process.exit(2);
              }
            );
        }, 500);
      } else {
        await browser.close();
      }
    }
  }, 500);
}
(async () => {
  browser = await puppeteer.launch({
    args: ['--no-sandbox', '--disable-web-security', '--single-process'],
    headless: true,
  });
  const page = await browser.newPage();

  await page.setViewport({width: 1920, height: 1080});
  await page.setRequestInterception(true);
  page.on('pageerror', async (e) => {
    console.log('Page error');
    console.log(e);
    await browser.close();
    process.exit(2);
  });
  page.on('dialog', async (e) => {
    console.log('Unexpected alert message');
    console.log(e);
    await browser.close();
    process.exit(2);
  });
  page.on('request', (request) => {
    const originalUrl = request.url();
    if (process.env.CI != 'true') {
      loaded(page, browser);
    }
    let url = originalUrl;
    if (process.env.CI != 'true') {
      if (process.env.HTTP_MAP) {
        const http_map = JSON.parse(process.env.HTTP_MAP);
        for (const key in http_map) {
          if (url.startsWith(key)) {
            url = url.replace(key, http_map[key]);
          }
        }
      }
      request.continue({
        url,
      });
      return;
    }
    if (url.startsWith('http://localhost:8080/')) {
      url = url.replace('http://localhost:8080/', 'https://geomapfish-demo-2-7.camptocamp.com/');
    }
    if (url == 'https://ows.asitvd.ch/wmts/1.0.0/WMTSCapabilities.xml') {
      request.respond(ASITVDCapabilities);
    } else if (
      parse(url).host == parse(page_url).host ||
      url.startsWith('http://localhost:') ||
      url.startsWith('https://geomapfish-demo') ||
      url.startsWith('https://wmts.geo.admin.ch/') ||
      url.startsWith('https://wms.geo.admin.ch/')
    ) {
      if (originalUrl.includes('/tiles/') && originalUrl.endsWith('.png')) {
        request.respond(OSMImage);
      } else {
        console.log(originalUrl);
        requestsURL.add(originalUrl);
        if (url.startsWith('https://geomapfish-demo')) {
          request.headers().origin = 'http://localhost:3001';
        }
        console.log(`Request: ${url}`);
        request.continue({
          url,
          headers: {
            // Don't be intranet
            'Forwarded': 'for=8.8.8.8;proto=https',
            'Cache-Control': 'no-cache',
          },
        });
      }
    } else if (
      url.includes('tile.openstreetmap.org') ||
      url.startsWith('https://tiles.openseamap.org/') ||
      url.startsWith('https://wms.geo.admin.ch/') ||
      url.startsWith('https://ows.asitvd.ch/') ||
      url.startsWith('https://ows1.asitvd.ch/') ||
      url.startsWith('https://ows2.asitvd.ch/') ||
      url.startsWith('https://ows3.asitvd.ch/') ||
      url.startsWith('https://ows4.asitvd.ch/')
    ) {
      request.respond(OSMImage);
    } else {
      console.log(`Abort request on '${url}'`);
      request.abort('failed');
    }
  });
  page.on('requestfinished', async (request) => {
    const ci = process.env.CI == 'true';
    const url = request.url();
    requestsURL.delete(url);
    if (process.env.CI != 'true' || !url.includes('/tiles/')) {
      loaded(page, browser);
    }
    if (
      ci &&
      url.startsWith('https://geomapfish-demo') &&
      request.headers()['sec-fetch-mode'] == 'cors' &&
      request.response().headers()['access-control-allow-origin'] == undefined
    ) {
      console.log(`CORS error on: ${url}`);
      console.log('= Request headers');
      for (const n in request.headers()) {
        console.log(`${n}: ${request.headers()[n]}`);
      }
      console.log('= Response headers');
      const response = request.response();
      for (const n in response.headers()) {
        console.log(`${n}: ${response.headers()[n]}`);
      }
      if (response.headers()['content-type'] == 'text/html') {
        const text = await response.text();
        console.log('= Response body');
        console.log(text);
      }
    }
  });
  page.on('requestfailed', async (request) => {
    const url = request.url();
    if (
      !url.startsWith('https://www.camptocamp.com/') &&
      !url.startsWith('https://cdn.polyfill.io/') &&
      !url.startsWith('https://maps.googleapis.com/')
    ) {
      console.log(`Request failed on: ${url}`);
      await browser.close();
      process.exit(2);
    }
    loaded(page, browser);
  });
  page.on('console', async (message) => {
    const type = message.type();
    const location = message.location();
    if (
      !location.url.startsWith('http://localhost:3001/.build/examples-hosted/dist/vendor.js') &&
      location.url.startsWith('http://localhost:3001/')
    ) {
      console.log(`Console ${type}`);
      console.log(`On: ${location.url} ${location.lineNumber}:${location.columnNumber}.`);
      console.log(message.text());
      if (!message.text().includes('CORS')) {
        await browser.close();
        process.exit(2);
      }
    }
  });
  await page.goto(page_url).catch(async (error) => {
    console.log(`Page load error: ${error}.`);
    await browser.close();
    process.exit(2);
  });
  loaded(page, browser);
})().catch(async (error) => {
  console.log(`Unexpected error: ${error}.`);
  await browser.close();
  process.exit(2);
});
<commit_msg>Don't fail on Sentry request<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2014-2021 Camptocamp SA
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

const path = require('path');
const fs = require('fs');
const puppeteer = require('puppeteer');
const parse = require('url-parse');

const arg = process.argv[2];
if (!arg) {
  throw new Error('Please provide a HTML file as the first argument');
}
const screenshot = !arg.startsWith('http');
const screenshotPath = screenshot ? `${arg}.png` : undefined;
const page_url = screenshot ? `http://localhost:3001/${arg}` : arg;

function fileMock(name, contentType) {
  return {
    status: 200,
    headers: {
      'content-type': contentType,
    },
    body: (() => {
      try {
        return fs.readFileSync(path.resolve(__dirname, name));
      } catch (e) {
        // Ignore
        return undefined;
      }
    })(),
  };
}

const OSMImage = fileMock('osm.png', 'image/png');
const ASITVDCapabilities = fileMock('asitvd.capabilities.xml', 'text/xml');
let browser;

process.on('unhandledRejection', async (error) => {
  console.log(`UnhandledRejection: ${error.message}.`);
  await browser.close();
  process.exit(2);
});

const requestsURL = new Set();
const start = new Date();
let timeout = undefined;
function loaded(page, browser) {
  if (timeout !== undefined) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(async () => {
    if (requestsURL.size) {
      if (new Date() - start > 60000) {
        console.log(`The page take more than 60s. to load (${(new Date() - start) / 1000}).`);
        console.log('Pending requests:');
        requestsURL.forEach((request) => console.log(request));
        await browser.close();
        process.exit(2);
      } else {
        timeout = undefined;
        loaded(page, browser);
      }
    } else {
      console.log(`Check finished in ${(new Date() - start) / 1000} seconds`);
      if (screenshot) {
        timeout = setTimeout(async () => {
          page
            .screenshot({
              path: screenshotPath,
            })
            .then(
              async () => {
                console.log(`Screenshot saved at: ${screenshotPath}`);
                await browser.close();
              },
              async (e) => {
                console.log(`Screenshot error: ${e}`);
                await browser.close();
                process.exit(2);
              }
            );
        }, 500);
      } else {
        await browser.close();
      }
    }
  }, 500);
}
(async () => {
  browser = await puppeteer.launch({
    args: ['--no-sandbox', '--disable-web-security', '--single-process'],
    headless: true,
  });
  const page = await browser.newPage();

  await page.setViewport({width: 1920, height: 1080});
  await page.setRequestInterception(true);
  page.on('pageerror', async (e) => {
    console.log('Page error');
    console.log(e);
    await browser.close();
    process.exit(2);
  });
  page.on('dialog', async (e) => {
    console.log('Unexpected alert message');
    console.log(e);
    await browser.close();
    process.exit(2);
  });
  page.on('request', (request) => {
    const originalUrl = request.url();
    if (process.env.CI != 'true') {
      loaded(page, browser);
    }
    let url = originalUrl;
    if (process.env.CI != 'true') {
      if (process.env.HTTP_MAP) {
        const http_map = JSON.parse(process.env.HTTP_MAP);
        for (const key in http_map) {
          if (url.startsWith(key)) {
            url = url.replace(key, http_map[key]);
          }
        }
      }
      request.continue({
        url,
      });
      return;
    }
    if (url.startsWith('http://localhost:8080/')) {
      url = url.replace('http://localhost:8080/', 'https://geomapfish-demo-2-7.camptocamp.com/');
    }
    if (url == 'https://ows.asitvd.ch/wmts/1.0.0/WMTSCapabilities.xml') {
      request.respond(ASITVDCapabilities);
    } else if (
      parse(url).host == parse(page_url).host ||
      url.startsWith('http://localhost:') ||
      url.startsWith('https://geomapfish-demo') ||
      url.startsWith('https://wmts.geo.admin.ch/') ||
      url.startsWith('https://wms.geo.admin.ch/')
    ) {
      if (originalUrl.includes('/tiles/') && originalUrl.endsWith('.png')) {
        request.respond(OSMImage);
      } else {
        console.log(originalUrl);
        requestsURL.add(originalUrl);
        if (url.startsWith('https://geomapfish-demo')) {
          request.headers().origin = 'http://localhost:3001';
        }
        console.log(`Request: ${url}`);
        request.continue({
          url,
          headers: {
            // Don't be intranet
            'Forwarded': 'for=8.8.8.8;proto=https',
            'Cache-Control': 'no-cache',
          },
        });
      }
    } else if (
      url.includes('tile.openstreetmap.org') ||
      url.startsWith('https://tiles.openseamap.org/') ||
      url.startsWith('https://wms.geo.admin.ch/') ||
      url.startsWith('https://ows.asitvd.ch/') ||
      url.startsWith('https://ows1.asitvd.ch/') ||
      url.startsWith('https://ows2.asitvd.ch/') ||
      url.startsWith('https://ows3.asitvd.ch/') ||
      url.startsWith('https://ows4.asitvd.ch/')
    ) {
      request.respond(OSMImage);
    } else {
      console.log(`Abort request on '${url}'`);
      request.abort('failed');
    }
  });
  page.on('requestfinished', async (request) => {
    const ci = process.env.CI == 'true';
    const url = request.url();
    requestsURL.delete(url);
    if (process.env.CI != 'true' || !url.includes('/tiles/')) {
      loaded(page, browser);
    }
    if (
      ci &&
      url.startsWith('https://geomapfish-demo') &&
      request.headers()['sec-fetch-mode'] == 'cors' &&
      request.response().headers()['access-control-allow-origin'] == undefined
    ) {
      console.log(`CORS error on: ${url}`);
      console.log('= Request headers');
      for (const n in request.headers()) {
        console.log(`${n}: ${request.headers()[n]}`);
      }
      console.log('= Response headers');
      const response = request.response();
      for (const n in response.headers()) {
        console.log(`${n}: ${response.headers()[n]}`);
      }
      if (response.headers()['content-type'] == 'text/html') {
        const text = await response.text();
        console.log('= Response body');
        console.log(text);
      }
    }
  });
  page.on('requestfailed', async (request) => {
    const url = request.url();
    if (
      !url.startsWith('https://www.camptocamp.com/') &&
      !url.startsWith('https://o330647.ingest.sentry.io/') &&
      !url.startsWith('https://cdn.polyfill.io/') &&
      !url.startsWith('https://maps.googleapis.com/')
    ) {
      console.log(`Request failed on: ${url}`);
      await browser.close();
      process.exit(2);
    }
    loaded(page, browser);
  });
  page.on('console', async (message) => {
    const type = message.type();
    const location = message.location();
    if (
      !location.url.startsWith('http://localhost:3001/.build/examples-hosted/dist/vendor.js') &&
      location.url.startsWith('http://localhost:3001/')
    ) {
      console.log(`Console ${type}`);
      console.log(`On: ${location.url} ${location.lineNumber}:${location.columnNumber}.`);
      console.log(message.text());
      if (!message.text().includes('CORS')) {
        await browser.close();
        process.exit(2);
      }
    }
  });
  await page.goto(page_url).catch(async (error) => {
    console.log(`Page load error: ${error}.`);
    await browser.close();
    process.exit(2);
  });
  loaded(page, browser);
})().catch(async (error) => {
  console.log(`Unexpected error: ${error}.`);
  await browser.close();
  process.exit(2);
});
<|endoftext|>


<commit_before>// Underscore-contrib (underscore.function.arity.js 0.3.0)
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors
// Underscore-contrib may be freely distributed under the MIT license.

(function(root) {

  // Baseline setup
  // --------------

  // Establish the root object, `window` in the browser, or `global` on the server.
  var _ = root._ || require('underscore');

  // Setup for variadic operators
  // ----------------------------

  // Turn a binary math operator into a variadic operator
  function variadicMath(operator) {
    return function(args) {
      var numbersToOperateOn = isArrayLike(args) ? args : arguments;
      return _.reduce(numbersToOperateOn, operator);
    };
  }

  // Turn a binary comparator into a variadic comparator
  function variadicComparator(comparator) {
    return function(args) {
        var numbersToCompare = isArrayLike(args) ? args : arguments;
        var result;

        for (var i = 0; i < numbersToCompare.length - 1; i++) {
          result = comparator(numbersToCompare[i], numbersToCompare[i + 1]);
        if (result === false) return result;
      }

      return result;
    };
  }

  function isArrayLike(obj) {
    return obj != null && typeof obj.length === "number";
  }

  // Turn a boolean-returning function into one with the opposite meaning
  function invert(fn) {
    return function() {
      return !fn.apply(this, arguments);
    };
  }

  // Basic math operators
  function add(x, y) {
    return x + y;
  }

  function sub(x, y) {
    return x - y;
  }

  function mul(x, y) {
    return x * y;
  }

  function div(x, y) {
    return x / y;
  }

  function mod(x, y) {
    return x % y;
  }

  function inc(x) {
    return ++x;
  }

  function dec(x) {
    return --x;
  }

  function neg(x) {
    return -x;
  }

  // Bitwise operators
  function bitwiseAnd(x, y) {
    return x & y;
  }

  function bitwiseOr(x, y) {
    return x | y;
  }

  function bitwiseXor(x, y) {
    return x ^ y;
  }

  function bitwiseLeft(x, y) {
    return x << y;
  }

  function bitwiseRight(x, y) {
    return x >> y;
  }

  function bitwiseZ(x, y) {
    return x >>> y;
  }

  function bitwiseNot(x) {
    return ~x;
  }

  // Basic comparators
  function eq(x, y) {
    return x == y;
  }

  function seq(x, y) {
    return x === y;
  }

  // Not
  function not(x) {
    return !x;
  }

  // Relative comparators
  function gt(x, y) {
    return x > y;
  }

  function lt(x, y) {
    return x < y;
  }

  function gte(x, y) {
    return x >= y;
  }

  function lte(x, y) {
    return x <= y;
  }

  // Mixing in the operator functions
  // -----------------------------

  _.mixin({
    add: variadicMath(add),
    sub: variadicMath(sub),
    mul: variadicMath(mul),
    div: variadicMath(div),
    mod: mod,
    inc: inc,
    dec: dec,
    neg: neg,
    eq: variadicComparator(eq),
    seq: variadicComparator(seq),
    neq: invert(variadicComparator(eq)),
    sneq: invert(variadicComparator(seq)),
    not: not,
    gt: variadicComparator(gt),
    lt: variadicComparator(lt),
    gte: variadicComparator(gte),
    lte: variadicComparator(lte),
    bitwiseAnd: variadicMath(bitwiseAnd),
    bitwiseOr: variadicMath(bitwiseOr),
    bitwiseXor: variadicMath(bitwiseXor),
    bitwiseNot: bitwiseNot,
    bitwiseLeft: variadicMath(bitwiseLeft),
    bitwiseRight: variadicMath(bitwiseRight),
    bitwiseZ: variadicMath(bitwiseZ)
  });
})(this);
<commit_msg>util.operators: refactor variadic functions<commit_after>// Underscore-contrib (underscore.function.arity.js 0.3.0)
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors
// Underscore-contrib may be freely distributed under the MIT license.

(function(root) {

  // Baseline setup
  // --------------

  // Establish the root object, `window` in the browser, or `global` on the server.
  var _ = root._ || require('underscore');

  // Setup for variadic operators
  // ----------------------------

  // Turn a binary math operator into a variadic operator
  function variadicMath(operator) {
    return variaderize(function(numbersToOperateOn) {
      return _.reduce(numbersToOperateOn, operator);
    });
  }

  // Turn a binary comparator into a variadic comparator
  function variadicComparator(comparator) {
    return variaderize(function(numbersToCompare) {
      var result;

      for (var i = 0; i < numbersToCompare.length - 1; i++) {
        result = comparator(numbersToCompare[i], numbersToCompare[i + 1]);
        if (result === false) return result;
      }

      return result;
    });
  }

  // Converts a unary function that operates on an array into one that also works with a variable number of arguments
  function variaderize(func) {
    return function (args) {
      var allArgs = isArrayLike(args) ? args : arguments;
      return func(allArgs);
    };
  }

  function isArrayLike(obj) {
    return obj != null && typeof obj.length === "number";
  }

  // Turn a boolean-returning function into one with the opposite meaning
  function invert(fn) {
    return function() {
      return !fn.apply(this, arguments);
    };
  }

  // Basic math operators
  function add(x, y) {
    return x + y;
  }

  function sub(x, y) {
    return x - y;
  }

  function mul(x, y) {
    return x * y;
  }

  function div(x, y) {
    return x / y;
  }

  function mod(x, y) {
    return x % y;
  }

  function inc(x) {
    return ++x;
  }

  function dec(x) {
    return --x;
  }

  function neg(x) {
    return -x;
  }

  // Bitwise operators
  function bitwiseAnd(x, y) {
    return x & y;
  }

  function bitwiseOr(x, y) {
    return x | y;
  }

  function bitwiseXor(x, y) {
    return x ^ y;
  }

  function bitwiseLeft(x, y) {
    return x << y;
  }

  function bitwiseRight(x, y) {
    return x >> y;
  }

  function bitwiseZ(x, y) {
    return x >>> y;
  }

  function bitwiseNot(x) {
    return ~x;
  }

  // Basic comparators
  function eq(x, y) {
    return x == y;
  }

  function seq(x, y) {
    return x === y;
  }

  // Not
  function not(x) {
    return !x;
  }

  // Relative comparators
  function gt(x, y) {
    return x > y;
  }

  function lt(x, y) {
    return x < y;
  }

  function gte(x, y) {
    return x >= y;
  }

  function lte(x, y) {
    return x <= y;
  }

  // Mixing in the operator functions
  // -----------------------------

  _.mixin({
    add: variadicMath(add),
    sub: variadicMath(sub),
    mul: variadicMath(mul),
    div: variadicMath(div),
    mod: mod,
    inc: inc,
    dec: dec,
    neg: neg,
    eq: variadicComparator(eq),
    seq: variadicComparator(seq),
    neq: invert(variadicComparator(eq)),
    sneq: invert(variadicComparator(seq)),
    not: not,
    gt: variadicComparator(gt),
    lt: variadicComparator(lt),
    gte: variadicComparator(gte),
    lte: variadicComparator(lte),
    bitwiseAnd: variadicMath(bitwiseAnd),
    bitwiseOr: variadicMath(bitwiseOr),
    bitwiseXor: variadicMath(bitwiseXor),
    bitwiseNot: bitwiseNot,
    bitwiseLeft: variadicMath(bitwiseLeft),
    bitwiseRight: variadicMath(bitwiseRight),
    bitwiseZ: variadicMath(bitwiseZ)
  });
})(this);
<|endoftext|>


<commit_before>// Underscore-contrib (underscore.function.arity.js 0.3.0)
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors
// Underscore-contrib may be freely distributed under the MIT license.

(function(root) {

  // Baseline setup
  // --------------

  // Establish the root object, `window` in the browser, or `global` on the server.
  var _ = root._ || require('underscore');

  // Setup for variadic operators
  // ----------------------------

  // Turn a binary math operator into a variadic operator
  function variadicMath(operator) {
    return variaderize(function(numbersToOperateOn) {
      return _.reduce(numbersToOperateOn, operator);
    });
  }

  // Turn a binary comparator into a variadic comparator
  function variadicComparator(comparator) {
    return variaderize(function(numbersToCompare) {
      var result;

      for (var i = 0; i < numbersToCompare.length - 1; i++) {
        result = comparator(numbersToCompare[i], numbersToCompare[i + 1]);
        if (result === false) return result;
      }

      return result;
    });
  }

  // Converts a unary function that operates on an array into one that also works with a variable number of arguments
  function variaderize(func) {
    return function (args) {
      var allArgs = isArrayLike(args) ? args : arguments;
      return func(allArgs);
    };
  }

  function isArrayLike(obj) {
    return obj != null && typeof obj.length === "number";
  }

  // Turn a boolean-returning function into one with the opposite meaning
  function invert(fn) {
    return function() {
      return !fn.apply(this, arguments);
    };
  }

  // Basic math operators
  function add(x, y) {
    return x + y;
  }

  function sub(x, y) {
    return x - y;
  }

  function mul(x, y) {
    return x * y;
  }

  function div(x, y) {
    return x / y;
  }

  function mod(x, y) {
    return x % y;
  }

  function inc(x) {
    return ++x;
  }

  function dec(x) {
    return --x;
  }

  function neg(x) {
    return -x;
  }

  // Bitwise operators
  function bitwiseAnd(x, y) {
    return x & y;
  }

  function bitwiseOr(x, y) {
    return x | y;
  }

  function bitwiseXor(x, y) {
    return x ^ y;
  }

  function bitwiseLeft(x, y) {
    return x << y;
  }

  function bitwiseRight(x, y) {
    return x >> y;
  }

  function bitwiseZ(x, y) {
    return x >>> y;
  }

  function bitwiseNot(x) {
    return ~x;
  }

  // Basic comparators
  function eq(x, y) {
    return x == y;
  }

  function seq(x, y) {
    return x === y;
  }

  // Not
  function not(x) {
    return !x;
  }

  // Relative comparators
  function gt(x, y) {
    return x > y;
  }

  function lt(x, y) {
    return x < y;
  }

  function gte(x, y) {
    return x >= y;
  }

  function lte(x, y) {
    return x <= y;
  }

  // Mixing in the operator functions
  // -----------------------------

  _.mixin({
    add: variadicMath(add),
    sub: variadicMath(sub),
    mul: variadicMath(mul),
    div: variadicMath(div),
    mod: mod,
    inc: inc,
    dec: dec,
    neg: neg,
    eq: variadicComparator(eq),
    seq: variadicComparator(seq),
    neq: invert(variadicComparator(eq)),
    sneq: invert(variadicComparator(seq)),
    not: not,
    gt: variadicComparator(gt),
    lt: variadicComparator(lt),
    gte: variadicComparator(gte),
    lte: variadicComparator(lte),
    bitwiseAnd: variadicMath(bitwiseAnd),
    bitwiseOr: variadicMath(bitwiseOr),
    bitwiseXor: variadicMath(bitwiseXor),
    bitwiseNot: bitwiseNot,
    bitwiseLeft: variadicMath(bitwiseLeft),
    bitwiseRight: variadicMath(bitwiseRight),
    bitwiseZ: variadicMath(bitwiseZ)
  });
})(this);
<commit_msg>util.operators: rename function variable - numbersToCompare -> itemsToCompare<commit_after>// Underscore-contrib (underscore.function.arity.js 0.3.0)
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors
// Underscore-contrib may be freely distributed under the MIT license.

(function(root) {

  // Baseline setup
  // --------------

  // Establish the root object, `window` in the browser, or `global` on the server.
  var _ = root._ || require('underscore');

  // Setup for variadic operators
  // ----------------------------

  // Turn a binary math operator into a variadic operator
  function variadicMath(operator) {
    return variaderize(function(numbersToOperateOn) {
      return _.reduce(numbersToOperateOn, operator);
    });
  }

  // Turn a binary comparator into a variadic comparator
  function variadicComparator(comparator) {
    return variaderize(function(itemsToCompare) {
      var result;

      for (var i = 0; i < itemsToCompare.length - 1; i++) {
        result = comparator(itemsToCompare[i], itemsToCompare[i + 1]);
        if (result === false) return result;
      }

      return result;
    });
  }

  // Converts a unary function that operates on an array into one that also works with a variable number of arguments
  function variaderize(func) {
    return function (args) {
      var allArgs = isArrayLike(args) ? args : arguments;
      return func(allArgs);
    };
  }

  function isArrayLike(obj) {
    return obj != null && typeof obj.length === "number";
  }

  // Turn a boolean-returning function into one with the opposite meaning
  function invert(fn) {
    return function() {
      return !fn.apply(this, arguments);
    };
  }

  // Basic math operators
  function add(x, y) {
    return x + y;
  }

  function sub(x, y) {
    return x - y;
  }

  function mul(x, y) {
    return x * y;
  }

  function div(x, y) {
    return x / y;
  }

  function mod(x, y) {
    return x % y;
  }

  function inc(x) {
    return ++x;
  }

  function dec(x) {
    return --x;
  }

  function neg(x) {
    return -x;
  }

  // Bitwise operators
  function bitwiseAnd(x, y) {
    return x & y;
  }

  function bitwiseOr(x, y) {
    return x | y;
  }

  function bitwiseXor(x, y) {
    return x ^ y;
  }

  function bitwiseLeft(x, y) {
    return x << y;
  }

  function bitwiseRight(x, y) {
    return x >> y;
  }

  function bitwiseZ(x, y) {
    return x >>> y;
  }

  function bitwiseNot(x) {
    return ~x;
  }

  // Basic comparators
  function eq(x, y) {
    return x == y;
  }

  function seq(x, y) {
    return x === y;
  }

  // Not
  function not(x) {
    return !x;
  }

  // Relative comparators
  function gt(x, y) {
    return x > y;
  }

  function lt(x, y) {
    return x < y;
  }

  function gte(x, y) {
    return x >= y;
  }

  function lte(x, y) {
    return x <= y;
  }

  // Mixing in the operator functions
  // -----------------------------

  _.mixin({
    add: variadicMath(add),
    sub: variadicMath(sub),
    mul: variadicMath(mul),
    div: variadicMath(div),
    mod: mod,
    inc: inc,
    dec: dec,
    neg: neg,
    eq: variadicComparator(eq),
    seq: variadicComparator(seq),
    neq: invert(variadicComparator(eq)),
    sneq: invert(variadicComparator(seq)),
    not: not,
    gt: variadicComparator(gt),
    lt: variadicComparator(lt),
    gte: variadicComparator(gte),
    lte: variadicComparator(lte),
    bitwiseAnd: variadicMath(bitwiseAnd),
    bitwiseOr: variadicMath(bitwiseOr),
    bitwiseXor: variadicMath(bitwiseXor),
    bitwiseNot: bitwiseNot,
    bitwiseLeft: variadicMath(bitwiseLeft),
    bitwiseRight: variadicMath(bitwiseRight),
    bitwiseZ: variadicMath(bitwiseZ)
  });
})(this);
<|endoftext|>