code: def test_tsdataset_rolling_feature_multiple(self):
      df = get_multi_id_ts_df()
      horizon = random.randint(2, 10)
      lookback = random.randint(2, 20)
      tsdata = TSDataset.from_pandas(
          df,
          dt_col="datetime",
          target_col="value",
          extra_feature_col=["extra feature"],
          id_col="id",
      )
      tsdata.gen_rolling_feature(
          settings="minimal", window_size=lookback
      )
      tsdata._check_basic_invariants()
      tsdata = TSDataset.from_pandas(
          df,
          dt_col="datetime",
          target_col="value",
          extra_feature_col=["extra feature"],
          id_col="id",
      )
      tsdata.gen_rolling_feature(
          settings="minimal", window_size=lookback, n_jobs=2
      )
      tsdata._check_basic_invariants()
  
      # roll train
      tsdata.roll(lookback=lookback, horizon=horizon)
      x, y = tsdata.to_numpy()
      feature_num = len(tsdata.feature_col) + len(tsdata.target_col)
      assert x.shape == (
          (50 - lookback - horizon + 1) * 2,
          lookback,
          feature_num,
      )
      assert y.shape == ((50 - lookback - horizon + 1) * 2, horizon, 1)
  
      tsdata.roll(lookback=lookback, horizon=horizon, id_sensitive=True)
      x, y = tsdata.to_numpy()
      assert x.shape == (
          (50 - lookback - horizon + 1),
          lookback,
          feature_num * 2,
      )
      assert y.shape == ((50 - lookback - horizon + 1), horizon, 2)
  
      tsdata._check_basic_invariants()
  
imports: import pytest
  import numpy
  import pandas
  import random
  import tempfile
  import os
  import shutil
  from test.zoo.pipeline.utils.test_utils import ZooTestCase
  from zoo.chronos.data import TSDataset
  from pandas.testing import assert_frame_equal
  from numpy.testing import assert_array_almost_equal
label_desc: Use image node_id 25 for calling the TestTSDataset obj's underlying member method code with example usage: obj.test_tsdataset_rolling_feature_multiple() without return types