Skip to content

Commit 4331246

Browse files
committed
Use a shell script as test credentails providers
1 parent 37d1f96 commit 4331246

4 files changed

Lines changed: 108 additions & 89 deletions

File tree

Package.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,16 @@ let package = Package(
116116
dependencies: [],
117117
swiftSettings: swiftSettings
118118
),
119-
.executableTarget(
120-
name: "credential-process-test-helper",
121-
path: "Sources/credential-process-test-helper"
122-
),
123119
.testTarget(
124120
name: "SotoCoreTests",
125121
dependencies: [
126122
.byName(name: "SotoCore"),
127123
.byName(name: "SotoTestUtils"),
128124
.product(name: "NIOPosix", package: "swift-nio"),
129125
.product(name: "InMemoryTracing", package: "swift-distributed-tracing"),
126+
],
127+
resources: [
128+
.copy("Resources/credential-process-test-helper.sh")
130129
]
131130
),
132131
.testTarget(

Sources/credential-process-test-helper/main.swift

Lines changed: 0 additions & 81 deletions
This file was deleted.

Tests/SotoCoreTests/Credential/CredentialProcessProviderTests.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,21 @@ import Foundation
3030

3131
@Suite("Credential Process Provider")
3232
struct CredentialProcessProviderTests {
33-
/// swift test always runs from the project root directory.
34-
let testHelperPath = ".build/debug/credential-process-test-helper"
33+
/// Path to the test helper shell script bundled as a test resource.
34+
let testHelperPath: String
3535
let logger = Logger(label: "test")
3636

37+
init() throws {
38+
guard let resourcePath = Bundle.module.path(forResource: "credential-process-test-helper", ofType: "sh") else {
39+
throw TestHelperError.resourceNotFound
40+
}
41+
testHelperPath = resourcePath
42+
}
43+
44+
enum TestHelperError: Error {
45+
case resourceNotFound
46+
}
47+
3748
func save(content: String, prefix: String) throws -> String {
3849
let filepath = "\(prefix)-\(UUID().uuidString)"
3950
try content.write(toFile: filepath, atomically: true, encoding: .utf8)
@@ -314,9 +325,8 @@ struct CredentialProcessProviderTests {
314325
func endToEndExpiringWithConfigFile() async throws {
315326
// The INI parser strips spaces from values, so we use a wrapper script
316327
// to pass arguments to the test helper.
328+
let scriptContent = "#!/bin/sh\nexec \"\(testHelperPath)\" --expiring\n"
317329
let cwd = FileManager.default.currentDirectoryPath
318-
let absoluteHelperPath = "\(cwd)/\(testHelperPath)"
319-
let scriptContent = "#!/bin/sh\nexec \"\(absoluteHelperPath)\" --expiring\n"
320330
let scriptPath = "\(cwd)/" + (try save(content: scriptContent, prefix: "expiring-script"))
321331
try FileManager.default.setAttributes(
322332
[.posixPermissions: 0o755],
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/bin/sh
2+
#===----------------------------------------------------------------------===#
3+
#
4+
# This source file is part of the Soto for AWS open source project
5+
#
6+
# Copyright (c) 2017-2026 the Soto project authors
7+
# Licensed under Apache License v2.0
8+
#
9+
# See LICENSE.txt for license information
10+
# See CONTRIBUTORS.txt for the list of Soto project authors
11+
#
12+
# SPDX-License-Identifier: Apache-2.0
13+
#
14+
#===----------------------------------------------------------------------===#
15+
16+
# Test helper script for CredentialProcessProvider tests.
17+
# Mimics the output of a credential_process command as defined by the AWS CLI spec.
18+
# Accepts flags to control output for different test scenarios.
19+
20+
# Check for flags
21+
INVALID_JSON=false
22+
INVALID_VERSION=false
23+
EXPIRING=false
24+
NO_SESSION_TOKEN=false
25+
EXIT_CODE=""
26+
27+
while [ $# -gt 0 ]; do
28+
case "$1" in
29+
--invalid-json)
30+
INVALID_JSON=true
31+
shift
32+
;;
33+
--invalid-version)
34+
INVALID_VERSION=true
35+
shift
36+
;;
37+
--expiring)
38+
EXPIRING=true
39+
shift
40+
;;
41+
--no-session-token)
42+
NO_SESSION_TOKEN=true
43+
shift
44+
;;
45+
--exit-code)
46+
EXIT_CODE="$2"
47+
shift 2
48+
;;
49+
*)
50+
shift
51+
;;
52+
esac
53+
done
54+
55+
# Handle --invalid-json: output garbage and exit
56+
if [ "$INVALID_JSON" = true ]; then
57+
echo "this is not json{{{"
58+
exit 0
59+
fi
60+
61+
# Handle --exit-code: exit with the specified code
62+
if [ -n "$EXIT_CODE" ]; then
63+
exit "$EXIT_CODE"
64+
fi
65+
66+
# Build the JSON output
67+
VERSION=1
68+
if [ "$INVALID_VERSION" = true ]; then
69+
VERSION=2
70+
fi
71+
72+
# Start building JSON fields
73+
FIELDS="\"Version\":$VERSION,\"AccessKeyId\":\"AKID-CREDENTIAL-PROCESS\",\"SecretAccessKey\":\"SECRET-CREDENTIAL-PROCESS\""
74+
75+
if [ "$NO_SESSION_TOKEN" = false ]; then
76+
FIELDS="$FIELDS,\"SessionToken\":\"TOKEN-CREDENTIAL-PROCESS\""
77+
fi
78+
79+
if [ "$EXPIRING" = true ]; then
80+
# Generate an ISO8601 date 1 hour in the future
81+
if date --version >/dev/null 2>&1; then
82+
# GNU date (Linux)
83+
EXPIRATION=$(date -u -d "+1 hour" "+%Y-%m-%dT%H:%M:%SZ")
84+
else
85+
# BSD date (macOS)
86+
EXPIRATION=$(date -u -v+1H "+%Y-%m-%dT%H:%M:%SZ")
87+
fi
88+
FIELDS="$FIELDS,\"Expiration\":\"$EXPIRATION\""
89+
fi
90+
91+
echo "{$FIELDS}"

0 commit comments

Comments
 (0)