Skip to content

Commit 4dce1e7

Browse files
committed
Move windows matcher logic so all platforms can use
There shouldn't be any need to make the platform matcher stuff for Windows to only be available on Windows since none of it is dependent on the machine running it. Signed-off-by: Brian Goff <[email protected]>
1 parent 9ada2e3 commit 4dce1e7

8 files changed

+320
-366
lines changed

defaults_test.go

+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package platforms
18+
19+
import (
20+
"reflect"
21+
"runtime"
22+
"sort"
23+
"testing"
24+
25+
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
26+
)
27+
28+
// TestMatchComparerMatch_ABICheckWCOW checks windows platform matcher
29+
// behavior for stable ABI and non-stable ABI compliant versions
30+
func TestMatchComparerMatch_ABICheckWCOW(t *testing.T) {
31+
platformNoVersion := imagespec.Platform{
32+
Architecture: "amd64",
33+
OS: "windows",
34+
}
35+
platformWS2019 := imagespec.Platform{
36+
Architecture: "amd64",
37+
OS: "windows",
38+
OSVersion: "10.0.17763",
39+
}
40+
platformWS2022 := imagespec.Platform{
41+
Architecture: "amd64",
42+
OS: "windows",
43+
OSVersion: "10.0.20348",
44+
}
45+
platformWindows11 := imagespec.Platform{
46+
Architecture: "amd64",
47+
OS: "windows",
48+
OSVersion: "10.0.22621",
49+
}
50+
51+
for _, test := range []struct {
52+
hostPlatform imagespec.Platform
53+
testPlatform imagespec.Platform
54+
match bool
55+
}{
56+
{
57+
hostPlatform: platformWS2019,
58+
testPlatform: imagespec.Platform{
59+
Architecture: "amd64",
60+
OS: "windows",
61+
OSVersion: "10.0.17763",
62+
},
63+
match: true,
64+
},
65+
{
66+
hostPlatform: platformWS2019,
67+
testPlatform: imagespec.Platform{
68+
Architecture: "amd64",
69+
OS: "windows",
70+
OSVersion: "10.0.20348",
71+
},
72+
match: false,
73+
},
74+
{
75+
hostPlatform: platformWS2022,
76+
testPlatform: imagespec.Platform{
77+
Architecture: "amd64",
78+
OS: "windows",
79+
OSVersion: "10.0.17763",
80+
},
81+
match: false,
82+
},
83+
{
84+
hostPlatform: platformWS2022,
85+
testPlatform: imagespec.Platform{
86+
Architecture: "amd64",
87+
OS: "windows",
88+
OSVersion: "10.0.20348",
89+
},
90+
match: true,
91+
},
92+
{
93+
hostPlatform: platformWindows11,
94+
testPlatform: imagespec.Platform{
95+
Architecture: "amd64",
96+
OS: "windows",
97+
OSVersion: "10.0.17763",
98+
},
99+
match: false,
100+
},
101+
{
102+
hostPlatform: platformWindows11,
103+
testPlatform: imagespec.Platform{
104+
Architecture: "amd64",
105+
OS: "windows",
106+
OSVersion: "10.0.20348",
107+
},
108+
match: true,
109+
},
110+
{
111+
hostPlatform: platformNoVersion,
112+
testPlatform: platformWS2019,
113+
match: true,
114+
},
115+
{
116+
hostPlatform: platformNoVersion,
117+
testPlatform: platformNoVersion,
118+
match: true,
119+
},
120+
{
121+
hostPlatform: platformNoVersion,
122+
testPlatform: platformWindows11,
123+
match: true,
124+
},
125+
} {
126+
matcher := NewMatcher(test.hostPlatform)
127+
if actual := matcher.Match(test.testPlatform); actual != test.match {
128+
t.Errorf("should match: %t, test(%s) to host(%s)", test.match, test.hostPlatform, test.testPlatform)
129+
}
130+
}
131+
}
132+
133+
func TestWindowsMatchComparerLess(t *testing.T) {
134+
p := imagespec.Platform{
135+
Architecture: "amd64",
136+
OS: "windows",
137+
OSVersion: "10.0.17763.1",
138+
}
139+
140+
m := NewMatcher(p)
141+
if runtime.GOOS != "windows" {
142+
// By default NewMatcher only returns the MatchComparer interface on Windows (which is only for backwards compatibility).
143+
// On other platforms, we need to wrap the matcher in a windowsMatchComparer since the test is using it.
144+
m = &windowsMatchComparer{m}
145+
}
146+
platforms := []imagespec.Platform{
147+
{
148+
Architecture: "amd64",
149+
OS: "windows",
150+
OSVersion: "10.0.17764.1",
151+
},
152+
{
153+
Architecture: "amd64",
154+
OS: "windows",
155+
},
156+
{
157+
Architecture: "amd64",
158+
OS: "windows",
159+
OSVersion: "10.0.17763.1",
160+
},
161+
{
162+
Architecture: "amd64",
163+
OS: "windows",
164+
OSVersion: "10.0.17763.2",
165+
},
166+
{
167+
Architecture: "amd64",
168+
OS: "windows",
169+
OSVersion: "10.0.17762.1",
170+
},
171+
}
172+
expected := []imagespec.Platform{
173+
{
174+
Architecture: "amd64",
175+
OS: "windows",
176+
OSVersion: "10.0.17763.2",
177+
},
178+
{
179+
Architecture: "amd64",
180+
OS: "windows",
181+
OSVersion: "10.0.17763.1",
182+
},
183+
{
184+
Architecture: "amd64",
185+
OS: "windows",
186+
},
187+
{
188+
Architecture: "amd64",
189+
OS: "windows",
190+
OSVersion: "10.0.17764.1",
191+
},
192+
{
193+
Architecture: "amd64",
194+
OS: "windows",
195+
OSVersion: "10.0.17762.1",
196+
},
197+
}
198+
sort.SliceStable(platforms, func(i, j int) bool {
199+
return m.(MatchComparer).Less(platforms[i], platforms[j])
200+
})
201+
if !reflect.DeepEqual(platforms, expected) {
202+
t.Errorf("expected: %s\nactual : %s", expected, platforms)
203+
}
204+
}

defaults_windows.go

-76
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ package platforms
1919
import (
2020
"fmt"
2121
"runtime"
22-
"strconv"
23-
"strings"
2422

2523
specs "github.com/opencontainers/image-spec/specs-go/v1"
2624
"golang.org/x/sys/windows"
@@ -38,80 +36,6 @@ func DefaultSpec() specs.Platform {
3836
}
3937
}
4038

41-
type windowsmatcher struct {
42-
specs.Platform
43-
osVersionPrefix string
44-
defaultMatcher Matcher
45-
}
46-
47-
// Match matches platform with the same windows major, minor
48-
// and build version.
49-
func (m windowsmatcher) Match(p specs.Platform) bool {
50-
match := m.defaultMatcher.Match(p)
51-
52-
if match && m.OS == "windows" {
53-
// HPC containers do not have OS version filled
54-
if m.OSVersion == "" || p.OSVersion == "" {
55-
return true
56-
}
57-
58-
hostOsVersion := getOSVersion(m.osVersionPrefix)
59-
ctrOsVersion := getOSVersion(p.OSVersion)
60-
return checkHostAndContainerCompat(hostOsVersion, ctrOsVersion)
61-
}
62-
63-
return match
64-
}
65-
66-
func getOSVersion(osVersionPrefix string) osVersion {
67-
parts := strings.Split(osVersionPrefix, ".")
68-
if len(parts) < 3 {
69-
return osVersion{}
70-
}
71-
72-
majorVersion, _ := strconv.ParseUint(parts[0], 10, 8)
73-
minorVersion, _ := strconv.ParseUint(parts[1], 10, 8)
74-
buildNumber, _ := strconv.ParseUint(parts[2], 10, 16)
75-
76-
return osVersion{
77-
MajorVersion: uint8(majorVersion),
78-
MinorVersion: uint8(minorVersion),
79-
Build: uint16(buildNumber),
80-
}
81-
}
82-
83-
// Less sorts matched platforms in front of other platforms.
84-
// For matched platforms, it puts platforms with larger revision
85-
// number in front.
86-
func (m windowsmatcher) Less(p1, p2 specs.Platform) bool {
87-
m1, m2 := m.Match(p1), m.Match(p2)
88-
if m1 && m2 {
89-
r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
90-
return r1 > r2
91-
}
92-
return m1 && !m2
93-
}
94-
95-
func revision(v string) int {
96-
parts := strings.Split(v, ".")
97-
if len(parts) < 4 {
98-
return 0
99-
}
100-
r, err := strconv.Atoi(parts[3])
101-
if err != nil {
102-
return 0
103-
}
104-
return r
105-
}
106-
107-
func prefix(v string) string {
108-
parts := strings.Split(v, ".")
109-
if len(parts) < 4 {
110-
return v
111-
}
112-
return strings.Join(parts[0:3], ".")
113-
}
114-
11539
// Default returns the current platform's default platform specification.
11640
func Default() MatchComparer {
11741
return Only(DefaultSpec())

0 commit comments

Comments
 (0)