@BeforeClass
  public void setUpClass() {

    ImmutableMap<Class<?>, Object> components = generateComponents();
    VersionCorrectionProvider vcProvider = new FixedInstantVersionCorrectionProvider(Instant.now());
    ServiceContext serviceContext =
        ServiceContext.of(components).with(VersionCorrectionProvider.class, vcProvider);
    ThreadLocalServiceContext.init(serviceContext);

    ComponentMap componentMap = ComponentMap.of(components);
    MarketDataSource marketDataSource =
        InterestRateMockSources.createMarketDataSource(MARKET_DATA_DATE, true);
    TestMarketDataFactory marketDataFactory = new TestMarketDataFactory(marketDataSource);
    ConfigLink<CurrencyMatrix> currencyMatrixLink =
        ConfigLink.resolved(componentMap.getComponent(CurrencyMatrix.class));
    List<MarketDataBuilder> builders =
        MarketDataBuilders.standard(componentMap, "dataSource", currencyMatrixLink);

    MarketDataEnvironmentFactory environmentFactory =
        new MarketDataEnvironmentFactory(marketDataFactory, builders);

    _functionRunner = new FunctionRunner(environmentFactory);
    _normalIRFutureOptionFn =
        FunctionModel.build(IRFutureOptionFn.class, normalConfig(), componentMap);
    _blackIRFutureOptionFn =
        FunctionModel.build(IRFutureOptionFn.class, blackConfig(), componentMap);
  }
  public void testPricingMethodCanBeCaptured() {

    // Test that we can capture results when we have trades/securities involved
    AvailableOutputs availableOutputs = createAvailableOutputs();
    AvailableImplementations availableImplementations = createAvailableImplementations();

    ViewFactory viewFactory =
        EngineTestUtils.createViewFactory(
            InterestRateMockSources.generateBaseComponents(),
            availableOutputs,
            availableImplementations);

    // Run view
    View view = viewFactory.createView(createIrsPricerConfig(), InterestRateSwapSecurity.class);

    VersionCorrection versionCorrection =
        ThreadLocalServiceContext.getInstance()
            .get(VersionCorrectionProvider.class)
            .getConfigVersionCorrection();
    CycleArguments cycleArguments =
        CycleArguments.builder(InterestRateMockSources.createMarketDataEnvironment())
            .versionCorrection(versionCorrection)
            .captureInputs(true)
            .build();

    Results run = view.run(cycleArguments, ImmutableList.of(createFixedVsLibor3mSwap()));
    Result<Object> pvResult = run.get(0, 0).getResult();
    if (!pvResult.isSuccess()) {
      fail(pvResult.toString());
    }
    Result<Object> pv01Result = run.get(0, 1).getResult();
    if (!pv01Result.isSuccess()) {
      fail(pv01Result.toString());
    }

    // Capture results
    ViewResultsSerializer serializer = new ViewResultsSerializer(run);

    // Write inputs to stream
    ByteArrayOutputStream inputsBaos = new ByteArrayOutputStream(1_000_000);
    serializer.serializeViewInputs(inputsBaos);

    ByteArrayOutputStream outputsBaos = new ByteArrayOutputStream(1_000_000);
    serializer.serializeViewOutputs(outputsBaos);

    ViewResultsDeserializer inputsDeserializer =
        new ViewResultsDeserializer(new ByteArrayInputStream(inputsBaos.toByteArray()));
    ViewInputs viewInputs = inputsDeserializer.deserialize(ViewInputs.class);
    assertThat(viewInputs, is(notNullValue()));

    ViewResultsDeserializer outputsDeserializer =
        new ViewResultsDeserializer(new ByteArrayInputStream(outputsBaos.toByteArray()));
    ViewOutputs viewOutputs = outputsDeserializer.deserialize(ViewOutputs.class);
    assertThat(viewOutputs, is(notNullValue()));

    CapturedResultsLoader loader =
        new CapturedResultsLoader(viewInputs, availableOutputs, availableImplementations);
    loader.addExtraConfigData("EmptyCurrencyMatrix", ConfigItem.of(new SimpleCurrencyMatrix()));
    Results run2 = loader.runViewFromInputs();
    System.out.println(run2);

    Result<Object> pvResult2 = run2.get(0, 0).getResult();
    if (!pvResult2.isSuccess()) {
      fail(pvResult2.toString());
    }
    Result<Object> pv01Result2 = run2.get(0, 1).getResult();
    if (!pv01Result2.isSuccess()) {
      fail(pv01Result2.toString());
    }

    // Check results are same as original ones
    assertThat(pvResult2.getValue(), is(pvResult.getValue()));
    assertThat(pv01Result2.getValue(), is(pv01Result.getValue()));

    // TODO - this should work but seems to be prevented by a Fudge issue
    // assertThat(view2Outputs, is(viewOutputs));
  }
  public void testCurveViewCanBeSavedAndRead() {

    AvailableOutputs availableOutputs = createAvailableOutputs();
    AvailableImplementations availableImplementations = createAvailableImplementations();

    ImmutableMap<Class<?>, Object> components = InterestRateMockSources.generateBaseComponents();

    ViewFactory viewFactory =
        EngineTestUtils.createViewFactory(components, availableOutputs, availableImplementations);

    View view = viewFactory.createView(createCurveBundleConfig("TEST"));

    VersionCorrection versionCorrection =
        ThreadLocalServiceContext.getInstance()
            .get(VersionCorrectionProvider.class)
            .getConfigVersionCorrection();
    CycleArguments cycleArguments =
        CycleArguments.builder(InterestRateMockSources.createMarketDataEnvironment())
            .versionCorrection(versionCorrection)
            .captureInputs(true)
            .build();

    Results run = view.run(cycleArguments);
    Result<Object> result = run.getNonPortfolioResults().get("TEST").getResult();
    if (!result.isSuccess()) {
      fail(result.getFailureMessage());
    }

    // Capture results
    ViewResultsSerializer serializer = new ViewResultsSerializer(run);

    // Write inputs to stream
    ByteArrayOutputStream inputsBaos = new ByteArrayOutputStream(1_000_000);
    serializer.serializeViewInputs(inputsBaos);

    ByteArrayOutputStream outputsBaos = new ByteArrayOutputStream(1_000_000);
    serializer.serializeViewOutputs(outputsBaos);

    ViewResultsDeserializer inputsDeserializer =
        new ViewResultsDeserializer(new ByteArrayInputStream(inputsBaos.toByteArray()));
    ViewInputs viewInputs2 = inputsDeserializer.deserialize(ViewInputs.class);
    assertThat(viewInputs2, is(notNullValue()));

    ViewResultsDeserializer outputsDeserializer =
        new ViewResultsDeserializer(new ByteArrayInputStream(outputsBaos.toByteArray()));
    ViewOutputs viewOutputs = outputsDeserializer.deserialize(ViewOutputs.class);
    assertThat(viewOutputs, is(notNullValue()));

    CapturedResultsLoader loader =
        new CapturedResultsLoader(viewInputs2, availableOutputs, availableImplementations);
    loader.addExtraConfigData("EmptyCurrencyMatrix", ConfigItem.of(new SimpleCurrencyMatrix()));
    Results run2 = loader.runViewFromInputs();

    Result<Object> result2 = run2.getNonPortfolioResults().get("TEST").getResult();
    if (!result2.isSuccess()) {
      fail(result2.toString());
    }

    // Check results are same as original ones
    ViewOutputs view2Outputs =
        ViewOutputs.builder()
            .nonPortfolioResults(run2.getNonPortfolioResults())
            .columnNames(run2.getColumnNames())
            .rows(run2.getRows())
            .build();

    assertThat(result2.getValue(), is(result.getValue()));
    assertThat(view2Outputs, is(viewOutputs));
  }