blob: 9123085637b333ddfe8ca3ce71a92cba192fc93e [file] [log] [blame]
Jeremy Ronquillo6df87812017-08-28 16:17:36 +00001# Copyright 2017 Open Networking Foundation (ONF)
2#
3# Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
4# the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
5# or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
6#
7# TestON is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 2 of the License, or
10# (at your option) any later version.
11#
12# TestON is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with TestON. If not, see <http://www.gnu.org/licenses/>.
19#
20# If you have any questions, or if you don't understand R,
Jeremy Ronquillob6268842017-10-03 13:02:58 -070021# please contact Jeremy Ronquillo: j_ronquillo@u.pacific.edu
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000022
23# **********************************************************
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070024# STEP 1: Data management.
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000025# **********************************************************
Devin Lim0e967162017-11-03 15:59:53 -070026has_flow_obj = 1
27database_host = 2
28database_port = 3
29database_u_id = 4
30database_pw = 5
31test_name = 6
32branch_name = 7
33has_neighbors = 8
34old_flow = 9
35save_directory = 10
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000036
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070037print( "**********************************************************" )
38print( "STEP 1: Data management." )
39print( "**********************************************************" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000040
Jeremy Ronquillob6268842017-10-03 13:02:58 -070041# Command line arguments are read.
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000042print( "Reading commmand-line args." )
43args <- commandArgs( trailingOnly=TRUE )
44
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070045# ----------------
46# Import Libraries
47# ----------------
48
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000049print( "Importing libraries." )
50library( ggplot2 )
51library( reshape2 )
52library( RPostgreSQL ) # For databases
53
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070054# -------------------
55# Check CLI Arguments
56# -------------------
57
58print( "Verifying CLI args." )
59
Devin Lim0e967162017-11-03 15:59:53 -070060if ( is.na( args[ save_directory ] ) ){
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070061
62 print( paste( "Usage: Rscript SCPFflowTp1g.R",
63 "<has-flow-obj>",
64 "<database-host>",
65 "<database-port>",
66 "<database-user-id>",
67 "<database-password>",
68 "<test-name>",
69 "<branch-name>",
70 "<has-neighbors>",
Devin Lim0e967162017-11-03 15:59:53 -070071 "<using-old-flow>",
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070072 "<directory-to-save-graphs>",
73 sep=" " ) )
74
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000075 q() # basically exit(), but in R
76}
77
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070078# -----------------
79# Create File Names
80# -----------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000081
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070082print( "Creating filenames and title of graph." )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000083
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070084chartTitle <- "Flow Throughput Test"
85fileNeighborsModifier <- "no"
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000086commandNeighborModifier <- ""
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070087fileFlowObjModifier <- ""
88sqlFlowObjModifier <- ""
Devin Lim0e967162017-11-03 15:59:53 -070089if ( args[ has_flow_obj ] == 'y' ){
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070090 fileFlowObjModifier <- "_flowObj"
91 sqlFlowObjModifier <- "_fobj"
92 chartTitle <- paste( chartTitle, " with Flow Objectives", sep="" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000093}
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070094
95chartTitle <- paste( chartTitle, "\nNeighbors =", sep="" )
96
Devin Lim0e967162017-11-03 15:59:53 -070097fileOldFlowModifier <- ""
98if ( args[ has_neighbors ] == 'y' ){
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070099 fileNeighborsModifier <- "all"
Jeremy Ronquillo2d2649d2017-09-14 12:53:06 -0700100 commandNeighborModifier <- "scale=1 OR NOT "
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700101 chartTitle <- paste( chartTitle, "Cluster Size - 1" )
102} else {
103 chartTitle <- paste( chartTitle, "0" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000104}
Devin Lim0e967162017-11-03 15:59:53 -0700105if ( args[ old_flow ] == 'y' ){
106 fileOldFlowModifier <- "_OldFlow"
Devin Lim1bba7622017-11-14 16:31:41 -0800107 chartTitle <- paste( chartTitle, "With Eventually Consistent Flow Rule Store", sep="\n" )
Devin Lim0e967162017-11-03 15:59:53 -0700108}
109errBarOutputFile <- paste( args[ save_directory ],
110 args[ test_name ],
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700111 "_",
Devin Lim0e967162017-11-03 15:59:53 -0700112 args[ branch_name ],
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700113 "_",
114 fileNeighborsModifier,
115 "-neighbors",
116 fileFlowObjModifier,
Devin Lim0e967162017-11-03 15:59:53 -0700117 fileOldFlowModifier,
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700118 "_graph.jpg",
119 sep="" )
120# ------------------
121# SQL Initialization
122# ------------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000123
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700124print( "Initializing SQL" )
125
126con <- dbConnect( dbDriver( "PostgreSQL" ),
127 dbname = "onostest",
Devin Lim0e967162017-11-03 15:59:53 -0700128 host = args[ database_host ],
129 port = strtoi( args[ database_port ] ),
130 user = args[ database_u_id ],
131 password = args[ database_pw ] )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700132
133# ---------------------------
134# Flow Throughput SQL Command
135# ---------------------------
136
137print( "Generating Flow Throughput SQL command." )
138
139command <- paste( "SELECT scale, avg( avg ), avg( std ) FROM flow_tp",
140 sqlFlowObjModifier,
141 "_tests WHERE (",
142 commandNeighborModifier,
143 "neighbors = 0 ) AND branch = '",
Devin Lim0e967162017-11-03 15:59:53 -0700144 args[ branch_name ],
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700145 "' AND date IN ( SELECT max( date ) FROM flow_tp",
146 sqlFlowObjModifier,
147 "_tests WHERE branch='",
Devin Lim0e967162017-11-03 15:59:53 -0700148 args[ branch_name ],
149 "' AND ",
150 ( if( args[ old_flow ] == 'y' ) "" else "NOT " ),
151 "is_old_flow",
152 " ) GROUP BY scale ORDER BY scale",
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700153 sep="" )
154
155print( "Sending SQL command:" )
156print( command )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000157
158fileData <- dbGetQuery( con, command )
159
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000160# **********************************************************
161# STEP 2: Organize data.
162# **********************************************************
163
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700164print( "**********************************************************" )
165print( "STEP 2: Organize Data." )
166print( "**********************************************************" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000167
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700168# ------------
169# Data Sorting
170# ------------
171
172print( "Sorting data for Flow Throughput." )
173
174colnames( fileData ) <- c( "scale",
175 "avg",
176 "std" )
177
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000178avgs <- c( fileData[ 'avg' ] )
179
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700180
181# ----------------------------
182# Flow TP Construct Data Frame
183# ----------------------------
184
185print( "Constructing Flow TP data frame." )
186
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000187dataFrame <- melt( avgs ) # This is where reshape2 comes in. Avgs list is converted to data frame
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700188dataFrame$scale <- fileData$scale # Add node scaling to the data frame.
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000189dataFrame$std <- fileData$std
190
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700191colnames( dataFrame ) <- c( "throughput",
192 "type",
193 "scale",
194 "std" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000195
Jeremy Ronquillo2d2649d2017-09-14 12:53:06 -0700196dataFrame <- na.omit( dataFrame ) # Omit any data that doesn't exist
197
198print( "Data Frame Results:" )
199print( dataFrame )
200
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000201# **********************************************************
202# STEP 3: Generate graphs.
203# **********************************************************
204
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700205print( "**********************************************************" )
206print( "STEP 3: Generate Graph." )
207print( "**********************************************************" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000208
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700209# ------------------
210# Generate Main Plot
211# ------------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000212
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700213print( "Generating main plot." )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000214# Create the primary plot here.
215# ggplot contains the following arguments:
216# - data: the data frame that the graph will be based off of
217# - aes: the asthetics of the graph which require:
218# - x: x-axis values (usually node scaling)
219# - y: y-axis values (usually time in milliseconds)
220# - fill: the category of the colored side-by-side bars (usually type)
Jeremy Ronquillo2d2649d2017-09-14 12:53:06 -0700221
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700222mainPlot <- ggplot( data = dataFrame, aes( x = scale,
223 y = throughput,
224 ymin = throughput,
225 ymax = throughput + std,
226 fill = type ) )
227# ------------------------------
228# Fundamental Variables Assigned
229# ------------------------------
Jeremy Ronquillo2d2649d2017-09-14 12:53:06 -0700230
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700231print( "Generating fundamental graph data." )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000232
233# Formatting the plot
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700234theme_set( theme_grey( base_size = 22 ) ) # set the default text size of the graph.
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000235width <- 0.7 # Width of the bars.
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700236xScaleConfig <- scale_x_continuous( breaks = dataFrame$scale,
237 label = dataFrame$scale )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000238xLabel <- xlab( "Scale" )
Jeremy Ronquillo1bdaae52017-09-22 11:39:48 -0700239yLabel <- ylab( "Throughput (,000 Flows/sec)" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000240fillLabel <- labs( fill="Type" )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700241imageWidth <- 15
242imageHeight <- 10
243imageDPI <- 200
244errorBarColor <- rgb( 140, 140, 140, maxColorValue=255 )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000245
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700246theme <- theme( plot.title = element_text( hjust = 0.5,
247 size = 32,
248 face = 'bold' ) )
249title <- ggtitle( chartTitle )
Jeremy Ronquillo4363d092017-10-13 13:28:47 -0700250
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000251# Store plot configurations as 1 variable
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700252fundamentalGraphData <- mainPlot +
253 xScaleConfig +
254 xLabel +
255 yLabel +
256 fillLabel +
257 theme +
258 title
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000259
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700260# ---------------------------
261# Generating Bar Graph Format
262# ---------------------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000263
264# Create the stacked bar graph with error bars.
265# geom_bar contains:
266# - stat: data formatting (usually "identity")
267# - width: the width of the bar types (declared above)
268# geom_errorbar contains similar arguments as geom_bar.
269print( "Generating bar graph with error bars." )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700270barGraphFormat <- geom_bar( stat = "identity",
271 width = width,
272 fill = "#FFAA3C" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000273
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700274errorBarFormat <- geom_errorbar( width = width,
275 position = position_dodge(),
276 color = errorBarColor )
277
278values <- geom_text( aes( x = dataFrame$scale,
279 y = dataFrame$throughput + 0.03 * max( dataFrame$throughput ),
280 label = format( dataFrame$throughput,
281 digits=3,
282 big.mark = ",",
283 scientific = FALSE ) ),
284 size = 7.0,
285 fontface = "bold" )
286
287result <- fundamentalGraphData +
288 barGraphFormat +
289 errorBarFormat +
290 values
291
292# -----------------------
293# Exporting Graph to File
294# -----------------------
295
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000296print( paste( "Saving bar chart with error bars to", errBarOutputFile ) )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700297
298ggsave( errBarOutputFile,
299 width = imageWidth,
300 height = imageHeight,
301 dpi = imageDPI )
302
303print( paste( "[SUCCESS] Successfully wrote bar chart with error bars out to", errBarOutputFile ) )