ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:24.87 GB of 70.42 GB (35.32%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ http/ root/ hls/ tests/ unit/ controller/ - drwxr-xr-x

Directory:
Viewing file:     stream-controller.js (12.18 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
import Hls from '../../../src/hls';
import Event from '../../../src/events';
import { FragmentTracker, FragmentState } from '../../../src/controller/fragment-tracker';
import StreamController from '../../../src/controller/stream-controller';
import { State } from '../../../src/controller/base-stream-controller';
import { mockFragments } from '../../mocks/data';
import Fragment from '../../../src/loader/fragment';
import M3U8Parser from '../../../src/loader/m3u8-parser';

import sinon from 'sinon';

describe('StreamController', function () {
  let hls;
  let fragmentTracker;
  let streamController;
  beforeEach(function () {
    hls = new Hls({});
    fragmentTracker = new FragmentTracker(hls);
    streamController = new StreamController(hls, fragmentTracker);
    streamController.startFragRequested = true;
  });

  /**
   * Assert: streamController should be started
   * @param {StreamController} streamController
   */
  const assertStreamControllerStarted = (streamController) => {
    expect(streamController.hasInterval()).to.be.true;
    expect(streamController.state).to.equal(State.IDLE, 'StreamController\'s state should not be STOPPED');
  };

  /**
   * Assert: streamController should be stopped
   * @param {StreamController} streamController
   */
  const assertStreamControllerStopped = (streamController) => {
    expect(streamController.hasInterval()).to.be.false;
    expect(streamController.state).to.equal(State.STOPPED, 'StreamController\'s state should be STOPPED');
  };

  describe('StreamController', function () {
    it('should be STOPPED when it is initialized', function () {
      assertStreamControllerStopped(streamController);
    });

    it('should trigger STREAM_STATE_TRANSITION when state is updated', function () {
      const spy = sinon.spy();
      hls.on(Event.STREAM_STATE_TRANSITION, spy);
      streamController.state = State.ENDED;
      expect(spy.args[0][1]).to.deep.equal({ previousState: State.STOPPED, nextState: State.ENDED });
    });

    it('should not trigger STREAM_STATE_TRANSITION when state is not updated', function () {
      const spy = sinon.spy();
      hls.on(Event.STREAM_STATE_TRANSITION, spy);
      // no update
      streamController.state = State.STOPPED;
      expect(spy.called).to.be.false;
    });

    it('should not start when controller does not have level data', function () {
      streamController.startLoad(1);
      assertStreamControllerStopped(streamController);
    });

    it('should start without levels data', function () {
      const manifest = `#EXTM3U
  #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=836280,RESOLUTION=848x360,NAME="480"
  http://proxy-62.dailymotion.com/sec(3ae40f708f79ca9471f52b86da76a3a8)/video/107/282/158282701_mp4_h264_aac_hq.m3u8#cell=core`;
      const result = M3U8Parser.parseMasterPlaylist(manifest, 'http://www.dailymotion.com');
      // load levels data
      streamController.onManifestParsed(result);
      streamController.startLoad(1);
      assertStreamControllerStarted(streamController);
      streamController.stopLoad();
      assertStreamControllerStopped(streamController);
    });
  });

  describe('SN Searching', function () {
    let fragPrevious = {
      programDateTime: 1505502671523,
      endProgramDateTime: 1505502676523,
      duration: 5.000,
      level: 1,
      start: 10.000,
      sn: 2, // Fragment with PDT 1505502671523 in level 1 does not have the same sn as in level 2 where cc is 1
      cc: 0
    };

    let fragLen = mockFragments.length;
    let levelDetails = {
      startSN: mockFragments[0].sn,
      endSN: mockFragments[mockFragments.length - 1].sn
    };
    let bufferEnd = fragPrevious.start + fragPrevious.duration;
    let end = mockFragments[mockFragments.length - 1].start + mockFragments[mockFragments.length - 1].duration;

    before(function () {
      levelDetails.hasProgramDateTime = false;
    });

    it('PTS search choosing wrong fragment (3 instead of 2) after level loaded', function () {
      let foundFragment = streamController._findFragment(0, fragPrevious, fragLen, mockFragments, bufferEnd, end, levelDetails);
      let resultSN = foundFragment ? foundFragment.sn : -1;
      expect(foundFragment).to.equal(mockFragments[3], 'Expected sn 3, found sn segment ' + resultSN);
    });

    // TODO: This test fails if using a real instance of Hls
    it('PTS search choosing the right segment if fragPrevious is not available', function () {
      let foundFragment = streamController._findFragment(0, null, fragLen, mockFragments, bufferEnd, end, levelDetails);
      let resultSN = foundFragment ? foundFragment.sn : -1;
      expect(foundFragment).to.equal(mockFragments[3], 'Expected sn 3, found sn segment ' + resultSN);
    });

    it('returns the last fragment if the stream is fully buffered', function () {
      const actual = streamController._findFragment(0, null, mockFragments.length, mockFragments, end, end, levelDetails);
      expect(actual).to.equal(mockFragments[mockFragments.length - 1]);
    });

    describe('PDT Searching during a live stream', function () {
      before(function () {
        levelDetails.hasProgramDateTime = true;
      });

      it('PDT search choosing fragment after level loaded', function () {
        levelDetails.PTSKnown = false;
        levelDetails.live = true;

        let foundFragment = streamController._ensureFragmentAtLivePoint(levelDetails, bufferEnd, 0, end, fragPrevious, mockFragments, mockFragments.length);
        let resultSN = foundFragment ? foundFragment.sn : -1;
        expect(foundFragment).to.equal(mockFragments[2], 'Expected sn 2, found sn segment ' + resultSN);
      });

      it('PDT search hitting empty discontinuity', function () {
        let discontinuityPDTHit = 6.00;

        let foundFragment = streamController._ensureFragmentAtLivePoint(levelDetails, discontinuityPDTHit, 0, end, fragPrevious, mockFragments, mockFragments.length);
        let resultSN = foundFragment ? foundFragment.sn : -1;
        expect(foundFragment).to.equal(mockFragments[2], 'Expected sn 2, found sn segment ' + resultSN);
      });
    });
  });

  describe('fragment loading', function () {
    function fragStateStub (state) {
      return sinon.stub(fragmentTracker, 'getState').callsFake(() => state);
    }

    let triggerSpy;
    let frag;
    beforeEach(function () {
      triggerSpy = sinon.spy(hls, 'trigger');
      frag = new Fragment();
    });

    function assertLoadingState (frag) {
      expect(triggerSpy).to.have.been.calledWith(Event.FRAG_LOADING, { frag });
      expect(streamController.state).to.equal(State.FRAG_LOADING);
    }

    function assertNotLoadingState () {
      expect(triggerSpy).to.not.have.been.called;
      expect(hls.state).to.not.equal(State.FRAG_LOADING);
    }

    it('should load a complete fragment which has not been previously appended', function () {
      fragStateStub(FragmentState.NOT_LOADED);
      streamController._loadFragment(frag, {}, 0, 0);
      assertLoadingState(frag);
    });

    it('should load a partial fragment', function () {
      fragStateStub(FragmentState.PARTIAL);
      streamController._loadFragment(frag, {}, 0, 0);
      assertLoadingState(frag);
    });

    it('should load a frag which has backtracked', function () {
      fragStateStub(FragmentState.OK);
      frag.backtracked = true;
      streamController._loadFragment(frag, {}, 0, 0);
      assertLoadingState(frag);
    });

    it('should not load a fragment which has completely & successfully loaded', function () {
      fragStateStub(FragmentState.OK);
      streamController._loadFragment(frag, {}, 0, 0);
      assertNotLoadingState();
    });

    it('should not load a fragment while it is appending', function () {
      fragStateStub(FragmentState.APPENDING);
      streamController._loadFragment(frag, {}, 0, 0);
      assertNotLoadingState();
    });
  });

  describe('checkBuffer', function () {
    const sandbox = sinon.createSandbox();
    let bufStart = 5;

    beforeEach(function () {
      streamController.gapController = {
        poll: function () {}
      };
      streamController.media = {
        buffered: {
          start () {
            return bufStart;
          },
          length: 1
        }
      };
    });
    afterEach(function () {
      sandbox.restore();
    });

    it('should not throw when media is undefined', function () {
      streamController.media = null;
      streamController._checkBuffer();
    });

    it('should seek to start pos when metadata has not yet been loaded', function () {
      const seekStub = sandbox.stub(streamController, '_seekToStartPos');
      streamController.loadedmetadata = false;
      streamController._checkBuffer();
      expect(seekStub).to.have.been.calledOnce;
      expect(streamController.loadedmetadata).to.be.true;
    });

    it('should not seek to start pos when metadata has been loaded', function () {
      const seekStub = sandbox.stub(streamController, '_seekToStartPos');
      streamController.loadedmetadata = true;
      streamController._checkBuffer();
      expect(seekStub).to.have.not.been.called;
      expect(streamController.loadedmetadata).to.be.true;
    });

    it('should not seek to start pos when nothing has been buffered', function () {
      const seekStub = sandbox.stub(streamController, '_seekToStartPos');
      streamController.media.buffered.length = 0;
      streamController._checkBuffer();
      expect(seekStub).to.have.not.been.called;
      expect(streamController.loadedmetadata).to.not.exist;
    });

    it('should complete the immediate switch if signalled', function () {
      const levelSwitchStub = sandbox.stub(streamController, 'immediateLevelSwitchEnd');
      streamController.loadedmetadata = true;
      streamController.immediateSwitch = true;
      streamController._checkBuffer();
      expect(levelSwitchStub).to.have.been.calledOnce;
    });

    describe('_seekToStartPos', function () {
      it('should seek to startPosition when startPosition is not buffered & the media is not seeking', function () {
        streamController.startPosition = 5;
        streamController._seekToStartPos();
        expect(streamController.media.currentTime).to.equal(5);
      });

      it('should not seek to startPosition when it is buffered', function () {
        streamController.startPosition = 5;
        streamController.media.currentTime = 5;
        streamController._seekToStartPos();
        expect(streamController.media.currentTime).to.equal(5);
      });
    });

    describe('startLoad', function () {
      beforeEach(function () {
        streamController.levels = [];
        streamController.media = null;
      });
      it('should not start when controller does not have level data', function () {
        streamController.levels = null;
        streamController.startLoad();
        assertStreamControllerStopped(streamController);
      });

      it('should start when controller has level data', function () {
        streamController.startLoad(5);
        assertStreamControllerStarted(streamController);
        expect(streamController.nextLoadPosition).to.equal(5);
        expect(streamController.startPosition).to.equal(5);
        expect(streamController.lastCurrentTime).to.equal(5);
      });

      it('should set startPosition to lastCurrentTime if unset', function () {
        streamController.lastCurrentTime = 5;
        streamController.startLoad(-1);
        assertStreamControllerStarted(streamController);
        expect(streamController.nextLoadPosition).to.equal(5);
        expect(streamController.startPosition).to.equal(5);
        expect(streamController.lastCurrentTime).to.equal(5);
      });

      it('sets up for a bandwidth test if starting at auto', function () {
        streamController.startFragRequested = false;
        hls.startLevel = -1;

        streamController.startLoad();
        expect(streamController.level).to.equal(0);
        expect(streamController.bitrateTest).to.be.true;
      });

      it('should not signal a bandwidth test if config.testBandwidth is false', function () {
        streamController.startFragRequested = false;
        hls.startLevel = -1;
        hls.nextAutoLevel = 3;
        hls.config.testBandwidth = false;

        streamController.startLoad();
        expect(streamController.level).to.equal(hls.nextAutoLevel);
        expect(streamController.bitrateTest).to.be.false;
      });
    });
  });
});
Command:
Quick Commands:
Upload:
[Read-Only] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [Read-Only]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.2075 seconds