solaris-patch 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +26 -0
- data/README.rdoc +71 -0
- data/Rakefile +27 -0
- data/lib/solaris/exception.rb +31 -0
- data/lib/solaris/foo +13 -0
- data/lib/solaris/patch.rb +116 -0
- data/lib/solaris/patchdiag.rb +135 -0
- data/lib/solaris/patchdiag_entry.rb +182 -0
- data/lib/solaris/util.rb +68 -0
- data/lib/solaris.rb +10 -0
- data/test/test_patch.rb +100 -0
- data/test/test_patchdiag.rb +198 -0
- data/test/test_patchdiag_entry.rb +115 -0
- data/test/test_solaris.rb +29 -0
- data/test/test_util.rb +31 -0
- metadata +98 -0
data/LICENSE
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright 2011 Martin Carpenter. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
4
|
+
permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
7
|
+
conditions and the following disclaimer.
|
8
|
+
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
10
|
+
of conditions and the following disclaimer in the documentation and/or other materials
|
11
|
+
provided with the distribution.
|
12
|
+
|
13
|
+
THIS SOFTWARE IS PROVIDED BY Martin Carpenter ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
14
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Martin Carpenter OR
|
16
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
17
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
18
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
19
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
20
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
21
|
+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
|
+
|
23
|
+
The views and conclusions contained in the software and documentation are those of the
|
24
|
+
authors and should not be interpreted as representing official policies, either expressed
|
25
|
+
or implied, of Martin Carpenter.
|
26
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
|
2
|
+
= solaris-patch
|
3
|
+
|
4
|
+
Author:: Martin Carpenter
|
5
|
+
Email:: mcarpenter@free.fr
|
6
|
+
Copyright:: Copyright (c) Martin Carpenter 2011
|
7
|
+
|
8
|
+
== About
|
9
|
+
The solaris-patch gem helps with the manipulation of SunOS and Solaris
|
10
|
+
patches.
|
11
|
+
|
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
|
+
|
18
|
+
== Examples
|
19
|
+
|
20
|
+
=== Download a patch
|
21
|
+
|
22
|
+
require 'solaris/patch'
|
23
|
+
Solaris::Patch.download_patch!('123456-78',
|
24
|
+
:to_file => '/tmp/123456-78.zip')
|
25
|
+
|
26
|
+
Alternatively:
|
27
|
+
|
28
|
+
patch = Solaris::Patch.new( '123456-78' )
|
29
|
+
patch.download_patch!( :to_dir => '/tmp' )
|
30
|
+
|
31
|
+
=== Get the latest version of a patch
|
32
|
+
|
33
|
+
require 'solaris/patch'
|
34
|
+
Solaris::Patchdiag.open( '/tmp/patchdiag.xref' ).latest( '123456-01' )
|
35
|
+
=> "123456|12|..."
|
36
|
+
|
37
|
+
=== Get the latest non-obsolete version of an possibly obsoleted patch
|
38
|
+
|
39
|
+
require 'solaris/patch'
|
40
|
+
Solaris::Patchdiag.open( '/tmp/patchdiag.xref' ).successor( '123456-01' )
|
41
|
+
=> "234567|12|..."
|
42
|
+
|
43
|
+
=== Interrogate patchdiag.xref
|
44
|
+
|
45
|
+
require 'solaris/patch'
|
46
|
+
|
47
|
+
# slurp in patchdiag.xref
|
48
|
+
patchdiag = Solaris::Patchdiag.new( '/tmp/patchdiag.xref' )
|
49
|
+
|
50
|
+
# all sparc patches
|
51
|
+
patchdiag.all.select { |p| p.archs.include? 'sparc' }.inspect
|
52
|
+
=> [ "123456-78", ... ]
|
53
|
+
|
54
|
+
# latest line added to patchdiag.xref
|
55
|
+
most_recent = patchdiag.all( :sort_by => :date, :order => ascending ).max
|
56
|
+
most_recent
|
57
|
+
=> "123456|78|..."
|
58
|
+
|
59
|
+
# most recent patch number
|
60
|
+
most_recent.patch
|
61
|
+
=> "123456-78"
|
62
|
+
|
63
|
+
# most recent patch's README if it was recommended
|
64
|
+
most_recent.download_readme! if most_recent.recommended?
|
65
|
+
=> "Patch-ID# 123456-78..."
|
66
|
+
|
67
|
+
== Known issues
|
68
|
+
|
69
|
+
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 Century.
|
71
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/testtask'
|
6
|
+
|
7
|
+
desc 'Default task (package)'
|
8
|
+
task :default => [:package]
|
9
|
+
|
10
|
+
Rake::TestTask.new( 'test' )
|
11
|
+
|
12
|
+
SPECFILE = 'solaris-patch.gemspec'
|
13
|
+
if File.exist?( SPECFILE )
|
14
|
+
spec = eval( File.read( SPECFILE ) )
|
15
|
+
Rake::GemPackageTask.new( spec ).define
|
16
|
+
end
|
17
|
+
|
18
|
+
Rake::RDocTask.new do |rdoc|
|
19
|
+
rdoc.rdoc_dir = 'rdoc'
|
20
|
+
rdoc.title = 'solaris-patch'
|
21
|
+
rdoc.options << '--charset' << 'utf-8'
|
22
|
+
rdoc.options << '--all'
|
23
|
+
rdoc.rdoc_files.include( 'README.rdoc' )
|
24
|
+
rdoc.rdoc_files.include( FileList[ 'lib/**/*' ] )
|
25
|
+
rdoc.rdoc_files.include( FileList[ 'test/**/*' ] )
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
module Solaris
|
3
|
+
|
4
|
+
class Patch
|
5
|
+
|
6
|
+
# Superclass for all throwable exceptions.
|
7
|
+
class Exception < ::Exception ; end
|
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
|
+
# Exception is raised when the terminal (non-obsolete) succesor
|
15
|
+
# to a patch has been withdrawn (is bad).
|
16
|
+
class BadSuccessor < Exception ; end
|
17
|
+
|
18
|
+
# Raised if the "obsoleted by" value for this patchdiag entry is not
|
19
|
+
# comprehensible.
|
20
|
+
class InvalidSuccessor < Exception ; end
|
21
|
+
|
22
|
+
# Raised if a patchdiag entry appears to have multiple successors.
|
23
|
+
class MultipleSuccessors < Exception ; end
|
24
|
+
|
25
|
+
# Raised if one tries to determine the successor of a non-obsolete patch.
|
26
|
+
class NotObsolete < Exception ; end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end # Solaris
|
31
|
+
|
data/lib/solaris/foo
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
|
2
|
+
module Solaris
|
3
|
+
|
4
|
+
# Class to represent a patch number.
|
5
|
+
class Patch
|
6
|
+
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
require 'solaris/util'
|
10
|
+
require 'solaris/exception'
|
11
|
+
require 'solaris/patchdiag'
|
12
|
+
require 'solaris/patchdiag_entry'
|
13
|
+
|
14
|
+
# Hash of URL patterns for downloads of type :patch or :readme.
|
15
|
+
# The string format parameter (%s) is the full patch number.
|
16
|
+
URL = {
|
17
|
+
:patch => 'https://getupdates.oracle.com/all_unsigned/%s.zip',
|
18
|
+
:readme => 'https://getupdates.oracle.com/readme/README.%s'
|
19
|
+
}
|
20
|
+
|
21
|
+
# The major number of the patch (integer), the part before the dash.
|
22
|
+
attr_accessor :major
|
23
|
+
|
24
|
+
# The minor number of the patch (integer), the part after the dash.
|
25
|
+
# Since this is an integer, values less than 10 will not be left
|
26
|
+
# padded with zero (see Patch::pad_minor). May be nil if not specified
|
27
|
+
# in the constructor.
|
28
|
+
attr_accessor :minor
|
29
|
+
|
30
|
+
# Create a patch. May take zero, one or two parameters.
|
31
|
+
#
|
32
|
+
# In the one parameter form, this is a string of the patch number
|
33
|
+
# eg '123456-78'. (If you specify integer 123456-78 then the
|
34
|
+
# resulting object will have major number 123378 and no minor
|
35
|
+
# number; this is probably not what you want).
|
36
|
+
#
|
37
|
+
# In the two parameter form, the first parameter is the major
|
38
|
+
# patch number (123456) and the second is the minor number (78).
|
39
|
+
# Although it is possible to provide strings or integers here strings
|
40
|
+
# should be prefered since a leading zero on an integer in Ruby
|
41
|
+
# indicates an octal representation (in the tradition of C). This can
|
42
|
+
# cause problems with a revision number of 09, since this is not a
|
43
|
+
# valid octal representation.
|
44
|
+
#
|
45
|
+
# TLDR: Patch.new('123456-78')
|
46
|
+
def initialize(major=nil, minor=nil)
|
47
|
+
if major
|
48
|
+
patch_no = major.to_s + ( minor ? "-#{minor}" : '' )
|
49
|
+
if patch_no =~ /^(\d+)(-(\d+))?$/
|
50
|
+
@major = $1.to_i
|
51
|
+
@minor = $3.to_i if $3
|
52
|
+
else
|
53
|
+
raise ArgumentError, "Invalid patch number string #{patch_no.inspect}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Download this patch. For the options hash see private method Patch#download!
|
59
|
+
def download_patch!(opts={})
|
60
|
+
download!( :patch, opts )
|
61
|
+
end
|
62
|
+
|
63
|
+
# Download this README. For the options hash see private method Patch#download!
|
64
|
+
def download_readme!(opts={})
|
65
|
+
download!( :readme, opts )
|
66
|
+
end
|
67
|
+
|
68
|
+
# Return a string representation of this patch. If the minor
|
69
|
+
# number has not been set then just return the major number.
|
70
|
+
def to_s
|
71
|
+
minor ? "#{@major}-#{Patch.pad_minor( @minor )}" : "#{@major}"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Compare patch versions. (Performs a string compare on the full patch numbers).
|
75
|
+
def <=>(other)
|
76
|
+
self.to_s <=> other.to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
# Download the given patch (this may be a Patch object or a string
|
80
|
+
# like '123456-78'). For the options hash see Patch#download!.
|
81
|
+
def Patch.download_patch!(patch, opts={})
|
82
|
+
patch_to_dl = Patch.new( patch.to_s )
|
83
|
+
patch_to_dl.download_patch!( opts )
|
84
|
+
end
|
85
|
+
|
86
|
+
# Download the given readme (this may be a Patch object or a string
|
87
|
+
# like '123456-78'). For the options hash see Patch#download!.
|
88
|
+
def Patch.download_readme!(patch, opts={})
|
89
|
+
patch_to_dl = Patch.new( patch.to_s )
|
90
|
+
patch_to_dl.download_readme!( opts )
|
91
|
+
end
|
92
|
+
|
93
|
+
# Left pad a minor version number with zeros as required.
|
94
|
+
def Patch.pad_minor(minor)
|
95
|
+
"#{minor.to_s.rjust( 2, '0' )}"
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
# Download this patch or readme from Oracle.
|
101
|
+
# For the options hash argument see Solaris::Util.download!
|
102
|
+
def download!(type, opts={})
|
103
|
+
raise ArgumentError, "Patch #{self.inspect} requires a major number to download" unless @major
|
104
|
+
raise ArgumentError, "Patch #{self.inspect} requires a minor number to download" unless @minor
|
105
|
+
raise ArgumentError, "Unknown type #{type.inspect}" unless URL[ type ]
|
106
|
+
url = URL[ type ] % self.to_s
|
107
|
+
opts = {
|
108
|
+
:agent => 'Wget/1.10.2', # default user agent, required by Oracle
|
109
|
+
}.merge( opts )
|
110
|
+
Solaris::Util.download!( url, opts )
|
111
|
+
end
|
112
|
+
|
113
|
+
end # Patch
|
114
|
+
|
115
|
+
end # Solaris
|
116
|
+
|
@@ -0,0 +1,135 @@
|
|
1
|
+
|
2
|
+
module Solaris
|
3
|
+
|
4
|
+
# Class to represent the Oracle patchdiag "database" (file).
|
5
|
+
# See the following Oracle support publication for format:
|
6
|
+
# https://support.oracle.com/CSP/main/article?cmd=show&type=NOT&doctype=REFERENCE&id=1019527.1
|
7
|
+
class Patchdiag
|
8
|
+
|
9
|
+
require 'date'
|
10
|
+
|
11
|
+
require 'solaris/exception'
|
12
|
+
require 'solaris/patchdiag_entry'
|
13
|
+
require 'solaris/util'
|
14
|
+
|
15
|
+
# Default patchdiag.xref file, as for Patch Check Advanced cache
|
16
|
+
DEFAULT_XREF_FILE = '/var/tmp/patchdiag.xref'
|
17
|
+
|
18
|
+
# URL of latest patchdiag.xref from Oracle.
|
19
|
+
DEFAULT_XREF_URL = 'https://getupdates.oracle.com/reports/patchdiag.xref'
|
20
|
+
|
21
|
+
# An array containing all entries (of class PatchdiagEntry) read
|
22
|
+
# from the patchdiag.xref file.
|
23
|
+
attr_accessor :entries
|
24
|
+
|
25
|
+
# Create a new patchdiag database object by reading the given
|
26
|
+
# xref file (this may be a filename (string) or a fileish object
|
27
|
+
# (File, StringIO)). If no xref file is given then the default
|
28
|
+
# is read (/var/tmp/patchdiag.xref); this is the cache file used
|
29
|
+
# by Patch Check Advanced (pca).
|
30
|
+
def initialize(xref_file=DEFAULT_XREF_FILE)
|
31
|
+
xref_file = File.new( xref_file ) if xref_file.is_a?(String)
|
32
|
+
@entries = xref_file.
|
33
|
+
readlines.
|
34
|
+
reject { |line| line =~ /^#|^\s*$/ }. # discard comments, blanks
|
35
|
+
map { |line| PatchdiagEntry.new( line ) }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Download the patchdiag database and return it as a string.
|
39
|
+
# Note the contents will be returned as a string but not saved
|
40
|
+
# to disk unless :to_file or :to_dir are given.
|
41
|
+
# For the options hash argument see Solaris::Util.download!
|
42
|
+
def Patchdiag.download!(opts={})
|
43
|
+
url = opts.delete( :url ) || DEFAULT_XREF_URL
|
44
|
+
Util.download!( url, opts )
|
45
|
+
end
|
46
|
+
|
47
|
+
# Open the given optional patchdiag xref file and yield to the optional
|
48
|
+
# block.
|
49
|
+
def Patchdiag.open(xref_file=DEFAULT_XREF_FILE, &blk)
|
50
|
+
patchdiag = Patchdiag.new( xref_file )
|
51
|
+
if block_given?
|
52
|
+
yield patchdiag
|
53
|
+
else
|
54
|
+
patchdiag
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns an array of Solaris::PatchdiagEntry from the patchdiag with the given
|
59
|
+
# patch number (a String like xxxxxx-yy or xxxxxx or a Solaris::Patch). Returns an
|
60
|
+
# empty array if no such patches can be found.
|
61
|
+
def find(patch)
|
62
|
+
patch = Patch.new( patch.to_s )
|
63
|
+
property = patch.minor ? :to_s : :major
|
64
|
+
comparator = patch.send( property )
|
65
|
+
all.select { |pde| pde.patch.send( property ) == comparator }
|
66
|
+
end
|
67
|
+
|
68
|
+
# Return the Solaris::PatchdiagEntry of the latest version of the given patch
|
69
|
+
# (a String like xxxxxx-yy or xxxxxx or a Solaris::Patch).
|
70
|
+
# Throws Solaris::Patch::NotFound if the patch cannot be found in patchdiag.xref.
|
71
|
+
def latest(patch)
|
72
|
+
major = Patch.new( patch.to_s ).major
|
73
|
+
find( major ).max ||
|
74
|
+
raise( Solaris::Patch::NotFound, "Cannot find patch #{patch} in patchdiag.xref" )
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return the Solaris::PatchdiagEntry of the latest non-obsolete successor
|
78
|
+
# of this patch. Throws Solaris::Patch::NotFound if the patch or any of its
|
79
|
+
# named successors cannot be found in patchdiag.xref.
|
80
|
+
def successor(patch)
|
81
|
+
patch = Patch.new( patch.to_s )
|
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
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return all patchdiag entries (PatchdiagEntry) defined in the patchdiag.xref.
|
98
|
+
# This method scans the entire patchdiag database so may be a little slow:
|
99
|
+
# callers are encouraged to cache or memoize their results.
|
100
|
+
def all(opts={})
|
101
|
+
|
102
|
+
# Defaults
|
103
|
+
order = :ascending
|
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
|
119
|
+
|
120
|
+
# Compute the lambda for sorting.
|
121
|
+
if order == :ascending
|
122
|
+
boat_op = lambda { |x,y| x.send( sort_by ) <=> y.send( sort_by ) }
|
123
|
+
else
|
124
|
+
boat_op = lambda { |x,y| y.send( sort_by ) <=> x.send( sort_by ) }
|
125
|
+
end
|
126
|
+
|
127
|
+
# Sort and return.
|
128
|
+
@entries.sort { |x,y| boat_op.call( x, y ) }
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end # Patchdiag
|
133
|
+
|
134
|
+
end # Solaris
|
135
|
+
|
@@ -0,0 +1,182 @@
|
|
1
|
+
|
2
|
+
module Solaris
|
3
|
+
|
4
|
+
# Class to represent a line from Sun's patchdiag.xref patch "database".
|
5
|
+
# See the following Oracle support publication for format:
|
6
|
+
# https://support.oracle.com/CSP/main/article?cmd=show&type=NOT&doctype=REFERENCE&id=1019527.1
|
7
|
+
class PatchdiagEntry
|
8
|
+
|
9
|
+
include Comparable
|
10
|
+
|
11
|
+
require 'date'
|
12
|
+
|
13
|
+
require 'solaris/exception'
|
14
|
+
require 'solaris/patch'
|
15
|
+
|
16
|
+
# An array of architectures for this patch. Values are strings like
|
17
|
+
# "sparc", "i386".
|
18
|
+
attr_accessor :archs
|
19
|
+
|
20
|
+
# The bad field from the patchdiag xref database. Should be either 'B'
|
21
|
+
# or the empty string. See also PatchdiagEntry#bad?
|
22
|
+
attr_accessor :bad
|
23
|
+
|
24
|
+
# The date of this patch (a Date object).
|
25
|
+
attr_accessor :date
|
26
|
+
|
27
|
+
# The operating system for this patch, a string like "2.4, "10",
|
28
|
+
# "10_x86" or "Unbundled".
|
29
|
+
attr_accessor :os
|
30
|
+
|
31
|
+
# The patch object (class Patch) that this entry represents. See
|
32
|
+
# also convenience methods PatchdiagEntry#major and PatchdiagEntry#minor.
|
33
|
+
attr_accessor :patch
|
34
|
+
|
35
|
+
# An array of packages that pertain to this patch. Values are strings
|
36
|
+
# like "SUNWcsr".
|
37
|
+
attr_accessor :pkgs
|
38
|
+
|
39
|
+
# The recommended field from the patchdiag xref database. Should be either 'R'
|
40
|
+
# or the empty string. See also PatchdiagEntry#recommended?
|
41
|
+
attr_accessor :recommended
|
42
|
+
|
43
|
+
# The security field from the patchdiag xref database. Should be either 'S'
|
44
|
+
# or the empty string. See also PatchdiagEntry#security?
|
45
|
+
attr_accessor :security
|
46
|
+
|
47
|
+
# This synopsis of this patch from the patchdiag xref database. This is a free
|
48
|
+
# text field (string).
|
49
|
+
attr_accessor :synopsis
|
50
|
+
|
51
|
+
def initialize(patchdiag_line)
|
52
|
+
fields = patchdiag_line.split('|')[0..10]
|
53
|
+
major, minor, date, @recommended, @security, @obsolete, @bad, @os, archs, pkgs, @synopsis = *fields
|
54
|
+
@archs = archs.split( ';' )
|
55
|
+
if date == ''
|
56
|
+
year, month, day = 1970, 1, 1
|
57
|
+
else
|
58
|
+
month_s, day_s, year_s = *date.split( '/' )
|
59
|
+
year = ( year_s.to_i > 50 ? "19#{year_s}" : "20#{year_s}" ).to_i
|
60
|
+
month = Date::ABBR_MONTHNAMES.index( month_s )
|
61
|
+
day = day_s.to_i
|
62
|
+
end
|
63
|
+
@date = Date.new( year, month, day )
|
64
|
+
@patch = Patch.new( major, minor )
|
65
|
+
@pkgs = pkgs.split( ';' )
|
66
|
+
end
|
67
|
+
|
68
|
+
# Boolean, returns true if this patch is marked as "bad" in the patchdiag
|
69
|
+
# xref database.
|
70
|
+
def bad? ; @bad == 'B' end
|
71
|
+
|
72
|
+
# Download this patch. For options hash see Patch#download!.
|
73
|
+
def download_patch!(opts={}) ;
|
74
|
+
@patch.download_patch!( opts )
|
75
|
+
end
|
76
|
+
|
77
|
+
# Download the README for this patch. For options hash see Patch#download!.
|
78
|
+
def download_readme!(opts={})
|
79
|
+
@patch.download_readme!( opts )
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns this entries major patch number as an integer.
|
83
|
+
def major ; @patch.major end
|
84
|
+
|
85
|
+
# Returns this entries minor patch number as an integer.
|
86
|
+
def minor ; @patch.minor end
|
87
|
+
|
88
|
+
# Boolean, returns true if this patch is marked as "obsolete" in the patchdiag
|
89
|
+
# xref database.
|
90
|
+
def obsolete? ; @obsolete == 'O' end
|
91
|
+
|
92
|
+
# Boolean, returns true if this patch is marked as "recommended" in the patchdiag
|
93
|
+
# xref database.
|
94
|
+
def recommended? ; @recommended == 'R' end
|
95
|
+
|
96
|
+
# Boolean, returns true if this patch is marked as "security" in the patchdiag
|
97
|
+
# xref database.
|
98
|
+
def security? ; @security == 'S' end
|
99
|
+
|
100
|
+
# Return the Solaris::Patch by which this entry is obsoleted.
|
101
|
+
# Throws Solaris::Patch::NotObsolete if this entry is not obsolete.
|
102
|
+
# Throws Solaris::Patch::MultipleSuccessors if this entry has more than
|
103
|
+
# one successor.
|
104
|
+
# Throws Solaris::Patch::InvalidSuccessor if the "obsoleted by" entry cannot
|
105
|
+
# be understood.
|
106
|
+
def successor
|
107
|
+
# I <3 consistency:
|
108
|
+
# Obsoleted by : XXXXXX-XX
|
109
|
+
# Obsoleted by: XXXXXX-XX
|
110
|
+
# OBSOLETED by: XXXXXX
|
111
|
+
# Obsoleted by: XXXXXX-XX OBSOLETED by WITHDRAWN
|
112
|
+
# OBSOLETED by WITHDRAWN
|
113
|
+
# OBSOLETED by XXXXXX
|
114
|
+
# OBSOLETED by XXXXXX and XXXXXX # we ignore this pattern, see below
|
115
|
+
# Obsoleted by XXXXXX-XX:
|
116
|
+
# OBSOLETED by XXXXXX-XX:
|
117
|
+
# WITHDRAWN Obsoleted by: XXXXXX-XX
|
118
|
+
# WITHDRAWN PATCH Obsolete by:
|
119
|
+
# WITHDRAWN PATCH Obsoleted by:
|
120
|
+
# WITHDRAWN PATCH Obsoleted by XXXXXX-XX:
|
121
|
+
|
122
|
+
# Fail if this entry is not actually obsolete
|
123
|
+
raise Solaris::Patch::NotObsolete,
|
124
|
+
"Entry #{patch.inspect} not obsolete" unless obsolete?
|
125
|
+
|
126
|
+
# Fail on these two entries from 1999 since they are the only ones ever
|
127
|
+
# that are succeeded by two patches each
|
128
|
+
raise Solaris::Patch::MultipleSuccessors,
|
129
|
+
"More than one successor for entry #{patch.inspect}" if [ 105716, 105717 ].include?( self.major )
|
130
|
+
|
131
|
+
# See if we can find a successor
|
132
|
+
if synopsis =~ /obsolete(d?) by\s*(:?)\s*(\d+(-\d+)?)/i
|
133
|
+
Patch.new( $3 )
|
134
|
+
else
|
135
|
+
raise Solaris::Patch::InvalidSuccessor,
|
136
|
+
"Failed to parse successor to obsolete patchdiag entry for patch #{patch.inspect}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Output this patchdiag xref entry as a string, in format of Oracle's
|
141
|
+
# database.
|
142
|
+
def to_s
|
143
|
+
[ patch.major,
|
144
|
+
Patch.pad_minor( patch.minor ),
|
145
|
+
date_s,
|
146
|
+
@recommended,
|
147
|
+
@security,
|
148
|
+
@obsolete,
|
149
|
+
@bad,
|
150
|
+
@os,
|
151
|
+
join_semis( @archs ),
|
152
|
+
join_semis( @pkgs ),
|
153
|
+
@synopsis
|
154
|
+
].join('|')
|
155
|
+
end
|
156
|
+
|
157
|
+
# Compare (by delegated comparison of patch versions, see Solaris::Patch#<=>).
|
158
|
+
def <=>(other)
|
159
|
+
self.patch <=> other.patch
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
# Convert the Date object to a date string as found in patchdiag.xref.
|
165
|
+
def date_s
|
166
|
+
[ Date::ABBR_MONTHNAMES[ @date.mon ], # month eg Jan
|
167
|
+
@date.mday.to_s.rjust(2, '0'), # day of month
|
168
|
+
@date.year % 100 # 2 digit year
|
169
|
+
].join('/')
|
170
|
+
end
|
171
|
+
|
172
|
+
# Join an array of items with semicolons and append a trailing
|
173
|
+
# semicolon if the array is non-empty, otherwise return the
|
174
|
+
# empty string. Used to format @archs and @pkgs for #to_s.
|
175
|
+
def join_semis(a)
|
176
|
+
a.empty? ? '' : a.join(';') + ';'
|
177
|
+
end
|
178
|
+
|
179
|
+
end # PatchdiagEntry
|
180
|
+
|
181
|
+
end # Solaris
|
182
|
+
|
data/lib/solaris/util.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
module Solaris
|
3
|
+
|
4
|
+
# Utility module.
|
5
|
+
module Util
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
gem 'mechanize', '>= 1.0.0'
|
9
|
+
require 'mechanize'
|
10
|
+
|
11
|
+
# Download the given URL, return the document body. Options:
|
12
|
+
# :agent -- set HTTP user agent
|
13
|
+
# :password -- Oracle support password
|
14
|
+
# :to_file -- a file path to which the patch/readme should be saved
|
15
|
+
# :to_dir -- a directory path to which the patch/readme should be saved
|
16
|
+
# :user -- Oracle support username
|
17
|
+
# (:to_dir and :to_file are mutually exclusive)
|
18
|
+
def Util.download!(url, opts={})
|
19
|
+
agent = Mechanize.new
|
20
|
+
dirname, filename = nil, nil
|
21
|
+
opts.each do |key, value|
|
22
|
+
case key
|
23
|
+
when :agent
|
24
|
+
agent.user_agent = value
|
25
|
+
when :to_dir
|
26
|
+
dirname = value
|
27
|
+
when :to_file
|
28
|
+
filename = value
|
29
|
+
when :password, :user
|
30
|
+
# noop
|
31
|
+
else
|
32
|
+
raise ArgumentError, "Unknown option key #{key.inspect}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
# If we got a filename then open now before attempting download
|
36
|
+
raise ArgumentError, 'Cannot specify both :to_dir and :to_file' if filename && dirname
|
37
|
+
filename = File.join( dirname, File.basename( url ) ) if dirname
|
38
|
+
begin
|
39
|
+
file = File.open( filename, 'w' ) if filename
|
40
|
+
# Set agent authentication parameters
|
41
|
+
if opts[:user] && opts[:password]
|
42
|
+
agent.basic_auth( opts[:user], opts[:password] )
|
43
|
+
elsif opts[:user]
|
44
|
+
raise ArgumentError, 'Cannot authenticate without a password'
|
45
|
+
elsif opts[:password]
|
46
|
+
raise ArgumentError, 'Cannot authenticate without a username'
|
47
|
+
end
|
48
|
+
# Download file and save as required
|
49
|
+
page = agent.get( url )
|
50
|
+
if file
|
51
|
+
file.write( page.body )
|
52
|
+
file.close
|
53
|
+
end
|
54
|
+
rescue => exception
|
55
|
+
# Try to remove incomplete file on error
|
56
|
+
if file
|
57
|
+
begin file.close ; rescue ; end
|
58
|
+
begin File.unlink( file ) ; rescue ; end
|
59
|
+
end
|
60
|
+
raise exception # rethrow original exception
|
61
|
+
end
|
62
|
+
page.body # return file as string (even if written)
|
63
|
+
end
|
64
|
+
|
65
|
+
end # Util
|
66
|
+
|
67
|
+
end # Solaris
|
68
|
+
|
data/lib/solaris.rb
ADDED
data/test/test_patch.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
require 'solaris/patch'
|
4
|
+
|
5
|
+
# Unit tests for class Patch.
|
6
|
+
class TestPatch < Test::Unit::TestCase #:nodoc:
|
7
|
+
|
8
|
+
def test_new_string_major_only
|
9
|
+
patch = Solaris::Patch.new( '123456' )
|
10
|
+
assert_equal( 123456, patch.major )
|
11
|
+
assert_nil( patch.minor )
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_new_int_major_only
|
15
|
+
patch = Solaris::Patch.new( 123456 )
|
16
|
+
assert_equal( 123456, patch.major )
|
17
|
+
assert_nil( patch.minor )
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_new_string_minor_only
|
21
|
+
assert_raise( ArgumentError ) do
|
22
|
+
Solaris::Patch.new( '-78' )
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_new_string_major_and_minor
|
27
|
+
patch = Solaris::Patch.new( '123456-78' )
|
28
|
+
assert_equal( 123456, patch.major )
|
29
|
+
assert_equal( 78, patch.minor )
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_new_int_major_and_minor
|
33
|
+
patch = Solaris::Patch.new( 123456, 78 )
|
34
|
+
assert_equal( 123456, patch.major )
|
35
|
+
assert_equal( 78, patch.minor )
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_new_no_args
|
39
|
+
patch = Solaris::Patch.new()
|
40
|
+
assert_nil( patch.major )
|
41
|
+
assert_nil( patch.minor )
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_new_valid_opts
|
45
|
+
patch = Solaris::Patch.new( '123456-78' )
|
46
|
+
assert_equal( 123456, patch.major )
|
47
|
+
assert_equal( 78, patch.minor )
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_to_s
|
51
|
+
patch = Solaris::Patch.new( '123456-78' )
|
52
|
+
assert_equal( '123456-78', patch.to_s )
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_to_s_padding
|
56
|
+
patch = Solaris::Patch.new( '123456-7' )
|
57
|
+
assert_equal( '123456-07', patch.to_s )
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_to_s_major_only
|
61
|
+
patch = Solaris::Patch.new( 123456 )
|
62
|
+
assert_equal( '123456', patch.to_s )
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_comparison
|
66
|
+
assert( Solaris::Patch.new( '123456-78' ) == Solaris::Patch.new( '123456-78' ) )
|
67
|
+
assert( Solaris::Patch.new( '123456-1' ) == Solaris::Patch.new( '123456-01' ) )
|
68
|
+
assert( Solaris::Patch.new( '123456' ) == Solaris::Patch.new( '123456' ) )
|
69
|
+
assert( Solaris::Patch.new( '123456-78' ) < Solaris::Patch.new( '123456-79' ) )
|
70
|
+
assert( Solaris::Patch.new( '123456-78' ) < Solaris::Patch.new( '123457-78' ) )
|
71
|
+
assert( Solaris::Patch.new( '123456-1' ) < Solaris::Patch.new( '123456-10' ) )
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_download_requires_major
|
75
|
+
patch = Solaris::Patch.new
|
76
|
+
patch.minor = 1
|
77
|
+
assert_raise( ArgumentError ) { patch.download_patch! }
|
78
|
+
assert_raise( ArgumentError ) { patch.download_readme! }
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_download_requires_minor
|
82
|
+
patch = Solaris::Patch.new
|
83
|
+
patch.major = 123456
|
84
|
+
assert_raise( ArgumentError ) { patch.download_patch! }
|
85
|
+
assert_raise( ArgumentError ) { patch.download_readme! }
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_download!
|
89
|
+
skip 'Mock required'
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_pad_minor
|
93
|
+
assert_equal( '00', Solaris::Patch.pad_minor( 0 ) )
|
94
|
+
assert_equal( '01', Solaris::Patch.pad_minor( 1 ) )
|
95
|
+
assert_equal( '12', Solaris::Patch.pad_minor( 12 ) )
|
96
|
+
assert_equal( '123', Solaris::Patch.pad_minor( 123 ) )
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,198 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
require 'stringio'
|
4
|
+
require 'solaris/patchdiag'
|
5
|
+
|
6
|
+
# Unit tests for class Patchdiag.
|
7
|
+
class TestPatchdiag < Test::Unit::TestCase #:nodoc:
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@empty_file = '/dev/null'
|
11
|
+
@patchdiag_fileish = StringIO.new(<<-EOF
|
12
|
+
## PATCHDIAG TOOL CROSS-REFERENCE FILE AS OF Feb/10/11 ##
|
13
|
+
##
|
14
|
+
## The content of this file has changed as of Jun/04/10. Due to the merging of
|
15
|
+
## the Sun Alert and Recommended patch clusters, some patches tagged with the
|
16
|
+
## "R" flag may now be obsoleted patches (and as a result additionally have the
|
17
|
+
## "O" flag set).
|
18
|
+
## Details of this change are explained in the following blog posting:
|
19
|
+
## http://blogs.sun.com/patch/entry/merging_the_solaris_recommended_and
|
20
|
+
## The following Technical Info Document explains the various fields in the
|
21
|
+
## patchdiag.xref file:
|
22
|
+
## https://support.oracle.com/CSP/main/article?cmd=show&type=NOT&doctype=REFERENCE&id=1019527.1
|
23
|
+
100287|05|Oct/31/91| | | | |Unbundled|||PC-NFS 3.5c: Jumbo patch (updated PRT.COM to v3.5c)
|
24
|
+
100323|05|Feb/11/92| | | | |Unbundled|||PC-NFS Advanced Telnet: bug fixes, National Character Set support
|
25
|
+
100386|01|Sep/20/91| | | | |Unbundled|||PC-NFS Programmer's Toolkit/2.0: Runtime modules
|
26
|
+
100393|01|Sep/02/94| | |O| |Unbundled|||OBSOLETED by 100394
|
27
|
+
100438|01|Dec/02/91| | | | |Unbundled|||PCNFS/v3.5c: PC-NFS loses mounted printer names when PCNFSLPD load
|
28
|
+
100455|01|Dec/17/91| | | | |Unbundled|||LifeLine/2.0: Does not parse the FROM: and/or Reply-TO: fields cor
|
29
|
+
100648|01|Jun/11/92| | | | |Unbundled|||PC-NFS/4.0a: Jumbo Patch
|
30
|
+
100701|03|Feb/17/93| | | | |Unbundled|sparc;|SUNWowbcp:1.8.1;SUNWowbcp:2.10;|OpenWindows 3.0.1;3.1: programs compiled under Solaris 1.x /usr/5b
|
31
|
+
100791|04|Apr/12/93| | |O| |Unbundled||SPROsw:2.1.0.1;|OBSOLETED by 100974
|
32
|
+
100791|05|Apr/12/93| | |O| |Unbundled||SPROsw:2.1.0.1;|OBSOLETED by 100974
|
33
|
+
100807|03|May/02/94| | |O| B|Unbundled|||OBSOLETED by WITHDRAWN
|
34
|
+
100807|04|Jul/07/94| | | | |Unbundled|sparc;|SPROswmgr:2.1.2.1;|Sparcworks 2.0.1: statically linking X11 library doesn't run on As
|
35
|
+
100811|01|Mar/17/93| | |O| |Unbundled||SPROcpl:2.1.0.3;SPROlang:2.1.0.3;|OBSOLETED by 100967
|
36
|
+
100812|02|Jan/27/93| | | | |Unbundled|sparc;|SUNWowrqd:1.16.2;|OpenWindows 3.0.1: Binder as root with "-system" or "-network" doe
|
37
|
+
100824|03|Jun/29/93| | | | |Unbundled|sparc;|SUNWowrqd:2.10;|OpenWindows 3.1: fixes various bugs in xnews server
|
38
|
+
100830|01|Mar/12/93| | |O| |Unbundled||SPROlang:2.1.0.1;|OBSOLETED by 100861
|
39
|
+
100837|01|Jan/20/93| | | | |Unbundled|sparc;|SUNWowrqd:2.10.0.1;|OpenWindows 3.1: core dump in ras3,ras4,ras5 and install_check on
|
40
|
+
100843|01|Feb/05/93| | | | |Unbundled|||PC-NFS/4.0a: various, system or print server hangs under heavy loa
|
41
|
+
100849|01|Jan/20/93| | |O| |Unbundled||SPROpas:2.1.0.1;|OBSOLETED by 100964
|
42
|
+
100852|02|Jul/01/93| | |O| |2.1||SUNWcsu:11.4.2,PATCH=28;|OBSOLETED by WITHDRAWN
|
43
|
+
146124|01|Dec/08/10| | | | |10|sparc;|SUNWthunderbirdl10n-de-DE:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-es-ES:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-extra:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-fr-FR:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-it-IT:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-ja-JP:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-ko-KR:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-pl-PL:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-pt-BR:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-ru-RU:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-sv-SE:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-zh-CN:3.0.3,REV=101.0.3;SUNWthunderbirdl10n-zh-TW:3.0.3,REV=101.0.3;|SunOS 5.10: Thunderbird l10n packages update Patch
|
44
|
+
146132|01|Jan/05/11| | | | |10|sparc;137137-09;141444-09;|SUNWcsu:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: newfs fails on newly-formatted floppy disk
|
45
|
+
146133|01|Jan/05/11| | | | |10_x86|i386;137138-09;141445-09;|SUNWcsu:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: newfs fails on newly-formatted floppy disk
|
46
|
+
146236|01|Dec/10/10| | | | |10|sparc;137137-09;|SUNWckr:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: dcfs patch
|
47
|
+
146237|01|Dec/10/10| | | | |10_x86|i386;141445-09;|SUNWckr:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: dcfs patch
|
48
|
+
146241|02|Dec/16/10| | | | |Unbundled|sparc;|SUNWscsaa:3.3.0,REV=2010.07.26.12.56;|Oracle Solaris Cluster 3.3: SWIFTAllianceAccess patch
|
49
|
+
146277|01|Dec/10/10| | | | |10|sparc;118833-36;120011-14;127127-11;139555-08;142909-17;|SUNWcslr:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: libnsl patch
|
50
|
+
146278|01|Dec/10/10| | | | |10_x86|i386;118855-36;120012-14;127128-11;139556-08;142910-17;|SUNWcslr:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: libnsl patch
|
51
|
+
146279|01|Dec/22/10|R|S| | |10|sparc;|SUNWbnuu:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: uucp patch
|
52
|
+
146280|01|Dec/22/10|R|S| | |10_x86|i386;|SUNWbnuu:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: uucp patch
|
53
|
+
146281|01|Dec/15/10| | | | |10|sparc;|SUNWckr:11.10.0,REV=2005.01.21.15.53;SUNWhea:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: ldterm patch
|
54
|
+
146282|01|Dec/15/10| | | | |10_x86|i386;|SUNWckr:11.10.0,REV=2005.01.21.16.34;SUNWhea:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: ldterm patch
|
55
|
+
146283|01|Dec/10/10| | | | |10|sparc;118833-36;137137-09;142909-17;|SUNWckr:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: lofi patch
|
56
|
+
146284|01|Dec/10/10| | | | |10_x86|i386;118855-36;137138-09;142910-17;|SUNWckr:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: lofi patch
|
57
|
+
146287|01|Jan/24/11| | | | |10|sparc.sun4u;sparc.sun4us;sparc.sun4v;118833-36;120011-14;|SUNWkvm:11.10.0,REV=2005.01.20.17.25;SUNWkvm:11.10.0,REV=2005.01.21.15.53;SUNWkvm:11.10.0,REV=2005.08.04.12.25;|SunOS 5.10: trapstat Patch
|
58
|
+
146332|02|Feb/03/11| | | | |10|sparc;142909-17;|SUNWaccu:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: sadc patch
|
59
|
+
146333|02|Feb/03/11| | | | |10_x86|i386;142910-17;|SUNWaccu:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: sadc patch
|
60
|
+
146334|01|Jan/19/11| | | | |10|sparc;120011-14;121133-02;127127-11;139555-08;142909-17;|SUNWzoneu:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: zlogin patch
|
61
|
+
146335|01|Jan/19/11| | | | |10_x86|i386;120012-14;121334-04;127128-11;139556-08;142910-17;|SUNWzoneu:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: zlogin patch
|
62
|
+
146336|01|Jan/13/11| | | | |10|sparc;118833-36;120011-14;127127-11;137137-09;142909-17;|SUNWarc:11.10.0,REV=2005.01.21.15.53;SUNWcsl:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: libsldap.so.1 patch
|
63
|
+
146337|01|Jan/13/11| | | | |10_x86|i386;120012-14;127128-11;137138-09;142910-17;|SUNWarc:11.10.0,REV=2005.01.21.16.34;SUNWcsl:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: libsldap.so.1 patch
|
64
|
+
146363|01|Jan/04/11|R|S| | |10|sparc;119757-19;|SUNWsfman:11.10.0,REV=2005.01.08.05.16;SUNWsmbaS:11.10.0,REV=2005.01.08.05.16;SUNWsmbar:11.10.0,REV=2005.01.08.05.16;SUNWsmbau:11.10.0,REV=2005.01.08.05.16;|SunOS 5.10: Samba patch
|
65
|
+
146364|01|Jan/04/11|R|S| | |10_x86|i386;119758-19;|SUNWsfman:11.10.0,REV=2005.01.08.01.09;SUNWsmbaS:11.10.0,REV=2005.01.08.01.09;SUNWsmbar:11.10.0,REV=2005.01.08.01.09;SUNWsmbau:11.10.0,REV=2005.01.08.01.09;|SunOS 5.10_x86: Samba patch
|
66
|
+
146435|01|Feb/01/11| | | | |Unbundled|||Hardware FC Disk Drive Patch : Download program and FC Disk Drive
|
67
|
+
146440|01|Jan/13/11| | | | |10|sparc;118833-36;120011-14;137137-09;139555-08;141444-09;142909-17;|SUNWckr:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: dld patch
|
68
|
+
146441|01|Jan/13/11| | | | |10_x86|i386;118855-36;120012-14;139556-08;141445-09;142910-17;|SUNWckr:11.10.0,REV=2005.01.21.16.34;|SunOS 5.10_x86: dld patch
|
69
|
+
146442|01|Jan/24/11| | | | |10|sparc;126897-02;127127-11;127755-01;137137-09;139555-08;141444-09;142909-17;|SUNWfmd:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: libldom.so.1 patch
|
70
|
+
146443|01|Feb/09/11| | | | |10|sparc;142909-17;|SUNWfmd:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: gmem.eft and generic-mem.so patch
|
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
|
+
800054|01|Mar/16/01| | |O| |Unbundled|||Obsoleted by: 111346-01 Hardware/PROM: Sun Fire 3800/4800/4810/680
|
73
|
+
100974|02|Mar/14/95| | | | |Unbundled|sparc;|SPROsw:2.1.0;|SparcWorks 2.0.1: dbx jumbo patch
|
74
|
+
EOF
|
75
|
+
)
|
76
|
+
@patchdiag = Solaris::Patchdiag.open( @patchdiag_fileish )
|
77
|
+
end
|
78
|
+
|
79
|
+
def teardown
|
80
|
+
@empty_file = nil
|
81
|
+
@patchdiag = nil
|
82
|
+
@patchdiag_fileish = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_new_by_fileish
|
86
|
+
assert_equal( 51, @patchdiag.entries.size )
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_new_by_filename
|
90
|
+
temp = Tempfile.new( 'test_patchdiag' )
|
91
|
+
path = temp.path
|
92
|
+
temp.write( @patchdiag_fileish )
|
93
|
+
temp.close
|
94
|
+
patchdiag = Solaris::Patchdiag.new( path )
|
95
|
+
File.unlink( path )
|
96
|
+
assert_equal( 51, @patchdiag.entries.size )
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_new_empty_file
|
100
|
+
if File.exists?( @empty_file )
|
101
|
+
patchdiag = Solaris::Patchdiag.new( @empty_file )
|
102
|
+
assert_equal( 0, patchdiag.entries.size )
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_all
|
107
|
+
assert_equal( 51, @patchdiag.all.size )
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_all_sort_by_date_order_ascending
|
111
|
+
all = @patchdiag.all( :sort_by => :date, :order => :ascending )
|
112
|
+
first = all.first.patch # oldest
|
113
|
+
last = all.last.patch # newest
|
114
|
+
assert_equal( Solaris::Patch.new( '100386-01' ), first )
|
115
|
+
assert_equal( Solaris::Patch.new( '146443-01' ), last )
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_all_sort_by_patch_order_descending
|
119
|
+
all = @patchdiag.all( :sort_by => :patch, :order => :descending )
|
120
|
+
first = all.first.patch # largest
|
121
|
+
last = all.last.patch # smallest
|
122
|
+
assert_equal( Solaris::Patch.new( '800054-01' ), first )
|
123
|
+
assert_equal( Solaris::Patch.new( '100287-05' ), last )
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_open_block
|
127
|
+
ret = Solaris::Patchdiag.open( @patchdiag_fileish ) do |patchdiag|
|
128
|
+
assert_equal( Solaris::Patchdiag, patchdiag.class )
|
129
|
+
:return_code
|
130
|
+
end
|
131
|
+
assert_equal( :return_code, ret )
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_open_return
|
135
|
+
assert_equal( Solaris::Patchdiag, @patchdiag.class )
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_find
|
139
|
+
assert_equal( [], @patchdiag.find( 123456 ) )
|
140
|
+
assert_equal( [], @patchdiag.find( '123456' ) )
|
141
|
+
assert_equal( [], @patchdiag.find( '123456-78' ) )
|
142
|
+
assert_equal( [], @patchdiag.find( Solaris::Patch.new( 123456 ) ) )
|
143
|
+
assert_equal( [], @patchdiag.find( Solaris::Patch.new( '123456' ) ) )
|
144
|
+
assert_equal( [], @patchdiag.find( Solaris::Patch.new( '123456-78' ) ) )
|
145
|
+
assert_equal( [], @patchdiag.find( '100791-01' ) )
|
146
|
+
assert_equal( [], @patchdiag.find( Solaris::Patch.new( '100791-01' ) ) )
|
147
|
+
assert_equal( '100791-04', @patchdiag.find( 100791 ).first.patch.to_s )
|
148
|
+
assert_equal( '100791-04', @patchdiag.find( '100791' ).first.patch.to_s )
|
149
|
+
assert_equal( '100791-04', @patchdiag.find( '100791-04' ).first.patch.to_s )
|
150
|
+
assert_equal( '100791-04', @patchdiag.find( Solaris::Patch.new( 100791) ).first.patch.to_s )
|
151
|
+
assert_equal( '100791-04', @patchdiag.find( Solaris::Patch.new( '100791') ).first.patch.to_s )
|
152
|
+
assert_equal( '100791-04', @patchdiag.find( Solaris::Patch.new( '100791-04') ).first.patch.to_s )
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_latest
|
156
|
+
assert_raise( Solaris::Patch::NotFound ) do
|
157
|
+
@patchdiag.latest( 123456 )
|
158
|
+
end
|
159
|
+
assert_equal( '100791-05', @patchdiag.latest( 100791 ).patch.to_s )
|
160
|
+
assert_equal( '100791-05', @patchdiag.latest( '100791' ).patch.to_s )
|
161
|
+
assert_equal( '100791-05', @patchdiag.latest( '100791-01' ).patch.to_s )
|
162
|
+
assert_equal( '100791-05', @patchdiag.latest( '100791-05' ).patch.to_s )
|
163
|
+
assert_equal( '100791-05', @patchdiag.latest( Solaris::Patch.new( 100791 ) ).patch.to_s )
|
164
|
+
assert_equal( '100791-05', @patchdiag.latest( Solaris::Patch.new( '100791' ) ).patch.to_s )
|
165
|
+
assert_equal( '100791-05', @patchdiag.latest( Solaris::Patch.new( '100791-01' ) ).patch.to_s )
|
166
|
+
assert_equal( '100791-05', @patchdiag.latest( Solaris::Patch.new( '100791-05' ) ).patch.to_s )
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_successor
|
170
|
+
assert_raise( Solaris::Patch::NotFound ) do
|
171
|
+
@patchdiag.latest( 123456 )
|
172
|
+
end
|
173
|
+
assert_equal( '100287-05', @patchdiag.successor( 100287 ).patch.to_s )
|
174
|
+
assert_equal( '100287-05', @patchdiag.successor( '100287' ).patch.to_s )
|
175
|
+
assert_equal( '100287-05', @patchdiag.successor( '100287-05' ).patch.to_s )
|
176
|
+
assert_equal( '100287-05', @patchdiag.successor( Solaris::Patch.new( '100287-05' ) ).patch.to_s )
|
177
|
+
assert_equal( '100974-02', @patchdiag.successor( 100791 ).patch.to_s )
|
178
|
+
assert_raise( Solaris::Patch::NotFound ) do
|
179
|
+
@patchdiag.successor( 100393 ) # successor 100394 not in patchdiag.xref
|
180
|
+
end
|
181
|
+
assert_equal( '100807-04', @patchdiag.successor( '100807-01' ).patch.to_s )
|
182
|
+
assert_raise( Solaris::Patch::InvalidSuccessor ) do
|
183
|
+
@patchdiag.successor( '100807-03' ) # successor 100807-03 WITHDRAWN
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_download!
|
188
|
+
skip 'Mock required'
|
189
|
+
end
|
190
|
+
|
191
|
+
private
|
192
|
+
|
193
|
+
def successor(patch)
|
194
|
+
@patchdiag.successor( patch ).patch.to_s
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
require 'solaris/patchdiag_entry'
|
4
|
+
|
5
|
+
# Unit tests for class PatchdiagEntry.
|
6
|
+
class TestPatchdiagEntry < Test::Unit::TestCase #:nodoc:
|
7
|
+
|
8
|
+
def test_146636_01
|
9
|
+
line = '146336|01|Jan/13/11| | | | |10|sparc;118833-36;120011-14;127127-11;137137-09;142909-17;|SUNWarc:11.10.0,REV=2005.01.21.15.53;SUNWcsl:11.10.0,REV=2005.01.21.15.53;|SunOS 5.10: libsldap.so.1 patch'
|
10
|
+
pde = Solaris::PatchdiagEntry.new( line )
|
11
|
+
assert_equal( 146336, pde.major )
|
12
|
+
assert_equal( 1, pde.minor )
|
13
|
+
assert_equal( false, pde.recommended? )
|
14
|
+
assert_equal( false, pde.obsolete? )
|
15
|
+
assert_equal( false, pde.security? )
|
16
|
+
assert_equal( Date.new(2011, 1, 13), pde.date )
|
17
|
+
assert_equal( '10', pde.os )
|
18
|
+
assert_equal( '146336-01', pde.patch.to_s )
|
19
|
+
assert_equal( ['SUNWarc:11.10.0,REV=2005.01.21.15.53',
|
20
|
+
'SUNWcsl:11.10.0,REV=2005.01.21.15.53'], pde.pkgs )
|
21
|
+
assert_equal( [ 'sparc', '118833-36', '120011-14', '127127-11', '137137-09', '142909-17' ], pde.archs )
|
22
|
+
assert_equal( 'SunOS 5.10: libsldap.so.1 patch', pde.synopsis )
|
23
|
+
assert_equal( line, pde.to_s )
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_100393_01
|
27
|
+
line = '100393|01|Sep/02/94| | |O| |Unbundled|||OBSOLETED by 100394'
|
28
|
+
pde = Solaris::PatchdiagEntry.new( line )
|
29
|
+
assert_equal( 100393, pde.major )
|
30
|
+
assert_equal( 1, pde.minor )
|
31
|
+
assert_equal( false, pde.recommended? )
|
32
|
+
assert_equal( true, pde.obsolete? )
|
33
|
+
assert_equal( false, pde.security? )
|
34
|
+
assert_equal( Date.new(1994, 9, 2), pde.date )
|
35
|
+
assert_equal( 'Unbundled', pde.os )
|
36
|
+
assert_equal( '100393-01', pde.patch.to_s )
|
37
|
+
assert_equal( [], pde.pkgs )
|
38
|
+
assert_equal( [], pde.archs )
|
39
|
+
assert_equal( 'OBSOLETED by 100394', pde.synopsis )
|
40
|
+
assert_equal( line, pde.to_s )
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_146364_01
|
44
|
+
line = '146364|01|Jan/04/11|R|S| | |10_x86|i386;119758-19;|SUNWsfman:11.10.0,REV=2005.01.08.01.09;SUNWsmbaS:11.10.0,REV=2005.01.08.01.09;SUNWsmbar:11.10.0,REV=2005.01.08.01.09;SUNWsmbau:11.10.0,REV=2005.01.08.01.09;|SunOS 5.10_x86: Samba patch'
|
45
|
+
pde = Solaris::PatchdiagEntry.new( line )
|
46
|
+
assert_equal( 146364, pde.major )
|
47
|
+
assert_equal( 1, pde.minor )
|
48
|
+
assert_equal( true, pde.recommended? )
|
49
|
+
assert_equal( false, pde.obsolete? )
|
50
|
+
assert_equal( true, pde.security? )
|
51
|
+
assert_equal( Date.new(2011, 1, 4), pde.date )
|
52
|
+
assert_equal( '10_x86', pde.os )
|
53
|
+
assert_equal( '146364-01', pde.patch.to_s )
|
54
|
+
assert_equal( ['SUNWsfman:11.10.0,REV=2005.01.08.01.09',
|
55
|
+
'SUNWsmbaS:11.10.0,REV=2005.01.08.01.09',
|
56
|
+
'SUNWsmbar:11.10.0,REV=2005.01.08.01.09',
|
57
|
+
'SUNWsmbau:11.10.0,REV=2005.01.08.01.09'],
|
58
|
+
pde.pkgs )
|
59
|
+
assert_equal( ['i386', '119758-19'], pde.archs )
|
60
|
+
assert_equal( 'SunOS 5.10_x86: Samba patch', pde.synopsis )
|
61
|
+
assert_equal( line, pde.to_s )
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_compare_equal
|
65
|
+
line = '100393|01|Sep/02/94| | |O| |Unbundled|||OBSOLETED by 100394'
|
66
|
+
assert_equal(Solaris::PatchdiagEntry.new( line ),
|
67
|
+
Solaris::PatchdiagEntry.new( line ))
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_compare_less_than
|
71
|
+
line1 = '100393|01|Sep/02/94| | |O| |Unbundled|||OBSOLETED by 100394'
|
72
|
+
line2 = '146364|01|Jan/04/11|R|S| | |10_x86|i386;119758-19;|SUNWsfman:11.10.0,REV=2005.01.08.01.09;SUNWsmbaS:11.10.0,REV=2005.01.08.01.09;SUNWsmbar:11.10.0,REV=2005.01.08.01.09;SUNWsmbau:11.10.0,REV=2005.01.08.01.09;|SunOS 5.10_x86: Samba patch'
|
73
|
+
assert( Solaris::PatchdiagEntry.new( line1 ) < Solaris::PatchdiagEntry.new( line2 ) )
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_successor
|
77
|
+
assert_raise( Solaris::Patch::NotObsolete ) do
|
78
|
+
successor( '100287|05|Oct/31/91| | | | |Unbundled|||PC-NFS 3.5c: Jumbo patch (updated PRT.COM to v3.5c)' )
|
79
|
+
end
|
80
|
+
assert_equal( '110258-01', successor( '109687|01|Aug/11/00| | |O| |Unbundled|sparc;|VRTSvxvm:3.0.4,REV=04.18.2000.10.00;|Obsoleted by : 110258-01 VxVM 3.0.4: vxio and vxdmp driver patch' ) )
|
81
|
+
assert_equal( '101318-94', successor( '101859|01|Feb/06/01| | |O| |2.3|sparc;|SUNWcsr:11.5.0,REV=2.0.19,PATCH=118;|Obsoleted by: 101318-94 SunOS 5.3: socket lib in 2.3/2.2 have prob' ) )
|
82
|
+
assert_equal( '106542', successor( '107440|01|Mar/26/99| | |O| |7_x86||SUNWcar:11.7.0,REV=1998.09.01.04.53;|OBSOLETED by: 106542 SunOS 5.7_x86: /platform/i86pc/kernel/mmu/mm' ) )
|
83
|
+
assert_equal( '109212-02', successor( '108191|01|Sep/07/99| | |O| B|Unbundled|||Obsoleted by: 109212-02 OBSOLETED by WITHDRAWN' ) )
|
84
|
+
assert_raise( Solaris::Patch::InvalidSuccessor ) do
|
85
|
+
successor( '100807|03|May/02/94| | |O| B|Unbundled|||OBSOLETED by WITHDRAWN' )
|
86
|
+
end
|
87
|
+
assert_equal( '100394', successor( '100393|01|Sep/02/94| | |O| |Unbundled|||OBSOLETED by 100394' ) )
|
88
|
+
assert_raise( Solaris::Patch::MultipleSuccessors ) do
|
89
|
+
successor( '105716|07|Jun/30/99| |S|O| |Unbundled||SUNWdtbas:1.0.2,REV=10.96.04.12;|OBSOLETED by 108363 and 108289' )
|
90
|
+
end
|
91
|
+
assert_raise( Solaris::Patch::MultipleSuccessors ) do
|
92
|
+
successor( '105717|06|Jun/30/99| |S|O| |Unbundled||SUNWdtbas:1.0.2,REV=10.96.04.12;|OBSOLETED by 108290 and 108364' )
|
93
|
+
end
|
94
|
+
assert_equal( '110256-01', successor( '109685|02|Feb/09/01| | |O| |Unbundled|sparc;|VRTSvxvm:3.0.4,REV=04.18.2000.10.00;|Obsoleted by 110256-01: VxVM 3.0.4: vxio and vxdmp driver patch' ) )
|
95
|
+
assert_equal( '110257-01', successor( '109686|02|Feb/09/01| | |O| |Unbundled|sparc;|VRTSvxvm:3.0.4,REV=04.18.2000.10.00;|OBSOLETED by 110257-01: VxVM 3.0.4: vxio and vxdmp driver patch' ) )
|
96
|
+
assert_equal( '106513-07', successor( '106513|06|Oct/03/00| | |O| B|Unbundled|sparc;|SUNWosafw:6.01,REV=01.11;SUNWosau:6.01,REV=01.11;108555-02;|WITHDRAWN Obsoleted by: 106513-07 RM 6.1.1: generic Raid Manager 6' ) )
|
97
|
+
assert_raise( Solaris::Patch::InvalidSuccessor ) do
|
98
|
+
# NB fudged the obsolete flag here
|
99
|
+
successor( '111442|01|May/04/01| | |O| B|2.5.1|sparc;sparc.sun4c;sparc.sun4d;sparc.sun4m;sparc.sun4u;sparc.sun4u1;103640-35;|SUNWcar:11.5.1,REV=96.05.02.21.09;SUNWcar:11.5.1,REV=97.02.21.21.14;SUNWcsr:11.5.1,REV=96.05.02.21.09;103640-36;|WITHDRAWN PATCH Obsolete by: <INTEGRATION> SunOS 5.5.1: Supplement' )
|
100
|
+
end
|
101
|
+
assert_equal( '103901-08', successor( '103901|07|Aug/05/97| |S|O| B|2.5.1|||WITHDRAWN PATCH Obsoleted by: 103901-08 OpenWindows 3.5.1: Xview P' ) )
|
102
|
+
assert_raise( Solaris::Patch::InvalidSuccessor ) do
|
103
|
+
# NB fudged the obsolete flag here
|
104
|
+
successor( '111433|02|Jun/04/01| | |O| B|8|sparc;sparc.sun4d;sparc.sun4m;sparc.sun4u;sparc.sun4us;108528-08;|FJSVhea:1.0,REV=1999.12.23.19.10;SUNWcar:11.8.0,REV=2000.01.08.18.12;SUNWcar:11.8.0,REV=2000.01.13.13.40;SUNWcarx:11.8.0,REV=2000.01.08.18.12;SUNWcarx:11.8.0,REV=2000.01.13.13.40;SUNWcsr:11.8.0,REV=2000.01.08.18.12;SUNWhea:11.8.0,REV=2000.01.08.18.12;108528-09;|WITHDRAWN PATCH Obsoleted by: <Integration> SunOS 5.8: Supplementa' )
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def successor(line)
|
111
|
+
Solaris::PatchdiagEntry.new( line ).successor.to_s
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
require 'solaris'
|
4
|
+
|
5
|
+
# Unit tests for top level require.
|
6
|
+
class TestSolaris < Test::Unit::TestCase #:nodoc:
|
7
|
+
|
8
|
+
def test_solaris
|
9
|
+
assert_nothing_raised { Solaris }
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_solaris_patch
|
13
|
+
assert_nothing_raised { Solaris::Patch }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_solaris_patchdiag
|
17
|
+
assert_nothing_raised { Solaris::Patchdiag }
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_solaris_patchdiag_entry
|
21
|
+
assert_nothing_raised { Solaris::PatchdiagEntry }
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_test
|
25
|
+
assert_raise( NameError ) { Solaris::DoesNotExist }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
data/test/test_util.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
require 'solaris/util'
|
4
|
+
|
5
|
+
# Unit tests for utility module.
|
6
|
+
class TestUtil < Test::Unit::TestCase #:nodoc:
|
7
|
+
|
8
|
+
def test_to_dir_to_file_mutually_exclusive
|
9
|
+
assert_raise( ArgumentError ) do
|
10
|
+
Solaris::Util.download!('http://example.com',
|
11
|
+
:to_dir => 'dir',
|
12
|
+
:to_file => 'file')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_user_without_password
|
17
|
+
assert_raise( ArgumentError ) do
|
18
|
+
Solaris::Util.download!('http://example.com',
|
19
|
+
:user => 'user')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_password_without_user
|
24
|
+
assert_raise( ArgumentError ) do
|
25
|
+
Solaris::Util.download!('http://example.com',
|
26
|
+
:password => 'password')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: solaris-patch
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 1.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Martin Carpenter
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-05-03 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: mechanize
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 1.0.0
|
33
|
+
type: :runtime
|
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 eg seeking the latest non-obsolete version of a patch
|
36
|
+
email: mcarpenter@free.fr
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- Rakefile
|
44
|
+
- README.rdoc
|
45
|
+
files:
|
46
|
+
- lib/solaris/exception.rb
|
47
|
+
- lib/solaris/patch.rb
|
48
|
+
- lib/solaris/foo
|
49
|
+
- lib/solaris/patchdiag_entry.rb
|
50
|
+
- lib/solaris/util.rb
|
51
|
+
- lib/solaris/patchdiag.rb
|
52
|
+
- lib/solaris.rb
|
53
|
+
- test/test_patchdiag_entry.rb
|
54
|
+
- test/test_patch.rb
|
55
|
+
- test/test_util.rb
|
56
|
+
- test/test_solaris.rb
|
57
|
+
- test/test_patchdiag.rb
|
58
|
+
- LICENSE
|
59
|
+
- Rakefile
|
60
|
+
- README.rdoc
|
61
|
+
has_rdoc: true
|
62
|
+
homepage: http://mcarpenter.org/projects/solaris-patch
|
63
|
+
licenses:
|
64
|
+
- BSD
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.3.7
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Facilitate the manipulation of Solaris patches
|
93
|
+
test_files:
|
94
|
+
- test/test_patchdiag_entry.rb
|
95
|
+
- test/test_patch.rb
|
96
|
+
- test/test_util.rb
|
97
|
+
- test/test_solaris.rb
|
98
|
+
- test/test_patchdiag.rb
|