Skip to content

Commit 77caa0c

Browse files
committed
test: add comprehensive secrets handling test coverage
Add test cases for: - Detection of 'secrets.PATTERN' unresolved secrets - Detection of '[secret]' placeholder patterns - Proper handling of null and empty credentials - Fallback constructor behavior with secrets - Comprehensive error message validation - Integration testing with ChannelSqlExtension Ensures robust validation of secrets detection functionality and provides regression protection for the secrets handling feature. Signed-off-by: Edmund Miller <[email protected]>
1 parent accb952 commit 77caa0c

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

plugins/nf-sqldb/src/test/nextflow/sql/ChannelSqlExtensionTest.groovy

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,42 @@ class ChannelSqlExtensionTest extends Specification {
9595
rows.alpha == ['x1','y2','z3']
9696
}
9797

98+
def 'should provide helpful error message for unresolved secrets' () {
99+
given:
100+
def session = Mock(Session) {
101+
getConfig() >> [sql: [db: [athena: [
102+
url: 'jdbc:awsathena://AwsRegion=us-east-1;S3OutputLocation=s3://bucket;Workgroup=CompBio',
103+
user: 'secrets.ATHENA_USER',
104+
password: '[secret]'
105+
]]]]
106+
}
107+
def sqlExtension = new ChannelSqlExtension()
108+
109+
when:
110+
sqlExtension.init(session)
111+
112+
then:
113+
def e = thrown(IllegalArgumentException)
114+
e.message.contains("Unresolved secret detected")
115+
e.message.contains("secrets.ATHENA_USER")
116+
e.message.contains("workspace secrets are not properly configured")
117+
}
118+
119+
def 'should handle unknown database' () {
120+
given:
121+
def session = Mock(Session) {
122+
getConfig() >> [sql: [db: [default: [url: 'jdbc:h2:mem:'], postgres: [url: 'jdbc:postgresql:']]]]
123+
}
124+
def sqlExtension = new ChannelSqlExtension()
125+
sqlExtension.init(session)
126+
127+
when:
128+
sqlExtension.fromQuery([db: 'invalid'], 'select * from table')
129+
130+
then:
131+
def e = thrown(IllegalArgumentException)
132+
e.message.contains("Unknown db name: invalid")
133+
e.message.contains("Available databases:")
134+
}
135+
98136
}

plugins/nf-sqldb/src/test/nextflow/sql/config/SqlDataSourceTest.groovy

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,76 @@ class SqlDataSourceTest extends Specification {
132132
ds1.hashCode() == ds2.hashCode()
133133
ds1.hashCode() != ds3.hashCode()
134134
}
135+
136+
def 'should handle null credentials gracefully' () {
137+
when:
138+
def ds = new SqlDataSource([url: 'jdbc:h2:mem:', user: null, password: null])
139+
then:
140+
ds.user == SqlDataSource.DEFAULT_USER
141+
ds.password == null
142+
}
143+
144+
def 'should handle empty string credentials' () {
145+
when:
146+
def ds = new SqlDataSource([url: 'jdbc:h2:mem:', user: '', password: ''])
147+
then:
148+
ds.user == SqlDataSource.DEFAULT_USER
149+
ds.password == null
150+
}
151+
152+
def 'should detect unresolved secrets.* pattern' () {
153+
when:
154+
new SqlDataSource([user: 'secrets.ATHENA_USER'])
155+
then:
156+
def e = thrown(IllegalArgumentException)
157+
e.message.contains("Unresolved secret detected for user")
158+
e.message.contains("secrets.ATHENA_USER")
159+
e.message.contains("workspace secrets are not properly configured")
160+
}
161+
162+
def 'should detect unresolved [secret] pattern' () {
163+
when:
164+
new SqlDataSource([password: '[secret]'])
165+
then:
166+
def e = thrown(IllegalArgumentException)
167+
e.message.contains("Unresolved secret detected for password")
168+
e.message.contains("[secret]")
169+
e.message.contains("workspace secrets are not properly configured")
170+
}
171+
172+
def 'should allow valid secret-like strings that are not unresolved' () {
173+
when:
174+
def ds = new SqlDataSource([user: 'mysecret', password: 'secretpassword'])
175+
then:
176+
ds.user == 'mysecret'
177+
ds.password == 'secretpassword'
178+
}
179+
180+
def 'should handle secrets in fallback constructor' () {
181+
given:
182+
def fallback = new SqlDataSource([user: 'fallback_user', password: 'fallback_pass'])
183+
184+
when:
185+
new SqlDataSource([user: 'secrets.ATHENA_USER'], fallback)
186+
then:
187+
def e = thrown(IllegalArgumentException)
188+
e.message.contains("Unresolved secret detected for user")
189+
}
190+
191+
def 'should provide comprehensive error message for secrets' () {
192+
when:
193+
new SqlDataSource([user: 'secrets.MISSING_SECRET'])
194+
then:
195+
def e = thrown(IllegalArgumentException)
196+
with(e.message) {
197+
contains("Unresolved secret detected")
198+
contains("secrets.MISSING_SECRET")
199+
contains("workspace secrets are not properly configured")
200+
contains("secret is defined in your workspace")
201+
contains("secret name matches exactly")
202+
contains("proper permissions")
203+
contains("Nextflow version supports secrets")
204+
contains("https://www.nextflow.io/docs/latest/secrets.html")
205+
}
206+
}
135207
}

0 commit comments

Comments
 (0)