class_docstr: we test data loading, model instantiation, forecasting consistency, in particular
  (1) load a testing data
  (2) transform data
  (3) instantiate the model and train
  (4) forecast, and the forecasting result agrees with the reference
code: def test_forecast(self):
      logger.info("Training model...")
      yhat, _ = self.model.train(self.train_data_norm)
  
      maxlags = self.model.model.config.maxlags
      dataset = RollingWindowDataset(
          self.test_data_norm,
          self.i,
          maxlags,
          self.max_forecast_steps,
          ts_index=True,
      )
      testing_instance, testing_label = next(iter(dataset))
      pred, _ = self.model.forecast(
          testing_label.time_stamps, testing_instance
      )
      self.assertEqual(len(pred), self.max_forecast_steps)
      smape = ForecastMetric.sMAPE.value(
          predict=pred, ground_truth=testing_label
      )
      logger.info(f"SMAPE = {smape}")
  
      # save and load
      savedir = join(rootdir, "tmp", "default", "forecast", "multi")
      self.model.save(dirname=savedir)
      loaded_model = DefaultForecaster.load(dirname=savedir)
      new_pred, _ = loaded_model.forecast(
          testing_label.time_stamps, testing_instance
      )
      new_smape = ForecastMetric.sMAPE.value(
          predict=new_pred, ground_truth=testing_label
      )
      self.assertAlmostEqual(smape, new_smape, places=4)
  
imports: import logging
  from os.path import abspath, dirname, join
  import sys
  import unittest
  import pandas
  from merlion.evaluate.forecast import ForecastMetric
  from merlion.models.defaults import DefaultForecaster, DefaultForecasterConfig
  from merlion.models.utils.rolling_window_dataset import RollingWindowDataset
  from merlion.transform.bound import LowerUpperClip
  from merlion.transform.normalize import MinMaxNormalize
  from merlion.transform.resample import TemporalResample
  from merlion.transform.sequence import TransformSequence
  from merlion.utils.time_series import TimeSeries, to_pd_datetime
  from ts_datasets.forecast import SeattleTrail
label_desc: Use image node_id 2 for calling the TestMultivariate obj's underlying member method code with example usage: obj.test_forecast() without return types