Skip to content

Commit

Permalink
[POC] Trigger os-autoinst-distri-example tests from fresh openQA
Browse files Browse the repository at this point in the history
With this PR a logged in user can trigger a job via a form, providing
settings, git repo and a scenarion definition. User doesnt need to have
special role. Keep in mind that NEEDLES_DIR doesnt need for
os-autoinst-distri-example.
Things which stayed out of this PR are:
- The UI design
- Posibility to upload the yaml definition
- Some way to return data to the webUI, like the job id
- Input validation
- Additional error handling (maybe)

https://progress.opensuse.org/issues/162899

Signed-off-by: ybonatakis <[email protected]>
  • Loading branch information
b10n1k committed Sep 11, 2024
1 parent 679c533 commit 2032ec7
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 97 deletions.
3 changes: 3 additions & 0 deletions assets/assetpack.def
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@
! ws_console.js
< javascripts/ws_console.js

! run_example.js
< javascripts/run_example.js

! logo-16.png
< images/logo-16.png

Expand Down
29 changes: 29 additions & 0 deletions assets/javascripts/run_example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function runExample(form) {
let data = $(form).serialize();
console.log('Ser data ' + data + '<<');
let postUrl = form.dataset.postUrl;
$.ajax({
url: postUrl,
method: 'POST',
data: data,
success: function (response) {
console.log(response.ids);
for (newjobid in response.ids) {
console.log('id ' + response.ids[newjobid]);
alert('job runs on localhost/tests/' + response.ids[newjobid]);
}
//fetchHtmlEntry(rowUrl + response.id, targetElement);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(ajaxOptions);
console.log(xhr);

if (xhr.responseJSON.error) {
console.log(xhr.responseJSON.error);
} else {
console.log(thrownError);
}
}
});
event.preventDefault();
}
4 changes: 4 additions & 0 deletions assets/stylesheets/forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,7 @@
background-color: $default-bg-color-dark;
}
}

label.form-label {
font-weight: bold;
}
3 changes: 3 additions & 0 deletions lib/OpenQA/WebAPI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ sub startup ($self) {
$r->get('/search')->name('search')->to(template => 'search/search');

$r->get('/tests')->name('tests')->to('test#list');

$r->get('/run_test_case')->name('run_test_case')->to('NewJob#create');

# we have to set this and some later routes up differently on Mojo
# < 9 and Mojo >= 9.11
if ($Mojolicious::VERSION > 9.10) {
Expand Down
3 changes: 2 additions & 1 deletion lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ created, their job ids and the information for jobs that could not be scheduled.

sub create {
my ($self) = @_;

my $params = $self->req->params->to_hash;
use Data::Dumper;
print(">>>>>> " . Dumper($params) . " <<<<<<<<<<n");

Check warning on line 104 in lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm

View workflow job for this annotation

GitHub Actions / Perlcritic

Useless interpolation of literal string - severity 3

[ValuesAndExpressions::ProhibitInterpolationOfLiterals] See page 51 of PBP

Check warning on line 104 in lib/OpenQA/WebAPI/Controller/API/V1/Iso.pm

View workflow job for this annotation

GitHub Actions / Perlcritic

Useless interpolation of literal string - severity 3

[ValuesAndExpressions::ProhibitInterpolationOfLiterals] See page 51 of PBP
my $async = delete $params->{async}; # whether to run the operation as a Minion job
my $scheduled_product_clone_id
= delete $params->{scheduled_product_clone_id}; # ID of a previous product to clone settings from
Expand Down
25 changes: 1 addition & 24 deletions lib/OpenQA/WebAPI/Controller/NewJob.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,9 @@
package OpenQA::WebAPI::Controller::NewJob;
use Mojo::Base 'Mojolicious::Controller', -signatures;

#use Cwd 'realpath';
#use Encode 'decode_utf8';
#use Mojo::File 'path';
#use Mojo::URL;
#use Mojo::Util 'decode';
# use OpenQA::Utils qw(ensure_timestamp_appended find_bug_number locate_needle needledir testcasedir);
# use OpenQA::Jobs::Constants;
# use File::Basename;
# use File::Which 'which';
# use POSIX 'strftime';
# use Mojo::JSON 'decode_json';

sub create ($self) {
#my $self = shift;
warn "route called";

Check warning on line 8 in lib/OpenQA/WebAPI/Controller/NewJob.pm

View workflow job for this annotation

GitHub Actions / Perlcritic

Useless interpolation of literal string - severity 3

[ValuesAndExpressions::ProhibitInterpolationOfLiterals] See page 51 of PBP
#$self->stash(msg => "Trigger job");
$self->render(template => "NewJob/create", msg => "Trigger job");
# openqa-cli schedule \
# --monitor \
# --host "${OPENQA_HOST:-https://openqa.opensuse.org}/" \
# --apikey "$OPENQA_API_KEY" --apisecret "$OPENQA_API_SECRET" \
# --param-file SCENARIO_DEFINITIONS_YAML=scenario-definitions.yaml \
# DISTRI=example VERSION=0 FLAVOR=DVD ARCH=x86_64 TEST=simple_boot \
# BUILD="$GH_REPO.git#$GH_REF" _GROUP_ID="0" \
# CASEDIR="$GITHUB_SERVER_URL/$GH_REPO.git#$GH_REF" \
# NEEDLES_DIR="%%CASEDIR%%/needles"
$self->render(template => "NewJob/create");

Check warning on line 9 in lib/OpenQA/WebAPI/Controller/NewJob.pm

View workflow job for this annotation

GitHub Actions / Perlcritic

Useless interpolation of literal string - severity 3

[ValuesAndExpressions::ProhibitInterpolationOfLiterals] See page 51 of PBP
}


Expand Down
136 changes: 66 additions & 70 deletions templates/webapi/NewJob/create.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,75 @@
%= asset 'ace.css'
% end

% title 'New job';
% title 'Run a Job';

<div>
<h2><%= title %></h2>

%= include 'layouts/info'

<form class="row g-3" id="form">
<p><b>Hint:</b> Experimental form to trigger a test E.g. see <%= link_to 'this
link' => url_for('not_found') %>.
</p>
<div class="container-md">
<form class="row g-3" onsubmit="runExample(this);" data-post-url="/api/v1/isos">
<div class="col-md-6">
<label for="distri" class="form-label">Distri</label>
<label for="distri" class="form-label">
<strong>Distri</strong></label>
<input type="text" class="form-control" id="distri"
placeholder="example" name="distri">
placeholder="example" value="example" name="DISTRI">
</div>
<div class="col-md-6">
<label for="version" class="form-label">Version</label>
<input type="text" class="form-control" id="version" placeholder="0" name="version">
<label for="version" class="form-label">
<strong>Version</strong></label>
<input type="text" class="form-control" id="version" placeholder="0" value="0" name="VERSION">
</div>
<div class="col-6">
<label for="flavor" class="form-label">Flavor</label>
<input type="text" class="form-control" id="flavor" placeholder="DVD" name="Flavor">
<label for="flavor" class="form-label">
<strong>Flavor</strong></label>
<input type="text" class="form-control" id="flavor" placeholder="DVD" value="DVD" name="FLAVOR">
</div>
<div class="col-12">
<label for="arch" class="form-label">Arch</label>
<select id="arch" class="form-select" name="arch">
<option selected>Choose...</option>
<option>x86_64</option>
<div class="col-6">
<label for="arch" class="form-label">
<strong>Arch</strong></label>
<select id="arch" class="form-select" name="ARCH">
<option></option>
<option selected>x86_64</option>
<option>arch64</option>
</select>
</div>
<div class="col-md-6">
<label for="test" class="form-label">Test Name</label>
<input type="text" class="form-control" id="test" placeholder="simple_boot" name="TEST">
<label for="test" class="form-label">
<strong>Test Name</strong></label>
<input type="text" class="form-control" id="test"
placeholder="simple_boot" value="simple_boot" name="TEST">
</div>
<div class="col-md-6">
<label for="build" class="form-label">Build</label>
<input type="text" class="form-control" id="build" name="BUILD">
<label for="build" class="form-label">
<strong>Build</strong></label>
<input type="text" class="form-control" id="build" value="openqa" name="BUILD">
</div>
<div class="col-md-6">
<label for="casedir" class="form-label">CASEDIR</label>
<div class="col-md-12">
<label for="casedir" class="form-label">
<strong>CASEDIR</strong></label>
<input type="text" class="form-control" id="casedir"
placeholder="https://github.com/os-autoinst/os-autoinst-distri-example.git"
value="https://github.com/os-autoinst/os-autoinst-distri-example.git"
name="casedir" name="CASEDIR">
</div>
<div class="col-md-6">
<label for="needles_dir" class="form-label">NEEDLES_DIR=</label>
<input type="text" class="form-control" id="needles_dir" placeholder="%%CASEDIR%%/needles" name="NEEDLES_DIR">
<div class="col-md-12">
<label for="needles_dir" class="form-label">
<strong>NEEDLES_DIR</strong></label>
<input type="text" class="form-control" id="needles_dir"
placeholder="https://github.com/os-autoinst/os-autoinst-distri-example/tree/main/needles"
name="NEEDLES_DIR">
</div>

<div class="md-12">
<label for="scenario_definition" class="form-label col-sm-2 control-label">scenario definition</label>
<label for="scenario_definition" class="form-label col-sm-2
control-label">
</strong>Scenario Definition</strong></label>
<textarea type="text" class="form-control" id="scenario_definition"
rows="15">
rows="15" name="SCENARIO_DEFINITIONS_YAML">
---
products:
example:
Expand All @@ -73,54 +91,32 @@ job_templates:
</div>

<div class="col-12">
<button type="submit" class="btn btn-light">
<button type="submit" class="btn btn-light" data-bs-toggle="modal" data-bs-target="#exampleModal">
<span><span class="glyphicon glyphicon-th-list"
aria-hidden="true"></span> Trigger os-autoinst-distri-example test</span>
aria-hidden="true"></span><strong> Trigger os-autoinst-distri-example test</strong></span>
</button>
</div>

</form>
<!-- %= include 'admin/group/group_property_editor', group => $group, --
-- is_parent => 1 -->
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">New Openqa Job</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>New job runs on localhost/tests/" + response.ids[newjobid])</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Go to job</button>
</div>
</div>
</div>
</div>
%= asset 'run_example.js'

<p><b>Hint:</b> Calling any non-existent route from your browser will show an
error page with all available routes as help. E.g. try <%= link_to 'this
link' => url_for('not_found') %>.
</p>
</div>

<script type="text/javascript">

const form = document.querySelector('form');

console.log("log: " + form);
form.addEventListener('submit', (e) => {
e.preventDefault();
const fs = require('fs')
var textToWrite = document.getElementById('textarea').innerHTML;
//var textFileAsBlob = new Blob([ textToWrite ], { type: 'text/plain' });
var fileNameToSaveAs = "scenario-definitions.yaml";
fs.writeFile(fileNameToSaveAs, textToWrite, (err) => {
// In case of a error throw err.
if (err) throw err;
})

const formData = new FormData(form);
const fdata = Object.fromEntries(formData);
const payload = JSON.stringify(fdata);
console.log(payload);
//formData.append('SCENARIO_DEFINITIONS_YAML', fileNameToSaveAs);
for (item of formData) {
console.log(item);
}
fetch("http://localhost/api/v1/isos", {
method: 'POST',
body: payload,
headers: {
'Content-Type': 'application/json',
}
})
.then(res => res.json())
.then(res => console.log(res));
})
</script>
4 changes: 2 additions & 2 deletions templates/webapi/layouts/navbar.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
% }
</ul>
</li>
<li class='nav-item' id="new_tests">
%= link_to 'Start New Test' => url_for('new_test_case') => class =>'nav-link', title => 'Run a new Test Case'
<li class='nav-item' id="run_test">
%= link_to 'Run an Example' => url_for('run_test_case') => class =>'nav-link', title => 'Run a Test Case'
</li>
</ul>
<ul class="navbar-nav ms-auto">
Expand Down

0 comments on commit 2032ec7

Please sign in to comment.