Home | History | Annotate | Download | only in runner
      1 /*
      2  * Copyright (C) 2013 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.caliper.runner;
     18 
     19 import static com.google.common.base.Preconditions.checkState;
     20 
     21 import com.google.caliper.bridge.LogMessage;
     22 import com.google.caliper.bridge.OpenedSocket;
     23 import com.google.caliper.model.BenchmarkSpec;
     24 import com.google.caliper.model.Host;
     25 import com.google.caliper.model.Run;
     26 import com.google.caliper.model.Scenario;
     27 import com.google.caliper.model.Trial;
     28 import com.google.caliper.runner.Instrument.MeasurementCollectingVisitor;
     29 import com.google.caliper.util.Parser;
     30 import com.google.common.util.concurrent.ListenableFuture;
     31 import dagger.Module;
     32 import dagger.Provides;
     33 
     34 import java.util.UUID;
     35 
     36 /**
     37  * Configuration for a {@link TrialRunLoop}.
     38  */
     39 @Module
     40 final class TrialModule {
     41 
     42   private final UUID trialId;
     43   private final int trialNumber;
     44   private final Experiment experiment;
     45 
     46   TrialModule(UUID trialId, int trialNumber, Experiment experiment) {
     47     this.trialId = trialId;
     48     this.trialNumber = trialNumber;
     49     this.experiment = experiment;
     50   }
     51 
     52   @TrialScoped
     53   @Provides
     54   @TrialId
     55   UUID provideTrialId() {
     56     return trialId;
     57   }
     58 
     59   @TrialScoped
     60   @Provides
     61   @TrialNumber
     62   int provideTrialNumber() {
     63     return trialNumber;
     64   }
     65 
     66   @TrialScoped
     67   @Provides
     68   Experiment provideExperiment() {
     69     return experiment;
     70   }
     71 
     72   @TrialScoped
     73   @Provides
     74   static BenchmarkSpec provideBenchmarkSpec(Experiment experiment) {
     75     return new BenchmarkSpec.Builder()
     76         .className(experiment.instrumentation().benchmarkMethod().getDeclaringClass().getName())
     77         .methodName(experiment.instrumentation().benchmarkMethod().getName())
     78         .addAllParameters(experiment.userParameters())
     79         .build();
     80   }
     81 
     82   @Provides
     83   @TrialScoped
     84   static ListenableFuture<OpenedSocket> provideTrialSocket(
     85       @TrialId UUID trialId,
     86       ServerSocketService serverSocketService) {
     87     return serverSocketService.getConnection(trialId);
     88   }
     89 
     90   @Provides
     91   static MeasurementCollectingVisitor provideMeasurementCollectingVisitor(Experiment experiment) {
     92     return experiment.instrumentation().getMeasurementCollectingVisitor();
     93   }
     94 
     95   @Provides
     96   @TrialScoped
     97   static TrialSchedulingPolicy provideTrialSchedulingPolicy(Experiment experiment) {
     98     return experiment.instrumentation().instrument().schedulingPolicy();
     99   }
    100 
    101   @Provides
    102   @TrialScoped
    103   static StreamService provideStreamService(
    104       WorkerProcess worker,
    105       Parser<LogMessage> logMessageParser,
    106       TrialOutputLogger trialOutput) {
    107     return new StreamService(worker, logMessageParser, trialOutput);
    108   }
    109 
    110   // TODO(user): make this a singleton in a higher level module.
    111   @Provides
    112   @TrialScoped
    113   static ShutdownHookRegistrar provideShutdownHook() {
    114     return new RuntimeShutdownHookRegistrar();
    115   }
    116 
    117   @Provides static TrialResultFactory provideTrialFactory(
    118       @TrialId final UUID trialId,
    119       final Run run,
    120       final Host host,
    121       final Experiment experiment,
    122       final BenchmarkSpec benchmarkSpec) {
    123     return new TrialResultFactory() {
    124       @Override public TrialResult newTrialResult(
    125           VmDataCollectingVisitor dataCollectingVisitor,
    126           MeasurementCollectingVisitor measurementCollectingVisitor) {
    127         checkState(measurementCollectingVisitor.isDoneCollecting());
    128         // TODO(lukes): should the trial messages be part of the Trial datastructure?  It seems like
    129         // the web UI could make use of them.
    130         return new TrialResult(
    131             new Trial.Builder(trialId)
    132                 .run(run)
    133                 .instrumentSpec(experiment.instrumentation().instrument().getSpec())
    134                 .scenario(new Scenario.Builder()
    135                     .host(host)
    136                     .vmSpec(dataCollectingVisitor.vmSpec())
    137                     .benchmarkSpec(benchmarkSpec))
    138                 .addAllMeasurements(measurementCollectingVisitor.getMeasurements())
    139                 .build(),
    140             experiment,
    141             measurementCollectingVisitor.getMessages());
    142       }
    143     };
    144   }
    145 }
    146