package com.salesforce.dva.argus.service.tsdb;

import com.salesforce.dva.argus.AbstractTest;
import com.salesforce.dva.argus.service.TSDBService;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

public class AbstractTSDBServiceTest extends AbstractTest {
    static final int RUNS = 100;
    static final int THREADS = 20;

    @Test
    public void testCyclingIterator() {
        AbstractTSDBService service = new AbstractTSDBService(system.getConfiguration(), system.getServiceFactory().getMonitorService());
        String[][] endpointTrials = {
                {"1"},
                {"1", "2", "3", "4"}
        };

        for (int j = 0; j < endpointTrials.length; j++) {
            String[] endpoints = endpointTrials[j];
            Iterator iter = service.constructCyclingIterator(endpoints);
            List<Thread> threads = new ArrayList<>();
            System.out.println(String.format("Trying %d .next() calls with %d threads calling cycling iterator on endpoints %s", RUNS, THREADS, String.join(", ", endpoints)));
            for (int i = 0; i < THREADS; i++) {
                Thread thread = new Thread(new IterateTask(iter));
                threads.add(thread);
                thread.start();
            }
            for (Thread t : threads) {
                try {
                    t.join();
                } catch (InterruptedException ex) {
                    return;
                }
            }
        }
    }

    class IterateTask implements Runnable {
        Random random = new Random();
        Iterator iter;

        IterateTask(Iterator iterator) {
            this.iter = iterator;
        }
        @Override
        public void run() {
            try {
                for (int i = 0; i < RUNS; i++) {
                    iter.next();
                    Thread.sleep(3 + random.nextInt(5));
                }
            } catch (InterruptedException ex) {
                return;
            }
        }
    }
}

@@ -91,61 +91,8 @@
 st;%0A
-import com.salesforce.dva.argus.service.TSDBService;%0A
 impo
@@ -135,24 +135,50 @@
 .ArrayList;%0A
+import java.util.HashMap;%0A
 import java.
@@ -211,24 +211,46 @@
 .util.List;%0A
+import java.util.Map;%0A
 import java.
@@ -261,16 +261,113 @@
 .Random;
+%0Aimport java.util.concurrent.ConcurrentLinkedQueue;%0A%0Aimport static org.junit.Assert.assertEquals;
 %0A%0Apublic
@@ -774,16 +774,106 @@
 3%22, %224%22%7D
+,%0A                %7B%224%22, %226%22, %22133%22, %22200%22, %221133%22, %222244%22, %224466%22, %228989%22, %2219200%22, %22320%22%7D
 %0A       
@@ -1003,24 +1003,32 @@
     Iterator
+%3CString%3E
  iter = serv
@@ -1118,24 +1118,105 @@
 ayList%3C%3E();%0A
+            ConcurrentLinkedQueue%3CString%3E queue = new ConcurrentLinkedQueue%3C%3E();%0A
             
@@ -1490,16 +1490,23 @@
 ask(iter
+, queue
 ));%0A    
@@ -1779,32 +1779,648 @@
 %7D%0A            %7D%0A
+            Map%3CString, Integer%3E counts = new HashMap%3C%3E();%0A            String%5B%5D actuals = queue.toArray(new String%5B0%5D);%0A            for (String s: actuals) %7B%0A                Integer count = counts.get(s);%0A                if (count == null) %7B%0A                    counts.put(s, 1);%0A                %7D else %7B%0A                    counts.put(s, count + 1);%0A                %7D%0A            %7D%0A            /* The inserted items should each have been inserted ( #insertions / #element) times */%0A            for (int count: counts.values()) %7B%0A                assertEquals(RUNS * THREADS / endpoints.length, count);%0A            %7D%0A
         %7D%0A    %7D%0A
@@ -2518,21 +2518,74 @@
 Iterator
- iter
+%3CString%3E iter;%0A        ConcurrentLinkedQueue%3CString%3E queue
 ;%0A%0A     
@@ -2607,16 +2607,24 @@
 Iterator
+%3CString%3E
  iterato
@@ -2624,16 +2624,53 @@
 iterator
+, ConcurrentLinkedQueue%3CString%3E queue
 ) %7B%0A    
@@ -2699,16 +2699,48 @@
 erator;%0A
+            this.queue = queue;%0A
         
@@ -2874,16 +2874,26 @@
         
+queue.add(
 iter.nex
@@ -2895,16 +2895,17 @@
 r.next()
+)
 ;%0A      

add assert to tsdb cycling iterator test