blob: 8c59c0d22b314fb4d99b356144b54b2c6764e758 [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# This is the R script that generates the SCPF front page graphs.
24
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070025
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000026# **********************************************************
27# STEP 1: Data management.
28# **********************************************************
29
Devin Lim0e967162017-11-03 15:59:53 -070030database_host = 1
31database_port = 2
32database_u_id = 3
33database_pw = 4
34graph_title = 5
35branch_name = 6
36num_dates = 7
37sql_commands = 8
38y_axis = 9
39old_flow = 10
40save_directory = 11
41
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070042print( "**********************************************************" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000043print( "STEP 1: Data management." )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070044print( "**********************************************************" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000045
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070046# ----------------
47# Import Libraries
48# ----------------
49
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000050print( "Importing libraries." )
51library( ggplot2 )
52library( reshape2 )
53library( RPostgreSQL )
54
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070055# -------------------
56# Check CLI Arguments
57# -------------------
58
59print( "Verifying CLI args." )
60
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000061# Command line arguments are read. Args include the database credentials, test name, branch name, and the directory to output files.
62print( "Reading commmand-line args." )
63args <- commandArgs( trailingOnly=TRUE )
64
65# Check if sufficient args are provided.
Devin Lim0e967162017-11-03 15:59:53 -070066if ( is.na( args[ save_directory ] ) ){
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070067
68 print( paste( "Usage: Rscript testresultgraph.R",
69 "<database-host>",
70 "<database-port>",
71 "<database-user-id>",
72 "<database-password>",
73 "<graph-title>", # part of the output filename as well
74 "<branch-name>", # part of the output filename
75 "<#-dates>", # part of the output filename
76 "<SQL-command>",
77 "<y-axis-title>", # y-axis may be different among other SCPF graphs (ie: batch size, latency, etc. )
Devin Lim0e967162017-11-03 15:59:53 -070078 "<using-old-flow>",
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070079 "<directory-to-save-graph>",
80 sep = " " ) )
Jeremy Ronquillo9ea85d02017-11-27 10:21:03 -080081 quit( status = 1 ) # basically exit(), but in R
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000082}
83
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070084# -------------------------------
85# Create Title and Graph Filename
86# -------------------------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000087
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070088print( "Creating title of graph" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000089
90# Title of graph based on command line args.
Devin Lim0e967162017-11-03 15:59:53 -070091
92title <- args[ graph_title ]
Devin Lim1bba7622017-11-14 16:31:41 -080093title <- paste( title, if( args[ old_flow ] == "y" ) "\nWith Eventually Consistent Flow Rule Store" else "" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +000094
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070095print( "Creating graph filename." )
96
97# Filenames for the output graph include the testname, branch, and the graph type.
Devin Lim0e967162017-11-03 15:59:53 -070098outputFile <- paste( args[ save_directory ],
Jeremy Ronquillo7673f802017-10-30 09:42:44 -070099 "SCPF_Front_Page_",
Devin Lim0e967162017-11-03 15:59:53 -0700100 gsub( " ", "_", args[ graph_title ] ),
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700101 "_",
Devin Lim0e967162017-11-03 15:59:53 -0700102 args[ branch_name ],
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700103 "_",
Devin Lim0e967162017-11-03 15:59:53 -0700104 args[ num_dates ],
105 "-dates",
106 if( args[ old_flow ] == "y" ) "_OldFlow" else "",
107 "_graph.jpg",
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700108 sep="" )
109
110# ------------------
111# SQL Initialization
112# ------------------
113
114print( "Initializing SQL" )
115con <- dbConnect( dbDriver( "PostgreSQL" ),
116 dbname = "onostest",
Devin Lim0e967162017-11-03 15:59:53 -0700117 host = args[ database_host ],
118 port = strtoi( args[ database_port ] ),
119 user = args[ database_u_id ],
120 password = args[ database_pw ] )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700121
122print( "Sending SQL command:" )
Devin Lim0e967162017-11-03 15:59:53 -0700123print( args[ sql_commands ] )
Jeremy Ronquillo9d867f42017-11-28 14:31:18 -0800124
Devin Lim0e967162017-11-03 15:59:53 -0700125fileData <- dbGetQuery( con, args[ sql_commands ] )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700126
Jeremy Ronquillo9d867f42017-11-28 14:31:18 -0800127# Check if data has been received
128if ( nrow( fileData ) == 0 ){
129 print( "[ERROR]: No data received from the databases. Please double check this by manually running the SQL command." )
130 quit( status = 1 )
131}
132
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000133# **********************************************************
134# STEP 2: Organize data.
135# **********************************************************
136
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700137print( "**********************************************************" )
138print( "STEP 2: Organize Data." )
139print( "**********************************************************" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000140
141# Create lists c() and organize data into their corresponding list.
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700142print( "Combine data retrieved from databases into a list." )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000143
Jeremy Ronquillo20a79662017-12-20 10:58:59 -0800144buildNums <- fileData$build
145fileData$build <- c()
146print( fileData )
147
Jeremy Ronquillo9d867f42017-11-28 14:31:18 -0800148if ( ncol( fileData ) > 1 ){
149 for ( i in 2:ncol( fileData ) ){
150 fileData[ i ] <- fileData[ i - 1 ] + fileData[ i ]
151 }
152}
Jeremy Ronquillo9ea85d02017-11-27 10:21:03 -0800153
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000154
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700155# --------------------
156# Construct Data Frame
157# --------------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000158
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700159print( "Constructing data frame from combined data." )
160
161dataFrame <- melt( fileData )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000162dataFrame$date <- fileData$date
163
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700164colnames( dataFrame ) <- c( "Legend",
165 "Values" )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000166
167# Format data frame so that the data is in the same order as it appeared in the file.
168dataFrame$Legend <- as.character( dataFrame$Legend )
169dataFrame$Legend <- factor( dataFrame$Legend, levels=unique( dataFrame$Legend ) )
Jeremy Ronquillo20a79662017-12-20 10:58:59 -0800170dataFrame$build <- buildNums
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000171
Jeremy Ronquillo2d2649d2017-09-14 12:53:06 -0700172# Adding a temporary iterative list to the dataFrame so that there are no gaps in-between date numbers.
173dataFrame$iterative <- rev( seq( 1, nrow( fileData ), by = 1 ) )
174
175dataFrame <- na.omit( dataFrame ) # Omit any data that doesn't exist
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000176
177print( "Data Frame Results:" )
178print( dataFrame )
179
180# **********************************************************
181# STEP 3: Generate graphs.
182# **********************************************************
183
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700184print( "**********************************************************" )
185print( "STEP 3: Generate Graph." )
186print( "**********************************************************" )
187
188# -------------------
189# Main Plot Generated
190# -------------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000191
192print( "Creating main plot." )
193# Create the primary plot here.
194# ggplot contains the following arguments:
195# - data: the data frame that the graph will be based off of
196# - aes: the asthetics of the graph which require:
197# - x: x-axis values (usually iterative, but it will become date # later)
198# - y: y-axis values (usually tests)
199# - color: the category of the colored lines (usually legend of test)
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700200
201mainPlot <- ggplot( data = dataFrame, aes( x = iterative,
202 y = Values,
203 color = Legend ) )
204
205# -------------------
206# Main Plot Formatted
207# -------------------
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000208
209print( "Formatting main plot." )
210
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700211limitExpansion <- expand_limits( y = 0 )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000212
Jeremy Ronquillo20a79662017-12-20 10:58:59 -0800213tickLength <- 3
214breaks <- seq( max( dataFrame$iterative ) %% tickLength, max( dataFrame$iterative ), by = tickLength )
215breaks <- breaks[ which( breaks != 0 ) ]
216
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700217maxYDisplay <- max( dataFrame$Values ) * 1.05
218yBreaks <- ceiling( max( dataFrame$Values ) / 10 )
219yScaleConfig <- scale_y_continuous( breaks = seq( 0, maxYDisplay, by = yBreaks ) )
Jeremy Ronquillo20a79662017-12-20 10:58:59 -0800220xScaleConfig <- scale_x_continuous( breaks = breaks, label = rev( dataFrame$build )[ breaks ] )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000221
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700222# ------------------------------
223# Fundamental Variables Assigned
224# ------------------------------
225
226print( "Generating fundamental graph data." )
227
228theme_set( theme_grey( base_size = 22 ) ) # set the default text size of the graph.
229xLabel <- xlab( "Build" )
Devin Lim0e967162017-11-03 15:59:53 -0700230yLabel <- ylab( args[ y_axis ] )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000231
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700232imageWidth <- 15
233imageHeight <- 10
234imageDPI <- 200
235
236# Set other graph configurations here.
Jeremy Ronquillo20a79662017-12-20 10:58:59 -0800237theme <- theme( axis.text.x = element_text( angle = 0, size = 13 ),
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700238 plot.title = element_text( size = 32, face='bold', hjust = 0.5 ),
239 legend.position = "bottom",
240 legend.text = element_text( size=22 ),
241 legend.title = element_blank(),
242 legend.key.size = unit( 1.5, 'lines' ),
Jeremy Ronquillo94f99dd2018-01-05 11:11:27 -0800243 legend.direction = 'horizontal',
244 plot.subtitle = element_text( size=16, hjust=1.0 ) )
245
246subtitle <- paste( "Last Updated: ", format( Sys.time(), format = "%b %d, %Y at %I:%M %p %Z" ), sep="" )
247
248title <- labs( title = title, subtitle = subtitle )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700249
250# Colors used for the lines.
251# Note: graphs that have X lines will use the first X colors in this list.
252colors <- scale_color_manual( values=c( "#111111", # black
253 "#008CFF", # blue
254 "#FF3700", # red
255 "#00E043", # green
256 "#EEB600", # yellow
257 "#E500FF") ) # purple (not used)
258
259wrapLegend <- guides( color = guide_legend( nrow = 2, byrow = TRUE ) )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700260
261fundamentalGraphData <- mainPlot +
262 limitExpansion +
Jeremy Ronquillo20a79662017-12-20 10:58:59 -0800263 xScaleConfig +
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700264 yScaleConfig +
265 xLabel +
266 yLabel +
267 theme +
268 colors +
269 wrapLegend +
270 title
271
272# ----------------------------
273# Generating Line Graph Format
274# ----------------------------
275
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000276print( "Generating line graph." )
277
Jeremy Ronquilloe9063762017-10-17 15:36:09 -0700278lineGraphFormat <- geom_line( size = 0.75 )
279pointFormat <- geom_point( size = 1.75 )
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000280
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700281result <- fundamentalGraphData +
282 lineGraphFormat +
283 pointFormat
Jeremy Ronquillo0e27b912017-10-21 14:34:24 -0700284
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700285# -----------------------
286# Exporting Graph to File
287# -----------------------
288
Jeremy Ronquillo6df87812017-08-28 16:17:36 +0000289print( paste( "Saving result graph to", outputFile ) )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700290
Jeremy Ronquillo9ea85d02017-11-27 10:21:03 -0800291tryCatch( ggsave( outputFile,
292 width = imageWidth,
293 height = imageHeight,
294 dpi = imageDPI ),
295 error = function( e ){
296 print( "[ERROR] There was a problem saving the graph due to a graph formatting exception. Error dump:" )
297 print( e )
298 quit( status = 1 )
299 }
300 )
Jeremy Ronquillo7673f802017-10-30 09:42:44 -0700301
302print( paste( "[SUCCESS] Successfully wrote result graph out to", outputFile ) )
Jeremy Ronquillo9ea85d02017-11-27 10:21:03 -0800303quit( status = 0 )