blob: 3b1ac6c5461bf851555f92a3a007c827f81551c6 [file] [log] [blame]
Jeremy Ronquillob4076492018-05-11 13:04:16 -07001# 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# Example script:
Jeremy Ronquillob9c92942018-05-15 17:26:52 -070021# Rscript trendCHO event.csv failure.csv error.csv master 60 168 /path/to/save/directory/
Jeremy Ronquillob4076492018-05-11 13:04:16 -070022
Jeremy Ronquillob4076492018-05-11 13:04:16 -070023# **********************************************************
24# STEP 1: Data management.
25# **********************************************************
26
27print( "**********************************************************" )
28print( "STEP 1: Data management." )
29print( "**********************************************************" )
30
31# Command line arguments are read. Args include the database credentials, test name, branch name, and the directory to output files.
32print( "Reading commmand-line args." )
33args <- commandArgs( trailingOnly=TRUE )
34
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -070035
36limitToDisplayIndividually <- 37 # must be less than this number to display individually
37
Jeremy Ronquillob4076492018-05-11 13:04:16 -070038event_input_file <- 1
39failure_input_file <- 2
40error_input_file <- 3
41branch_name <- 4
42time_quantum <- 5
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -070043maxDataToDisplayParam <- 6 # the maximum amount of data to display on the graph. Last data point is most recent
44save_directory <- 7
Jeremy Ronquillob4076492018-05-11 13:04:16 -070045
46# ----------------
47# Import Libraries
48# ----------------
49
50print( "Importing libraries." )
51library( ggplot2 )
52library( reshape2 )
53library( RPostgreSQL )
Devin Lim324806b2018-05-11 15:36:52 -070054source( "~/OnosSystemTest/TestON/JenkinsFile/wikiGraphRScripts/dependencies/saveGraph.R" )
55source( "~/OnosSystemTest/TestON/JenkinsFile/wikiGraphRScripts/dependencies/fundamentalGraphData.R" )
Jeremy Ronquillob4076492018-05-11 13:04:16 -070056
57# -------------------
58# Check CLI Arguments
59# -------------------
60
61print( "Verifying CLI args." )
62
63if ( length( args ) != save_directory ){
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -070064 print( "Usage: Rscript trendCHO.R <events-input-file> <failures-input-file> <errors-input-file> <branch-name> <time_quantum> <max-data-to-display> <directory-to-save-graph>" )
Jeremy Ronquillob4076492018-05-11 13:04:16 -070065 quit( status = 1 )
66}
67
68# ----------------------
69# Read From File: Events
70# ----------------------
71
72print( "Reading from file for 'events' input." )
73
74event_fileData <- read.delim2( args[ event_input_file ],
75 header = TRUE,
76 sep = ",",
77 dec = "." )
78print( "Event File Data:" )
79print( event_fileData )
80
81# ------------------------
82# Read From File: Failures
83# ------------------------
84
85print( "Reading from file for 'failure' input." )
86
87failure_fileData <- read.delim2( args[ failure_input_file ],
88 header = TRUE,
89 sep = ",",
90 dec = "." )
91print( "Failure File Data:" )
92print( failure_fileData )
93
94# ----------------------
95# Read From File: Errors
96# ----------------------
97
98print( "Reading from file for 'errors' input." )
99
100error_fileData <- read.delim2( args[ error_input_file ],
101 header = TRUE,
102 sep = ",",
103 dec = "." )
104print( "Error File Data:" )
105print( error_fileData )
106
107# -------------------------------
108# Create Title and Graph Filename
109# -------------------------------
110
111print( "Creating titles of graphs." )
112
113failedChecksTitle <- paste( "Failed Checks - ",
114 args[ branch_name ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700115 "\nFrequency per ",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700116 args[ time_quantum ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700117 " Minutes - Last ",
118 args[ maxDataToDisplayParam ],
119 " Hours",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700120 sep="" )
121
122eventsTitle <- paste( "Network, Application, and ONOS Events - ",
123 args[ branch_name ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700124 "\nFrequency per ",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700125 args[ time_quantum ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700126 " Minutes - Last ",
127 args[ maxDataToDisplayParam ],
128 " Hours",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700129 sep="" )
130
131errorsTitle <- paste( "Warnings, Errors, and Exceptions from Logs - ",
132 args[ branch_name ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700133 "\nFrequency per ",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700134 args[ time_quantum ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700135 " Minutes - Last ",
136 args[ maxDataToDisplayParam ],
137 " Hours",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700138 sep="" )
139
140print( "Creating graph filenames." )
141
142failedChecksFilename <- paste( args[ save_directory ],
143 "CHO_Failure-Check_",
144 args[ branch_name ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700145 "_",
146 args[ maxDataToDisplayParam ],
147 "-maxData_graph.jpg",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700148 sep="" )
149
150eventsFilename <- paste( args[ save_directory ],
151 "CHO_Events_",
152 args[ branch_name ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700153 "_",
154 args[ maxDataToDisplayParam ],
155 "-maxData_graph.jpg",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700156 sep="" )
157
158errorsFilename <- paste( args[ save_directory ],
159 "CHO_Errors_",
160 args[ branch_name ],
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700161 "_",
162 args[ maxDataToDisplayParam ],
163 "-maxData_graph.jpg",
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700164 sep="" )
165
166# **********************************************************
167# STEP 2: Organize data.
168# **********************************************************
169
170print( "**********************************************************" )
171print( "STEP 2: Organize Data." )
172print( "**********************************************************" )
173
174# -------------------------------------------------------
175# Verifying all required columns are present.
176# -------------------------------------------------------
177
178# ------------------
179# Verifying 'Events'
180# ------------------
181
182print( "Verifying all required columns are present for 'events'." )
183
184requiredColumns <- c( "Link.Down",
185 "Link.Up",
186 "Device.Down",
187 "Device.Up",
188 "Add.Host.Intent",
189 "Delete.Host.Intent",
190 "Add.Point.Intent",
191 "Delete.Point.Intent",
192 "ONOS.Down",
193 "ONOS.Up" )
194
195tryCatch( eventsCombined <- c( event_fileData[ requiredColumns] ),
196 error = function( e ) {
197 print( "[ERROR] One or more expected columns are missing from 'events'. Please check that the data and file are valid, then try again." )
198 print( "Required columns: " )
199 print( requiredColumns )
200 print( "Actual columns: " )
201 print( names( event_fileData ) )
202 print( "Error dump:" )
203 print( e )
204 quit( status = 1 )
205 }
206 )
207
208# --------------------
209# Verifying 'Failures'
210# --------------------
211
212print( "Verifying all required columns are present for 'failures'." )
213
214requiredColumns <- c( "Intent.Check.Failure",
215 "Flow.Check.Failure",
216 "Traffic.Check.Failure",
217 "Topo.Check.Failure",
218 "ONOS.Check.Failure" )
219
220tryCatch( failureCombined <- c( failure_fileData[ requiredColumns] ),
221 error = function( e ) {
222 print( "[ERROR] One or more expected columns are missing from 'failures'. Please check that the data and file are valid, then try again." )
223 print( "Required columns: " )
224 print( requiredColumns )
225 print( "Actual columns: " )
226 print( names( failure_fileData ) )
227 print( "Error dump:" )
228 print( e )
229 quit( status = 1 )
230 }
231 )
232
233# ------------------
234# Verifying 'Errors'
235# ------------------
236
237print( "Verifying all required columns are present for 'errors'." )
238
239requiredColumns <- c( "Test.Warnings",
240 "ONOS.Warnings",
241 "ONOS.Errors",
242 "Exceptions" )
243
244tryCatch( errorCombined <- c( error_fileData[ requiredColumns] ),
245 error = function( e ) {
246 print( "[ERROR] One or more expected columns are missing from 'errors'. Please check that the data and file are valid, then try again." )
247 print( "Required columns: " )
248 print( requiredColumns )
249 print( "Actual columns: " )
250 print( names( error_fileData ) )
251 print( "Error dump:" )
252 print( e )
253 quit( status = 1 )
254 }
255 )
256
257# -------------------------------
258# Create Events Data Frame
259# -------------------------------
260
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700261maxDataToDisplay <- strtoi( args[ maxDataToDisplayParam ] )
262
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700263# -------------------
264# 'Events' Data Frame
265# -------------------
266
267print( "Constructing data frame for 'events'." )
268
269events_dataFrame <- melt( eventsCombined )
270
271# Rename column names in events_dataFrame
272colnames( events_dataFrame ) <- c( "Events",
273 "Type" )
274
275# Format data frame so that the data is in the same order as it appeared in the file.
276events_dataFrame$Type <- as.character( events_dataFrame$Type )
277events_dataFrame$Type <- factor( events_dataFrame$Type, levels = unique( events_dataFrame$Type ) )
278
You Wang69a19512018-05-15 11:03:11 -0700279events_dataFrame$timeStamps <- gsub('^(.{11})(.*)$', '\\1\n\\2', event_fileData$Time )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700280
281# Adding a temporary reversed iterative list to the events_dataFrame so that there are no gaps in-between build numbers.
You Wang69a19512018-05-15 11:03:11 -0700282events_dataFrame$iterative <- seq( 1, nrow( event_fileData ), by = 1 )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700283
284# Omit any data that doesn't exist
285events_dataFrame <- na.omit( events_dataFrame )
286
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700287
288dataLength <- nrow( event_fileData )
289moduloFactor <- floor( dataLength / limitToDisplayIndividually ) + 1
290
291if ( dataLength > maxDataToDisplay ){
292 events_dataFrame <- events_dataFrame[ events_dataFrame$iterative >= dataLength - maxDataToDisplay, ]
293}
294
295if ( moduloFactor > 1 ){
296 events_dataFrame[ events_dataFrame$iterative %% moduloFactor != dataLength %% moduloFactor, ]$timeStamps <- ""
297}
298
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700299print( "'Events' Data Frame Results:" )
300print( events_dataFrame )
301
302# ---------------------
303# 'Failures' Data Frame
304# ---------------------
305
306print( "Constructing data frame for 'failures'." )
307
308failures_dataFrame <- melt( failureCombined )
309
310# Rename column names in failures_dataFrame
311colnames( failures_dataFrame ) <- c( "Failures",
312 "Type" )
313
314# Format data frame so that the data is in the same order as it appeared in the file.
315failures_dataFrame$Type <- as.character( failures_dataFrame$Type )
316failures_dataFrame$Type <- factor( failures_dataFrame$Type, levels = unique( failures_dataFrame$Type ) )
317
You Wang69a19512018-05-15 11:03:11 -0700318failures_dataFrame$timeStamps <- gsub('^(.{11})(.*)$', '\\1\n\\2', failure_fileData$Time )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700319
320# Adding a temporary reversed iterative list to the failures_dataFrame so that there are no gaps in-between build numbers.
You Wang69a19512018-05-15 11:03:11 -0700321failures_dataFrame$iterative <- seq( 1, nrow( failure_fileData ), by = 1 )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700322
323# Omit any data that doesn't exist
324failures_dataFrame <- na.omit( failures_dataFrame )
325
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700326if ( dataLength > maxDataToDisplay ){
327 failures_dataFrame <- failures_dataFrame[ failures_dataFrame$iterative >= dataLength - maxDataToDisplay, ]
328}
329
330if ( moduloFactor > 1 ){
331 failures_dataFrame[ failures_dataFrame$iterative %% moduloFactor != dataLength %% moduloFactor, ]$timeStamps <- ""
332}
333
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700334print( "'Failures' Data Frame Results:" )
335print( failures_dataFrame )
336
337# -------------------
338# 'Errors' Data Frame
339# -------------------
340
341print( "Constructing data frame for 'errors'." )
342
343errors_dataFrame <- melt( errorCombined )
344
345# Rename column names in errors_dataFrame
346colnames( errors_dataFrame ) <- c( "Errors",
347 "Type" )
348
349# Format data frame so that the data is in the same order as it appeared in the file.
350errors_dataFrame$Type <- as.character( errors_dataFrame$Type )
351errors_dataFrame$Type <- factor( errors_dataFrame$Type, levels = unique( errors_dataFrame$Type ) )
352
353errors_dataFrame$timeStamps <- gsub('^(.{11})(.*)$', '\\1\n\\2', error_fileData$Time )
354
355# Adding a temporary reversed iterative list to the errors_dataFrame so that there are no gaps in-between build numbers.
356errors_dataFrame$iterative <- seq( 1, nrow( error_fileData ), by = 1 )
357
358# Omit any data that doesn't exist
359errors_dataFrame <- na.omit( errors_dataFrame )
360
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700361if ( dataLength > maxDataToDisplay ){
362 errors_dataFrame <- errors_dataFrame[ errors_dataFrame$iterative >= dataLength - maxDataToDisplay, ]
363}
364
365if ( moduloFactor > 1 ){
366 errors_dataFrame[ errors_dataFrame$iterative %% moduloFactor != dataLength %% moduloFactor, ]$timeStamps <- ""
367}
368
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700369print( "'Errors' Data Frame Results:" )
370print( errors_dataFrame )
371
372# **********************************************************
373# STEP 3: Generate graphs.
374# **********************************************************
375
376print( "**********************************************************" )
377print( "STEP 3: Generate Graph." )
378print( "**********************************************************" )
379
380# -------------------
381# Main Plot Generated
382# -------------------
383
384print( "Creating main plots." )
385
386eventsPlot <- ggplot( data = events_dataFrame, aes( x = iterative,
387 y = Events,
388 color = Type ) )
389
390failuresPlot <- ggplot( data = failures_dataFrame, aes( x = iterative,
391 y = Failures,
392 color = Type ) )
393
394errorsPlot <- ggplot( data = errors_dataFrame, aes( x = iterative,
395 y = Errors,
396 color = Type ) )
397
398# ------------------------------
399# Fundamental Variables Assigned
400# ------------------------------
401
402print( "Generating fundamental graph data used in all 3 graphs." )
403
404defaultTextSize()
405
406yAxisTicksExponents <- seq( -1, floor( max( c( max( events_dataFrame$Events ), max( failures_dataFrame$Failures ), max( errors_dataFrame$Errors ) ) ) ^ 0.1 ) + 1, by=1 )
407yAxisTicks <- 10 ^ yAxisTicksExponents
408yAxisTicksLabels <- floor( yAxisTicks )
409
410yScaleConfig <- scale_y_log10( breaks = yAxisTicks,
411 labels = yAxisTicksLabels )
412xLabel <- xlab( "Time" )
413
414print( "Generating line graph." )
415
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700416lineGraphFormat <- geom_line( size = 0.5 )
417pointFormat <- geom_point( size = 0 )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700418
Jeremy Ronquillo75c8a052018-05-11 15:59:40 -0700419graphTheme <- graphTheme() + theme( axis.text.x = element_text( angle = 90, hjust = 1.0, vjust = 0.5, size = 11 ),
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700420 axis.text.y = element_text( size = 17 ) )
421
422# -------------------
423# 'Events' Graph Data
424# -------------------
425
426print( "Generating 'events' graph data." )
427
428yLabel <- ylab( "Events" )
429
430xScaleConfig <- scale_x_continuous( breaks = events_dataFrame$iterative,
431 label = events_dataFrame$timeStamps )
432
433lineColorsAndLabels <- scale_color_manual( values=c( webColor( "light_blue" ),
434 webColor( "red" ),
435 webColor( "purple" ),
436 webColor( "yellow" ),
437 webColor( "orange" ),
438 webColor( "blue" ),
439 webColor( "magenta" ),
440 webColor( "green" ),
441 webColor( "brown" ),
442 webColor( "black" )
443 ),
444 labels = c( "Link Down",
445 "Link Up",
446 "Device Down",
447 "Device Up",
448 "Add Host Intent",
449 "Delete Host Intent",
450 "Add Point Intent",
451 "Delete Point Intent",
452 "ONOS Down",
453 "ONOS Up" )
454 )
455
Jeremy Ronquillo76efee42020-01-13 13:27:44 -0800456title <- labs( title = eventsTitle, subtitle = lastUpdatedLabel( Sys.time() ) )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700457
458result <- eventsPlot +
459 xScaleConfig +
460 yScaleConfig +
461 xLabel +
462 yLabel +
463 graphTheme +
464 title +
465 lineGraphFormat +
466 lineColorsAndLabels +
467 pointFormat
468
469# -----------------------
470# Exporting Graph to File
471# -----------------------
472
473saveGraph( eventsFilename ) # from saveGraph.R
474
475# ---------------------
476# 'Failures' Graph Data
477# ---------------------
478
479print( "Generating 'failures' graph data." )
480
481yLabel <- ylab( "Failures" )
482
483xScaleConfig <- scale_x_continuous( breaks = failures_dataFrame$iterative,
484 label = failures_dataFrame$timeStamps )
485
486lineColorsAndLabels <- scale_color_manual( values=c( webColor( "red" ),
487 webColor( "yellow" ),
488 webColor( "green" ),
489 webColor( "blue" ),
490 webColor( "magenta" )
491 ),
492 labels = c( "Intent Check Failure",
493 "Flow Check Failure",
494 "Traffic Check Failure",
495 "Topo Check Failure",
496 "ONOS Check Failure" )
497 )
498
Jeremy Ronquillo76efee42020-01-13 13:27:44 -0800499title <- labs( title = failedChecksTitle, subtitle = lastUpdatedLabel( Sys.time() ) )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700500
501result <- failuresPlot +
502 xScaleConfig +
503 yScaleConfig +
504 xLabel +
505 yLabel +
506 graphTheme +
507 title +
508 lineGraphFormat +
509 lineColorsAndLabels + wrapLegend(byrow=FALSE) +
510 pointFormat
511
512
513# -----------------------
514# Exporting Graph to File
515# -----------------------
516
517saveGraph( failedChecksFilename ) # from saveGraph.R
518
519# ---------------------
520# 'Errors' Graph Data
521# ---------------------
522
523print( "Generating 'errors' graph data." )
524
Jeremy Ronquillob9c92942018-05-15 17:26:52 -0700525yLabel <- ylab( "Warnings/Errors" )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700526
527xScaleConfig <- scale_x_continuous( breaks = errors_dataFrame$iterative,
528 label = errors_dataFrame$timeStamps )
529
530lineColorsAndLabels <- scale_color_manual( values=c( webColor( "magenta" ),
531 webColor( "yellow" ),
532 webColor( "orange" ),
533 webColor( "red" )
534 ),
535 labels = c( "Test Warnings",
536 "ONOS Warnings",
537 "ONOS Errors",
538 "Exceptions" )
539 )
540
Jeremy Ronquillo76efee42020-01-13 13:27:44 -0800541title <- labs( title = errorsTitle, subtitle = lastUpdatedLabel( Sys.time() ) )
Jeremy Ronquillob4076492018-05-11 13:04:16 -0700542
543result <- errorsPlot +
544 xScaleConfig +
545 yScaleConfig +
546 xLabel +
547 yLabel +
548 graphTheme +
549 title +
550 lineGraphFormat +
551 lineColorsAndLabels +
552 pointFormat
553
554# -----------------------
555# Exporting Graph to File
556# -----------------------
557
Devin Lim324806b2018-05-11 15:36:52 -0700558saveGraph( errorsFilename ) # from saveGraph.R