Skip to content

Commit

Permalink
Issue ReactiveX#30 Switch from jacoco to cobertura
Browse files Browse the repository at this point in the history
* test coverage added + jacoco excludes for benchmark classes

* Issue#15 circular fifo bufer optimization (ReactiveX#29)

* Issue#15 New optimized implementation of CircularFifoBuffer

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Updated documentation

* Move all test reporting to cobertura

* Time alignment for decorator test

* Additional tests and time alignment in spin loop
  • Loading branch information
storozhukBM authored and RobWin committed Dec 10, 2016
1 parent 73d7f75 commit 17b2197
Show file tree
Hide file tree
Showing 15 changed files with 573 additions and 109 deletions.
17 changes: 16 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
language: java
jdk:
- oraclejdk8

before_install:
- chmod +x gradlew

script:
- ./gradlew clean check allTests -x test

after_success:
- ./gradlew jacocoTestReport coveralls
- ./gradlew coberturaReport coveralls
- ./gradlew artifactoryPublish -PbintrayUsername="${BINTRAY_USER}" -PbintrayApiKey="${BINTRAY_KEY}"

before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/

notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/088d6d0266532abc60ee
on_success: change
on_failure: always
on_start: false

env:
global:
- secure: OpcatJV2E2u1Li7KXacvTq6O+c/2TZor7dHl2dlo/8jDgGOZFK4rsZlTVWWqcwP1lOr5s5yOsysrJZ+3ZzFFpJ4VsTKyNQZEwzl7si40l4I29NU9fiySFSGOCYqIclXHh2lJgLhXPZonzr5KQVcEcRSNQHLDO22BVf8uUX8WOqM/ZMZyjQkYzgBfhaHoXnlRxuGoWWEolyBdKHf4Cr480u3Ep//7eZwKK/JpkM8DTu63TnjDh/Tpao95LQNY8RaRn7NAom6A0IlGR9gDLPnCNlziUPxHAL2KbUL4ePWICg/wYTiTvnh1D0gNGGHSC/jRfYE8BzBrXEwD9JUGkT+yMhUaWj+5/hxQbBivtGGuTrzMoJchiaBGjK2r17Xao4nkQF2MjsSJIzh5uE/td88tSrAVM1W0Ee7TlbtArR0knbvzZt4YyZjv26m0dEHmDx9Q+g1cjWKsCiPXlSvc8jOOoNlaq0dk8/bRu6D7yaHsxGhAokxcf/qzTF8zPp3ODrY5M6f5l4LFN8j7STFXt4GeR/B6W6uPL0JrPQhq5I54SJPGIv7amYv/QnmTMxLg1rCRA/Rnngz9IPKNzFcpNVVPL95v/W76xlk6UvCvm1aFBQd7KQ2qgGMZgSlxv5FX77Tzf3C97VNVm6JbBfkJEpIWiR1CUJAjWR6u2avS3jPShTk=
Expand Down
24 changes: 17 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ buildscript {
}
}
dependencies {
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.0.1'
classpath 'net.saliman:gradle-cobertura-plugin:2.3.2'
classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.7.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
classpath 'me.champeau.gradle:jmh-gradle-plugin:0.3.1'
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0'
Expand All @@ -20,7 +21,7 @@ buildscript {
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'jacoco'
apply plugin: 'net.saliman.cobertura'
apply plugin: 'com.github.kt3k.coveralls'
apply plugin: 'com.jfrog.bintray'
apply plugin: "com.jfrog.artifactory"
Expand Down Expand Up @@ -81,6 +82,12 @@ dependencies {
jmh "org.openjdk.jmh:jmh-generator-annprocess:1.12"
}

test {
exclude 'io/github/robwin/circularbuffer/concurrent/'
}

task allTests(type: Test) {}

task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
Expand All @@ -96,11 +103,14 @@ artifacts {
archives javadocJar
}

jacocoTestReport {
reports {
xml.enabled = true // coveralls plugin depends on xml format report
html.enabled = true
}
cobertura {
coverageFormats = ['html', 'xml']
// afterEvaluate {
// classDirectories = files(classDirectories.files.collect {
// fileTree(dir: it,
// exclude: ['**/**Benchmark**'])
// })
// }
}

tasks.coveralls {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
*
* Copyright 2016 Robert Winkler and Bohdan Storozhuk
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
*/
package io.github.robwin.circularbuffer;


import javaslang.collection.List;
import javaslang.control.Option;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Group;
import org.openjdk.jmh.annotations.GroupThreads;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

import java.util.concurrent.TimeUnit;

/**
* @author bstorozhuk
*/
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
public class CircularBufferBenchmark {
public static final int FORK_COUNT = 2;
private static final int WARMUP_COUNT = 10;
private static final int ITERATION_COUNT = 10;
private static final int CAPACITY = 10;
private CircularFifoBuffer<Object> circularFifoBuffer;
private Object event;

@Setup
public void setUp() {
event = new Object();
circularFifoBuffer = new ConcurrentCircularFifoBuffer<>(CAPACITY);
}

@Benchmark
@Warmup(iterations = WARMUP_COUNT)
@Fork(value = FORK_COUNT)
@Measurement(iterations = ITERATION_COUNT)
@Group("circularBuffer")
@GroupThreads(1)
public void circularBufferAddEvent() {
circularFifoBuffer.add(event);
}

@Benchmark
@Warmup(iterations = WARMUP_COUNT)
@Fork(value = FORK_COUNT)
@Measurement(iterations = ITERATION_COUNT)
@Group("circularBuffer")
@GroupThreads(1)
public void circularBufferToList(Blackhole bh) {
List<Object> events = circularFifoBuffer.toList();
bh.consume(events);
}

@Benchmark
@Warmup(iterations = WARMUP_COUNT)
@Fork(value = FORK_COUNT)
@Measurement(iterations = ITERATION_COUNT)
@Group("circularBuffer")
@GroupThreads(1)
public void circularBufferSize(Blackhole bh) {
int size = circularFifoBuffer.size();
bh.consume(size);
}

@Benchmark
@Warmup(iterations = WARMUP_COUNT)
@Fork(value = FORK_COUNT)
@Measurement(iterations = ITERATION_COUNT)
@Group("circularBuffer")
@GroupThreads(1)
public void circularBufferTakeEvent(Blackhole bh) {
Option<Object> event = circularFifoBuffer.take();
bh.consume(event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class CircuitBreakerConfig {
private int ringBufferSizeInClosedState = DEFAULT_RING_BUFFER_SIZE_IN_CLOSED_STATE;
private Duration waitDurationInOpenState = Duration.ofSeconds(DEFAULT_WAIT_DURATION_IN_OPEN_STATE);
// The default exception predicate counts all exceptions as failures.
private Predicate<Throwable> recordFailurePredicate = (exception) -> true;
private Predicate<? super Throwable> recordFailurePredicate = (exception) -> true;

private CircuitBreakerConfig(){
}
Expand All @@ -58,7 +58,7 @@ public int getRingBufferSizeInClosedState() {
return ringBufferSizeInClosedState;
}

public Predicate<Throwable> getRecordFailurePredicate() {
public Predicate<? super Throwable> getRecordFailurePredicate() {
return recordFailurePredicate;
}

Expand Down Expand Up @@ -158,7 +158,7 @@ public Builder ringBufferSizeInClosedState(int ringBufferSizeInClosedState) {
* @param predicate the Predicate which evaluates if an exception should be recorded as a failure and thus trigger the CircuitBreaker
* @return the CircuitBreakerConfig.Builder
*/
public Builder recordFailure(Predicate<Throwable> predicate) {
public Builder recordFailure(Predicate<? super Throwable> predicate) {
config.recordFailurePredicate = predicate;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/**
* A CircuitBreakerEvent which informs that an error has been recorded
*/
public class CircuitBreakerOnErrorEvent extends AbstractCircuitBreakerEvent{
public class CircuitBreakerOnErrorEvent extends AbstractCircuitBreakerEvent {

private final Throwable throwable;
private final Duration elapsedDuration;
Expand All @@ -48,12 +48,12 @@ public Type getEventType() {
}

@Override
public String toString(){
public String toString() {
return String.format("%s: CircuitBreaker '%s' recorded an error: '%s'. Elapsed time: %s ms",
getCreationTime(),
getCircuitBreakerName(),
throwable.toString(),
elapsedDuration.toMillis());
getCreationTime(),
getCircuitBreakerName(),
getThrowable().toString(),
getElapsedDuration().toMillis());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/**
* A CircuitBreakerEvent which informs that an error has been ignored
*/
public class CircuitBreakerOnIgnoredErrorEvent extends AbstractCircuitBreakerEvent{
public class CircuitBreakerOnIgnoredErrorEvent extends AbstractCircuitBreakerEvent {

private final Throwable throwable;
private final Duration elapsedDuration;
Expand All @@ -48,11 +48,11 @@ public Type getEventType() {
}

@Override
public String toString(){
public String toString() {
return String.format("%s: CircuitBreaker '%s' has ignored an error: '%s'. Elapsed time: %s ms",
getCreationTime(),
getCircuitBreakerName(),
throwable.toString(),
elapsedDuration.toMillis());
getCreationTime(),
getCircuitBreakerName(),
getThrowable().toString(),
getElapsedDuration().toMillis());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/**
* A CircuitBreakerEvent which informs that a success has been recorded
*/
public class CircuitBreakerOnSuccessEvent extends AbstractCircuitBreakerEvent{
public class CircuitBreakerOnSuccessEvent extends AbstractCircuitBreakerEvent {

private final Duration elapsedDuration;

Expand All @@ -42,10 +42,10 @@ public Type getEventType() {
}

@Override
public String toString(){
public String toString() {
return String.format("%s: CircuitBreaker '%s' recorded a successful call. Elapsed time: %s ms",
getCreationTime(),
getCircuitBreakerName(),
elapsedDuration.toMillis());
getCreationTime(),
getCircuitBreakerName(),
getElapsedDuration().toMillis());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@ public long getNanosToWait() {
return estimatedState.nanosToWait;
}

/**
* @return estimated current cycle
*/
public long getCycle() {
State currentState = state.get();
State estimatedState = calculateNextState(-1, currentState);
return estimatedState.activeCycle;
}
}

/**
Expand Down
Loading

0 comments on commit 17b2197

Please sign in to comment.