Browse Source

Added full unit test for reference CppCMS session handling

master
Artyom Beilis 7 years ago
parent
commit
cd3a7696d8
4 changed files with 455 additions and 0 deletions
  1. +28
    -0
      contrib/integration/session/reference/config.js
  2. +13
    -0
      contrib/integration/session/reference/index.html
  3. +171
    -0
      contrib/integration/session/reference/test.cpp
  4. +243
    -0
      contrib/integration/session/reference/tester.js

+ 28
- 0
contrib/integration/session/reference/config.js View File

@@ -0,0 +1,28 @@
{
"service" : {
"api" : "http",
"port" : 8080,
"ip" : "0.0.0.0"
},
"http" : {
"script" : "/test"
},
"session" : {
"expire" : "renew",
"timeout" : 604800,
"location" : "both",
"client" : {
"hmac" : "sha1",
"hmac_key" : "3891bbf7f845fd4277008a63d72640fc13bb9a31"
},
"server" : {
"storage" : "memory"
}

},
"security" : { "csrf" : {"enable" : true}},
"file_server" : {
"enable" : true,
"document_root" : "."
},
}

+ 13
- 0
contrib/integration/session/reference/index.html View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head><title>Unit test</title></head>
<body>
<script src="/tester.js" ></script>
<button onclick="tester('/test')">Run Test</button><span id="wait" style="color:green"></span>
<table border='1' width='80%'>
<thead>
<tr><th width='200px'>Test</th><th width='100px'>Status</th><th>Comment</th></tr>
<tbody id='log'>
</tbody>
</table>
</body>

+ 171
- 0
contrib/integration/session/reference/test.cpp View File

@@ -0,0 +1,171 @@
#include <cppcms/application.h>
#include <cppcms/applications_pool.h>
#include <cppcms/session_interface.h>
#include <cppcms/http_request.h>
#include <cppcms/http_response.h>
#include <cppcms/service.h>

#include <iostream>
#include <sstream>


std::string int2str(int v)
{
std::ostringstream ss;
ss << v;
return ss.str();
}

std::string to_hex(std::string const &v)
{
std::string result;
for(size_t i=0;i<v.size();i++) {
unsigned char c=v[i];
char const *msg = "0123456789abcdef";
result += msg[c >> 4];
result += msg[c & 0xF];
}
return result;
}

unsigned char hex2c(char c)
{
if('0' <= c && c<='9')
return c-'0';
if('a' <=c && c<= 'f')
return c-'a' + 10;
if('A' <=c && c<= 'F')
return c-'A' + 10;
return 0;
}

std::string from_hex(std::string const &v)
{
std::string r;
for(size_t i=0;i<v.size() / 2;i++) {
char h=v[i*2];
char l=v[i*2+1];
char v = (hex2c(h) << 4) | hex2c(l);
r+=v;
}
return r;
}

class tester : public cppcms::application {
public:
tester(cppcms::service &s) : cppcms::application(s)
{
}

void main(std::string /*url*/)
{
std::ostringstream final_result;
try {
for(int i=1;;i++) {
std::string id = "_" + int2str(i);
std::string op = request().get("op" + id);
if(op.empty())
break;
std::string key = request().get("key" + id);
std::string value = request().get("value" + id);
std::string result = "ok";
std::cerr << "Got " << op << std::endl;

if(op=="is_set") {
result = session().is_set(key) ? "yes" : "no";
}
else if(op == "erase") {
session().erase(key);
}
else if(op == "clear") {
session().clear();
}
else if(op == "is_exposed") {
result = session().is_exposed(key) ? "yes" : "no";
}
else if(op == "expose") {
session().expose(key,atoi(value.c_str()));
}
else if(op == "get") {
result = session().get(key);
}
else if(op == "set") {
session().set(key,value);
}
else if(op == "get_binary") {
result = to_hex(session().get(key));
}
else if(op == "set_binary") {
session().set(key,from_hex(value));
}
else if(op == "get_age") {
result = int2str(session().age());
}
else if(op == "set_age") {
session().age(atoi(value.c_str()));
}
else if(op == "default_age") {
session().default_age();
}
else if(op == "get_expiration") {
result = int2str(session().expiration());
}
else if(op == "set_expiration") {
session().expiration(atoi(value.c_str()));
}
else if(op == "default_expiration") {
session().default_expiration();
}
else if(op == "get_on_server") {
result = session().on_server() ? "yes" : "no";
}
else if(op == "set_on_server") {
session().on_server(atoi(value.c_str()));
}
else if(op == "reset_session") {
session().reset_session();
}
else if(op == "csrf_token") {
result = "t=" + session().get_csrf_token();
}
else if(op == "keys") {
result = "";
std::set<std::string> keys = session().key_set();
for(std::set<std::string>::iterator p=keys.begin();p!=keys.end();++p) {
if(!result.empty())
result += ",";
result += "[" + *p + "]";
}
}
else {
result = "invalid op=" + op;
}
std::cerr << " Res " << result << std::endl;
final_result << i << ":" << result << ";";
}
}
catch(std::exception const &e) {
response().set_plain_text_header();
response().out() << "ERROR:" << e.what();
return;
}
std::cerr << "OUT: " << final_result.str() << std::endl;
response().set_plain_text_header();
response().out() << final_result.str();
}
};

int main(int argc,char ** argv)
{
try {
cppcms::service app(argc,argv);
app.applications_pool().mount(cppcms::create_pool<tester>());
app.run();
}
catch(std::exception const &e) {
std::cerr<<e.what()<<std::endl;
}
}



+ 243
- 0
contrib/integration/session/reference/tester.js View File

@@ -0,0 +1,243 @@
function report(id,st,msg)
{
var okfail = st ? '<span style="color:#00AA00">OK</span>' : '<span style="color:red">FAIL</span>';
document.getElementById('log').innerHTML += '<tr><td>' + id + '</td><td>' + okfail + '</td><td>' + msg + '</td></tr>';
}

function get_cookie(name){
var pattern = RegExp(name + "=.[^;]*")
matched = document.cookie.match(pattern)
if(matched){
var cookie = matched[0].split('=')
return cookie[1]
}
return '';
}

function reset_report()
{
document.getElementById('log').innerHTML = '';
}
function wait_please(how)
{
document.getElementById('wait').innerHTML = 'Please wait - manual delay of ' + how + ' seconds in progress';
}
function wait_done()
{
document.getElementById('wait').innerHTML = ''
}
function run_test(baseurl,test,next_test)
{
wait_done();
var url = baseurl + '?';
for(var i=0;i<test.request.length;i++) {
if(i!=0)
url = url + '&';
var st = test.request[i];
var id = i+1;
var tmp = 'op_' + id + '=' + st.op;
if(typeof st.key != 'undefined')
tmp = tmp + '&key_' + id + '=' + st.key;
if(typeof st.value != 'undefined')
tmp = tmp + '&value_' + id + '=' + st.value;
url = url + tmp;
}
var xhr = new XMLHttpRequest();
//console.log(url);
xhr.open('GET',url,true);
xhr.onreadystatechange = function(e) {
if(xhr.readyState == 4) {
var text = xhr.responseText;
if(test.response instanceof RegExp ? text.match(test.response) : text == test.response) {
if(test.callback == undefined)
report(test.id,true,'');
else {
var res = test.callback();
if(res == null)
report(test.id,true,'');
else
report(test.id,false,res);
}
}
else {
total_tests_failed ++;
report(test.id,false, text + ' != ' + test.response);
}
var next = function() {
next_test(baseurl);
};
if(test.delay == undefined)
next();
else {
wait_please(test.delay);
setTimeout(next,test.delay * 1000);
}
}
};
xhr.send();
}


function run_test_set(url,set,id)
{
if(id == 0) {
total_tests_failed = 0;
}
if(id >= set.length) {
report('SUMMARY',total_tests_failed == 0,'Failed tests: ' + total_tests_failed);
return;
}
run_test(url,set[id],function(url) {
run_test_set(url,set,id+1);
});
}

function tester(url)
{
reset_report();
var all_tests = [
{
id:'init',
request: [{op:'clear'} ],
response : '1:ok;'
},
{
id:'set',
request: [{op:'is_set',key:'x'},{op:'set',key:'x',value:'val'} ],
response : '1:no;2:ok;'
},
{
id:'get',
request: [{op:'is_set',key:'x'},{op:'get',key:'x'}],
response : '1:yes;2:val;'
},
{
id:'erase',
request:[{op:'erase',key:'x'}],
response : '1:ok;'
},
{
id:'is_get false',
request: [{op:'is_set',key:'x'}],
response : '1:no;'
},
{
id:'set binary',
request: [{op:'set',key:'a',value:'test'},{op:'set_binary',key:'b',value:'54455354'},{op:'set_binary',key:'c',value:'0001'} ],
response : '1:ok;2:ok;3:ok;'
},
{
id:'get binary',
request: [{op:'get_binary',key:'a'},{op:'get',key:'b'},{op:'get_binary',key:'c'} ],
response : '1:74657374;2:TEST;3:0001;'
},
{
id:'expire set',
request:[{op:'get_age'},{op:'set_age',value:20},{op:'get_age'},{op:'default_age'},{op:'get_age'},{op:'set_age',value:'3'},{op:'get',key:'a'},{op:'get_age'}],
response: "1:604800;2:ok;3:20;4:ok;5:604800;6:ok;7:test;8:3;",
delay: 5,
},
{
id:'expired',
request:[{op:'get_age'},{op:'is_set',key:'a'}],
response: "1:604800;2:no;",
},
{
id:'expiration',
request:[{op:'set_expiration',value:'0'},{op:'get_expiration'},{op:'default_expiration'},{op:'get_expiration'},{op:'set_expiration',value:'0'},{op:'set_age',value:'8'},{op:'set',key:'x',value:'test'}],
response:'1:ok;2:0;3:ok;4:1;5:ok;6:ok;7:ok;',
delay:6,
},
{
id:'expiration a',
request:[{op:'get_expiration'},{op:'get',key:'x'}],
response:'1:0;2:test;',
delay:5,
},
{
id:'expiration b',
request:[{op:'get_expiration'},{op:'is_set',key:'x'}],
response:'1:1;2:no;',
},
{
id:'expose',
request:[{op:'set',value:'test',key:'x'},{op:'expose','value':1,'key':'x'},{op:'is_exposed',key:'x'},
{op:'set',value:'ttt',key:'y'},{op:'is_exposed',key:'y'}],
response:'1:ok;2:ok;3:yes;4:ok;5:no;',
callback:function() {
if(get_cookie('cppcms_session_x')!='test')
return 'invalid x cookie';
if(get_cookie('cppcms_session_y')!='')
return 'invalid_y cookie';
return null;
}
},
{
id:'exposed 2',
request: [{op:'is_exposed',key:'x'},{op:'expose',key:'x',value:'0'}],
response: '1:yes;2:ok;',
callback: function() {
if(get_cookie('cppcms_session_x')!='')
return 'x exists';
return null;
},
},
{
id:'client server',
request:[{op:'get_on_server'},{op:'set_on_server','value':1},{op:'get_on_server'}],
response:'1:no;2:ok;3:yes;',
callback: function() {
var sid = get_cookie('cppcms_session');
if(sid[0]!='I')
return 'not ID session ' + sid;
global_cppcms_session_id = sid;
return null;
},
},
{
id:'reset',
request:[{op:'get_on_server'},{op:'reset_session'}],
response:'1:yes;2:ok;',
callback: function() {
var sid = get_cookie('cppcms_session');
if(sid[0]!='I')
return 'not ID session ' + sid;
if(typeof global_cppcms_session_id === 'undefined')
return null;
if(sid === global_cppcms_session_id)
return 'session id ' + global_cppcms_session_id + ' had not change';
return null;
},
},
{
id:'back client',
request:[{op:'set_on_server',value:'0'}],
response:'1:ok;',
callback: function() {
var sid = get_cookie('cppcms_session');
if(sid[0]!='C')
return 'not cliend session ' + sid;
return null;
}
},
{
id:'keys',
request:[{op:'keys'}],
response:'1:[x],[y];'
},
{
id:'csrf',
request:[{op:'csrf_token'}],
response: /^1:t=.+;$/,
},
///////////////////////////////////////////////////////
{
id:'last',
request: [{op:'set',key:'x',value:'val'} ],
response : '1:ok;'
}

];
run_test_set(url,all_tests,0);
}


Loading…
Cancel
Save