<commit_before>/* global describe, it, afterEach */
'use strict';

const InstanceManager = require('../../InstanceManager.js');
const endpointToUrl = require('../../common.js').endpointToUrl;

const rp = require('request-promise');
const arangojs = require('arangojs');
const expect = require('chai').expect;
const sleep = (ms= 1000) => new Promise(resolve => setTimeout(resolve, ms));

// <copied from agency.js>
let agencyRequest = function(options) {
  options.followRedirects = options.followRedirects || false;
  return rp(options)
    .then(response => {
      return response;
    })
    .catch(err => {
      if (err.statusCode === 307) {
        options.url = err.response.headers["location"];
        return agencyRequest(options);
      } else if (err.statusCode === 503 && err.message === "No leader") {
        options.retries = (options.retries || 0) + 1;
        if (options.retries < 5) {
          return agencyRequest(options);
        }
        return Promise.reject(new Error("no leader after 5 retries"));
      }
      return Promise.reject(err);
    });
};

let waitForLeader = function(agents) {
  return rp({
    url: endpointToUrl(agents[0].endpoint) + "/_api/agency/config",
    json: true
  })
    .then(result => {
      if (result.leaderId === "") {
        return Promise.reject(new Error("no leader"));
      }
      return result.leaderId;
    })
    .catch(() => {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, 100);
      }).then(() => {
        return waitForLeader(agents);
      });
    });
};

let getLeadAgentInstance = function(agents) {
  return waitForLeader(agents).then(leaderId => {
    return agents.reduce((leaderInstance, agent) => {
      if (leaderInstance) {
        return leaderInstance;
      }

      return agencyRequest({
        url: agent.endpoint + "/_api/agency/config",
        json: true
      }).then(result => {
        if (result.configuration.id === leaderId) {
          return agent;
        }
      });
    });
  });
};
// </copied from agency.js>

/// return the list of endpoints, in a normal cluster this is the list of
/// coordinator endpoints.
async function requestEndpoints(url) {
  url = endpointToUrl(url);
  const body = await rp.get({ uri: `${url}/_api/cluster/endpoints`, json: true});
  if (body.error ) {
    throw new Error(body);
  }
  if (!body.endpoints || body.endpoints.length == 0) {
    throw new Error(`AsyncReplication: not all servers ready. Have ${body.endpoints.length} servers`);
  }
  return body.endpoints;
};

describe('Leader-Follower failover + agency outage', async function() {

  const instanceManager = new InstanceManager('setup');
  let agents = [];
  
  // start a resilient agency
  beforeEach(async function(){
    agents = await instanceManager.startAgency({agencySize:3});        
  });

  afterEach(function() {
    instanceManager.moveServerLogs(this.currentTest);
    return instanceManager.cleanup().catch(() => {});<commit_msg>Removing unused code<commit_after>/* global describe, it, afterEach */
'use strict';

const InstanceManager = require('../../InstanceManager.js');
const endpointToUrl = require('../../common.js').endpointToUrl;

const rp = require('request-promise');
const arangojs = require('arangojs');
const expect = require('chai').expect;

// <copied from agency.js>
let agencyRequest = function(options) {
  options.followRedirects = options.followRedirects || false;
  return rp(options)
    .then(response => {
      return response;
    })
    .catch(err => {
      if (err.statusCode === 307) {
        options.url = err.response.headers["location"];
        return agencyRequest(options);
      } else if (err.statusCode === 503 && err.message === "No leader") {
        options.retries = (options.retries || 0) + 1;
        if (options.retries < 5) {
          return agencyRequest(options);
        }
        return Promise.reject(new Error("no leader after 5 retries"));
      }
      return Promise.reject(err);
    });
};

let waitForLeader = function(agents) {
  return rp({
    url: endpointToUrl(agents[0].endpoint) + "/_api/agency/config",
    json: true
  })
    .then(result => {
      if (result.leaderId === "") {
        return Promise.reject(new Error("no leader"));
      }
      return result.leaderId;
    })
    .catch(() => {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, 100);
      }).then(() => {
        return waitForLeader(agents);
      });
    });
};

let getLeadAgentInstance = function(agents) {
  return waitForLeader(agents).then(leaderId => {
    return agents.reduce((leaderInstance, agent) => {
      if (leaderInstance) {
        return leaderInstance;
      }

      return agencyRequest({
        url: agent.endpoint + "/_api/agency/config",
        json: true
      }).then(result => {
        if (result.configuration.id === leaderId) {
          return agent;
        }
      });
    });
  });
};
// </copied from agency.js>

describe('Leader-Follower failover + agency outage', async function() {

  const instanceManager = new InstanceManager('setup');
  let agents = [];
  
  // start a resilient agency
  beforeEach(async function(){
    agents = await instanceManager.startAgency({agencySize:3});        
  });

  afterEach(function() {
    instanceManager.moveServerLogs(this.currentTest);
    return instanceManager.cleanup().catch(() => {});
{'fraction_non_alphanumeric': 0.15445948451696645, 'fraction_numerical': 0.006489894307435564, 'mean_word_length': 2.894584837545126, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1521049', 'n_tokens_mistral': 1622, 'n_tokens_neox': 1556, 'n_words': 362}