classdef mds_basic_tests < matlab.unittest.TestCase
  % a simple parametrized test for mds
  % see documentation of matlab.unittest suite for more details!
  
  
  properties
    Shot = 40000;
    Tree = 'tcv_shot';
    DefaultServer = 'tcvdata.epfl.ch'; % default server to try direct connection
    ServerPort = 8000; % port to look for in server
    Server; % final server for mdsconnect (determined later)
    verbosity = false;
    version_used; % static or shared depending on ClassSetup parameters
  end
  
  properties(TestParameter)
    config   = {'remote','local'}
    datatype = {'int8','uint8','int16','uint16','int32','uint32','single'}
    array    = {false,true}
  end
  
  methods(TestClassSetup)
    function temporary_working_folder(testCase)
      testCase.assertTrue(~verLessThan('matlab','8.2'),'This test suite is incompatible with MATLAB 8.1 or earlier');
      if ~verLessThan('matlab','9.0')
        testCase.applyFixture(matlab.unittest.fixtures.WorkingFolderFixture);
      else
        tempFixture = testCase.applyFixture(matlab.unittest.fixtures.TemporaryFolderFixture);
        testCase.addTeardown(@() cd(pwd));
        cd(tempFixture.Folder);
      end
      fprintf('Created folder %s as temporary working folder\n',pwd);
    end

    function check_server_options(testCase)
      % check default server
      
      % ping it
      if ispc
        ping_cmd = 'ping -n 1 %s';
      else
        ping_cmd = 'ping -c1 %s';
      end
      [status,stdout] = system(sprintf(ping_cmd,testCase.DefaultServer));
      if ~status % if ping ok
        % check if we can mdsconnect to it
        fprintf('Attempt to mdsconnect to %s\n',testCase.DefaultServer);
        success = mdsconnect(testCase.DefaultServer);
        if success % all ok
          testCase.Server = testCase.DefaultServer;
          return
        else
          fprintf('Could not mdsconnect to %s',testCase.DefaultServer);
        end
      else
        fprintf('Could not ping %s, returned: %s',testCase.DefaultServer,stdout);
      end
      
    end
  end
  
  methods(Test)
    
    function test_mds_connect(testCase)
      mdsconnect(testCase.Server);
      mdsdisconnect;
    end
    
    function test_datatypes(testCase,config,datatype,array)
      % check that both value and valueraw work as expected
      
      switch config
        case 'remote'
          mdsconnect(testCase.Server);
        case 'local'
          mdsconnect('local');
      end
      
      if array, dims = [4,3];
      else,     dims = [1,1];end
      
      s = rng(1);
      data = randi(12,dims,datatype);
      rng(s);
      
      value = mdsvalue('$',data);
      testCase.verifyClass(value,'double');
      
      valueraw = mdsvalueraw('$',data);
      testCase.verifyClass(valueraw,datatype);
      
      testCase.verifyEqual(value,double(valueraw));
    end
    
    function test_mds_open(testCase)
      
      mdsconnect(testCase.Server);
      [shoto,stat] = mdsopen(testCase.Shot);
      testCase.verifyTrue(mod(stat,2)==1,'mdsopen returned odd status');
      testCase.verifyEqual(shoto,testCase.Shot);
      mdsclose;
      
      [shoto,stat] = mdsopen(testCase.Tree,testCase.Shot);
      testCase.verifyTrue(mod(stat,2)==1,'mdsopen returned odd status');
      testCase.verifyEqual(shoto,testCase.Shot);
      mdsclose;
    end
    
    function test_mdsvalue(testCase)
      mdsconnect(testCase.Server);
      mdsopen(testCase.Tree,testCase.Shot);
      
      test_expression = '\magnetics::iplasma:trapeze';
      mdsvalue(test_expression);
      
      test_expression = 'dim_of(\magnetics::iplasma:trapeze)';
      mdsvalue(test_expression);
      
      mdsclose;
    end
    
    function test_mdsput(testCase)
      testCase.assumeFail('Ignore mdsput test for now pending better implementation by IT group')
      
      % Below, find a stub for this test
      % write to local tree on Cristian Galperti's machine (for testing)
      server = 'crpppc171.epfl.ch';
      tree = 'tt1';
      node = 'FORCEON';
      
      testCase.assumeTrue(0==system(sprintf('ping -c1 %s > /dev/null',server)),sprintf('Could not ping %s',server));
      
      try
        mdsconnect('crpppc171');
        mdsopen('tt1',-1);
      catch ME
        disp(getReport(ME));
        testCase.assumeFalse(true,...
          sprintf('Could not open tree ''%s'' on ''%s''',tree,server)); % filter test otherwise
      end
      
      val = mdsvalue(node);
      mdsput(node,val+1);
      testCase.assertTrue(mdsvalue(node) == val+1)
      mdsput(node,val); % reset value
      testCase.assertTrue(mdsvalue(node) == val)
    end

    function test_mdsip_connection_error(testCase)
      % Test exception is thrown upon mdsip connection failures

      mdsconnect(testCase.Server);

      errorid = 'mdsipmex:connection';

      % Break it on purpose (this might not work anymore once we upgrade MDSplus on the server)
      testCase.verifyError(@() mdsvalue('_a=*,_a[0]'),errorid);

      % Check that further calls throw errors as well
      testCase.verifyError(@() mdsvalue('1'),errorid);

    end
    
  end
end
