mitchell852 closed pull request #3156: restore test/astats_sim that was deleted inadvertantly URL: https://github.com/apache/trafficcontrol/pull/3156
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/test/astats_sim/Readme.md b/test/astats_sim/Readme.md new file mode 100644 index 000000000..70bc620c3 --- /dev/null +++ b/test/astats_sim/Readme.md @@ -0,0 +1,20 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +An astats simulator tool written in javascript and perl. Used to test Traffic Monitor. diff --git a/test/astats_sim/_astats b/test/astats_sim/_astats new file mode 100644 index 000000000..7f2c96eb4 --- /dev/null +++ b/test/astats_sim/_astats @@ -0,0 +1,172 @@ +#!/usr/bin/perl + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + + +use strict; +use warnings; + +use DBI; +use JSON; +use CGI::Carp qw/fatalsToBrowser/; +use Data::Dumper; +use Encode; + +my %query_params = &getFormData(); +my $json = JSON->new->utf8; +my $json_obj; + +my $unixtime = time(); +my $server_name = $ENV{'SERVER_NAME'}; +my $cdn_domain_name = "<CDN-DOMAIN_NAME>"; +my $hex_string = $server_name; +$hex_string =~ s/(.)/sprintf("%d",ord($1))/eg; +my $int1 = int($hex_string) % 4; +my $int2 = $hex_string % 40; +my $int3 = $hex_string % 400; +my $int4 = $hex_string % 4000; +my $int5 = $hex_string % 40000; +my $int6 = $hex_string % 400000; +my $int7 = $hex_string % 4000000; +my $int8 = $hex_string % 40000000; +my $int9 = $hex_string % 40000000; +my $int10 = $hex_string % 400000000; + +my $hit_fresh = int($int10 + $unixtime + $int4); +my $hit_fresh_process = int($hit_fresh); +my $hit_revalidated = int(($int10/2) + $unixtime + $int1); +my $miss_cold = int(($int10/2) + $unixtime + $int3); +my $miss_not_cacheable = int(($int7/3) + $unixtime + $int1); +my $miss_changed = int(($unixtime/10000000) + $int1); +my $miss_client_no_cache = 0; +my $aborts = int(($unixtime/10000000) + $int2*2); +my $possible_aborts = 0; +my $connect_failed = int(($unixtime/1000000) + $int2*4 + $int1*2); +my $other = int((($unixtime/1000000) + $int3)/100); +my $unclassified = 0; +my $write_bytes = int($unixtime*50 + $int4*$int5); +my $current_client_connections = int($int5*rand()); +my $bytes_used = int($write_bytes/20 + $int2*$int5); +my $bytes_total = int($bytes_used + $int10); +my $v1_bytes_used = int($bytes_used); +my $v1_bytes_total = int($bytes_total); +my $load_avg_1 = sprintf("%.2f",$unixtime/100000000+(8*rand())); +my $load_avg_5 = sprintf("%.2f",$load_avg_1 / 2); +my $load_avg_15 = sprintf("%.2f",$load_avg_1 / 3); +my $running_procs = int(15*rand($int1)); +my $total_procs = int(2*$running_procs+($int1+2)*2); +my $last_proc_id = $int5; +my $proc_loadavg = "$load_avg_1 $load_avg_5 $load_avg_15 $running_procs/$total_procs $last_proc_id"; +my $if_rbytes = int($unixtime*760000000+$bytes_total); +my $if_rpackets = int($if_rbytes/875); +my $if_rmcast = int($if_rpackets/$int4); +my $if_tbytes = int($if_rbytes/1.5); +my $if_tpackets = int($if_tbytes/1500); +my $proc_net_dev = $query_params{'inf.name'}. ":$if_rbytes $if_rpackets 0 0 0 0 0 $if_rmcast $if_tbytes $if_tpackets 0 0 0 0 0 0"; +my @ds_bytes; +my @ds_bytes_in; +my @ds_200s; +my @ds_400s; +my @ds_500s; +for (my $i=1;$i<10;$i++) { + my $rand1 = undef; + $rand1 = rand($int1); + $ds_bytes[$i] = int($if_tbytes/10 + ($rand1*$rand1)); + $ds_bytes_in[$i] = int($if_rbytes/10 + ($rand1*$rand1)); + $ds_200s[$i] = int($ds_bytes[$i]/9000*0.95); + $ds_400s[$i] = int($ds_bytes[$i]/9000*0.04); + $ds_500s[$i] = int($ds_bytes[$i]/9000*0.01); +} +$ds_bytes[10] = int($if_tbytes/10 + rand($int1) * rand($int1)); +$ds_bytes_in[10] = int($if_rbytes/10 + rand($int1) * rand($int1)); +$ds_200s[10] = int($ds_bytes[10]/9000*0.95); +$ds_400s[10] = int($ds_bytes[10]/9000*0.04); +$ds_500s[10] = int($ds_bytes[10]/9000*0.01); + +#proc.net.dev: "bond0:181566812618839 43321349767 0 0 0 0 0 4710035 517574148613675 34658736727 0 0 0 0 0 0" + +if (exists $query_params{'application'} ) { + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.hit_fresh"} = $hit_fresh; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.hit_fresh.process"} = $hit_fresh_process; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.hit_revalidated"} = $hit_revalidated; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_cold"} = $miss_cold; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_not_cacheable"} = $miss_not_cacheable; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_changed"} = $miss_changed; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_client_no_cache"} = $miss_client_no_cache; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.aborts"} = $aborts; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.possible_aborts"} = $possible_aborts; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.connect_failed"} = $connect_failed; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.other"} = $other; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.other.unclassified"} = $unclassified; + $json_obj->{'ats'}->{"proxy.process.net.write_bytes"} = $write_bytes; + $json_obj->{'ats'}->{"proxy.process.http.current_client_connections"} = $current_client_connections; + $json_obj->{'ats'}->{"proxy.process.cache.bytes_used"} = $bytes_used; + $json_obj->{'ats'}->{"proxy.process.cache.bytes_total"} = $bytes_total; + $json_obj->{'ats'}->{"proxy.process.cache.volume_1.bytes_used"} = $v1_bytes_used; + $json_obj->{'ats'}->{"proxy.process.cache.volume_1.bytes_total"} = $v1_bytes_total; + for(my $i=1;$i<10;$i++) { + my $number = sprintf('%.2d', $i); + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.out_bytes"} = $ds_bytes[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.in_bytes"} = $ds_bytes_in[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_2xx"} = $ds_200s[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_4xx"} = $ds_400s[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_5xx"} = $ds_500s[$i]; + } + my $number = 10; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.out_bytes"} = $ds_bytes[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.in_bytes"} = $ds_bytes_in[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_2xx"} = $ds_200s[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_4xx"} = $ds_400s[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_5xx"} = $ds_500s[10]; + $json_obj->{'ats'}->{"server"} = "3.3.0-dev"; +} +$json_obj->{'system'}->{"inf.name"} = $query_params{"inf.name"}; +$json_obj->{'system'}->{"inf.speed"} = "10000"; +$json_obj->{'system'}->{"proc.net.dev"} = $proc_net_dev; +$json_obj->{'system'}->{"proc.loadavg"} = $proc_loadavg; +$json_obj->{'system'}->{"something"} = "here"; + + +print "Content-type: text/html\n\n"; +print $json->utf8->encode( $json_obj ); + + +sub getFormData { + my $buffer = ""; + my %hash = (); + my @params = (); + + if ($ENV{'REQUEST_METHOD'} eq 'GET') { + $buffer = $ENV{'QUERY_STRING'}; + $hash{"four"}="two"; + } + else { + read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); + } + if ($buffer =~ m/\&/) { + @params = split(/\&/,$buffer); + } + else { + @params = split(/\;/,$buffer); + } + foreach my $p (@params) { + (my $key, my $value) = split(/\=/,$p); + $hash{$key}=$value; + } + return %hash; +} diff --git a/test/astats_sim/_astats_static b/test/astats_sim/_astats_static new file mode 100644 index 000000000..61d12b9db --- /dev/null +++ b/test/astats_sim/_astats_static @@ -0,0 +1,171 @@ +#!/usr/bin/perl + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +use strict; +use warnings; + +use DBI; +use JSON; +use CGI::Carp qw/fatalsToBrowser/; +use Data::Dumper; +use Encode; + +my %query_params = &getFormData(); +my $json = JSON->new->utf8; +my $json_obj; + +my $unixtime = time(); +my $server_name = $ENV{'SERVER_NAME'}; +my $cdn_domain_name = "<CDN-DOMAIN_NAME>"; +my $hex_string = $server_name; +$hex_string =~ s/(.)/sprintf("%d",ord($1))/eg; +my $int1 = int($hex_string) % 4; +my $int2 = $hex_string % 40; +my $int3 = $hex_string % 400; +my $int4 = $hex_string % 4000; +my $int5 = $hex_string % 40000; +my $int6 = $hex_string % 400000; +my $int7 = $hex_string % 4000000; +my $int8 = $hex_string % 40000000; +my $int9 = $hex_string % 40000000; +my $int10 = $hex_string % 400000000; + +my $hit_fresh = int($int10 + $unixtime + $int4); +my $hit_fresh_process = int($hit_fresh); +my $hit_revalidated = int(($int10/2) + $unixtime + $int1); +my $miss_cold = int(($int10/2) + $unixtime + $int3); +my $miss_not_cacheable = int(($int7/3) + $unixtime + $int1); +my $miss_changed = int(($unixtime/10000000) + $int1); +my $miss_client_no_cache = 0; +my $aborts = int(($unixtime/10000000) + $int2*2); +my $possible_aborts = 0; +my $connect_failed = int(($unixtime/1000000) + $int2*4 + $int1*2); +my $other = int((($unixtime/1000000) + $int3)/100); +my $unclassified = 0; +my $write_bytes = int($unixtime*50 + $int4*$int5); +my $current_client_connections = int($int5*rand()); +my $bytes_used = int($write_bytes/20 + $int2*$int5); +my $bytes_total = int($bytes_used + $int10); +my $v1_bytes_used = int($bytes_used); +my $v1_bytes_total = int($bytes_total); +my $load_avg_1 = sprintf("%.2f",$unixtime/100000000+(8*rand())); +my $load_avg_5 = sprintf("%.2f",$load_avg_1 / 2); +my $load_avg_15 = sprintf("%.2f",$load_avg_1 / 3); +my $running_procs = int(15*rand($int1)); +my $total_procs = int(2*$running_procs+($int1+2)*2); +my $last_proc_id = $int5; +my $proc_loadavg = "$load_avg_1 $load_avg_5 $load_avg_15 $running_procs/$total_procs $last_proc_id"; +my $if_rbytes = int($unixtime*760000000+$bytes_total); +my $if_rpackets = int($if_rbytes/875); +my $if_rmcast = int($if_rpackets/$int4); +my $if_tbytes = int($if_rbytes/1.5); +my $if_tpackets = int($if_tbytes/1500); +my $proc_net_dev = $query_params{'inf.name'}. ":$if_rbytes $if_rpackets 0 0 0 0 0 $if_rmcast $if_tbytes $if_tpackets 0 0 0 0 0 0"; +my @ds_bytes; +my @ds_bytes_in; +my @ds_200s; +my @ds_400s; +my @ds_500s; +for (my $i=1;$i<10;$i++) { + my $rand1 = undef; + $rand1 = rand($int1); + $ds_bytes[$i] = int($if_tbytes/10 + ($rand1*$rand1)); + $ds_bytes_in[$i] = int($if_rbytes/10 + ($rand1*$rand1)); + $ds_200s[$i] = int($ds_bytes[$i]/9000*0.95); + $ds_400s[$i] = int($ds_bytes[$i]/9000*0.04); + $ds_500s[$i] = int($ds_bytes[$i]/9000*0.01); +} +$ds_bytes[10] = int($if_tbytes/10 + rand($int1) * rand($int1)); +$ds_bytes_in[10] = int($if_rbytes/10 + rand($int1) * rand($int1)); +$ds_200s[10] = int($ds_bytes[10]/9000*0.95); +$ds_400s[10] = int($ds_bytes[10]/9000*0.04); +$ds_500s[10] = int($ds_bytes[10]/9000*0.01); + +#proc.net.dev: "bond0:181566812618839 43321349767 0 0 0 0 0 4710035 517574148613675 34658736727 0 0 0 0 0 0" + +if (exists $query_params{'application'} ) { + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.hit_fresh"} = $hit_fresh; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.hit_fresh.process"} = $hit_fresh_process; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.hit_revalidated"} = $hit_revalidated; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_cold"} = $miss_cold; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_not_cacheable"} = $miss_not_cacheable; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_changed"} = $miss_changed; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.miss_client_no_cache"} = $miss_client_no_cache; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.aborts"} = $aborts; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.possible_aborts"} = $possible_aborts; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.connect_failed"} = $connect_failed; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.errors.other"} = $other; + $json_obj->{'ats'}->{"proxy.process.http.transaction_counts.other.unclassified"} = $unclassified; + $json_obj->{'ats'}->{"proxy.process.net.write_bytes"} = $write_bytes; + $json_obj->{'ats'}->{"proxy.process.http.current_client_connections"} = $current_client_connections; + $json_obj->{'ats'}->{"proxy.process.cache.bytes_used"} = $bytes_used; + $json_obj->{'ats'}->{"proxy.process.cache.bytes_total"} = $bytes_total; + $json_obj->{'ats'}->{"proxy.process.cache.volume_1.bytes_used"} = $v1_bytes_used; + $json_obj->{'ats'}->{"proxy.process.cache.volume_1.bytes_total"} = $v1_bytes_total; + for(my $i=1;$i<10;$i++) { + my $number = sprintf('%.2d', $i); + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.out_bytes"} = $ds_bytes[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.in_bytes"} = $ds_bytes_in[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_2xx"} = $ds_200s[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_4xx"} = $ds_400s[$i]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_5xx"} = $ds_500s[$i]; + } + my $number = 10; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.out_bytes"} = $ds_bytes[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.in_bytes"} = $ds_bytes_in[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_2xx"} = $ds_200s[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_4xx"} = $ds_400s[10]; + $json_obj->{'ats'}->{"plugin.remap_stats." . $server_name . ".omg-" . $number . "$cdn_domain_name.status_5xx"} = $ds_500s[10]; + $json_obj->{'ats'}->{"server"} = "3.3.0-dev"; +} +$json_obj->{'system'}->{"inf.name"} = $query_params{"inf.name"}; +$json_obj->{'system'}->{"inf.speed"} = "10000"; +$json_obj->{'system'}->{"proc.net.dev"} = $proc_net_dev; +$json_obj->{'system'}->{"proc.loadavg"} = $proc_loadavg; +$json_obj->{'system'}->{"something"} = "here"; + + +print "Content-type: text/html\n\n"; +print $json->utf8->encode( $json_obj ); + + +sub getFormData { + my $buffer = ""; + my %hash = (); + my @params = (); + + if ($ENV{'REQUEST_METHOD'} eq 'GET') { + $buffer = $ENV{'QUERY_STRING'}; + $hash{"four"}="two"; + } + else { + read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); + } + if ($buffer =~ m/\&/) { + @params = split(/\&/,$buffer); + } + else { + @params = split(/\;/,$buffer); + } + foreach my $p (@params) { + (my $key, my $value) = split(/\=/,$p); + $hash{$key}=$value; + } + return %hash; +} diff --git a/test/astats_sim/ats_sim.js b/test/astats_sim/ats_sim.js new file mode 100644 index 000000000..8bec5821f --- /dev/null +++ b/test/astats_sim/ats_sim.js @@ -0,0 +1,425 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +var myip = "127.0.0.1"; +var myport = 80; +var config_url = "https://traffic-ops.com/CRConfig-Snapshots/cdn-name/CRConfig.json"; +var to_user = ""; +var to_password = ""; +var to_login_api = "/api/1.2/user/login"; +var simulator_ua = "ATS Simulator/node.js " + process.version; + +// first argument to follow node ats_sim.js +if (process.argv[2]) { + config_url = process.argv[2]; +} + +// second argument to follow node ats_sim.js +if (process.argv[3]) { + myport = process.argv[3]; +} + +if (process.argv[4]) { + to_user = process.argv[4]; +} + +if (process.argv[5]) { + to_password = process.argv[5]; +} + +var to_credentials = JSON.stringify({ + "u": to_user, + "p": to_password, +}); + +var errorRateDenominator = 0; +var debug = 0; + +// https://${tmHostname}/CRConfig-Snapshots/${cdnName}/CRConfig.json +if (debug) console.log("point traffic_monitor::tm.crConfig.json.polling.url to: " + config_url); + +var date = new Date(); +var starttime = date.getTime(); +var timeseed = 1383769987010; + +console.log("Started " + date); + +var protocol = (/^https/.test(config_url) == true ? "https" : "http"); +var client_http = require(protocol); +var cr_config = ''; +var tld = ''; +var Url = require('url'); +var stats = new Object(); +var to_url = Url.parse(config_url, true); + +process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; +auth_get_config(); + +function auth_get_config() { + var to_cookie = ""; + var options = { + protocol: to_url.protocol, + hostname: to_url.hostname, + port: to_url.port, + path: to_login_api, + method: 'POST', + headers: { + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": Buffer.byteLength(to_credentials), + "User-Agent": simulator_ua + } + }; + + request = client_http.request(options, function(res) { + var cookie = res.headers["set-cookie"]; + + if (cookie) { + cookie.forEach( + function (cookieMonster) { + to_cookie += cookieMonster; + } + ); + } + + if (to_cookie) { + if (debug) console.log("Cookie: " + to_cookie); + } + + var body = ''; + + res.on('data', function(chunk) { + body += chunk; + }); + + res.on('end', function() { + response = JSON.parse(body); + + if (res.statusCode == 200) { + console.log("Successfully authenticated to Traffic Ops"); + get_config(options, to_cookie); + } else { + console.log("Authentication response: " + JSON.stringify(response)); + throw new Error("Authentication failed."); + } + }); + }).on('error', function(e) { + console.log("Got error: ", e); + }); + + request.write(to_credentials); + request.end(); +} + +function get_config(options, cookie) { + options.method = "GET"; + options.path = to_url.path; + options.headers = { + "Cookie": cookie, + "User-Agent": simulator_ua + }; + + request = client_http.request(options, function(res) { + var body = ''; + + res.on('data', function(chunk) { + body += chunk; + }); + + res.on('end', function() { + cr_config = JSON.parse(body); + tld = cr_config.config['domain_name']; + console.log("CDN TLD: " + tld); + + for(var cid in cr_config.contentServers) { + if(cid.indexOf("atsec-sim")!=-1) { + cr_config.contentServers[cid].queryIp = myip; + cr_config.contentServers[cid].port = myport; + } + } + + cr_config + }); + }).on('error', function(e) { + console.log("Got error: ", e); + }); + + request.end(); +} + +var http = require('http'); + +http.createServer(function (request, response) { + if (request.url == "/favicon.ico") { + response.writeHead(404); + response.end(); + return; + } + + // https://${tmHostname}/CRConfig-Snapshots/${cdnName}/CRConfig.json + if (request.url.indexOf("/CRConfig.json") != -1) { + console.log("Delivering CRConfig.json"); + response.end(JSON.stringify(cr_config, null, 4)); + return; + } + + if (errorRateDenominator && rand(errorRateDenominator) == 1) { + response.writeHead(404); + response.end(); + return; + } + + var objToJson = { }; + objToJson.cr_config = cr_config; + var str = JSON.stringify(getData(request)); + response.writeHead(200, {'Content-Type': 'application/json'}); + response.end(str); +}).listen(myport); + +console.log("HTTP Listener started on port " + myport); + +var util = require('util'); +var crypto = require('crypto') +var shasum = crypto.createHash('sha1'); + +function rand(n) { + return Math.floor((Math.random() * n) + 1); +} + +Number.prototype.zeroPad = function(numZeros) { + var n = Math.abs(this); + var zeros = Math.max(0, numZeros - n.toString().length); + var zeroString = Math.pow(10,zeros).toString().substr(1); + if( this < 0 ) { + zeroString = '-' + zeroString; + } + + return zeroString+n; +} + +function getData(request) { + var url_parts = Url.parse(request.url, true); + var query_params = url_parts.query; + + if (!request.headers.host) { + return; + } + + if (debug) console.log(request.url); + if (debug) console.log(query_params); + if (debug) console.log(query_params.a); + + var ret = {}; + var d = new Date(); + var n = d.getTime(); + var unixtime = d.getTime(); + var basetime = unixtime - timeseed; + var server_name = request.headers.host.split(':')[0]; + server_name = server_name.split(".")[0]; + var hex_string = server_name; + var hex = crypto.createHash('sha1').update(server_name).digest('hex'); + hex = parseInt(hex, 16); + ret.simulator = 1; + ret.time = unixtime; + ret.hex = hex; + var int1 = hex % 4; + var int2 = hex % 40; + var int3 = hex % 400; + var int4 = hex % 4000; + var int5 = hex % 40000; + var int6 = hex % 400000; + var int7 = hex % 4000000; + var int8 = hex % 40000000; + var int9 = hex % 40000000; + var int10 = hex % 400000000; + + var hit_fresh = unixtime / 2; + var hit_fresh_process = hit_fresh; + var hit_revalidated = (int10 / 2) + unixtime + int1; + var miss_cold = (int10 / 2) + unixtime + int3; + var miss_not_cacheable = (int7 / 3) + unixtime + int1; + var miss_changed = (unixtime / 10000000) + int1; + var miss_client_no_cache = 0; + var aborts = (unixtime / 10000000) + int2 * 2; + var possible_aborts = 0; + var connect_failed = (unixtime / 1000000) + int2 * 4 + int1 * 2; + var other = ((unixtime / 1000000) + int3) / 100; + var unclassified = 0; + var write_bytes = unixtime + int4 * int5; + var current_client_connections = Math.round(int5 * Math.random()); + var bytes_used = write_bytes / 20 + int2 * int5; + var bytes_total = bytes_used + int10; + var v1_bytes_used = bytes_used; + var v1_bytes_total = bytes_total; + var load_avg_1 = (8 * Math.random()).toFixed(2); + var load_avg_5 = (load_avg_1 / 2).toFixed(2); + var load_avg_15 = (load_avg_1 / 3).toFixed(2); + var running_procs = (15 * rand(int1)); + var total_procs = 2 * running_procs + (int1 + 2) * 2; + var last_proc_id = int5; + var proc_loadavg = util.format("%d %d %d %d/%d %d", load_avg_1, load_avg_5, load_avg_15, running_procs, total_procs, last_proc_id); + var if_rbytes = basetime * 500; + var if_rpackets = if_rbytes / 875; + var if_rmcast = if_rpackets / int4; + var if_tbytes = if_rbytes / 3; + var if_tpackets = if_tbytes / 1500; + var proc_net_dev = 'bond0'; + + if (query_params['inf.name']) { + proc_net_dev = query_params['inf.name']; + } + + proc_net_dev += util.format(":%d %d 0 0 0 0 0 %d %d %d 0 0 0 0 0 0", if_rbytes.toFixed(0), if_rpackets.toFixed(0), if_rmcast.toFixed(0), if_tbytes.toFixed(0), if_tpackets.toFixed(0)); + var ds_bytes = {}; + var ds_bytes_in = {}; + var ds_200s = {}; + var ds_400s = {}; + var ds_500s = {}; + + for (var i=1; i<=10; i++) { + var rand1 = rand(int1); + ds_bytes[i] = if_tbytes / 10; + ds_bytes_in[i] = if_rbytes / 10; + var tps = basetime / 10000; + ds_200s[i] = tps * 0.95; + ds_400s[i] = tps * 0.04; + ds_500s[i] = tps * 0.01; + } + + if (query_params.ds && query_params.p && query_params.v && query_params.m) { + var these_stats = new Object(); + these_stats.delivery_service = query_params.ds; + these_stats.parameter = query_params.p; + these_stats.value = parseInt(query_params.v); + these_stats.multiplier = parseFloat(query_params.m); + stats[server_name] = these_stats; + } else if (query_params.stats == 0) { + delete stats[server_name]; + } + + if (debug) console.log(stats); + +// #proc.net.dev: "bond0:181566812618839 43321349767 0 0 0 0 0 4710035 517574148613675 34658736727 0 0 0 0 0 0" + + ret.ats = {}; + ret.ats["proxy.process.http.transaction_counts.hit_fresh"] = hit_fresh; + ret.ats["proxy.process.http.transaction_counts.hit_fresh.process"] = hit_fresh_process; + ret.ats["proxy.process.http.transaction_counts.hit_revalidated"] = hit_revalidated; + ret.ats["proxy.process.http.transaction_counts.miss_cold"] = miss_cold; + ret.ats["proxy.process.http.transaction_counts.miss_not_cacheable"] = miss_not_cacheable; + ret.ats["proxy.process.http.transaction_counts.miss_changed"] = miss_changed; + ret.ats["proxy.process.http.transaction_counts.miss_client_no_cache"] = miss_client_no_cache; + ret.ats["proxy.process.http.transaction_counts.errors.aborts"] = aborts; + ret.ats["proxy.process.http.transaction_counts.errors.possible_aborts"] = possible_aborts; + ret.ats["proxy.process.http.transaction_counts.errors.connect_failed"] = connect_failed; + ret.ats["proxy.process.http.transaction_counts.errors.other"] = other; + ret.ats["proxy.process.http.transaction_counts.other.unclassified"] = unclassified; + ret.ats["proxy.process.net.write_bytes"] = write_bytes; + ret.ats["proxy.process.http.current_client_connections"] = current_client_connections; + ret.ats["proxy.process.cache.bytes_used"] = bytes_used; + ret.ats["proxy.process.cache.bytes_total"] = bytes_total; + ret.ats["proxy.process.cache.volume_1.bytes_used"] = v1_bytes_used; + ret.ats["proxy.process.cache.volume_1.bytes_total"] = v1_bytes_total; + + if (cr_config && cr_config.contentServers && server_name in cr_config.contentServers) { + if (debug) console.log("Attempting to build stats for " + server_name); + + for (var delivery_service in cr_config.contentServers[server_name]['deliveryServices']) { + var data = new Object(); + data['out_bytes'] = ds_bytes[rand(10)].toFixed(0); + data['in_bytes'] = ds_bytes_in[rand(10)].toFixed(0); + data['status_2xx'] = ds_200s[rand(10)].toFixed(0); + data['status_4xx'] = ds_400s[rand(10)].toFixed(0); + data['status_5xx'] = ds_500s[rand(10)].toFixed(0); + + var n = i.zeroPad(2); + var ds_fqdn = cr_config.contentServers[server_name]['deliveryServices'][delivery_service][0]; + + if (stats.hasOwnProperty(server_name) && stats[server_name].hasOwnProperty("delivery_service")) { + var ds_tld = ds_fqdn.substring(ds_fqdn.indexOf(".") + 1); + + if (stats[server_name].delivery_service == ds_tld && stats[server_name].parameter in data) { + var this_request = parseInt(d.getTime()); + + if (stats[server_name].hasOwnProperty("last_request") && stats[server_name].hasOwnProperty("last_value")) { + /* + I'm requiring bignum here to ensure that it's only required when running bandwidth simulations + if you need to install it: + npm install bignum + ..which will install it locally.. to install it globally add -g to the command + if you have problems loading it due to where you're running ats_sim.js: + export NODE_PATH=/path/to/the/node_modules + For example: + export NODE_PATH=/usr/local/lib/node_modules + ..and the bignum directory is under /usr/local/lib/node/modules + See: https://npmjs.org/package/bignum + ..and: http://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders + */ + var bignum = require('bignum'); + var max = bignum(18446744073709551615); // uint64 max + var seconds_elapsed = Math.ceil((this_request - stats[server_name].last_request) / 1000); // convert to seconds and round up + var last_value = bignum(stats[server_name].last_value); + var current_value = bignum(stats[server_name].value * seconds_elapsed * stats[server_name].multiplier).add(last_value); + + if (debug) console.log(seconds_elapsed + " second(s) elapsed since the last request"); + + if (current_value.cmp(max) > 0) { + if (debug) console.log("Accounting for uint64 rollover; " + current_value.toString() + " > " + max.toString()); + current_value = current_value.sub(max); + } + + if (debug) console.log("Overriding " + ds_tld + "'s " + stats[server_name].parameter + " with " + current_value.toString()); + data[stats[server_name].parameter] = current_value.toString(); // we'll reconvert this to a bignum next time through + } + + stats[server_name].last_value = data[stats[server_name].parameter]; + stats[server_name].last_request = this_request; + } else { + if (debug) console.log("Unable to find " + stats[server_name].parameter + " for " + ds_tld); + } + } + + for (var key in data) { + ret.ats["plugin.remap_stats." + ds_fqdn + "." + key] = parseInt(data[key]); + } + } + } else { + if (debug) console.log(server_name + " was not found in cr_config; returning default stats"); + + for(var i=1; i<=10; i++) { + var n = i.zeroPad(2); + ret.ats["plugin.remap_stats." + server_name + ".omg-" + n + tld+ ".out_bytes"] = parseInt(ds_bytes[i].toFixed(0)); + ret.ats["plugin.remap_stats." + server_name + ".omg-" + n + tld+ ".in_bytes"] = parseInt(ds_bytes_in[i].toFixed(0)); + ret.ats["plugin.remap_stats." + server_name + ".omg-" + n + tld+ ".status_2xx"] = parseInt(ds_200s[i].toFixed(0)); + ret.ats["plugin.remap_stats." + server_name + ".omg-" + n + tld+ ".status_4xx"] = parseInt(ds_400s[i].toFixed(0)); + ret.ats["plugin.remap_stats." + server_name + ".omg-" + n + tld+ ".status_5xx"] = parseInt(ds_500s[i].toFixed(0)); + } + } + + ret.ats["server"] = "5.3.2-dev"; + + ret.system = {}; + ret.system["inf.name"] = query_params["inf.name"]; + ret.system["inf.speed"] = 10000; + ret.system["proc.net.dev"] = proc_net_dev; + ret.system["proc.loadavg"] = proc_loadavg; + ret.system["something"] = "here"; + + return ret; +} ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
