@@ -0,0 +1,3483 @@
+package com.rackspacecloud.blueflood.service;%0A%0Aimport com.google.common.base.Ticker;%0Aimport com.rackspacecloud.blueflood.utils.TimeValue;%0Aimport com.rackspacecloud.blueflood.utils.Util;%0Aimport junit.framework.Assert;%0Aimport org.junit.Test;%0A%0Aimport java.util.Collection;%0Aimport java.util.Collections;%0Aimport java.util.concurrent.TimeUnit;%0Aimport java.util.concurrent.atomic.AtomicInteger;%0A%0Apublic class ShardStateWorkerTest %7B%0A    %0A    // Collection%3CInteger%3E allShards, ShardStateManager shardStateManager, TimeValue period%0A    @Test%0A    public void testStartStop() throws Exception %7B%0A        Collection%3CInteger%3E allShards = Collections.unmodifiableCollection(Util.parseShards(%22ALL%22));%0A        ShardStateManager manager = new ShardStateManager(allShards, new Ticker() %7B%0A            @Override%0A            public long read() %7B%0A                return System.currentTimeMillis();%0A            %7D%0A        %7D);%0A        %0A        final AtomicInteger counter = new AtomicInteger(0);%0A        final ShardStateWorker worker = new ShardStateWorker(allShards, manager, new TimeValue(100, TimeUnit.MILLISECONDS)) %7B%0A            @Override%0A            void performOperation() %7B%0A                counter.incrementAndGet();%0A            %7D%0A        %7D;%0A        %0A        final AtomicInteger errorCounter = new AtomicInteger(0);%0A        // we want starting/stopping to happen in other threads to verify that there are no synchronization usage errors.%0A        Runnable starter = new Runnable() %7B%0A            @Override%0A            public void run() %7B%0A                new Thread() %7B%0A                    public void run() %7B%0A                        try %7B%0A                            worker.setActive(true);%0A                        %7D catch (Exception ex) %7B%0A                            ex.printStackTrace();%0A                            errorCounter.incrementAndGet();%0A                        %7D%0A                    %7D%0A                %7D.start();%0A                try %7B Thread.sleep(100); %7D catch (Exception ex) %7B%7D;%0A            %7D%0A        %7D;%0A        Runnable stopper = new Runnable() %7B%0A            @Override%0A            public void run() %7B%0A                new Thread() %7B%0A                    public void run() %7B%0A                        try %7B%0A                            worker.setActive(false);%0A                        %7D catch (Exception ex) %7B%0A                            ex.printStackTrace();%0A                            errorCounter.incrementAndGet();%0A                        %7D%0A                    %7D%0A                %7D.start();%0A                try %7B Thread.sleep(100); %7D catch (Exception ex) %7B%7D;%0A            %7D%0A        %7D;%0A        %0A        // initially do nothing.%0A        stopper.run();%0A        %0A        Thread workerThread = new Thread(worker, %22worker thread%22);%0A        workerThread.start();%0A        %0A        // verify that it doesn't start out of the gate.%0A        Thread.sleep(1000);%0A        Assert.assertEquals(0, counter.get());%0A        %0A        starter.run();%0A        Thread.sleep(1000);%0A        stopper.run();%0A        %0A        // lower and upper bounds.%0A        Assert.assertTrue(Integer.toString(counter.get()), counter.get() %3E= 7);%0A        Assert.assertTrue(Integer.toString(counter.get()), counter.get() %3C= 10);%0A        %0A        starter.run();%0A        Thread.sleep(1000);%0A        stopper.run();%0A        %0A        // lower and upper bounds.%0A        Assert.assertTrue(Integer.toString(counter.get()), counter.get() %3E= 14);%0A        Assert.assertTrue(Integer.toString(counter.get()), counter.get() %3C= 20);%0A    %7D%0A    %0A    %0A%7D%0A

test to verify that the active/inactive semantics on `ShardStateWorker` work as expected.