From c7c74c4ff7c680cb5b5cddd2489656c07cbc30cc Mon Sep 17 00:00:00 2001
From: William Grzybowski <wg@FreeBSD.org>
Date: Fri, 11 Jul 2014 09:14:57 -0300
Subject: [PATCH] Add a Performance Test button

Ticket:	#5466
(cherry picked from commit ff7497b4b1a3df559ea28ba72074838898235676)
---
 gui/system/urls.py                      |   3 +
 gui/system/views.py                     | 101 ++++++++++++++++++++++++
 gui/templates/system/advanced_edit.html |   6 ++
 gui/templates/system/perftest.html      |  33 ++++++++
 4 files changed, 143 insertions(+)
 create mode 100644 gui/templates/system/perftest.html

diff --git a/gui/system/urls.py b/gui/system/urls.py
index cad89e8f3d..bb97f82ed0 100644
--- a/gui/system/urls.py
+++ b/gui/system/urls.py
@@ -53,6 +53,9 @@ urlpatterns = patterns('freenasUI.system.views',
     url(r'^clear-cache/$', 'clearcache', name="system_clearcache"),
     url(r'^lsdir/(?P<path>.*)$', 'directory_browser', name="system_dirbrowser"),
     url(r'^lsfiles/(?P<path>.*)$', 'file_browser', name="system_filebrowser"),
+    url(r'^perftest/$', 'perftest', name='system_perftest'),
+    url(r'^perftest/download/$', 'perftest_download', name='system_perftest_download'),
+    url(r'^perftest/progress/$', 'perftest_progress', name='system_perftest_progress'),
     url(r'^restart-httpd/$', 'restart_httpd', name="system_restart_httpd"),
     url(r'^reload-httpd/$', 'reload_httpd', name="system_reload_httpd"),
     url(r'^terminal/$', 'terminal', name="system_terminal"),
diff --git a/gui/system/views.py b/gui/system/views.py
index 091810a108..6dd606c91b 100644
--- a/gui/system/views.py
+++ b/gui/system/views.py
@@ -53,6 +53,7 @@ from freenasUI.common.system import get_sw_name, get_sw_version, send_mail
 from freenasUI.common.pipesubr import pipeopen
 from freenasUI.freeadmin.apppool import appPool
 from freenasUI.freeadmin.views import JsonResp
+from freenasUI.middleware.exceptions import MiddlewareError
 from freenasUI.middleware.notifier import notifier
 from freenasUI.network.models import GlobalConfiguration
 from freenasUI.storage.models import MountPoint
@@ -63,6 +64,7 @@ VERSION_FILE = '/etc/version'
 PGFILE = '/tmp/.extract_progress'
 DDFILE = '/tmp/.upgrade_dd'
 RE_DD = re.compile(r"^(\d+) bytes", re.M | re.S)
+PERFTEST_SIZE = 40 * 1024 * 1024 * 1024  # 40 GiB
 
 log = logging.getLogger('system.views')
 
@@ -523,6 +525,105 @@ def firmware_progress(request):
     return HttpResponse(content, content_type='application/json')
 
 
+def perftest(request):
+
+    systemdataset, volume, basename = notifier().system_dataset_settings()
+
+    if request.method == 'GET':
+        return render(request, 'system/perftest.html')
+
+    if not basename:
+        raise MiddlewareError(
+            _('System dataset is required to perform this action.')
+        )
+
+    dump = '/mnt/%s/perftest.txz' % basename
+    perftestdataset = '%s/perftest' % basename
+
+    with mntlock(mntpt='/mnt/%s' % basename):
+
+        _n = notifier()
+
+        rv, errmsg = _n.create_zfs_dataset(
+            path=perftestdataset,
+            props={
+                'primarycache': 'metadata',
+                'secondarycache': 'metadata',
+                'compression': 'off',
+            },
+            _restart_collectd=False,
+        )
+
+        currdir = os.getcwd()
+        os.chdir('/mnt/%s' % perftestdataset)
+        with open('/mnt/%s/iozone.txt' % perftestdataset, 'w') as f:
+            p1 = subprocess.Popen(
+                '/usr/local/bin/iozone -r 128 -s %sk -i 0 -i 1' % (
+                    PERFTEST_SIZE / 1024,
+                ),
+                stdout=f,
+                stderr=subprocess.STDOUT,
+                shell=True,
+            )
+            p1.communicate()
+
+        os.chdir('..')
+        p1 = pipeopen('tar -cJf %s perftest' % dump)
+        p1.communicate()
+
+        os.chdir(currdir)
+
+        _n.destroy_zfs_dataset(perftestdataset)
+
+        return JsonResp(
+            request,
+            message='Performance test has completed.',
+            events=[
+                'window.location=\'%s\'' % reverse('system_perftest_download'),
+            ],
+        )
+
+
+def perftest_download(request):
+
+    systemdataset, volume, basename = notifier().system_dataset_settings()
+    dump = '/mnt/%s/perftest.txz' % basename
+
+    wrapper = FileWrapper(file(dump))
+    response = StreamingHttpResponse(
+        wrapper,
+        content_type='application/octet-stream',
+    )
+    response['Content-Length'] = os.path.getsize(dump)
+    response['Content-Disposition'] = \
+        'attachment; filename=perftest-%s-%s.tgz' % (
+            socket.gethostname(),
+            time.strftime('%Y%m%d%H%M%S'))
+
+    return response
+
+
+def perftest_progress(request):
+    systemdataset, volume, basename = notifier().system_dataset_settings()
+    iozonefile = '/mnt/%s/perftest/iozone.tmp' % basename
+    percent = 0
+    step = 1
+    indeterminate = False
+    if os.path.exists(iozonefile):
+        size = os.stat(iozonefile).st_size
+        percent = int((float(size) / PERFTEST_SIZE) * 100.0)
+        if percent == 100:
+            step = 2
+            percent = 0
+            indeterminate = True
+    content = json.dumps({
+        'step': step,
+        'percent': percent,
+        'indeterminate': indeterminate,
+    })
+    return HttpResponse(content, content_type='application/json')
+
+
 def restart_httpd(request):
     """ restart httpd """
     notifier().restart("http")
diff --git a/gui/templates/system/advanced_edit.html b/gui/templates/system/advanced_edit.html
index 5000361202..a2fc7597f4 100644
--- a/gui/templates/system/advanced_edit.html
+++ b/gui/templates/system/advanced_edit.html
@@ -14,6 +14,12 @@
                     window.location='{% url "system_debug" %}';
                 </script>
             </button>
+            <button id="btn_{% cls_name form %}_PerfTest" data-dojo-type="dijit.form.Button" type="button">
+                {% trans "Performance Test" %}
+                <script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+                    editScaryObject('{% trans "Performance Test"|escapejs %}', '{% url "system_perftest" %}');
+                </script>
+            </button>
             <button id="btn_{% cls_name form %}_FwUpdate" data-dojo-type="dijit.form.Button" type="button">
                 {% trans "Firmware Update" %}
                 <script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
diff --git a/gui/templates/system/perftest.html b/gui/templates/system/perftest.html
new file mode 100644
index 0000000000..1c7de538b8
--- /dev/null
+++ b/gui/templates/system/perftest.html
@@ -0,0 +1,33 @@
+{% extends "freeadmin/generic_form.html" %}
+{% block onSubmit %}
+console.log("here");
+doSubmit({
+    form: this,
+    event: e,
+    url: '{{ request.path }}',
+    progressbar: {
+      steps: [
+         {"label": gettext("Writing file")},
+	 {"label": gettext("Reading file")}
+      ],
+      poolUrl: '{% url "system_perftest_progress" %}',
+      fileUpload: false
+    }
+});
+{% endblock %}
+{% block form %}
+<p>{% trans "You are about to start a performance test." %}
+<br />
+{% trans "Are you sure you want to proceed?" %}</p>
+{% endblock %}
+{% block buttons %}
+<button id="btn_PerfTest_Ok" data-dojo-type="dijit.form.Button" type="submit">
+    {% trans "Yes" %}
+</button>
+<button id="btn_PerfTest_Cancel" data-dojo-type="dijit.form.Button" type="button">
+    <script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+    cancelDialog(this);
+    </script>
+    {% trans "No" %}
+</button>
+{% endblock %}
-- 
GitLab