@Override
  public boolean processRow( final StepMetaInterface smi, final StepDataInterface sdi ) throws KettleException {
    this.meta = (TeraFastMeta) smi;

    Object[] row = getRow();
    if ( row == null ) {

      /* In case we have no data, we need to ensure that the printstream was ever initialized. It will if there is
      *  data. So we check for a null printstream, then we close the dataFile and execute only if it existed.
      */
      if ( this.dataFilePrintStream != null ) {
        this.dataFilePrintStream.close();
        IOUtils.closeQuietly( this.dataFile );
        this.execute();
      }

      setOutputDone();

      try {
        logBasic( BaseMessages.getString( PKG, "TeraFast.Log.WatingForFastload" ) );
        if ( this.process != null ) {
          final int exitVal = this.process.waitFor();
          if ( exitVal != 0 ) {
            setErrors( DEFAULT_ERROR_CODE );
          }
          logBasic( BaseMessages.getString( PKG, "TeraFast.Log.ExitValueFastloadPath", "" + exitVal ) );
        }
      } catch ( Exception e ) {
        logError( BaseMessages.getString( PKG, "TeraFast.Log.ErrorInStep" ), e );
        this.setDefaultError();
        stopAll();
      }

      return false;
    }

    if ( this.first ) {
      this.first = false;
      try {
        final File tempDataFile = new File( resolveFileName( this.meta.getDataFile().getValue() ) );
        this.dataFile = FileUtils.openOutputStream( tempDataFile );
        this.dataFilePrintStream = new PrintStream( dataFile );
      } catch ( IOException e ) {
        throw new KettleException( "Cannot open data file [path=" + this.dataFile + "]", e );
      }

      // determine column sort order according to field mapping
      // thus the columns in the generated datafile are always in the same order and have the same size as in the
      // targetTable
      this.tableRowMeta = this.meta.getRequiredFields( this.getTransMeta() );
      RowMetaInterface streamRowMeta = this.getTransMeta().getPrevStepFields( this.getStepMeta() );
      this.columnSortOrder = new ArrayList<>( this.tableRowMeta.size() );
      for ( int i = 0; i < this.tableRowMeta.size(); i++ ) {
        ValueMetaInterface column = this.tableRowMeta.getValueMeta( i );
        int tableIndex = this.meta.getTableFieldList().getValue().indexOf( column.getName() );
        if ( tableIndex >= 0 ) {
          String streamField = this.meta.getStreamFieldList().getValue().get( tableIndex );
          this.columnSortOrder.add( streamRowMeta.indexOfValue( streamField ) );
        }
      }
    }

    writeToDataFile( getInputRowMeta(), row );
    return true;
  }
@Test
  public void testNullDataFilePrintStream() throws KettleException {
    TeraFast teraFastDataFilePrintStreamIsNull = mock( TeraFast.class );
    doReturn( null ).when( teraFastDataFilePrintStreamIsNull ).getRow();
    TeraFastMeta meta = mock( TeraFastMeta.class );
    GenericStepData data = mock( GenericStepData.class );
    assertFalse( teraFastDataFilePrintStreamIsNull.processRow( meta, data ) );
  }