@Test
public void throughputPostWithAuthz() throws Throwable {

    setUpHost(true);
    URI factoryUri = UriUtils.buildFactoryUri(this.host, ExampleService.class);
    // assume system identity so we can create roles
    this.host.setSystemAuthorizationContext();
    List<String> userLinks = new ArrayList<>();
    for (int i = 0; i < this.authUserCount; i++) {
        userLinks.add(buildExampleUserLink(i));
    }
    // first test throughput sequentially, no contention among users
    for (String userLink : userLinks) {
        // assume authorized user identity
        this.host.assumeIdentity(userLink);
        this.host.log("(%d) (%s), Starting sequential factory POST, count:%d",
                0,
                OperationContext.getAuthorizationContext().getClaims().getSubject(),
                this.serviceCount);
        doThroughputPostWithNoQueryResults(false, factoryUri);
        this.host.deleteAllChildServices(factoryUri);
    }
    // now test service creation with contention across different authorized subjects
    TestContext ctx = this.host.testCreate(userLinks.size());
    Map<String, Runnable> postTasksPerSubject = new ConcurrentSkipListMap<>();
    Map<String, Long> durationPerSubject = new ConcurrentSkipListMap<>();
    for (String userLink : userLinks) {
        Runnable r = () -> {
            try {
                // assume authorized user identity
                this.host.assumeIdentity(userLink);
                this.host.log("(%d) (%s), Starting Factory POST, count:%d",
                        0,
                        OperationContext.getAuthorizationContext().getClaims().getSubject(),
                        this.serviceCount);
                long start = System.nanoTime();
                doThroughputPostWithNoQueryResults(false, factoryUri);
                long end = System.nanoTime();
                durationPerSubject.put(userLink, end - start);
                ctx.complete();
            } catch (Throwable e) {
                ctx.fail(e);
            }
        };
        postTasksPerSubject.put(userLink, r);
    }
    // Confirm fairness: Start one task before the two others, and see if the average throughput
    // for the last N tasks is similar. The initial task has a head start with no content, so its
    // expected that it has a higher throughput
    Runnable firstTask = postTasksPerSubject.remove(userLinks.remove(0));
    this.host.run(firstTask);
    // add a fixed delay per 1000 services, to allow the queue / index service to see lots of concurrent
    // requests for one subject, before others start in parallel
    Thread.sleep(10 * (this.serviceCount / 1000));
    for (Runnable r : postTasksPerSubject.values()) {
        ForkJoinPool.commonPool().execute(r);
    }
    this.host.testWait(ctx);
    // Until we confirm correctness, do not assert on durations. this will be enabled soon
    for (Entry<String, Long> e : durationPerSubject.entrySet()) {
        this.host.log("Subject: %s, duration(micros): %d", e.getKey(), e.getValue() / 1000);
    }
}