public void createPipeline() {
    synchronized (pipelineCreateLock) {
      if (pipeline != null) {
        return;
      }
      log.info("Session '{}': Creating MediaPipeline-{}", room, description);
      try {
        pipeline = kurento.createMediaPipeline();
        pipelineLatch.countDown();
        log.debug("Session '{}': Created MediaPipeline-{}", room, description);
      } catch (Exception e) {
        log.error("Unable to create MediaPipeline-{} for Session '{}'", description, room, e);
        pipelineLatch.countDown();
      }
      if (getPipeline() == null) {
        throw new RuntimeException(
            "Unable to create MediaPipeline-" + description + " for session '" + room + "'");
      }

      pipeline.addErrorListener(
          new EventListener<ErrorEvent>() {
            @Override
            public void onEvent(ErrorEvent event) {
              String desc =
                  event.getType()
                      + ": "
                      + event.getDescription()
                      + "(errCode="
                      + event.getErrorCode()
                      + ")";
              log.warn(
                  "Session '{}': Pipeline error encountered for MediaPipeline-{}: {}",
                  room,
                  description,
                  desc);
            }
          });
    }
  }
  public void doTest(
      final MediaProfileSpecType mediaProfileSpecType,
      String expectedAudioCodec,
      final String extension)
      throws Exception {

    long testDurationMillis =
        PropertiesManager.getProperty(TEST_DURATION_PROPERTY, DEFAULT_TEST_DURATION);

    MediaPipeline mp = kurentoClient.createMediaPipeline();

    final CountDownLatch errorPipelinelatch = new CountDownLatch(1);

    mp.addErrorListener(
        new EventListener<ErrorEvent>() {

          @Override
          public void onEvent(ErrorEvent event) {
            msgError = "Description:" + event.getDescription() + "; Error code:" + event.getType();
            log.error(msgError);
            errorPipelinelatch.countDown();
          }
        });
    final WebRtcEndpoint webRtcSender = new WebRtcEndpoint.Builder(mp).build();

    // WebRTC sender negotiation
    getPage().subscribeLocalEvents("playing");
    getPage().initWebRtc(webRtcSender, WebRtcChannel.AUDIO_ONLY, WebRtcMode.SEND_ONLY);
    Assert.assertTrue("Not received media in sender webrtc", getPage().waitForEvent("playing"));

    // Recorder
    String recordingFile = getRecordUrl(extension);
    RecorderEndpoint recorder =
        new RecorderEndpoint.Builder(mp, recordingFile)
            .withMediaProfile(mediaProfileSpecType)
            .build();
    webRtcSender.connect(recorder);

    // Start recorder
    recorder.record();

    // Wait recording time
    Thread.sleep(testDurationMillis);

    // Stop recorder
    final CountDownLatch recorderLatch = new CountDownLatch(1);
    recorder.stopAndWait(
        new Continuation<Void>() {

          @Override
          public void onSuccess(Void result) throws Exception {
            recorderLatch.countDown();
          }

          @Override
          public void onError(Throwable cause) throws Exception {
            recorderLatch.countDown();
          }
        });

    // Release Media Pipeline
    Assert.assertTrue(
        "Not stop properly", recorderLatch.await(getPage().getTimeout(), TimeUnit.SECONDS));
    if (mp != null) {
      mp.release();
    }

    Assert.assertTrue(msgError, errorPipelinelatch.getCount() == 1);

    waitForFileExists(recordingFile);

    // Assessments
    AssertMedia.assertDuration(recordingFile, testDurationMillis, THRESHOLD_MS);
  }