[gnome-continuous] Add "memusage" task
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-continuous] Add "memusage" task
- Date: Sun, 8 Dec 2013 22:11:12 +0000 (UTC)
commit 50a63f9755f6b5bfb859e4b24bf1ac3538669472
Author: Colin Walters <walters verbum org>
Date: Sun Dec 8 17:08:45 2013 -0500
Add "memusage" task
This just runs massif on gnome-shell right now.
To support this though, we need to also generate -devel-debug disk
images, since that tree contains valgrind. testbase.js defaults to
using the -runtime disk.
Makefile-ostbuild.am | 1 +
src/js/tasks/task-builddisks.js | 2 +-
src/js/tasks/task-integrationtest.js | 2 +-
src/js/tasks/task-memusage.js | 101 ++++++++++++++++++++++++++++++++++
src/js/tasks/testbase.js | 53 +++++++++++++++---
5 files changed, 149 insertions(+), 10 deletions(-)
---
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index 2ee96e2..b46ce63 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -96,6 +96,7 @@ jsosttasks_DATA= \
src/js/tasks/task-builddisks.js \
src/js/tasks/task-smoketest.js \
src/js/tasks/task-integrationtest.js \
+ src/js/tasks/task-memusage.js \
src/js/tasks/task-applicationstest.js \
src/js/tasks/task-zdisks.js \
src/js/tasks/testbase.js \
diff --git a/src/js/tasks/task-builddisks.js b/src/js/tasks/task-builddisks.js
index cd6503a..94c4b0b 100644
--- a/src/js/tasks/task-builddisks.js
+++ b/src/js/tasks/task-builddisks.js
@@ -46,7 +46,7 @@ const TaskBuildDisks = new Lang.Class({
_imageSubdir: 'images',
_inheritPreviousDisk: true,
- _onlyTreeSuffixes: ['-runtime'],
+ _onlyTreeSuffixes: ['-runtime', '-devel-debug'],
execute: function(cancellable) {
let isLocal = this._buildName == 'local';
diff --git a/src/js/tasks/task-integrationtest.js b/src/js/tasks/task-integrationtest.js
index 06649a7..db10b7d 100644
--- a/src/js/tasks/task-integrationtest.js
+++ b/src/js/tasks/task-integrationtest.js
@@ -78,7 +78,7 @@ const TaskIntegrationTest = new Lang.Class({
print(msg);
},
- _postQemu: function(cancellable) {
+ _postQemu: function(mntdir, cancellable) {
let testsJson = Gio.File.new_for_path('installed-test-results.json');
JSONUtil.writeJsonFileAtomic(testsJson, this._allTests, null);
diff --git a/src/js/tasks/task-memusage.js b/src/js/tasks/task-memusage.js
new file mode 100644
index 0000000..0d9cc0c
--- /dev/null
+++ b/src/js/tasks/task-memusage.js
@@ -0,0 +1,101 @@
+// -*- indent-tabs-mode: nil; tab-width: 2; -*-
+// Copyright (C) 2013 Colin Walters <walters verbum org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+const GLib = imports.gi.GLib;
+const OSTree = imports.gi.OSTree;
+const Gio = imports.gi.Gio;
+const Lang = imports.lang;
+const Format = imports.format;
+
+const GSystem = imports.gi.GSystem;
+
+const Builtin = imports.builtin;
+const ArgParse = imports.argparse;
+const ProcUtil = imports.procutil;
+const Task = imports.task;
+const TestBase = imports.tasks.testbase;
+const LibQA = imports.libqa;
+const JSUtil = imports.jsutil;
+const JSONUtil = imports.jsonutil;
+const FileUtil = imports.fileutil;
+
+const TaskMemusage = new Lang.Class({
+ Name: 'TaskMemusage',
+ Extends: TestBase.TestBase,
+
+ TaskDef: {
+ TaskName: "memusage",
+ TaskAfter: ['smoketest'],
+ },
+
+ TestTrees: ['-devel-debug'],
+ CompleteIdleWaitSeconds: 60,
+
+ RequiredMessageIDs: ["0ce153587afa4095832d233c17a88001" // gnome-session ok
+ ],
+
+ FailedMessageIDs: [],
+
+ _postQemu: function(mntdir, cancellable) {
+ let osname = this._buildData['snapshot']['osname'];
+ let varTmpDir = mntdir.resolve_relative_path('ostree/deploy/' + osname + '/var/tmp');
+ let copied = [];
+ print("Examining " + varTmpDir.get_path());
+ FileUtil.walkDir(varTmpDir, { nameRegex: /massif-gnome-shell.*/,
+ depth: 1 },
+ function (path, cancellable) {
+ let dest = Gio.File.new_for_path(path.get_basename());
+ print("Copying " + dest.get_path());
+ path.copy(dest, Gio.FileCopyFlags.OVERWRITE, cancellable, null, null);
+ copied.push(dest);
+ }, cancellable);
+ print("Copied " + copied.length + " massif data files");
+ for (let i = 0; i < copied.length; i++) {
+ let path = copied[i].get_path();
+ let context = new GSystem.SubprocessContext({ argv: ['ms_print', path ] });
+ context.set_stdout_file_path(path + '.txt');
+ let proc = new GSystem.Subprocess({ context: context });
+ proc.init(cancellable);
+ proc.wait_sync_check(cancellable);
+ }
+ },
+
+ _prepareDisk: function(mntdir, arch, cancellable) {
+ let osname = this._buildData['snapshot']['osname'];
+ let [deployDir, deployEtcDir] = LibQA.getDeployDirs(mntdir, osname);
+ let shellPath = deployDir.resolve_relative_path('usr/bin/gnome-shell');
+ let shellDotRealPath = deployDir.resolve_relative_path('usr/bin/gnome-shell.real');
+ GSystem.file_rename(shellPath, shellDotRealPath, cancellable);
+ let massifWrapper = '#!/bin/sh\ntouch /var/tmp/massif-started;exec valgrind --tool=massif
--smc-check=all --massif-out-file=/var/tmp/massif-gnome-shell.$$ /usr/bin/gnome-shell.real\n';
+ shellPath.replace_contents(massifWrapper, null, false,
+ Gio.FileCreateFlags.REPLACE_DESTINATION,
+ cancellable);
+ GSystem.file_chmod(shellPath, 493, cancellable);
+ print("Replaced " + shellPath.get_path() + " with massif wrapper");
+ let desktopFile = '[Desktop Entry]\n\
+Encoding=UTF-8\n\
+Name=Timed logout\n\
+Exec=/usr/bin/sh -c \'sleep 30; touch /var/tmp/timed-logout.done; killall gnome-session\'\n\
+Terminal=false\n\
+Type=Application\n';
+ let dest = deployEtcDir.resolve_relative_path('xdg/autostart/gnome-continuous-timed-logout.desktop');
+ GSystem.file_ensure_directory(dest.get_parent(), true, cancellable);
+ dest.replace_contents(desktopFile, null, false, Gio.FileCreateFlags.REPLACE_DESTINATION,
+ cancellable);
+ }
+});
diff --git a/src/js/tasks/testbase.js b/src/js/tasks/testbase.js
index 2b86859..67ef22e 100644
--- a/src/js/tasks/testbase.js
+++ b/src/js/tasks/testbase.js
@@ -33,7 +33,6 @@ const JSUtil = imports.jsutil;
const JSONUtil = imports.jsonutil;
const TIMEOUT_SECONDS = 10 * 60;
-const COMPLETE_IDLE_WAIT_SECONDS = 10;
const CommandSocketIface = '<node> \
<interface name="org.gnome.Continuous.Command"> \
@@ -162,10 +161,10 @@ const TestOneDisk = new Lang.Class({
this._parentTask._handleMessage(data, this._cancellable);
}
if (this._countPendingRequiredMessageIds == 0 && !this._foundAllMessageIds) {
- print("Found all required message IDs");
+ print("Found all required message IDs, waiting for " +
this._parentTask.CompleteIdleWaitSeconds);
this._foundAllMessageIds = true;
this._parentTask._onSuccess();
- GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, COMPLETE_IDLE_WAIT_SECONDS,
+ GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, this._parentTask.CompleteIdleWaitSeconds,
Lang.bind(this, this._onFinalWait));
} else {
this._readingJournal = true;
@@ -224,6 +223,12 @@ const TestOneDisk = new Lang.Class({
_onQemuCommandComplete: function(datain, result) {
let [response, len] = datain.read_line_finish_utf8(result);
+ let responseData = null;
+ try {
+ responseData = JSON.parse(response);
+ } catch (e) {}
+ if (responseData && responseData.error)
+ print("command response error=" + JSON.stringify(responseData.error));
let onComplete = this._qmpCommandOutstanding.shift();
if (this._qmpCommandOutstanding.length == 1)
this._qmpIn.read_line_async(GLib.PRIORITY_DEFAULT, this._cancellable,
@@ -293,10 +298,20 @@ const TestOneDisk = new Lang.Class({
if (isFinal) {
print("Final screenshot complete");
- this._loop.quit();
+ this._qmpCommand({"execute": "system_powerdown"},
+ Lang.bind(this, this._onFinalPoweroff));
}
},
+ _onFinalPoweroff: function() {
+ print("Poweroff request sent");
+ GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5,
+ Lang.bind(this, function() {
+ print("Poweroff timeout ");
+ this._loop.quit();
+ }));
+ },
+
_screenshot: function(params) {
params = Params.parse(params, { isFinal: false,
name: null });
@@ -328,7 +343,7 @@ const TestOneDisk = new Lang.Class({
},
_onFinalWait: function() {
- print("Final wait complete");
+ print("Final wait complete at " + GLib.DateTime.new_now_local().format('%c'));
this._screenshot({ isFinal: true });
},
@@ -498,9 +513,14 @@ const TestOneDisk = new Lang.Class({
GLib.source_remove(timeoutId);
- GSystem.shutil_rm_rf(diskClone, cancellable);
+ let [gfmnt, mntdir] = LibQA.newReadWriteMount(diskClone, cancellable);
+ try {
+ this._parentTask._postQemu(mntdir, cancellable);
+ } finally {
+ gfmnt.umount(cancellable);
+ }
- this._parentTask._postQemu(cancellable);
+ //GSystem.shutil_rm_rf(diskClone, cancellable);
if (this._failed) {
throw new Error(this._failedMessage);
@@ -519,6 +539,9 @@ const TestBase = new Lang.Class({
TaskAfter: ['builddisks'],
},
+ TestTrees: ['-runtime'],
+ CompleteIdleWaitSeconds: 10,
+
BaseRequiredMessageIDs: ["39f53479d3a045ac8e11786248231fbf", // graphical.target
"f77379a8490b408bbe5f6940505a777b", // systemd-journald
],
@@ -548,7 +571,7 @@ const TestBase = new Lang.Class({
_onSuccess: function() {
},
- _postQemu: function(cancellable) {
+ _postQemu: function(mntdir, cancellable) {
},
_screenshotTaken: function(path) {
@@ -572,9 +595,23 @@ const TestBase = new Lang.Class({
}
if (!JSUtil.stringEndswith(name, '.qcow2'))
continue;
+ let matches = false;
+ for (let i = 0; i < this.TestTrees.length; i++) {
+ let tree = this.TestTrees[i];
+ if (JSUtil.stringEndswith(name, tree + '.qcow2')) {
+ matches = true;
+ break;
+ }
+ }
+ if (!matches) {
+ print("Skipping disk " + name + " not in " + JSON.stringify(this.TestTrees));
+ continue;
+ }
disksToTest.push(name);
}
e.close(null);
+ if (disksToTest.length == 0)
+ throw new Error("Didn't find any matching .qcow2 disks in " + currentImages.get_path());
this._buildData = null;
if (buildJson != null)
this._buildData = JSONUtil.loadJson(buildJson, cancellable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]