38
38
import org .solid .common .vocab .EARL ;
39
39
import org .solid .common .vocab .PIM ;
40
40
import org .solid .common .vocab .RDF ;
41
+ import org .solid .testharness .api .TestHarnessApiException ;
41
42
import org .solid .testharness .http .ClientRegistry ;
42
43
import org .solid .testharness .http .HttpConstants ;
44
+ import org .solid .testharness .http .HttpUtils ;
43
45
import org .solid .testharness .http .SolidClientProvider ;
44
46
import org .solid .testharness .utils .DataRepository ;
45
47
import org .solid .testharness .utils .SolidContainerProvider ;
51
53
import java .io .IOException ;
52
54
import java .io .InputStream ;
53
55
import java .net .URI ;
56
+ import java .net .http .HttpResponse ;
54
57
import java .text .MessageFormat ;
55
58
import java .util .List ;
56
59
import java .util .Set ;
57
- import java .util .stream .Collectors ;
58
60
59
61
import static org .eclipse .rdf4j .model .util .Values .iri ;
60
62
@@ -154,6 +156,25 @@ public void prepareServer() {
154
156
testRunContainer = rootTestContainer .reserveContainer (rootTestContainer .generateId ()).instantiate ();
155
157
logger .debug ("Test run container content: {}" , testRunContainer .getContentAsTurtle ());
156
158
logger .debug ("Test run container access controls: {}" , testRunContainer .getAccessDataset ());
159
+
160
+ // check that we can change the access control of a resource so we know those tests can run
161
+ final var aclTestContainer = testRunContainer .reserveContainer ("acltest" );
162
+ try {
163
+ aclTestContainer .instantiate ();
164
+ final var builder = aclTestContainer .getAccessDatasetBuilder ();
165
+ final var bobReadAcl = builder
166
+ .setAgentAccess (
167
+ aclTestContainer .getUrl ().toString (),
168
+ config .getWebIds ().get (HttpConstants .BOB ),
169
+ List .of ("read" )
170
+ ).build ();
171
+ aclTestContainer .setAccessDataset (bobReadAcl ); // MOCK THIS PASS/FAIL
172
+ logger .info ("Confirmed we can create a container [{}] and set ACLs on it" , aclTestContainer .getUrl ());
173
+ } catch (TestHarnessException | TestHarnessApiException ex ) {
174
+ logger .warn ("Failed to create a container [{}] and set ACLs on it: {}" ,
175
+ aclTestContainer .getUrl (), ex .getMessage ());
176
+ throw ex ;
177
+ }
157
178
} catch (TestHarnessException | RuntimeException e ) {
158
179
throw new TestHarnessInitializationException ("Failed to prepare server" , e );
159
180
}
@@ -168,6 +189,7 @@ private void determineAccessControlImplementation(final SolidClientProvider owne
168
189
rootTestContainer .getUrl ());
169
190
}
170
191
accessControlMode = ownerClient .getAclType (aclUrl );
192
+ logger .info ("The Pod is using [{}] for access control" , accessControlMode );
171
193
}
172
194
173
195
URI findTestContainer () throws TestHarnessException {
@@ -198,37 +220,63 @@ URI findStorage() throws TestHarnessException {
198
220
final Model profile ;
199
221
try {
200
222
profile = publicClient .getContentAsModel (webId );
223
+ logger .info ("Loaded WebID Document for [{}]" , webId );
201
224
} catch (Exception e ) {
202
225
throw new TestHarnessInitializationException (MessageFormat .format (
203
- "Failed to read WebID Profile Document for [{0}]" , webId ), e );
226
+ "Failed to read WebID Document for [{0}]" , webId ), e );
204
227
}
205
- final List <URI > pods = profile .filter (iri (webId .toString ()), PIM .storage , null )
228
+
229
+ final var storages = profile .filter (iri (webId .toString ()), PIM .storage , null )
206
230
.objects ()
207
231
.stream ()
208
232
.filter (Value ::isIRI )
209
233
.map (Value ::stringValue )
210
234
.map (URI ::create )
235
+ .toList ();
236
+ if (storages .isEmpty ()) {
237
+ logger .warn ("No Pod references found in the WebID Document for [{}], looking for predicate [{}]" ,
238
+ webId , PIM .storage );
239
+ throw new TestHarnessInitializationException (MessageFormat .format (
240
+ "No Pod references found in the WebID Document for [{0}], looking for predicate [{1}]" ,
241
+ webId , PIM .storage ));
242
+ }
243
+ logger .info ("Found [{}] Pods, checking them..." , storages .size ());
244
+ final List <URI > pods = storages .stream ()
211
245
.filter (p -> isPodAccessible (p , ownerClient ))
212
- .collect (Collectors .toList ());
246
+ .toList ();
247
+
213
248
if (pods .isEmpty ()) {
214
249
throw new TestHarnessInitializationException (MessageFormat .format (
215
- "Pod provisioning is not yet implemented . " +
216
- "Please ensure the storage already exists for the test user: [{0}] " +
217
- "and that pim:storage is defined in the WebID Profile Document." , webId ));
250
+ "No accessible Pods were found for test user: [{0}] . " +
251
+ "Please check the logs to see why, then ensure that Pod storage exists " +
252
+ "and that pim:storage is defined in their WebID Document." , webId ));
218
253
// return provisionPod();
219
254
} else {
220
- logger .info ("Storage found via WebID Profile Document: {} " , pods .get (0 ));
255
+ logger .info ("Pod found: [{}] " , pods .get (0 ));
221
256
return pods .get (0 );
222
257
}
223
258
}
224
259
225
260
boolean isPodAccessible (final URI pod , final SolidClientProvider ownerClient ) {
261
+ logger .info ("Checking Pod [{}]" , pod );
226
262
try {
227
- return ownerClient .hasStorageType (pod );
263
+ // is it present?
264
+ final HttpResponse <Void > response = ownerClient .getClient ().head (pod );
265
+ if (!HttpUtils .isSuccessful (response .statusCode ())) {
266
+ logger .warn ("HEAD request to Pod [{}] returned [{}]" , pod , response .statusCode ());
267
+ return false ;
268
+ }
269
+ // is it a storage?
270
+ final var storageLink = HttpUtils .getHeaderLinkByType (response .headers (), PIM .Storage .toString ());
271
+ if (storageLink == null ) {
272
+ logger .warn ("Pod [{}] is not a valid storage as it missing a [{}] header" , pod , PIM .Storage );
273
+ return false ;
274
+ }
228
275
} catch (Exception e ) {
229
- logger .warn ("Failed to check pod accessibility: {} " , pod );
276
+ logger .warn ("Failed to check pod [{}] accessibility due to: [{}] " , pod , e . getMessage () );
230
277
return false ;
231
278
}
279
+ return true ;
232
280
}
233
281
234
282
/*
0 commit comments