Commit 7f622acd authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Commit Bot

Add test to check Metadata operations calls

Add test for the following use cases:
1. Navigate to a Downloads sub-sub-folder using directory tree.
2. Navigate to a Drive sub-sub-folder using directory tree.
3. Navigate to a Drive sub-folder with 50 files and 50 siblings
folders, using directory tree.
4. Navigate to Team Drives root using directory tree.

Add MetadataStats class to hold metadata operation counters. Change
MetadataModel to count operations only during tests using a global
instance of MetadataStats.

Add getMetadataStats test util function to return the MetadataStats
global value to test extension.

Add waitFor remote test function to wait for any remote test function
to return an expected result.

Bug: 880187
Change-Id: I024938cfe09c2599968100b978a071675072b2d8
Reviewed-on: https://chromium-review.googlesource.com/1188046
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593477}
parent 91027331
......@@ -619,6 +619,14 @@ WRAPPED_INSTANTIATE_TEST_CASE_P(
TestCase("recentsDownloadsAndDriveWithOverlap"),
TestCase("recentsDownloadsAndDriveWithOverlap").EnableDriveFs()));
WRAPPED_INSTANTIATE_TEST_CASE_P(
Metadata, /* metadata.js */
FilesAppBrowserTest,
::testing::Values(TestCase("metadataDownloads"),
TestCase("metadataDrive"),
TestCase("metadataTeamDrives"),
TestCase("metadataLargeDrive")));
// Structure to describe an account info.
struct TestAccountInfo {
const char* const gaia_id;
......
......@@ -663,3 +663,15 @@ test.util.registerRemoteTestUtils = function() {
}
});
};
/**
* Returns the MetadataStats collected in MetadataModel, it will be serialized
* as a plain object when sending to test extension.
*
* @suppress {missingProperties} metadataStats is only defined for foreground
* Window so it isn't visible in the background. Here it will return as JSON
* object to test extension.
*/
test.util.sync.getMetadataStats = function(contentWindow) {
return contentWindow.fileManager.metadataModel.getStats();
};
......@@ -2,6 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Stats collected about Metadata handling for tests.
* @struct
*/
class MetadataStats {
constructor() {
/** @public {number} Total of entries fulfilled from cache. */
this.fromCache = 0;
/** @public {number} Total of entries that requested to backends. */
this.fullFetch = 0;
/** @public {number} Total of entries that called to invalidate. */
this.invalidateCount = 0;
/** @public {number} Total of entries that called to clear. */
this.clearCacheCount = 0;
/** @public {number} Total of calls to function clearAllCache. */
this.clearAllCount = 0;
}
}
/**
* @param {!MetadataProvider} rawProvider
* @constructor
......@@ -25,6 +48,11 @@ function MetadataModel(rawProvider) {
* @const
*/
this.callbackRequests_ = [];
/** @private {?MetadataStats} record stats about Metadata when in tests. */
this.stats_ = null;
if (window.IN_TEST)
this.stats_ = new MetadataStats();
}
/**
......@@ -57,8 +85,14 @@ MetadataModel.prototype.get = function(entries, names) {
this.rawProvider_.checkPropertyNames(names);
// Check if the results are cached or not.
if (this.cache_.hasFreshCache(entries, names))
if (this.cache_.hasFreshCache(entries, names)) {
if (window.IN_TEST)
this.stats_.fromCache += entries.length;
return Promise.resolve(this.getCache(entries, names));
}
if (window.IN_TEST)
this.stats_.fullFetch += entries.length;
// The LRU cache may be cached out when the callback is completed.
// To hold cached values, create snapshot of the cache for entries.
......@@ -127,6 +161,8 @@ MetadataModel.prototype.getCache = function(entries, names) {
*/
MetadataModel.prototype.notifyEntriesCreated = function(entries) {
this.cache_.clear(util.entriesToURLs(entries));
if (window.IN_TEST)
this.stats_.clearCacheCount += entries.length;
};
/**
......@@ -136,6 +172,8 @@ MetadataModel.prototype.notifyEntriesCreated = function(entries) {
*/
MetadataModel.prototype.notifyEntriesRemoved = function(urls) {
this.cache_.clear(urls);
if (window.IN_TEST)
this.stats_.clearCacheCount += urls.length;
};
/**
......@@ -144,6 +182,8 @@ MetadataModel.prototype.notifyEntriesRemoved = function(urls) {
*/
MetadataModel.prototype.notifyEntriesChanged = function(entries) {
this.cache_.invalidate(this.cache_.generateRequestId(), entries);
if (window.IN_TEST)
this.stats_.invalidateCount += entries.length;
};
/**
......@@ -151,6 +191,13 @@ MetadataModel.prototype.notifyEntriesChanged = function(entries) {
*/
MetadataModel.prototype.clearAllCache = function() {
this.cache_.clearAll();
if (window.IN_TEST)
this.stats_.clearAllCount++;
};
/** @return {MetadataStats} */
MetadataModel.prototype.getStats = function() {
return this.stats_;
};
/**
......
This diff is collapsed.
......@@ -30,6 +30,7 @@
"file_manager/install_linux_package_dialog.js",
"file_manager/keyboard_operations.js",
"file_manager/launcher_search.js",
"file_manager/metadata.js",
"file_manager/my_files.js",
"file_manager/open_audio_files.js",
"file_manager/open_image_files.js",
......
......@@ -204,6 +204,38 @@ RemoteCall.prototype.waitForElementStyles = function(
});
};
/**
* Waits for a remote test function to return a specific result.
*
* @param {string} funcName Name of remote test function to be executed.
* @param {string} windowId Target window ID.
* @param {function(Object): boolean|Object} expectedResult An value to be
* checked against the return value of |funcName| or a callabck that
* receives the return value of |funcName| and returns true if the result
* is the expected value.
* @param {?Array<*>} args Arguments to be provided to |funcName| when executing
* it.
* @return {Promise} Promise to be fulfilled when the |expectedResult| is
* returned from |funcName| execution.
*/
RemoteCall.prototype.waitFor = function(
funcName, windowId, expectedResult, args) {
const caller = getCaller();
args = args || [];
return repeatUntil(() => {
return this.callRemoteTestUtil(funcName, windowId, args).then((result) => {
if (typeof expectedResult === 'function' && expectedResult(result))
return result;
if (expectedResult === result)
return result;
const msg = 'waitFor: Waiting for ' +
`${funcName} to return ${expectedResult}, ` +
`but got ${JSON.stringify(result)}.`;
return pending(caller, msg);
});
});
};
/**
* Waits for the specified element leaving from the DOM.
* @param {string} windowId Target window ID.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment