Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4400bb5

Browse files
committed
Use .bat for Windows version tests
1 parent23ebb16 commit4400bb5

File tree

3 files changed

+95
-66
lines changed

3 files changed

+95
-66
lines changed

‎src/main/kotlin/com/coder/gateway/settings/CoderSettings.kt‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ open class CoderSettings(
2222
privatevalstate:CoderSettingsState,
2323
// The location of the SSH config. Defaults to ~/.ssh/config.
2424
valsshConfigPath:Path =Path.of(System.getProperty("user.home")).resolve(".ssh/config"),
25-
//Env allows overridingthe default environment.
25+
//Overridesthe default environment (for tests).
2626
privatevalenv:Environment =Environment(),
27+
// Overrides the default binary name (for tests).
28+
privatevalbinaryName:String? =null,
2729
) {
2830
val tls=CoderTLSSettings(state)
2931
val enableDownloads:Boolean
@@ -68,10 +70,10 @@ open class CoderSettings(
6870
* To where the specified deployment should download the binary.
6971
*/
7072
funbinPath(url:URL,forceDownloadToData:Boolean = false):Path {
71-
valbinaryName= getCoderCLIForOS(getOS(), getArch())
73+
valname= binaryName?: getCoderCLIForOS(getOS(), getArch())
7274
val dir=if (forceDownloadToData|| state.binaryDirectory.isBlank()) dataDir(url)
7375
else withHost(Path.of(expand(state.binaryDirectory)), url)
74-
return dir.resolve(binaryName).toAbsolutePath()
76+
return dir.resolve(name).toAbsolutePath()
7577
}
7678

7779
/**

‎src/test/kotlin/com/coder/gateway/cli/CoderCLIManagerTest.kt‎

Lines changed: 83 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,34 @@ import kotlin.test.assertNotEquals
3232
importkotlin.test.assertTrue
3333

3434
internalclassCoderCLIManagerTest {
35-
privatefunmkbin(version:String):String {
36-
returnlistOf("#!/bin/sh","""echo '{"version": "$version"}'""")
37-
.joinToString("\n")
35+
/**
36+
* Return the contents of a script that contains the string.
37+
*/
38+
privatefunmkbin(str:String):String {
39+
returnif (getOS()==OS.WINDOWS) {
40+
// Must use a .bat extension for this to work.
41+
listOf("@echo off", str)
42+
}else {
43+
listOf("#!/bin/sh", str)
44+
}.joinToString(System.lineSeparator())
45+
}
46+
47+
/**
48+
* Return the contents of a script that outputs JSON containing the version.
49+
*/
50+
privatefunmkbinVersion(version:String):String {
51+
return mkbin(echo("""{"version": "$version"}"""))
3852
}
3953

4054
privatefunmockServer(errorCode:Int = 0,version:String? = null):Pair<HttpServer,URL> {
4155
val srv=HttpServer.create(InetSocketAddress(0),0)
4256
srv.createContext("/") {exchange->
4357
var code=HttpURLConnection.HTTP_OK
44-
// TODO: Is there some simple way to create an executable file on
45-
// Windows without having to execute something to generate said
46-
// executable or having to commit one to the repo?
47-
var response= mkbin(version?:"${srv.address.port}.0.0")
58+
var response= mkbinVersion(version?:"${srv.address.port}.0.0")
4859
val eTags= exchange.requestHeaders["If-None-Match"]
4960
if (exchange.requestURI.path=="/bin/override") {
5061
code=HttpURLConnection.HTTP_OK
51-
response=mkbin("0.0.0")
62+
response=mkbinVersion("0.0.0")
5263
}elseif (!exchange.requestURI.path.startsWith("/bin/coder-")) {
5364
code=HttpURLConnection.HTTP_NOT_FOUND
5465
response="not found"
@@ -159,22 +170,15 @@ internal class CoderCLIManagerTest {
159170

160171
assertEquals(true, ccm.download())
161172

162-
// The mock does not serve a binary that works on Windows so do not
163-
// actually execute. Checking the contents works just as well as proof
164-
// that the binary was correctly downloaded anyway.
165-
assertContains(ccm.localBinaryPath.toFile().readText(), url.port.toString())
166-
if (getOS()!=OS.WINDOWS) {
167-
assertEquals(SemVer(url.port.toLong(),0,0), ccm.version())
168-
}
173+
assertEquals(SemVer(url.port.toLong(),0,0), ccm.version())
169174

170175
// It should skip the second attempt.
171176
assertEquals(false, ccm.download())
172177

173178
// Should use the source override.
174179
ccm=CoderCLIManager(url,CoderSettings(CoderSettingsState(
175180
binarySource="/bin/override",
176-
dataDirectory= tmpdir.resolve("mock-cli").toString()))
177-
)
181+
dataDirectory= tmpdir.resolve("mock-cli").toString())))
178182

179183
assertEquals(true, ccm.download())
180184
assertContains(ccm.localBinaryPath.toFile().readText(),"0.0.0")
@@ -354,32 +358,52 @@ internal class CoderCLIManagerTest {
354358
}
355359
}
356360

357-
@Test
358-
funtestFailVersionParse() {
359-
if (getOS()==OS.WINDOWS) {
360-
return// Cannot execute mock binaries on Windows.
361+
/**
362+
* Return an echo command for the OS.
363+
*/
364+
privatefunecho(str:String):String {
365+
returnif (getOS()==OS.WINDOWS) {
366+
"echo$str"
367+
}else {
368+
"echo '$str'"
361369
}
370+
}
362371

372+
/**
373+
* Return an exit command for the OS.
374+
*/
375+
privatefunexit(code:Number):String {
376+
returnif (getOS()==OS.WINDOWS) {
377+
"exit /b$code"
378+
}else {
379+
"exit$code"
380+
}
381+
}
382+
383+
@Test
384+
funtestFailVersionParse() {
363385
val tests=mapOf(
364-
nulltoProcessInitException::class,
365-
"""echo '{"foo": true, "baz": 1}'""" toMissingVersionException::class,
366-
"""echo '{"version:'""" toJsonSyntaxException::class,
367-
"""echo '{"version": "invalid"}'""" toInvalidVersionException::class,
368-
"exit 0" toMissingVersionException::class,
369-
"exit 1" toInvalidExitValueException::class,
386+
null toProcessInitException::class,
387+
echo("""{"foo": true, "baz": 1}""") toMissingVersionException::class,
388+
echo("""{"version:""") toJsonSyntaxException::class,
389+
echo("""{"version": "invalid"}""") toInvalidVersionException::class,
390+
exit(0) toMissingVersionException::class,
391+
exit(1) toInvalidExitValueException::class,
370392
)
371393

372394
val ccm=CoderCLIManager(URL("https://test.coder.parse-fail.invalid"),CoderSettings(CoderSettingsState(
373-
binaryDirectory= tmpdir.resolve("bad-version").toString()))
374-
)
395+
binaryDirectory= tmpdir.resolve("bad-version").toString()),
396+
binaryName="coder.bat"))
375397
ccm.localBinaryPath.parent.toFile().mkdirs()
376398

377399
tests.forEach {
378400
if (it.key==null) {
379401
ccm.localBinaryPath.toFile().deleteRecursively()
380402
}else {
381-
ccm.localBinaryPath.toFile().writeText("#!/bin/sh\n${it.key}")
382-
ccm.localBinaryPath.toFile().setExecutable(true)
403+
ccm.localBinaryPath.toFile().writeText(mkbin(it.key!!))
404+
if (getOS()!=OS.WINDOWS) {
405+
ccm.localBinaryPath.toFile().setExecutable(true)
406+
}
383407
}
384408
assertFailsWith(
385409
exceptionClass= it.value,
@@ -389,39 +413,37 @@ internal class CoderCLIManagerTest {
389413

390414
@Test
391415
funtestMatchesVersion() {
392-
if (getOS()==OS.WINDOWS) {
393-
return
394-
}
395-
396416
val test=listOf(
397417
Triple(null,"v1.0.0",null),
398-
Triple("""echo '{"version": "v1.0.0"}'""","v1.0.0",true),
399-
Triple("""echo '{"version": "v1.0.0"}'""","v1.0.0-devel+b5b5b5b5",true),
400-
Triple("""echo '{"version": "v1.0.0-devel+b5b5b5b5"}'""","v1.0.0-devel+b5b5b5b5",true),
401-
Triple("""echo '{"version": "v1.0.0-devel+b5b5b5b5"}'""","v1.0.0",true),
402-
Triple("""echo '{"version": "v1.0.0-devel+b5b5b5b5"}'""","v1.0.0-devel+c6c6c6c6",true),
403-
Triple("""echo '{"version": "v1.0.0-prod+b5b5b5b5"}'""","v1.0.0-devel+b5b5b5b5",true),
404-
Triple("""echo '{"version": "v1.0.0"}'""","v1.0.1",false),
405-
Triple("""echo '{"version": "v1.0.0"}'""","v1.1.0",false),
406-
Triple("""echo '{"version": "v1.0.0"}'""","v2.0.0",false),
407-
Triple("""echo '{"version": "v1.0.0"}'""","v0.0.0",false),
408-
Triple("""echo '{"version": ""}'""","v1.0.0",null),
409-
Triple("""echo '{"version": "v1.0.0"}'""","",null),
410-
Triple("""echo '{"version'""","v1.0.0",null),
411-
Triple("""exit 0""","v1.0.0",null),
412-
Triple("""exit 1""","v1.0.0",null))
418+
Triple(echo("""{"version": "v1.0.0"}"""),"v1.0.0",true),
419+
Triple(echo("""{"version": "v1.0.0"}"""),"v1.0.0-devel+b5b5b5b5",true),
420+
Triple(echo("""{"version": "v1.0.0-devel+b5b5b5b5"}"""),"v1.0.0-devel+b5b5b5b5",true),
421+
Triple(echo("""{"version": "v1.0.0-devel+b5b5b5b5"}"""),"v1.0.0",true),
422+
Triple(echo("""{"version": "v1.0.0-devel+b5b5b5b5"}"""),"v1.0.0-devel+c6c6c6c6",true),
423+
Triple(echo("""{"version": "v1.0.0-prod+b5b5b5b5"}"""),"v1.0.0-devel+b5b5b5b5",true),
424+
Triple(echo("""{"version": "v1.0.0"}"""),"v1.0.1",false),
425+
Triple(echo("""{"version": "v1.0.0"}"""),"v1.1.0",false),
426+
Triple(echo("""{"version": "v1.0.0"}"""),"v2.0.0",false),
427+
Triple(echo("""{"version": "v1.0.0"}"""),"v0.0.0",false),
428+
Triple(echo("""{"version": ""}"""),"v1.0.0",null),
429+
Triple(echo("""{"version": "v1.0.0"}"""),"",null),
430+
Triple(echo("""{"version"""),"v1.0.0",null),
431+
Triple(exit(0),"v1.0.0",null),
432+
Triple(exit(1),"v1.0.0",null))
413433

414434
val ccm=CoderCLIManager(URL("https://test.coder.matches-version.invalid"),CoderSettings(CoderSettingsState(
415-
binaryDirectory= tmpdir.resolve("matches-version").toString()))
416-
)
435+
binaryDirectory= tmpdir.resolve("matches-version").toString()),
436+
binaryName="coder.bat"))
417437
ccm.localBinaryPath.parent.toFile().mkdirs()
418438

419439
test.forEach {
420440
if (it.first==null) {
421441
ccm.localBinaryPath.toFile().deleteRecursively()
422442
}else {
423-
ccm.localBinaryPath.toFile().writeText("#!/bin/sh\n${it.first}")
424-
ccm.localBinaryPath.toFile().setExecutable(true)
443+
ccm.localBinaryPath.toFile().writeText(mkbin(it.first!!))
444+
if (getOS()!=OS.WINDOWS) {
445+
ccm.localBinaryPath.toFile().setExecutable(true)
446+
}
425447
}
426448

427449
assertEquals(it.third, ccm.matchesVersion(it.second), it.first)
@@ -446,7 +468,9 @@ internal class CoderCLIManagerTest {
446468
@Test
447469
funtestEnsureCLI() {
448470
if (getOS()==OS.WINDOWS) {
449-
return// Cannot execute mock binaries on Windows and setWritable() works differently.
471+
// TODO: setWritable() does not work the same way on Windows but we
472+
// should test what we can.
473+
return
450474
}
451475

452476
val tests=listOf(
@@ -490,7 +514,7 @@ internal class CoderCLIManagerTest {
490514
// Create a binary in the regular location.
491515
if (it.version!=null) {
492516
settings.binPath(url).parent.toFile().mkdirs()
493-
settings.binPath(url).toFile().writeText(mkbin(it.version))
517+
settings.binPath(url).toFile().writeText(mkbinVersion(it.version))
494518
settings.binPath(url).toFile().setExecutable(true)
495519
}
496520

@@ -503,7 +527,7 @@ internal class CoderCLIManagerTest {
503527
// Create a binary in the fallback location.
504528
if (it.fallbackVersion!=null) {
505529
settings.binPath(url,true).parent.toFile().mkdirs()
506-
settings.binPath(url,true).toFile().writeText(mkbin(it.fallbackVersion))
530+
settings.binPath(url,true).toFile().writeText(mkbinVersion(it.fallbackVersion))
507531
settings.binPath(url,true).toFile().setExecutable(true)
508532
}
509533

@@ -553,10 +577,6 @@ internal class CoderCLIManagerTest {
553577

554578
@Test
555579
funtestFeatures() {
556-
if (getOS()==OS.WINDOWS) {
557-
return// Cannot execute mock binaries on Windows.
558-
}
559-
560580
val tests=listOf(
561581
Pair("2.5.0",Features(true)),
562582
Pair("4.9.0",Features(true)),
@@ -567,8 +587,8 @@ internal class CoderCLIManagerTest {
567587
tests.forEach {
568588
val (srv, url)= mockServer(version= it.first)
569589
val ccm=CoderCLIManager(url,CoderSettings(CoderSettingsState(
570-
dataDirectory= tmpdir.resolve("features").toString()))
571-
)
590+
dataDirectory= tmpdir.resolve("features").toString()),
591+
binaryName="coder.bat"))
572592
assertEquals(true, ccm.download())
573593
assertEquals(it.second, ccm.features,"version:${it.first}")
574594

‎src/test/kotlin/com/coder/gateway/settings/CoderSettingsTest.kt‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.coder.gateway.services.CoderSettingsState
44
importcom.coder.gateway.util.OS
55
importcom.coder.gateway.util.getOS
66
importcom.coder.gateway.util.withPath
7+
importorg.junit.Assert.assertNotEquals
78
importjava.net.URL
89
importjava.nio.file.Path
910
importkotlin.test.Test
@@ -84,6 +85,7 @@ internal class CoderSettingsTest {
8485
funtestBinPath() {
8586
val state=CoderSettingsState()
8687
val settings=CoderSettings(state)
88+
val settings2=CoderSettings(state, binaryName="foo-bar.baz")
8789
// The binary path should fall back to the data directory but that is
8890
// already tested in the data directory tests.
8991
val url=URL("http://localhost")
@@ -92,11 +94,16 @@ internal class CoderSettingsTest {
9294
state.binaryDirectory="/tmp/coder-gateway-test/bin-dir"
9395
var expected="/tmp/coder-gateway-test/bin-dir/localhost"
9496
assertEquals(Path.of(expected).toAbsolutePath(), settings.binPath(url).parent)
97+
assertEquals(Path.of(expected).toAbsolutePath(), settings2.binPath(url).parent)
9598

9699
// Second argument bypasses override.
97100
state.dataDirectory="/tmp/coder-gateway-test/data-dir"
98101
expected="/tmp/coder-gateway-test/data-dir/localhost"
99102
assertEquals(Path.of(expected).toAbsolutePath(), settings.binPath(url,true).parent)
103+
assertEquals(Path.of(expected).toAbsolutePath(), settings2.binPath(url,true).parent)
104+
105+
assertNotEquals("foo-bar.baz", settings.binPath(url).fileName)
106+
assertEquals("foo-bar.baz", settings2.binPath(url).fileName.toString())
100107
}
101108

102109
@Test

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp