solaris-patch 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +17 -11
- data/lib/solaris/exception.rb +9 -5
- data/lib/solaris/patchdiag.rb +94 -62
- data/lib/solaris/patchdiag_entry.rb +24 -8
- data/test/test_patchdiag.rb +108 -14
- metadata +4 -5
- data/lib/solaris/foo +0 -13
data/README.rdoc
CHANGED
@@ -9,32 +9,38 @@ Copyright:: Copyright (c) Martin Carpenter 2011
|
|
9
9
|
The solaris-patch gem helps with the manipulation of SunOS and Solaris
|
10
10
|
patches.
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
* Read (or write!) patchdiag.xref files.
|
13
|
+
* Find latest version of a patch.
|
14
|
+
* Find latest non-superseded version of a patch.
|
15
|
+
* Download patchdiag.xref, patches, readmes from Oracle.
|
16
|
+
* ...
|
17
17
|
|
18
18
|
== Examples
|
19
19
|
|
20
20
|
=== Download a patch
|
21
21
|
|
22
22
|
require 'solaris/patch'
|
23
|
-
Solaris::Patch.download_patch!('123456-78',
|
24
|
-
|
23
|
+
Solaris::Patch.download_patch!( '123456-78',
|
24
|
+
:to_file => '/tmp/123456-78.zip' )
|
25
25
|
|
26
26
|
Alternatively:
|
27
27
|
|
28
28
|
patch = Solaris::Patch.new( '123456-78' )
|
29
29
|
patch.download_patch!( :to_dir => '/tmp' )
|
30
30
|
|
31
|
+
=== Download a readme
|
32
|
+
|
33
|
+
require 'solaris/patch'
|
34
|
+
Solaris::Patch.download_readme!( '123456-78',
|
35
|
+
:to_file => '/tmp/123456-78.txt' )
|
36
|
+
|
31
37
|
=== Get the latest version of a patch
|
32
38
|
|
33
39
|
require 'solaris/patch'
|
34
40
|
Solaris::Patchdiag.open( '/tmp/patchdiag.xref' ).latest( '123456-01' )
|
35
41
|
=> "123456|12|..."
|
36
42
|
|
37
|
-
=== Get the latest non-obsolete version of
|
43
|
+
=== Get the latest non-obsolete version of a possibly obsoleted patch
|
38
44
|
|
39
45
|
require 'solaris/patch'
|
40
46
|
Solaris::Patchdiag.open( '/tmp/patchdiag.xref' ).successor( '123456-01' )
|
@@ -48,11 +54,11 @@ Alternatively:
|
|
48
54
|
patchdiag = Solaris::Patchdiag.new( '/tmp/patchdiag.xref' )
|
49
55
|
|
50
56
|
# all sparc patches
|
51
|
-
patchdiag.
|
57
|
+
patchdiag.select { |p| p.archs.include? 'sparc' }.inspect
|
52
58
|
=> [ "123456-78", ... ]
|
53
59
|
|
54
60
|
# latest line added to patchdiag.xref
|
55
|
-
most_recent = patchdiag.
|
61
|
+
most_recent = patchdiag.sort_by( &:date ).last
|
56
62
|
most_recent
|
57
63
|
=> "123456|78|..."
|
58
64
|
|
@@ -67,5 +73,5 @@ Alternatively:
|
|
67
73
|
== Known issues
|
68
74
|
|
69
75
|
Dates in patchdiag.xref are Mon/dd/yy format. This gem will break in
|
70
|
-
2050 since it assumes year 50 and above is in the 20th
|
76
|
+
2050 since it assumes year 50 and above is in the 20th century.
|
71
77
|
|
data/lib/solaris/exception.rb
CHANGED
@@ -6,11 +6,6 @@ module Solaris
|
|
6
6
|
# Superclass for all throwable exceptions.
|
7
7
|
class Exception < ::Exception ; end
|
8
8
|
|
9
|
-
# Exception is raised by #find_successor when the patch whose
|
10
|
-
# successor is to be sought or the supposed successor to a patch
|
11
|
-
# does not exist in patchdiag.xref.
|
12
|
-
class NotFound < Exception ; end
|
13
|
-
|
14
9
|
# Exception is raised when the terminal (non-obsolete) succesor
|
15
10
|
# to a patch has been withdrawn (is bad).
|
16
11
|
class BadSuccessor < Exception ; end
|
@@ -22,9 +17,18 @@ module Solaris
|
|
22
17
|
# Raised if a patchdiag entry appears to have multiple successors.
|
23
18
|
class MultipleSuccessors < Exception ; end
|
24
19
|
|
20
|
+
# Exception is raised by Patchdiag#successor when the patch whose
|
21
|
+
# successor is to be sought or the supposed successor to a patch
|
22
|
+
# does not exist in patchdiag.xref.
|
23
|
+
class NotFound < Exception ; end
|
24
|
+
|
25
25
|
# Raised if one tries to determine the successor of a non-obsolete patch.
|
26
26
|
class NotObsolete < Exception ; end
|
27
27
|
|
28
|
+
# Raised when seeking the successor to a patch in patchdiag.xref results
|
29
|
+
# in a loop.
|
30
|
+
class SuccessorLoop < Exception ; end
|
31
|
+
|
28
32
|
end
|
29
33
|
|
30
34
|
end # Solaris
|
data/lib/solaris/patchdiag.rb
CHANGED
@@ -12,24 +12,22 @@ module Solaris
|
|
12
12
|
require 'solaris/patchdiag_entry'
|
13
13
|
require 'solaris/util'
|
14
14
|
|
15
|
+
include Enumerable
|
16
|
+
|
15
17
|
# Default patchdiag.xref file, as for Patch Check Advanced cache
|
16
18
|
DEFAULT_XREF_FILE = '/var/tmp/patchdiag.xref'
|
17
19
|
|
18
20
|
# URL of latest patchdiag.xref from Oracle.
|
19
21
|
DEFAULT_XREF_URL = 'https://getupdates.oracle.com/reports/patchdiag.xref'
|
20
22
|
|
21
|
-
# An array containing all entries (of class PatchdiagEntry) read
|
22
|
-
# from the patchdiag.xref file.
|
23
|
-
attr_accessor :entries
|
24
|
-
|
25
23
|
# Create a new patchdiag database object by reading the given
|
26
24
|
# xref file (this may be a filename (string) or a fileish object
|
27
25
|
# (File, StringIO)). If no xref file is given then the default
|
28
26
|
# is read (/var/tmp/patchdiag.xref); this is the cache file used
|
29
27
|
# by Patch Check Advanced (pca).
|
30
28
|
def initialize(xref_file=DEFAULT_XREF_FILE)
|
31
|
-
xref_file = File.new( xref_file ) if xref_file.is_a?(String)
|
32
|
-
@
|
29
|
+
xref_file = File.new( xref_file ) if xref_file.is_a?( String )
|
30
|
+
@_entries = xref_file.
|
33
31
|
readlines.
|
34
32
|
reject { |line| line =~ /^#|^\s*$/ }. # discard comments, blanks
|
35
33
|
map { |line| PatchdiagEntry.new( line ) }
|
@@ -44,8 +42,8 @@ module Solaris
|
|
44
42
|
Util.download!( url, opts )
|
45
43
|
end
|
46
44
|
|
47
|
-
# Open the given optional patchdiag xref file and yield to the
|
48
|
-
# block.
|
45
|
+
# Open the given optional patchdiag xref file and yield to the
|
46
|
+
# optional block.
|
49
47
|
def Patchdiag.open(xref_file=DEFAULT_XREF_FILE, &blk)
|
50
48
|
patchdiag = Patchdiag.new( xref_file )
|
51
49
|
if block_given?
|
@@ -55,79 +53,113 @@ module Solaris
|
|
55
53
|
end
|
56
54
|
end
|
57
55
|
|
58
|
-
#
|
59
|
-
|
60
|
-
|
56
|
+
# Create and return a deep copy of this object.
|
57
|
+
def clone
|
58
|
+
Marshal.load( Marshal.dump( self ) )
|
59
|
+
end
|
60
|
+
|
61
|
+
# For Enumerator module: yields each Solaris::PatchdiagEntry in
|
62
|
+
# turn.
|
63
|
+
def each(&blk)
|
64
|
+
@_entries.each( &blk )
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns an array of Solaris::PatchdiagEntry from the
|
68
|
+
# patchdiag.xref with the given patch number (a String like
|
69
|
+
# xxxxxx-yy or xxxxxx or a Solaris::Patch), sorted by minor number.
|
70
|
+
# If both a major and minor number are supplied (xxxxxx-yy) then
|
71
|
+
# returned entries (normally only one) will match exactly. If only
|
72
|
+
# a major number (xxxxxx) is supplied then all entries with that
|
73
|
+
# major number are returned. Returns an empty array if no such
|
74
|
+
# patches can be found. This method overrides Enumerable#find.
|
61
75
|
def find(patch)
|
62
76
|
patch = Patch.new( patch.to_s )
|
63
77
|
property = patch.minor ? :to_s : :major
|
64
78
|
comparator = patch.send( property )
|
65
|
-
|
79
|
+
entries.select { |pde| pde.patch.send( property ) == comparator }
|
66
80
|
end
|
67
81
|
|
68
|
-
#
|
69
|
-
#
|
70
|
-
|
82
|
+
# Strangely Enumerable module does not define Enumerable#last (although
|
83
|
+
# it does define Enumerable#first) so we define last here.
|
84
|
+
def last
|
85
|
+
entries.last
|
86
|
+
end
|
87
|
+
|
88
|
+
# Return the Solaris::PatchdiagEntry of the latest version of the
|
89
|
+
# given patch (a String like xxxxxx-yy or xxxxxx or a
|
90
|
+
# Solaris::Patch). Throws Solaris::Patch::NotFound if the patch
|
91
|
+
# cannot be found in patchdiag.xref.
|
71
92
|
def latest(patch)
|
72
93
|
major = Patch.new( patch.to_s ).major
|
73
94
|
find( major ).max ||
|
74
|
-
raise( Solaris::Patch::NotFound,
|
95
|
+
raise( Solaris::Patch::NotFound,
|
96
|
+
"Cannot find patch #{patch} in patchdiag.xref" )
|
75
97
|
end
|
76
98
|
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
def
|
81
|
-
|
82
|
-
if ! patch.minor || ! entry = find( patch ).first
|
83
|
-
entry = latest( patch )
|
84
|
-
end
|
85
|
-
raise Solaris::Patch::NotFound,
|
86
|
-
"Cannot find patch #{patch} in patchdiag.xref" unless entry
|
87
|
-
if entry.obsolete?
|
88
|
-
succ = entry.successor # may raise
|
89
|
-
successor( succ )
|
90
|
-
elsif entry.bad?
|
91
|
-
raise BadSuccessor, "Terminal successor #{patch} is bad/withdrawn"
|
92
|
-
else
|
93
|
-
entry
|
94
|
-
end
|
99
|
+
# Returns a (deep) copy of +self+ with the entries sorted, takes an
|
100
|
+
# optional block. This method overrides Enumerable#sort. See also
|
101
|
+
# Solaris::Patchdiag#sort!.
|
102
|
+
def sort(&blk)
|
103
|
+
clone.sort!( &blk )
|
95
104
|
end
|
96
105
|
|
97
|
-
#
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
sort_by = :patch
|
105
|
-
|
106
|
-
# Parse options
|
107
|
-
opts.each do |key, value|
|
108
|
-
case key
|
109
|
-
when :sort_by
|
110
|
-
raise ArgumentError, "Invalid sort_by #{value.inspect}" unless [ :patch, :date ].include?( value )
|
111
|
-
sort_by = value
|
112
|
-
when :order
|
113
|
-
raise ArgumentError, "Invalid order #{value.inspect}" unless [ :ascending, :descending ].include?( value )
|
114
|
-
order = value
|
115
|
-
else
|
116
|
-
raise ArgumentError, "Unknown option key #{key.inspect}"
|
117
|
-
end
|
118
|
-
end
|
106
|
+
# Returns +self+ with the entries sorted in place, takes an optional
|
107
|
+
# block. See also Solaris::Patchdiag#sort.
|
108
|
+
def sort!(&blk)
|
109
|
+
# use @_entries since #entries returns a copy
|
110
|
+
@_entries.sort!( &blk )
|
111
|
+
self
|
112
|
+
end
|
119
113
|
|
120
|
-
|
121
|
-
|
122
|
-
|
114
|
+
# Return an array of Solaris::Patch of the successors to the given
|
115
|
+
# patch terminating in the latest non-obsolete successor (where that
|
116
|
+
# exists).
|
117
|
+
#
|
118
|
+
# Throws Solaris::Patch::NotFound if the patch or any of its named
|
119
|
+
# successors cannot be found in patchdiag.xref, or if no later version
|
120
|
+
# of the patch exists.
|
121
|
+
#
|
122
|
+
# Throws Solaris::Patch::SuccessorLoop if the successor of a patch refers
|
123
|
+
# to a patch that has already been referenced (an ancestor).
|
124
|
+
#
|
125
|
+
# The ancestors parameter is a recursion accumulator and should not
|
126
|
+
# normally be assigned to by callers.
|
127
|
+
def successors(patch, ancestors=[])
|
128
|
+
patch = Patch.new( patch.to_s )
|
129
|
+
raise Solaris::Patch::SuccessorLoop,
|
130
|
+
"Loop detected for patch #{patch} with ancestors #{ancestors.inspect}" if ancestors.include?( patch )
|
131
|
+
ancestors << patch
|
132
|
+
if ! patch.minor # patch has no minor number
|
133
|
+
successors( latest( patch ).patch, ancestors )
|
134
|
+
elsif ! entry = find( patch ).last # explicit patch not found
|
135
|
+
latest_patch = latest( patch ).patch
|
136
|
+
raise Solaris::Patch::NotFound,
|
137
|
+
"Patch #{patch} not found and has no later version" if latest_patch.minor <= patch.minor
|
138
|
+
successors( latest_patch, ancestors )
|
123
139
|
else
|
124
|
-
|
140
|
+
if entry.obsolete?
|
141
|
+
succ = entry.successor
|
142
|
+
successors( succ, ancestors )
|
143
|
+
elsif entry.bad?
|
144
|
+
raise BadSuccessor, "Terminal successor #{patch} is bad/withdrawn"
|
145
|
+
else
|
146
|
+
ancestors
|
147
|
+
end
|
125
148
|
end
|
149
|
+
end
|
126
150
|
|
127
|
-
|
128
|
-
|
151
|
+
# Return the Solaris::PatchdiagEntry of the latest non-obsolete successor
|
152
|
+
# of this patch. This is a convenience method for #successors.last.
|
153
|
+
def successor(patch)
|
154
|
+
latest( successors( patch ).last )
|
155
|
+
end
|
129
156
|
|
157
|
+
# Returns a string representation of the patchdiag.xref. All comments
|
158
|
+
# and blank lines are elided.
|
159
|
+
def to_s
|
160
|
+
entries.join("\n")
|
130
161
|
end
|
162
|
+
alias to_str to_s
|
131
163
|
|
132
164
|
end # Patchdiag
|
133
165
|
|
@@ -18,7 +18,9 @@ module Solaris
|
|
18
18
|
attr_accessor :archs
|
19
19
|
|
20
20
|
# The bad field from the patchdiag xref database. Should be either 'B'
|
21
|
-
# or the empty string. See also PatchdiagEntry#bad?
|
21
|
+
# or the empty string. See also PatchdiagEntry#bad? (and
|
22
|
+
# PatchdiagEntry#y2k? since these flags share the same column in
|
23
|
+
# patchdiag.xref).
|
22
24
|
attr_accessor :bad
|
23
25
|
|
24
26
|
# The date of this patch (a Date object).
|
@@ -48,9 +50,15 @@ module Solaris
|
|
48
50
|
# text field (string).
|
49
51
|
attr_accessor :synopsis
|
50
52
|
|
53
|
+
# The year 2000 field from the patchdiag xref database. Should be either 'Y'
|
54
|
+
# or the empty string. See also PatchdiagEntry#y2k? (and
|
55
|
+
# PatchdiagEntry#bad? since these flags share the same column in
|
56
|
+
# patchdiag.xref).
|
57
|
+
attr_accessor :y2k
|
58
|
+
|
51
59
|
def initialize(patchdiag_line)
|
52
|
-
fields = patchdiag_line.split('|')
|
53
|
-
major, minor, date, @recommended, @security, @obsolete,
|
60
|
+
fields = patchdiag_line.split( '|', 11 )
|
61
|
+
major, minor, date, @recommended, @security, @obsolete, bad, @os, archs, pkgs, @synopsis = *fields
|
54
62
|
@archs = archs.split( ';' )
|
55
63
|
if date == ''
|
56
64
|
year, month, day = 1970, 1, 1
|
@@ -60,9 +68,12 @@ module Solaris
|
|
60
68
|
month = Date::ABBR_MONTHNAMES.index( month_s )
|
61
69
|
day = day_s.to_i
|
62
70
|
end
|
71
|
+
@bad = bad =~ /B/ ? 'B' : ' '
|
72
|
+
@y2k = bad =~ /Y/ ? 'Y' : ' '
|
63
73
|
@date = Date.new( year, month, day )
|
64
74
|
@patch = Patch.new( major, minor )
|
65
75
|
@pkgs = pkgs.split( ';' )
|
76
|
+
@synopsis.chomp!
|
66
77
|
end
|
67
78
|
|
68
79
|
# Boolean, returns true if this patch is marked as "bad" in the patchdiag
|
@@ -123,10 +134,10 @@ module Solaris
|
|
123
134
|
raise Solaris::Patch::NotObsolete,
|
124
135
|
"Entry #{patch.inspect} not obsolete" unless obsolete?
|
125
136
|
|
126
|
-
# Fail
|
127
|
-
#
|
137
|
+
# Fail if this entry is obsoleted by two patches (currently 2011/05/04
|
138
|
+
# only 105716 and 105717)
|
128
139
|
raise Solaris::Patch::MultipleSuccessors,
|
129
|
-
"More than one successor for entry #{patch.inspect}" if
|
140
|
+
"More than one successor for entry #{patch.inspect}" if synopsis =~ /obsolete(d?) by\s*(:?)\s*(\d+(-\d+)?)\s+and\s+(\d+(-\d+)?)/i
|
130
141
|
|
131
142
|
# See if we can find a successor
|
132
143
|
if synopsis =~ /obsolete(d?) by\s*(:?)\s*(\d+(-\d+)?)/i
|
@@ -146,13 +157,18 @@ module Solaris
|
|
146
157
|
@recommended,
|
147
158
|
@security,
|
148
159
|
@obsolete,
|
149
|
-
@bad,
|
160
|
+
@bad + @y2k,
|
150
161
|
@os,
|
151
162
|
join_semis( @archs ),
|
152
163
|
join_semis( @pkgs ),
|
153
164
|
@synopsis
|
154
165
|
].join('|')
|
155
166
|
end
|
167
|
+
alias to_str to_s
|
168
|
+
|
169
|
+
# Boolean, returns true if this patch is marked as a year 2000 patch in the
|
170
|
+
# patchdiag xref database.
|
171
|
+
def y2k? ; @y2k == 'Y' end
|
156
172
|
|
157
173
|
# Compare (by delegated comparison of patch versions, see Solaris::Patch#<=>).
|
158
174
|
def <=>(other)
|
@@ -170,7 +186,7 @@ module Solaris
|
|
170
186
|
end
|
171
187
|
|
172
188
|
# Join an array of items with semicolons and append a trailing
|
173
|
-
# semicolon if the array is non-empty, otherwise return the
|
189
|
+
# semicolon if the array is non-empty, otherwise return the
|
174
190
|
# empty string. Used to format @archs and @pkgs for #to_s.
|
175
191
|
def join_semis(a)
|
176
192
|
a.empty? ? '' : a.join(';') + ';'
|
data/test/test_patchdiag.rb
CHANGED
@@ -8,7 +8,7 @@ class TestPatchdiag < Test::Unit::TestCase #:nodoc:
|
|
8
8
|
|
9
9
|
def setup
|
10
10
|
@empty_file = '/dev/null'
|
11
|
-
@
|
11
|
+
@patchdiag_string = <<-EOF
|
12
12
|
## PATCHDIAG TOOL CROSS-REFERENCE FILE AS OF Feb/10/11 ##
|
13
13
|
##
|
14
14
|
## The content of this file has changed as of Jun/04/10. Due to the merging of
|
@@ -71,8 +71,14 @@ class TestPatchdiag < Test::Unit::TestCase #:nodoc:
|
|
71
71
|
146444|01|Jan/27/11| | | | |10_x86|i386;120012-14;142910-17;|SUNWnge:11.10.0,REV=2005.06.22.03.40;|SunOS 5.10_x86: nge patch
|
72
72
|
800054|01|Mar/16/01| | |O| |Unbundled|||Obsoleted by: 111346-01 Hardware/PROM: Sun Fire 3800/4800/4810/680
|
73
73
|
100974|02|Mar/14/95| | | | |Unbundled|sparc;|SPROsw:2.1.0;|SparcWorks 2.0.1: dbx jumbo patch
|
74
|
+
654321|01|Jan/01/00| | |O| |Unbundled|||Obsoleted by: 654321-02
|
75
|
+
654321|02|Jan/01/00| | |O| |Unbundled|||Obsoleted by: 654321-03
|
76
|
+
654321|03|Jan/01/00| | |O| |Unbundled|||Obsoleted by: 654321-01
|
77
|
+
654322|01|Jan/01/00| | |O| |Unbundled|||Obsoleted by: 654321-05
|
78
|
+
115302|01|Jul/08/03| | |O| B|Unbundled|||WITHDRAWN PATCH Obsoleted by: 115302-02 Hardware/PROM: CP2060/CP20
|
74
79
|
EOF
|
75
|
-
|
80
|
+
@patchdiag_fileish = StringIO.new( @patchdiag_string )
|
81
|
+
@patchdiag_size = 56
|
76
82
|
@patchdiag = Solaris::Patchdiag.open( @patchdiag_fileish )
|
77
83
|
end
|
78
84
|
|
@@ -80,10 +86,12 @@ EOF
|
|
80
86
|
@empty_file = nil
|
81
87
|
@patchdiag = nil
|
82
88
|
@patchdiag_fileish = nil
|
89
|
+
@patchdiag_string = nil
|
90
|
+
@patchdiag_size = nil
|
83
91
|
end
|
84
92
|
|
85
93
|
def test_new_by_fileish
|
86
|
-
assert_equal(
|
94
|
+
assert_equal( @patchdiag_size, @patchdiag.entries.size )
|
87
95
|
end
|
88
96
|
|
89
97
|
def test_new_by_filename
|
@@ -93,7 +101,7 @@ EOF
|
|
93
101
|
temp.close
|
94
102
|
patchdiag = Solaris::Patchdiag.new( path )
|
95
103
|
File.unlink( path )
|
96
|
-
assert_equal(
|
104
|
+
assert_equal( @patchdiag_size, @patchdiag.entries.size )
|
97
105
|
end
|
98
106
|
|
99
107
|
def test_new_empty_file
|
@@ -103,24 +111,40 @@ EOF
|
|
103
111
|
end
|
104
112
|
end
|
105
113
|
|
106
|
-
def
|
107
|
-
|
114
|
+
def test_no_tailing_newline
|
115
|
+
s = StringIO.new('115302|01|Jul/08/03| | |O| B|Unbundled|||blah blah')
|
116
|
+
assert_equal( 1, Solaris::Patchdiag.new( s ).entries.size )
|
108
117
|
end
|
109
118
|
|
110
|
-
def
|
111
|
-
|
119
|
+
def test_clone
|
120
|
+
@cloned = @patchdiag.clone
|
121
|
+
assert_equal( @patchdiag.class, @cloned.class )
|
122
|
+
assert_equal( @patchdiag.entries.size, @cloned.entries.size )
|
123
|
+
assert_equal( @patchdiag.entries.first, @cloned.entries.first )
|
124
|
+
assert_not_equal( @patchdiag.object_id, @cloned.object_id )
|
125
|
+
@patchdiag.entries.zip( @cloned.entries ).each do |x,y|
|
126
|
+
assert_not_equal( x.object_id, y.object_id )
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_entries
|
131
|
+
assert_equal( @patchdiag_size, @patchdiag.entries.size )
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_sort_by_date_order_ascending
|
135
|
+
all = @patchdiag.sort_by( &:date )
|
112
136
|
first = all.first.patch # oldest
|
113
137
|
last = all.last.patch # newest
|
114
138
|
assert_equal( Solaris::Patch.new( '100386-01' ), first )
|
115
139
|
assert_equal( Solaris::Patch.new( '146443-01' ), last )
|
116
140
|
end
|
117
141
|
|
118
|
-
def
|
119
|
-
all = @patchdiag.
|
120
|
-
first = all.first.patch #
|
121
|
-
last = all.last.patch #
|
122
|
-
assert_equal( Solaris::Patch.new( '800054-01' ),
|
123
|
-
assert_equal( Solaris::Patch.new( '100287-05' ),
|
142
|
+
def test_sort_by_patch_order_ascending
|
143
|
+
all = @patchdiag.sort
|
144
|
+
first = all.first.patch # smallest
|
145
|
+
last = all.last.patch # largest
|
146
|
+
assert_equal( Solaris::Patch.new( '800054-01' ), last )
|
147
|
+
assert_equal( Solaris::Patch.new( '100287-05' ), first )
|
124
148
|
end
|
125
149
|
|
126
150
|
def test_open_block
|
@@ -135,6 +159,34 @@ EOF
|
|
135
159
|
assert_equal( Solaris::Patchdiag, @patchdiag.class )
|
136
160
|
end
|
137
161
|
|
162
|
+
def test_bad
|
163
|
+
entry = @patchdiag.latest( '115302' )
|
164
|
+
assert_equal( true, entry.bad? )
|
165
|
+
entry = @patchdiag.latest( '654321-01' )
|
166
|
+
assert_equal( false, entry.bad? )
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_recommended
|
170
|
+
entry = @patchdiag.latest( '146279-01' )
|
171
|
+
assert_equal( true, entry.recommended? )
|
172
|
+
entry = @patchdiag.latest( '654321-01' )
|
173
|
+
assert_equal( false, entry.recommended? )
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_security
|
177
|
+
entry = @patchdiag.latest( '146279-01' )
|
178
|
+
assert_equal( true, entry.security? )
|
179
|
+
entry = @patchdiag.latest( '654321-01' )
|
180
|
+
assert_equal( false, entry.security? )
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_obsolete
|
184
|
+
entry = @patchdiag.latest( '115302-01' )
|
185
|
+
assert_equal( true, entry.obsolete? )
|
186
|
+
entry = @patchdiag.latest( '100287-05' )
|
187
|
+
assert_equal( false, entry.obsolete? )
|
188
|
+
end
|
189
|
+
|
138
190
|
def test_find
|
139
191
|
assert_equal( [], @patchdiag.find( 123456 ) )
|
140
192
|
assert_equal( [], @patchdiag.find( '123456' ) )
|
@@ -152,6 +204,10 @@ EOF
|
|
152
204
|
assert_equal( '100791-04', @patchdiag.find( Solaris::Patch.new( '100791-04') ).first.patch.to_s )
|
153
205
|
end
|
154
206
|
|
207
|
+
def test_last
|
208
|
+
assert_equal( '115302-01', @patchdiag.last.patch.to_s )
|
209
|
+
end
|
210
|
+
|
155
211
|
def test_latest
|
156
212
|
assert_raise( Solaris::Patch::NotFound ) do
|
157
213
|
@patchdiag.latest( 123456 )
|
@@ -166,6 +222,24 @@ EOF
|
|
166
222
|
assert_equal( '100791-05', @patchdiag.latest( Solaris::Patch.new( '100791-05' ) ).patch.to_s )
|
167
223
|
end
|
168
224
|
|
225
|
+
def test_sort
|
226
|
+
assert_equal( '115302-01', @patchdiag.entries.last.patch.to_s )
|
227
|
+
sorted = @patchdiag.sort
|
228
|
+
assert_equal( Solaris::Patchdiag, sorted.class )
|
229
|
+
assert_equal( '800054-01', sorted.entries.last.patch.to_s )
|
230
|
+
assert_equal( '115302-01', @patchdiag.entries.last.patch.to_s )
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_sort!
|
234
|
+
assert_equal( '115302-01', @patchdiag.entries.last.patch.to_s )
|
235
|
+
size = @patchdiag.entries.size
|
236
|
+
ret = @patchdiag.sort!
|
237
|
+
assert_equal( @patchdiag, ret )
|
238
|
+
assert_equal( size, @patchdiag.entries.size )
|
239
|
+
assert_equal( Solaris::Patchdiag, @patchdiag.class )
|
240
|
+
assert_equal( '800054-01', @patchdiag.entries.last.patch.to_s )
|
241
|
+
end
|
242
|
+
|
169
243
|
def test_successor
|
170
244
|
assert_raise( Solaris::Patch::NotFound ) do
|
171
245
|
@patchdiag.latest( 123456 )
|
@@ -175,13 +249,33 @@ EOF
|
|
175
249
|
assert_equal( '100287-05', @patchdiag.successor( '100287-05' ).patch.to_s )
|
176
250
|
assert_equal( '100287-05', @patchdiag.successor( Solaris::Patch.new( '100287-05' ) ).patch.to_s )
|
177
251
|
assert_equal( '100974-02', @patchdiag.successor( 100791 ).patch.to_s )
|
252
|
+
assert_raise( Solaris::Patch::NotFound ) do
|
253
|
+
@patchdiag.successor( 123456 )
|
254
|
+
end
|
178
255
|
assert_raise( Solaris::Patch::NotFound ) do
|
179
256
|
@patchdiag.successor( 100393 ) # successor 100394 not in patchdiag.xref
|
180
257
|
end
|
258
|
+
assert_raise( Solaris::Patch::NotFound ) do
|
259
|
+
@patchdiag.successor( '654322-05' )
|
260
|
+
end
|
181
261
|
assert_equal( '100807-04', @patchdiag.successor( '100807-01' ).patch.to_s )
|
182
262
|
assert_raise( Solaris::Patch::InvalidSuccessor ) do
|
183
263
|
@patchdiag.successor( '100807-03' ) # successor 100807-03 WITHDRAWN
|
184
264
|
end
|
265
|
+
assert_raise( Solaris::Patch::SuccessorLoop ) do
|
266
|
+
@patchdiag.successor( 654321 )
|
267
|
+
end
|
268
|
+
assert_raise( Solaris::Patch::SuccessorLoop ) do
|
269
|
+
@patchdiag.successor( '654321-01' )
|
270
|
+
end
|
271
|
+
assert_raise( Solaris::Patch::NotFound ) do
|
272
|
+
@patchdiag.successor( 115302 )
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_successors
|
277
|
+
assert_equal( %w{ 100791 100791-05 100974 100974-02 },
|
278
|
+
@patchdiag.successors( 100791 ).map(&:to_s) )
|
185
279
|
end
|
186
280
|
|
187
281
|
def test_download!
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Martin Carpenter
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-05-
|
17
|
+
date: 2011-05-30 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 1.0.0
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
|
-
description: Provides methods to deal with Solaris patchdiag.xref and patches, including parsing patchdiag.xref, downloads from Oracle (patch and readme), patch version comparison, and
|
35
|
+
description: Provides methods to deal with Solaris patchdiag.xref and patches, including parsing patchdiag.xref, downloads from Oracle (patch and readme), patch version comparison, and generic patchdiag.xref manipulations such as seeking the latest non-obsolete version of a patch
|
36
36
|
email: mcarpenter@free.fr
|
37
37
|
executables: []
|
38
38
|
|
@@ -45,7 +45,6 @@ extra_rdoc_files:
|
|
45
45
|
files:
|
46
46
|
- lib/solaris/exception.rb
|
47
47
|
- lib/solaris/patch.rb
|
48
|
-
- lib/solaris/foo
|
49
48
|
- lib/solaris/patchdiag_entry.rb
|
50
49
|
- lib/solaris/util.rb
|
51
50
|
- lib/solaris/patchdiag.rb
|