Enhancements of simulators for DFC

New test cases for MR and DR simulators
Added simulator monitor server for simulator supervision
Update - Adapted simulators to changed naming of ftp files
Update2 - Added some more test behaviour to simulators.

Issue-ID: DCAEGEN2-1313

Change-Id: I90a346d44ab4e7c9f5a65f599b64f1907525dd51
Signed-off-by: BjornMagnussonXA <bjorn.magnusson@est.tech>
diff --git a/test/mocks/datafilecollector-testharness/dr-sim/dmaapDR.js b/test/mocks/datafilecollector-testharness/dr-sim/dmaapDR.js
index 4e73174..fffe57c 100644
--- a/test/mocks/datafilecollector-testharness/dr-sim/dmaapDR.js
+++ b/test/mocks/datafilecollector-testharness/dr-sim/dmaapDR.js
@@ -5,12 +5,33 @@
 const stream = require('stream');
 var app = express();
 var fs = require('fs');
-var path = require('path');
 var privateKey  = fs.readFileSync('cert/private.key', 'utf8');
 var certificate = fs.readFileSync('cert/certificate.crt', 'utf8');
 var credentials = {key: privateKey, cert: certificate};
-const allPublished = "allPublished";
-const nonePublished = "nonePublished";
+
+//For execution time calculation
+var startTime = Date.now();
+
+//Test case constants
+const tc_normal = "normal";
+const tc_none_published = "none_published";
+const tc_all_published = "all_published"
+const tc_10p_no_response = "10p_no_response";
+const tc_10first_no_response = "10first_no_response";
+const tc_100first_no_response = "100first_no_response";
+const tc_all_delay_10s = "all_delay_10s";
+const tc_10p_delay_10s = "10p_delay_10s";
+const tc_10p_error_response = "10p_error_response";
+const tc_10first_error_response = "10first_error_response";
+const tc_100first_error_response = "100first_error_response";
+
+//Counters
+var ctr_publish_query = 0;
+var ctr_publish_query_published = 0;
+var ctr_publish_query_not_published = 0;
+var ctr_publish_req = 0;
+var ctr_publish_req_redirect = 0;
+var ctr_publish_req_published = 0;
 
 var parser = new ArgumentParser({
 	  version: '0.0.1',
@@ -28,20 +49,59 @@
 
 var args = parser.parseArgs();
 
-if (args.tc=="nonePublished") {
-	console.log("TC: nonePublished")
-}
-if (args.tc=="allPublished") {
-	console.log("TC: allPublished")
-	//preparations
+if (args.tc==tc_normal) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_none_published) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_all_published) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_10p_no_response) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_10first_no_response) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_100first_no_response) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_all_delay_10s) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_10p_delay_10s) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_10p_error_response) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_10first_error_response) {
+	console.log("TC: " + args.tc)
+
+} else if (args.tc==tc_100first_error_response) {
+	console.log("TC: " + args.tc)
+} else {
+	console.log("No TC specified, use: --tc <tc-id>");
+	process.exit(0);
 }
 
 if (args.printtc) {
-	console.log("TC nonePublished: no file has already been published.");
-	console.log("TC allPublished: whatever is the request, this file is considered as published.");
-	console.log("No argument passed: normal behaviour, that is publish if not already published");
+	console.log("TC " + tc_normal + ": Normal case, query respone based on published files. Publish responde with ok/redirect depending on if file is published or not.");
+	console.log("TC " + tc_none_published + ": Query responde 'ok'. Publish respond with redirect.");
+	console.log("TC " + tc_all_published + ": Query respond with filename. Publish respond with 'ok'.");
+	console.log("TC " + tc_10p_no_response + ": 10% % no response for query and publish. Otherwise normal case.");
+	console.log("TC " + tc_10first_no_response + ": 10 first queries and requests gives no response for query and publish. Otherwise normal case.");
+	console.log("TC " + tc_100first_no_response + ": 100 first queries and requests gives no response for query and publish. Otherwise normal case.");
+	console.log("TC " + tc_all_delay_10s + ": All responses delayed 10s (both query and publish).");
+	console.log("TC " + tc_10p_delay_10s + ": 10% of responses delayed 10s, (both query and publish).");
+	console.log("TC " + tc_10p_error_response + ": 10% error response for query and publish. Otherwise normal case.");
+	console.log("TC " + tc_10first_error_response + ": 10 first queries and requests gives no response for query and publish. Otherwise normal case.");
+	console.log("TC " + tc_100first_error_response + ": 100 first queries and requests gives no response for query and publish. Otherwise normal case.");
+
 	process.exit(0);
-}
+  }
+
 
 var bodyParser = require('body-parser')
 app.use(bodyParser.urlencoded({ extended: false }))
@@ -52,55 +112,179 @@
 // parse application/vnd.api+json as json
 app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
 
-// parse some custom thing into a Buffer
-app.use(bodyParser.raw({limit:1024*1024*20, type: 'application/octet-stream' }))
+// parse some custom thing into a Buffer (to cater for 60MB files)
+app.use(bodyParser.raw({limit:1024*1024*60, type: 'application/octet-stream' }))
 // parse an HTML body into a string
 app.use(bodyParser.text({ type: 'text/html' }))
+
+
+
+//Is alive function
 app.get("/",function(req, res){
 	res.send("ok");
 })
 
-
-var published = [];
-app.get('/feedlog/1/',function(req, res){
-	var filename = req.query.filename;
-	if(args.tc == allPublished){
-		res.send("[" + filename + "]");
-	} else if(args.tc == nonePublished){
-		res.send("[]");
-	} else {
-		if (published.includes(filename)) {
-			res.send("[" + filename + "]");
-		} else {
-			res.send("[]");
-		}
-	}
+//Counter readout
+app.get("/ctr_publish_query",function(req, res){
+	res.send(""+ctr_publish_query);
+})
+app.get("/ctr_publish_query_published",function(req, res){
+	res.send(""+ctr_publish_query_published);
+})
+app.get("/ctr_publish_query_not_published",function(req, res){
+	res.send(""+ctr_publish_query_not_published);
+})
+app.get("/ctr_publish_req",function(req, res){
+	res.send(""+ctr_publish_req);
+})
+app.get("/ctr_publish_req_redirect",function(req, res){
+	res.send(""+ctr_publish_req_redirect);
+})
+app.get("/ctr_publish_req_published",function(req, res){
+	res.send(""+ctr_publish_req_published);
+})
+app.get("/ctr_published_files",function(req, res){
+	res.send(""+published.length);
+})
+app.get("/tc_info",function(req, res){
+	res.send(args.tc);
+})
+function fmtMSS(s){
+	return(s-(s%=60))/60+(9<s?':':':0')+s    //Format time diff in mm:ss
+}
+app.get("/execution_time",function(req, res){
+	diff = fmtMSS(Math.floor((Date.now()-startTime)/1000));
+	res.send(""+diff);
 })
 
+//db of published files
+var published = [];
 
-app.put('/publish/1/', function (req, res) {
+app.get('/feedlog/1/',function(req, res){
+	console.log("url:"+req.url);
+	ctr_publish_query++;
 	var filename = req.query.filename;
-	var type = req.query.type;
+	console.log(filename);
+	var qtype = req.query.type;
 	if(typeof(filename) == 'undefined'){
 		res.status(400).send({error: 'No filename provided.'});
-	} else if(typeof(type) == 'undefined'){
+		return;
+	} else if(typeof(qtype) == 'undefined'){
 		res.status(400).send({error: 'No type provided.'});
+		return;
+	}
+	
+	//Ugly fix, plus signs replaces with spaces in query params....need to put them back
+	filename = filename.replace(/ /g,"+");
+	
+	if (args.tc==tc_normal) {
+	  //continue
+	}  else if (args.tc==tc_none_published) {
+		ctr_publish_query_not_published++;
+		res.send("[]");
+		return;
+	} else if (args.tc==tc_all_published) {
+		ctr_publish_query_published++;
+		res.send("[" + filename + "]");
+		return;
+	} else if (args.tc==tc_10p_no_response && (ctr_publish_query%10) == 0) {
+		return;
+	} else if (args.tc==tc_10first_no_response && ctr_publish_query<11) {
+		return;
+	} else if (args.tc==tc_100first_no_response && ctr_publish_query<101) {
+		return;
+	} else if (args.tc==tc_all_delay_10s) {
+		console.log("sleep begin");
+		timer(10000).then(_=>console.log("sleeping done")); 
+	} else if (args.tc==tc_10p_delay_10s && (ctr_publish_query%10) == 0) {
+		console.log("sleep begin");
+		timer(10000).then(_=>console.log("sleeping done")); 
+	} else if (args.tc==tc_10p_error_response && (ctr_publish_query%10) == 0) {
+		res.send(400);
+		return;
+	} else if (args.tc==tc_10first_error_response && ctr_publish_query<11) {
+		res.send(400);
+		return;
+	} else if (args.tc==tc_100first_error_response & ctr_publish_query<101) {
+		res.send(400);
+		return;
+	}
+
+	if (published.includes(filename)) {
+		ctr_publish_query_published++;
+		res.send("[" + filename + "]");
 	} else {
-		if(args.tc == allPublished){
-			res.send("[" + filename + "]");
-		} else if(args.tc == nonePublished){
-			res.redirect(301, 'http://127.0.0.1:3908/publish/1/'+filename);
-		} else {
-			if (!published.includes(filename)) {
-				published.push(filename);
-				res.redirect(301, 'http://127.0.0.1:3908/publish/1/'+filename);
-			} else {
-				res.send("ok");
-			}
-		}
+		ctr_publish_query_not_published++;
+		res.send("[]");
 	}
 })
 
+app.put('/publish/1/:filename', function (req, res) {
+	console.log("url:"+req.url);
+	console.log("body (first 25 bytes):"+req.body.slice(0,25));
+	console.log("headers:"+req.headers);
+	ctr_publish_req++;
+
+	var filename = req.params.filename;
+	console.log(filename);
+
+	if (args.tc==tc_normal) {
+	    //continue
+	} else if (args.tc==tc_none_published) {
+		ctr_publish_req_redirect++;
+		res.redirect(301, 'http://127.0.0.1:3908/publish/1/'+filename);
+		return;
+	} else if (args.tc==tc_all_published) {
+		ctr_publish_req_published++;
+		res.send("ok");
+		return;
+	}else if (args.tc==tc_10p_no_response && (ctr_publish_req%10) == 0) {
+		return;
+	} else if (args.tc==tc_10first_no_response && ctr_publish_req<11) {
+		return;
+	} else if (args.tc==tc_100first_no_response && ctr_publish_req<101) {
+		return;
+	} else if (args.tc==tc_all_delay_10s) {
+		console.log("sleep begin");
+		timer(10000).then(_=>console.log("sleeping done")); 
+	} else if (args.tc==tc_10p_delay_10s && (ctr_publish_req%10) == 0) {
+		console.log("sleep begin");
+		timer(10000).then(_=>console.log("sleeping done")); 
+	} else if (args.tc==tc_10p_error_response && (ctr_publish_req%10) == 0) {
+		res.send(400);
+		return;
+	} else if (args.tc==tc_10first_error_response && ctr_publish_req<11) {
+		res.send(400);
+		return;
+	} else if (args.tc==tc_100first_error_response & ctr_publish_req<101) {
+		res.send(400);
+		return;
+	}
+
+	if (!published.includes(filename)) {
+		ctr_publish_req_redirect++;
+		res.redirect(301, 'http://127.0.0.1:3908/publish/1/'+filename);
+	} else {
+		ctr_publish_req_published++;
+		res.send("ok");
+	}
+})
+
+//Callback from DR REDIR server, when file is published ok this PUT request update the list of published files.
+app.put('/dr_redir_publish/:filename', function (req, res) {
+	console.log("url:"+req.url);
+	var filename = req.params.filename;
+	console.log(filename);
+
+	if (!published.includes(filename)) {
+		console.log("File marked as published by callback from DR redir SIM. url: " + req.url);
+		published.push(filename);
+	} else {
+		console.log("File already marked as published. Callback from DR redir SIM. url: " + req.url);
+	}
+
+	res.send("ok");
+})
 
 var httpServer = http.createServer(app);
 var httpsServer = https.createServer(credentials, app);