mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-20 21:04:28 -04:00
Renamed gui module to core
This commit is contained in:
parent
3a90fcd022
commit
dbf35b2423
688 changed files with 4 additions and 4 deletions
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.app;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.mock.env.MockPropertySource;
|
||||
|
||||
import static io.bitsquare.app.BitsquareEnvironment.*;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.core.env.PropertySource.named;
|
||||
import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
|
||||
import static org.springframework.core.env.StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME;
|
||||
|
||||
public class BitsquareEnvironmentTests {
|
||||
|
||||
@Test
|
||||
public void testPropertySourcePrecedence() {
|
||||
PropertySource commandlineProps = new MockPropertySource(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME)
|
||||
.withProperty("key.x", "x.commandline");
|
||||
|
||||
PropertySource filesystemProps = new MockPropertySource(BITSQUARE_APP_DIR_PROPERTY_SOURCE_NAME)
|
||||
.withProperty("key.x", "x.env")
|
||||
.withProperty("key.y", "y.env");
|
||||
|
||||
ConfigurableEnvironment env = new BitsquareEnvironment(commandlineProps) {
|
||||
@Override
|
||||
PropertySource<?> appDirProperties() {
|
||||
return filesystemProps;
|
||||
}
|
||||
};
|
||||
MutablePropertySources propertySources = env.getPropertySources();
|
||||
|
||||
assertThat(propertySources.precedenceOf(named(BITSQUARE_COMMANDLINE_PROPERTY_SOURCE_NAME)), equalTo(0));
|
||||
assertThat(propertySources.precedenceOf(named(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME)), equalTo(1));
|
||||
assertThat(propertySources.precedenceOf(named(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)), equalTo(2));
|
||||
assertThat(propertySources.precedenceOf(named(BITSQUARE_APP_DIR_PROPERTY_SOURCE_NAME)), equalTo(3));
|
||||
assertThat(propertySources.precedenceOf(named(BITSQUARE_HOME_DIR_PROPERTY_SOURCE_NAME)), equalTo(4));
|
||||
assertThat(propertySources.precedenceOf(named(BITSQUARE_CLASSPATH_PROPERTY_SOURCE_NAME)), equalTo(5));
|
||||
assertThat(propertySources.precedenceOf(named(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME)), equalTo(6));
|
||||
assertThat(propertySources.size(), equalTo(7));
|
||||
|
||||
assertThat(env.getProperty("key.x"), equalTo("x.commandline")); // commandline value wins due to precedence
|
||||
assertThat(env.getProperty("key.y"), equalTo("y.env")); // env value wins because it's the only one available
|
||||
}
|
||||
}
|
48
core/src/test/java/io/bitsquare/btc/RestrictionsTest.java
Normal file
48
core/src/test/java/io/bitsquare/btc/RestrictionsTest.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class RestrictionsTest {
|
||||
@Test
|
||||
public void testIsMinSpendableAmount() {
|
||||
Coin amount = null;
|
||||
assertFalse("tx unfunded, pending", Restrictions.isMinSpendableAmount(amount));
|
||||
|
||||
amount = Coin.ZERO;
|
||||
assertFalse("tx unfunded, pending", Restrictions.isMinSpendableAmount(amount));
|
||||
|
||||
amount = FeePolicy.TX_FEE;
|
||||
assertFalse("tx unfunded, pending", Restrictions.isMinSpendableAmount(amount));
|
||||
|
||||
amount = Transaction.MIN_NONDUST_OUTPUT;
|
||||
assertFalse("tx unfunded, pending", Restrictions.isMinSpendableAmount(amount));
|
||||
|
||||
amount = FeePolicy.TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT);
|
||||
assertFalse("tx unfunded, pending", Restrictions.isMinSpendableAmount(amount));
|
||||
|
||||
amount = FeePolicy.TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(Coin.valueOf(1));
|
||||
assertTrue("tx unfunded, pending", Restrictions.isMinSpendableAmount(amount));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.main.trade.createoffer;
|
||||
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.validation.BtcValidator;
|
||||
import io.bitsquare.gui.util.validation.FiatValidator;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class CreateOfferViewModelTest {
|
||||
|
||||
private CreateOfferDataModel model;
|
||||
private CreateOfferViewModel presenter;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.setLocale(Locale.US);
|
||||
formatter.setFiatCurrencyCode("USD");
|
||||
model = new CreateOfferDataModel(null, null, null, null, null, null, formatter);
|
||||
|
||||
presenter = new CreateOfferViewModel(model, new FiatValidator(null), new BtcValidator(), formatter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmount() {
|
||||
presenter.amount.set("0.0001");
|
||||
model.calculateAmount();
|
||||
assertEquals("0.0001", presenter.amount.get());
|
||||
assertEquals(Coin.parseCoin("0.0001"), model.amountAsCoin.get());
|
||||
presenter.amount.set("0.0009");
|
||||
model.calculateAmount();
|
||||
assertEquals("0.0009", presenter.amount.get());
|
||||
assertEquals(Coin.parseCoin("0.0009"), model.amountAsCoin.get());
|
||||
|
||||
presenter.amount.set("0.0029");
|
||||
model.calculateAmount();
|
||||
assertEquals("0.0029", presenter.amount.get());
|
||||
assertEquals(Coin.parseCoin("0.0029"), model.amountAsCoin.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindings() {
|
||||
presenter.price.set("500");
|
||||
presenter.volume.set("500");
|
||||
assertEquals("1.00", presenter.amount.get());
|
||||
assertEquals(Coin.COIN, model.amountAsCoin.get());
|
||||
assertEquals(Fiat.valueOf("USD", 500 * 10000), model.priceAsFiat.get());
|
||||
assertEquals(Fiat.valueOf("USD", 500 * 10000), model.volumeAsFiat.get());
|
||||
|
||||
presenter.price.set("300");
|
||||
presenter.volume.set("1000");
|
||||
assertEquals("3.3333", presenter.amount.get());
|
||||
assertEquals(Coin.parseCoin("3.3333"), model.amountAsCoin.get());
|
||||
assertEquals(Fiat.valueOf("USD", 300 * 10000), model.priceAsFiat.get());
|
||||
assertEquals(Fiat.valueOf("USD", 9999900), model.volumeAsFiat.get());
|
||||
|
||||
presenter.price.set("300");
|
||||
presenter.amount.set("3.3333");
|
||||
assertEquals("999.99", presenter.volume.get());
|
||||
assertEquals(Coin.parseCoin("3.3333"), model.amountAsCoin.get());
|
||||
assertEquals(Fiat.valueOf("USD", 300 * 10000), model.priceAsFiat.get());
|
||||
assertEquals(Fiat.valueOf("USD", 9999900), model.volumeAsFiat.get());
|
||||
|
||||
presenter.price.set("300");
|
||||
presenter.amount.set("3.33333333");
|
||||
assertEquals("999.99", presenter.volume.get());
|
||||
assertEquals(Coin.parseCoin("3.3333"), model.amountAsCoin.get());
|
||||
assertEquals(Fiat.valueOf("USD", 300 * 10000), model.priceAsFiat.get());
|
||||
assertEquals(Fiat.valueOf("USD", 9999900), model.volumeAsFiat.get());
|
||||
|
||||
|
||||
model.bankAccountType.set(BankAccountType.SEPA.toString());
|
||||
assertEquals("Sepa", presenter.bankAccountType.get());
|
||||
|
||||
model.bankAccountType.set(BankAccountType.WIRE.toString());
|
||||
assertEquals("Wire", presenter.bankAccountType.get());
|
||||
|
||||
|
||||
model.bankAccountCurrency.set("USD");
|
||||
assertEquals("USD", presenter.bankAccountCurrency.get());
|
||||
|
||||
model.bankAccountCurrency.set("USD");
|
||||
assertEquals("USD", presenter.bankAccountCurrency.get());
|
||||
|
||||
|
||||
model.bankAccountCounty.set("Spain");
|
||||
assertEquals("Spain", presenter.bankAccountCounty.get());
|
||||
|
||||
model.bankAccountCounty.set("Italy");
|
||||
assertEquals("Italy", presenter.bankAccountCounty.get());
|
||||
|
||||
model.acceptedCountries.add(new Country(null, "Italy", null));
|
||||
assertEquals("Italy", presenter.acceptedCountries.get());
|
||||
|
||||
model.acceptedCountries.add(new Country(null, "Spain", null));
|
||||
assertEquals("Italy, Spain", presenter.acceptedCountries.get());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
189
core/src/test/java/io/bitsquare/gui/util/BSFormatterTest.java
Normal file
189
core/src/test/java/io/bitsquare/gui/util/BSFormatterTest.java
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.util;
|
||||
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class BSFormatterTest {
|
||||
|
||||
@Test
|
||||
public void testParseToBtc() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.useMilliBitFormat(false);
|
||||
assertEquals(Coin.ZERO, formatter.parseToCoin("0"));
|
||||
assertEquals(Coin.COIN, formatter.parseToCoin("1"));
|
||||
assertEquals(Coin.SATOSHI, formatter.parseToCoin("0,00000001"));
|
||||
|
||||
assertEquals(Coin.parseCoin("-1"), formatter.parseToCoin("-1"));
|
||||
assertEquals(Coin.parseCoin("1.1"), formatter.parseToCoin("1,1"));
|
||||
assertEquals(Coin.parseCoin("1.1"), formatter.parseToCoin("1.1"));
|
||||
assertEquals(Coin.parseCoin("0"), formatter.parseToCoin("1.123,45"));
|
||||
assertEquals(Coin.parseCoin("0"), formatter.parseToCoin("1,123.45"));
|
||||
|
||||
assertEquals(Coin.parseCoin("1.1234"), formatter.parseToCoinWith4Decimals("1,12342"));
|
||||
assertEquals(Coin.parseCoin("1.1235"), formatter.parseToCoinWith4Decimals("1,12345"));
|
||||
assertEquals(Coin.parseCoin("1.1230"), formatter.parseToCoinWith4Decimals("1,123"));
|
||||
|
||||
// change to mBTC
|
||||
formatter.useMilliBitFormat(true);
|
||||
assertEquals(Coin.parseCoin("1"), formatter.parseToCoin("1000"));
|
||||
assertEquals(Coin.parseCoin("0.123"), formatter.parseToCoin("123"));
|
||||
assertEquals(Coin.parseCoin("0.1234"), formatter.parseToCoin("123.4"));
|
||||
assertEquals(Coin.parseCoin("0.12345"), formatter.parseToCoin("123.45"));
|
||||
assertEquals(Coin.parseCoin("0.123456"), formatter.parseToCoin("123.456"));
|
||||
assertEquals(Coin.parseCoin("0"), formatter.parseToCoin("123,456.7"));
|
||||
|
||||
assertEquals(Coin.parseCoin("0.001123"), formatter.parseToCoinWith4Decimals("1.123"));
|
||||
assertEquals(Coin.parseCoin("0.0011234"), formatter.parseToCoinWith4Decimals("1.1234"));
|
||||
assertEquals(Coin.parseCoin("0.0011234"), formatter.parseToCoinWith4Decimals("1.12342"));
|
||||
assertEquals(Coin.parseCoin("0.0011235"), formatter.parseToCoinWith4Decimals("1.12345"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatCoin() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.useMilliBitFormat(false);
|
||||
assertEquals("1.00", formatter.formatCoin(Coin.COIN));
|
||||
assertEquals("1.0120", formatter.formatCoin(Coin.parseCoin("1.012")));
|
||||
assertEquals("1012.30", formatter.formatCoin(Coin.parseCoin("1012.3")));
|
||||
assertEquals("1.0120", formatter.formatCoin(Coin.parseCoin("1.01200")));
|
||||
assertEquals("1.000123", formatter.formatCoin(Coin.parseCoin("1.0001234")));
|
||||
assertEquals("0.10", formatter.formatCoin(Coin.parseCoin("0.1")));
|
||||
assertEquals("0.01", formatter.formatCoin(Coin.parseCoin("0.01")));
|
||||
assertEquals("0.0010", formatter.formatCoin(Coin.parseCoin("0.001")));
|
||||
assertEquals("0.0001", formatter.formatCoin(Coin.parseCoin("0.0001")));
|
||||
|
||||
assertEquals("0.000010", formatter.formatCoin(Coin.parseCoin("0.00001")));
|
||||
assertEquals("0.000001", formatter.formatCoin(Coin.parseCoin("0.000001")));
|
||||
assertEquals("0.00", formatter.formatCoin(Coin.parseCoin("0.0000001")));
|
||||
|
||||
assertEquals("1.2345", formatter.formatCoin(Coin.parseCoin("1.2345")));
|
||||
assertEquals("1.002346", formatter.formatCoin(Coin.parseCoin("1.0023456")));
|
||||
assertEquals("1.002346", formatter.formatCoin(Coin.parseCoin("1.00234567")));
|
||||
assertEquals("1.002345", formatter.formatCoin(Coin.parseCoin("1.0023448")));
|
||||
|
||||
assertEquals("1.00", formatter.formatCoin(Coin.COIN));
|
||||
assertEquals("1012.30", formatter.formatCoin(Coin.parseCoin("1012.3")));
|
||||
|
||||
// change to mBTC
|
||||
formatter.useMilliBitFormat(true);
|
||||
assertEquals("1000.00", formatter.formatCoin(Coin.COIN));
|
||||
assertEquals("1.00", formatter.formatCoin(Coin.MILLICOIN));
|
||||
assertEquals("0.0010", formatter.formatCoin(Coin.MICROCOIN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatCoinWithCode() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.useMilliBitFormat(false);
|
||||
assertEquals("1.00 BTC", formatter.formatCoinWithCode(Coin.COIN));
|
||||
assertEquals("1.01 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.01")));
|
||||
assertEquals("1.0120 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.012")));
|
||||
assertEquals("1012.30 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1012.3")));
|
||||
assertEquals("1.0120 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.01200")));
|
||||
assertEquals("1.012340 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.01234")));
|
||||
assertEquals("1.012345 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.012345")));
|
||||
assertEquals("1.012345 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.0123454")));
|
||||
assertEquals("1.012346 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.0123455")));
|
||||
|
||||
assertEquals("0.10 BTC", formatter.formatCoinWithCode(Coin.parseCoin("0.1")));
|
||||
assertEquals("0.01 BTC", formatter.formatCoinWithCode(Coin.parseCoin("0.01")));
|
||||
assertEquals("0.0010 BTC", formatter.formatCoinWithCode(Coin.parseCoin("0.001")));
|
||||
assertEquals("0.0001 BTC", formatter.formatCoinWithCode(Coin.parseCoin("0.0001")));
|
||||
|
||||
assertEquals("1.2345 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.2345")));
|
||||
assertEquals("1.002346 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.0023456")));
|
||||
assertEquals("1.002346 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.00234567")));
|
||||
assertEquals("1.002345 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.0023448")));
|
||||
|
||||
assertEquals("1.00 BTC", formatter.formatCoinWithCode(Coin.COIN));
|
||||
assertEquals("1012.30 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1012.3")));
|
||||
|
||||
// change to mBTC
|
||||
formatter.useMilliBitFormat(true);
|
||||
assertEquals("1000.00 mBTC", formatter.formatCoinWithCode(Coin.COIN));
|
||||
assertEquals("1.00 mBTC", formatter.formatCoinWithCode(Coin.MILLICOIN));
|
||||
assertEquals("0.0010 mBTC", formatter.formatCoinWithCode(Coin.MICROCOIN));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParseToBtcWith4Decimals() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.useMilliBitFormat(false);
|
||||
assertEquals(Coin.parseCoin("0"), formatter.parseToCoinWith4Decimals("0"));
|
||||
assertEquals(Coin.parseCoin("0"), formatter.parseToCoinWith4Decimals(null));
|
||||
assertEquals(Coin.parseCoin("0"), formatter.parseToCoinWith4Decimals("s"));
|
||||
assertEquals(Coin.parseCoin("0.0012"), formatter.parseToCoinWith4Decimals("0,00123"));
|
||||
assertEquals(Coin.parseCoin("0.0013"), formatter.parseToCoinWith4Decimals("0,00125"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasBtcValidDecimals() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.useMilliBitFormat(false);
|
||||
formatter.setLocale(Locale.GERMAN);
|
||||
assertTrue(formatter.hasBtcValidDecimals(null));
|
||||
assertTrue(formatter.hasBtcValidDecimals("0"));
|
||||
assertTrue(formatter.hasBtcValidDecimals("0,0001"));
|
||||
assertTrue(formatter.hasBtcValidDecimals("0.0001"));
|
||||
assertTrue(formatter.hasBtcValidDecimals("0.0009"));
|
||||
assertTrue(formatter.hasBtcValidDecimals("20000000.0001"));
|
||||
assertFalse(formatter.hasBtcValidDecimals("20000000.000123"));
|
||||
assertFalse(formatter.hasBtcValidDecimals("0.00012"));
|
||||
assertFalse(formatter.hasBtcValidDecimals("0.0001222312312312313"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseToFiatWith2Decimals() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.useMilliBitFormat(false);
|
||||
formatter.setLocale(Locale.GERMAN);
|
||||
assertEquals("0", formatter.parseToFiatWith2Decimals("0").toPlainString());
|
||||
assertEquals("0", formatter.parseToFiatWith2Decimals(null).toPlainString());
|
||||
assertEquals("0", formatter.parseToFiatWith2Decimals("s").toPlainString());
|
||||
assertEquals("0.12", formatter.parseToFiatWith2Decimals("0.123").toPlainString());
|
||||
assertEquals("0.13", formatter.parseToFiatWith2Decimals("0.125").toPlainString());
|
||||
assertEquals("0.13", formatter.parseToFiatWith2Decimals("0,125").toPlainString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasFiatValidDecimals() {
|
||||
BSFormatter formatter = new BSFormatter(new User());
|
||||
formatter.useMilliBitFormat(false);
|
||||
formatter.setLocale(Locale.GERMAN);
|
||||
assertTrue(formatter.hasFiatValidDecimals(null));
|
||||
assertTrue(formatter.hasFiatValidDecimals("0"));
|
||||
assertTrue(formatter.hasFiatValidDecimals("0,01"));
|
||||
assertTrue(formatter.hasFiatValidDecimals("0.01"));
|
||||
assertTrue(formatter.hasFiatValidDecimals("0.09"));
|
||||
assertTrue(formatter.hasFiatValidDecimals("20000000.01"));
|
||||
assertFalse(formatter.hasFiatValidDecimals("20000000.0123"));
|
||||
assertFalse(formatter.hasFiatValidDecimals("0.012"));
|
||||
assertFalse(formatter.hasFiatValidDecimals("0.01222312312312313"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.util.validation;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class BtcValidatorTest {
|
||||
@Test
|
||||
public void testIsValid() {
|
||||
BtcValidator validator = new BtcValidator();
|
||||
|
||||
assertTrue(validator.validate("1").isValid);
|
||||
assertTrue(validator.validate("1,1").isValid);
|
||||
assertTrue(validator.validate("1.1").isValid);
|
||||
assertTrue(validator.validate(",1").isValid);
|
||||
assertTrue(validator.validate(".1").isValid);
|
||||
assertTrue(validator.validate("0.12345678").isValid);
|
||||
assertTrue(validator.validate(Coin.SATOSHI.toPlainString()).isValid);
|
||||
assertTrue(validator.validate(NetworkParameters.MAX_MONEY.toPlainString()).isValid);
|
||||
|
||||
assertFalse(validator.validate(null).isValid);
|
||||
assertFalse(validator.validate("").isValid);
|
||||
assertFalse(validator.validate("0").isValid);
|
||||
assertFalse(validator.validate("0.0").isValid);
|
||||
assertFalse(validator.validate("0,1,1").isValid);
|
||||
assertFalse(validator.validate("0.1.1").isValid);
|
||||
assertFalse(validator.validate("1,000.1").isValid);
|
||||
assertFalse(validator.validate("1.000,1").isValid);
|
||||
assertFalse(validator.validate("0.123456789").isValid);
|
||||
assertFalse(validator.validate("-1").isValid);
|
||||
assertFalse(validator.validate(String.valueOf(NetworkParameters.MAX_MONEY.longValue() + Coin.SATOSHI
|
||||
.longValue())).isValid);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.gui.util.validation;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class FiatValidatorTest {
|
||||
@Test
|
||||
public void testValidate() {
|
||||
FiatValidator validator = new FiatValidator(null);
|
||||
NumberValidator.ValidationResult validationResult;
|
||||
|
||||
|
||||
assertTrue(validator.validate("1").isValid);
|
||||
assertTrue(validator.validate("1,1").isValid);
|
||||
assertTrue(validator.validate("1.1").isValid);
|
||||
assertTrue(validator.validate(",1").isValid);
|
||||
assertTrue(validator.validate(".1").isValid);
|
||||
assertTrue(validator.validate("0.01").isValid);
|
||||
assertTrue(validator.validate("1000000.00").isValid);
|
||||
assertTrue(validator.validate(String.valueOf(FiatValidator.MIN_FIAT_VALUE)).isValid);
|
||||
assertTrue(validator.validate(String.valueOf(FiatValidator.MAX_FIAT_VALUE)).isValid);
|
||||
|
||||
assertFalse(validator.validate(null).isValid);
|
||||
assertFalse(validator.validate("").isValid);
|
||||
assertFalse(validator.validate("a").isValid);
|
||||
assertFalse(validator.validate("2a").isValid);
|
||||
assertFalse(validator.validate("a2").isValid);
|
||||
assertFalse(validator.validate("0").isValid);
|
||||
assertFalse(validator.validate("-1").isValid);
|
||||
assertFalse(validator.validate("0.0").isValid);
|
||||
assertFalse(validator.validate("0,1,1").isValid);
|
||||
assertFalse(validator.validate("0.1.1").isValid);
|
||||
assertFalse(validator.validate("1,000.1").isValid);
|
||||
assertFalse(validator.validate("1.000,1").isValid);
|
||||
assertFalse(validator.validate("0.009").isValid);
|
||||
assertFalse(validator.validate("1000000.01").isValid);
|
||||
|
||||
assertFalse(validator.validate(String.valueOf(FiatValidator.MIN_FIAT_VALUE - 0.0000001)).isValid);
|
||||
assertFalse(validator.validate(String.valueOf(FiatValidator.MAX_FIAT_VALUE + 0.0000001)).isValid);
|
||||
assertFalse(validator.validate(String.valueOf(Double.MIN_VALUE)).isValid);
|
||||
assertFalse(validator.validate(String.valueOf(Double.MAX_VALUE)).isValid);
|
||||
|
||||
}
|
||||
}
|
758
core/src/test/java/io/bitsquare/msg/TomP2PTests.java
Normal file
758
core/src/test/java/io/bitsquare/msg/TomP2PTests.java
Normal file
|
@ -0,0 +1,758 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.msg;
|
||||
|
||||
import io.bitsquare.network.BootstrapNodes;
|
||||
import io.bitsquare.network.ConnectionType;
|
||||
import io.bitsquare.network.Node;
|
||||
import io.bitsquare.util.Repeat;
|
||||
import io.bitsquare.util.RepeatRule;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.tomp2p.connection.Bindings;
|
||||
import net.tomp2p.connection.StandardProtocolFamily;
|
||||
import net.tomp2p.dht.FutureGet;
|
||||
import net.tomp2p.dht.FuturePut;
|
||||
import net.tomp2p.dht.FutureRemove;
|
||||
import net.tomp2p.dht.PeerBuilderDHT;
|
||||
import net.tomp2p.dht.PeerDHT;
|
||||
import net.tomp2p.futures.BaseFuture;
|
||||
import net.tomp2p.futures.BaseFutureListener;
|
||||
import net.tomp2p.futures.FutureBootstrap;
|
||||
import net.tomp2p.futures.FutureDirect;
|
||||
import net.tomp2p.futures.FutureDiscover;
|
||||
import net.tomp2p.futures.FuturePeerConnection;
|
||||
import net.tomp2p.nat.FutureNAT;
|
||||
import net.tomp2p.nat.FutureRelayNAT;
|
||||
import net.tomp2p.nat.PeerBuilderNAT;
|
||||
import net.tomp2p.nat.PeerNAT;
|
||||
import net.tomp2p.p2p.Peer;
|
||||
import net.tomp2p.p2p.PeerBuilder;
|
||||
import net.tomp2p.peers.Number160;
|
||||
import net.tomp2p.peers.PeerAddress;
|
||||
import net.tomp2p.peers.PeerMap;
|
||||
import net.tomp2p.peers.PeerMapConfiguration;
|
||||
import net.tomp2p.relay.tcp.TCPRelayClientConfig;
|
||||
import net.tomp2p.storage.Data;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test bootstrapping, DHT operations like put/get/add/remove and sendDirect in both LAN and WAN environment
|
||||
* Test scenarios in direct connection, auto port forwarding or relay mode.
|
||||
* <p>
|
||||
* To start a bootstrap node code use the {@link io.bitsquare.app.bootstrap.BootstrapNode} class.
|
||||
* <p>
|
||||
* To configure your test environment edit the static fields for id, IP and port.
|
||||
* In the configure method and the connectionType you can define your test scenario.
|
||||
*/
|
||||
@Ignore
|
||||
public class TomP2PTests {
|
||||
private static final Logger log = LoggerFactory.getLogger(TomP2PTests.class);
|
||||
|
||||
// If you want to test in one specific connection mode define it directly, otherwise use UNKNOWN
|
||||
private static final ConnectionType FORCED_CONNECTION_TYPE = ConnectionType.RELAY;
|
||||
|
||||
// Typically you run the bootstrap node in localhost to test direct connection.
|
||||
// If you have a setup where you are not behind a router you can also use a WAN bootstrap node.
|
||||
private static final Node BOOTSTRAP_NODE = (FORCED_CONNECTION_TYPE == ConnectionType.DIRECT) ?
|
||||
BootstrapNodes.LOCALHOST : Node.at("digitalocean1.dev.bitsquare.io", "188.226.179.109", 7367);
|
||||
|
||||
private static final PeerAddress BOOTSTRAP_NODE_ADDRESS;
|
||||
|
||||
static {
|
||||
try {
|
||||
BOOTSTRAP_NODE_ADDRESS = new PeerAddress(
|
||||
Number160.createHash(BOOTSTRAP_NODE.getName()),
|
||||
BOOTSTRAP_NODE.getIp(), BOOTSTRAP_NODE.getPort(), BOOTSTRAP_NODE.getPort());
|
||||
} catch (UnknownHostException ex) {
|
||||
throw new RuntimeException(BOOTSTRAP_NODE.toString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Use to stress tests by repeating them
|
||||
private static final int STRESS_TEST_COUNT = 1;
|
||||
|
||||
private Peer peer;
|
||||
private PeerDHT peer1DHT;
|
||||
private PeerDHT peer2DHT;
|
||||
private int client1Port;
|
||||
private int client2Port;
|
||||
private ConnectionType resolvedConnectionType;
|
||||
public @Rule RepeatRule repeatRule = new RepeatRule();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
client1Port = 7367;
|
||||
client2Port = 7368;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (peer1DHT != null)
|
||||
peer1DHT.shutdown().awaitUninterruptibly().awaitListenersUninterruptibly();
|
||||
|
||||
if (peer2DHT != null)
|
||||
peer2DHT.shutdown().awaitUninterruptibly().awaitListenersUninterruptibly();
|
||||
|
||||
if (peer != null)
|
||||
peer.shutdown().awaitUninterruptibly().awaitListenersUninterruptibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void bootstrapInUnknownMode() throws Exception {
|
||||
if (FORCED_CONNECTION_TYPE == ConnectionType.UNKNOWN) {
|
||||
peer = bootstrapInUnknownMode(client1Port);
|
||||
assertNotNull(peer);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testBootstrapDirectConnection() throws Exception {
|
||||
if (FORCED_CONNECTION_TYPE == ConnectionType.DIRECT) {
|
||||
peer = bootstrapDirectConnection(client1Port);
|
||||
assertNotNull(peer);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testBootstrapWithPortForwarding() throws Exception {
|
||||
if (FORCED_CONNECTION_TYPE == ConnectionType.AUTO_PORT_FORWARDING ||
|
||||
FORCED_CONNECTION_TYPE == ConnectionType.MANUAL_PORT_FORWARDING) {
|
||||
peer = bootstrapWithPortForwarding(client2Port);
|
||||
assertNotNull(peer);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testBootstrapInRelayMode() throws Exception {
|
||||
if (FORCED_CONNECTION_TYPE == ConnectionType.RELAY) {
|
||||
peer = bootstrapInRelayMode(client1Port);
|
||||
assertNotNull(peer);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testPut() throws Exception {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
FuturePut futurePut = peer1DHT.put(Number160.createHash("key")).data(new Data("hallo")).start();
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertTrue(futurePut.isSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testPutGet() throws Exception {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
FuturePut futurePut = peer1DHT.put(Number160.createHash("key")).data(new Data("hallo")).start();
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertTrue(futurePut.isSuccess());
|
||||
|
||||
peer2DHT = getDHTPeer(client2Port);
|
||||
FutureGet futureGet = peer2DHT.get(Number160.createHash("key")).start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertEquals("hallo", futureGet.data().object());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testAdd() throws Exception {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
FuturePut futurePut1 = peer1DHT.add(Number160.createHash("locationKey")).data(new Data("hallo1")).start();
|
||||
futurePut1.awaitUninterruptibly();
|
||||
assertTrue(futurePut1.isSuccess());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testAddGet() throws Exception {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
FuturePut futurePut1 = peer1DHT.add(Number160.createHash("locationKey")).data(new Data("hallo1"))
|
||||
.start();
|
||||
futurePut1.awaitUninterruptibly();
|
||||
assertTrue(futurePut1.isSuccess());
|
||||
|
||||
FuturePut futurePut2 = peer1DHT.add(Number160.createHash("locationKey")).data(new Data("hallo2"))
|
||||
.start();
|
||||
futurePut2.awaitUninterruptibly();
|
||||
assertTrue(futurePut2.isSuccess());
|
||||
|
||||
|
||||
peer2DHT = getDHTPeer(client2Port);
|
||||
FutureGet futureGet = peer2DHT.get(Number160.createHash("locationKey")).all().start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo1")));
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo2")));
|
||||
assertTrue(futureGet.dataMap().values().size() == 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testAddGetWithReconnect() throws Exception {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
FuturePut futurePut1 = peer1DHT.add(Number160.createHash("locationKey")).data(new Data("hallo1")).start();
|
||||
futurePut1.awaitUninterruptibly();
|
||||
assertTrue(futurePut1.isSuccess());
|
||||
FuturePut futurePut2 = peer1DHT.add(Number160.createHash("locationKey")).data(new Data("hallo2")).start();
|
||||
futurePut2.awaitUninterruptibly();
|
||||
assertTrue(futurePut2.isSuccess());
|
||||
|
||||
peer2DHT = getDHTPeer(client2Port);
|
||||
FutureGet futureGet = peer2DHT.get(Number160.createHash("locationKey")).all().start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo1")));
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo2")));
|
||||
assertTrue(futureGet.dataMap().values().size() == 2);
|
||||
|
||||
// shut down peer2
|
||||
BaseFuture future = peer2DHT.shutdown();
|
||||
future.awaitUninterruptibly();
|
||||
future.awaitListenersUninterruptibly();
|
||||
// start up peer2
|
||||
peer2DHT = getDHTPeer(client2Port);
|
||||
futureGet = peer2DHT.get(Number160.createHash("locationKey")).all().start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo1")));
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo2")));
|
||||
assertTrue(futureGet.dataMap().values().size() == 2);
|
||||
|
||||
futureGet = peer1DHT.get(Number160.createHash("locationKey")).all().start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo1")));
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo2")));
|
||||
assertTrue(futureGet.dataMap().values().size() == 2);
|
||||
|
||||
// shut down both
|
||||
future = peer2DHT.shutdown();
|
||||
future.awaitUninterruptibly();
|
||||
future.awaitListenersUninterruptibly();
|
||||
future = peer1DHT.shutdown();
|
||||
future.awaitUninterruptibly();
|
||||
future.awaitListenersUninterruptibly();
|
||||
|
||||
// start up both
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
futureGet = peer1DHT.get(Number160.createHash("locationKey")).all().start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo1")));
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo2")));
|
||||
assertTrue(futureGet.dataMap().values().size() == 2);
|
||||
|
||||
peer2DHT = getDHTPeer(client2Port);
|
||||
futureGet = peer2DHT.get(Number160.createHash("locationKey")).all().start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo1")));
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo2")));
|
||||
assertTrue(futureGet.dataMap().values().size() == 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testParallelStartupWithPutGet() throws IOException, ClassNotFoundException, InterruptedException {
|
||||
PeerMapConfiguration pmc1 = new PeerMapConfiguration(Number160.createHash("peer1")).peerNoVerification();
|
||||
PeerMap pm1 = new PeerMap(pmc1);
|
||||
|
||||
PeerDHT peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3006).peerMap(pm1).start()).start();
|
||||
|
||||
PeerMapConfiguration pmc2 = new PeerMapConfiguration(Number160.createHash("peer2")).peerNoVerification();
|
||||
PeerMap pm2 = new PeerMap(pmc2);
|
||||
|
||||
PeerDHT peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3007).peerMap(pm2).start()).start();
|
||||
|
||||
/* PeerAddress masterPeerAddress = new PeerAddress(Number160.createHash(BOOTSTRAP_NODE_ID),
|
||||
BOOTSTRAP_NODE_IP, BOOTSTRAP_NODE_PORT,
|
||||
BOOTSTRAP_NODE_PORT);
|
||||
|
||||
PeerDHT peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3006).start()).start();
|
||||
PeerDHT peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3007).start()).start();
|
||||
*/
|
||||
PeerAddress masterPeerAddress = new PeerAddress(Number160.createHash(BootstrapNodes.LOCALHOST.getName()),
|
||||
BootstrapNodes.LOCALHOST.getIp(), BootstrapNodes.LOCALHOST.getPort(),
|
||||
BootstrapNodes.LOCALHOST.getPort());
|
||||
|
||||
// start both at the same time
|
||||
BaseFuture fb1 = peer1.peer().bootstrap().peerAddress(masterPeerAddress).start();
|
||||
BaseFuture fb2 = peer2.peer().bootstrap().peerAddress(masterPeerAddress).start();
|
||||
|
||||
final AtomicBoolean peer1Done = new AtomicBoolean();
|
||||
final AtomicBoolean peer2Done = new AtomicBoolean();
|
||||
|
||||
fb1.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture future) throws Exception {
|
||||
peer1Done.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(Throwable t) throws Exception {
|
||||
log.error(t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
fb2.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture future) throws Exception {
|
||||
peer2Done.set(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(Throwable t) throws Exception {
|
||||
log.error(t.toString());
|
||||
}
|
||||
});
|
||||
|
||||
while (!peer1Done.get() && !peer2Done.get())
|
||||
Thread.sleep(100);
|
||||
|
||||
// both are started up
|
||||
Assert.assertTrue(fb1.isSuccess());
|
||||
Assert.assertTrue(fb2.isSuccess());
|
||||
|
||||
// peer1 put data
|
||||
FuturePut fp = peer1.put(Number160.ONE).object("test").start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fp.isSuccess());
|
||||
|
||||
// both get data
|
||||
FutureGet fg1 = peer1.get(Number160.ONE).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fg1.isSuccess());
|
||||
Assert.assertEquals("test", fg1.data().object());
|
||||
FutureGet fg2 = peer2.get(Number160.ONE).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fg2.isSuccess());
|
||||
Assert.assertEquals("test", fg2.data().object());
|
||||
|
||||
// shutdown both
|
||||
peer1.shutdown().awaitUninterruptibly().awaitListenersUninterruptibly();
|
||||
peer2.shutdown().awaitUninterruptibly().awaitListenersUninterruptibly();
|
||||
|
||||
// start both again at the same time
|
||||
peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3005).start()).start();
|
||||
peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3006).start()).start();
|
||||
|
||||
fb1 = peer1.peer().bootstrap().peerAddress(masterPeerAddress).start();
|
||||
fb2 = peer2.peer().bootstrap().peerAddress(masterPeerAddress).start();
|
||||
|
||||
peer1Done.set(false);
|
||||
peer2Done.set(false);
|
||||
|
||||
final PeerDHT _peer1 = peer1;
|
||||
fb1.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture future) throws Exception {
|
||||
peer1Done.set(true);
|
||||
|
||||
// when peer1 is ready it gets the data
|
||||
FutureGet fg = _peer1.get(Number160.ONE).start();
|
||||
fg.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture future) throws Exception {
|
||||
Assert.assertTrue(fg.isSuccess());
|
||||
Assert.assertEquals("test", fg.data().object());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(Throwable t) throws Exception {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(Throwable t) throws Exception {
|
||||
}
|
||||
});
|
||||
|
||||
final PeerDHT _peer2 = peer2;
|
||||
fb2.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture future) throws Exception {
|
||||
peer2Done.set(true);
|
||||
|
||||
// when peer2 is ready it gets the data
|
||||
FutureGet fg = _peer2.get(Number160.ONE).start();
|
||||
fg.addListener(new BaseFutureListener<BaseFuture>() {
|
||||
@Override
|
||||
public void operationComplete(BaseFuture future) throws Exception {
|
||||
Assert.assertTrue(fg.isSuccess());
|
||||
Assert.assertEquals("test", fg.data().object());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(Throwable t) throws Exception {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(Throwable t) throws Exception {
|
||||
}
|
||||
});
|
||||
|
||||
while (!peer1Done.get() && !peer2Done.get())
|
||||
Thread.sleep(100);
|
||||
|
||||
// both are started up
|
||||
Assert.assertTrue(fb1.isSuccess());
|
||||
Assert.assertTrue(fb2.isSuccess());
|
||||
|
||||
// get data again for both
|
||||
fg1 = peer1.get(Number160.ONE).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fg1.isSuccess());
|
||||
Assert.assertEquals("test", fg1.data().object());
|
||||
|
||||
fg2 = peer2.get(Number160.ONE).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fg2.isSuccess());
|
||||
Assert.assertEquals("test", fg2.data().object());
|
||||
|
||||
peer1.shutdown().awaitUninterruptibly().awaitListenersUninterruptibly();
|
||||
peer2.shutdown().awaitUninterruptibly().awaitListenersUninterruptibly();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testAddRemove() throws Exception {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
FuturePut futurePut1 = peer1DHT.add(Number160.createHash("locationKey")).data(new Data("hallo1")).start();
|
||||
futurePut1.awaitUninterruptibly();
|
||||
futurePut1.awaitListenersUninterruptibly();
|
||||
assertTrue(futurePut1.isSuccess());
|
||||
|
||||
FuturePut futurePut2 = peer1DHT.add(Number160.createHash("locationKey")).data(new Data("hallo2")).start();
|
||||
futurePut2.awaitUninterruptibly();
|
||||
futurePut2.awaitListenersUninterruptibly();
|
||||
assertTrue(futurePut2.isSuccess());
|
||||
|
||||
|
||||
peer2DHT = getDHTPeer(client2Port);
|
||||
Number160 contentKey = new Data("hallo1").hash();
|
||||
FutureRemove futureRemove = peer2DHT.remove(Number160.createHash("locationKey")).contentKey(contentKey).start();
|
||||
futureRemove.awaitUninterruptibly();
|
||||
futureRemove.awaitListenersUninterruptibly();
|
||||
|
||||
// We don't test futureRemove.isSuccess() as this API does not fit well to that operation,
|
||||
// it might change in future to something like foundAndRemoved and notFound
|
||||
// See discussion at: https://github.com/tomp2p/TomP2P/issues/57#issuecomment-62069840
|
||||
|
||||
assertTrue(futureRemove.isSuccess());
|
||||
|
||||
FutureGet futureGet = peer2DHT.get(Number160.createHash("locationKey")).all().start();
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
if (!futureGet.dataMap().values().contains(new Data("hallo2"))) {
|
||||
log.error("raw data has the value, the evaluated not!");
|
||||
}
|
||||
|
||||
assertTrue(futureGet.dataMap().values().contains(new Data("hallo2")));
|
||||
assertTrue(futureGet.dataMap().values().size() == 1);
|
||||
}
|
||||
|
||||
|
||||
// The sendDirect operation fails in port forwarding mode because most routers does not support NAT reflections.
|
||||
// So if both clients are behind NAT they cannot send direct message to each other.
|
||||
// Seems that in relay mode that is also not working
|
||||
// That will probably be fixed in a future version of TomP2P
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testSendDirectBetweenLocalPeers() throws Exception {
|
||||
if (FORCED_CONNECTION_TYPE == ConnectionType.DIRECT || resolvedConnectionType == ConnectionType.DIRECT) {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
peer2DHT = getDHTPeer(client2Port);
|
||||
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
|
||||
final StringBuilder result = new StringBuilder();
|
||||
peer2DHT.peer().objectDataReply((sender, request) -> {
|
||||
countDownLatch.countDown();
|
||||
result.append(String.valueOf(request));
|
||||
return "pong";
|
||||
});
|
||||
FuturePeerConnection futurePeerConnection = peer1DHT.peer().createPeerConnection(peer2DHT.peer()
|
||||
.peerAddress(), 500);
|
||||
FutureDirect futureDirect = peer1DHT.peer().sendDirect(futurePeerConnection).object("hallo").start();
|
||||
futureDirect.awaitUninterruptibly();
|
||||
|
||||
|
||||
countDownLatch.await(3, TimeUnit.SECONDS);
|
||||
if (countDownLatch.getCount() > 0)
|
||||
Assert.fail("The test method did not complete successfully!");
|
||||
|
||||
assertEquals("hallo", result.toString());
|
||||
assertTrue(futureDirect.isSuccess());
|
||||
log.debug(futureDirect.object().toString());
|
||||
assertEquals("pong", futureDirect.object());
|
||||
}
|
||||
}
|
||||
|
||||
// This test should always succeed as we use the bootstrap node as receiver.
|
||||
// A node can send a message to another peer which is not in the same LAN.
|
||||
@Test
|
||||
@Repeat(STRESS_TEST_COUNT)
|
||||
public void testSendDirectToSeedNode() throws Exception {
|
||||
peer1DHT = getDHTPeer(client1Port);
|
||||
FuturePeerConnection futurePeerConnection =
|
||||
peer1DHT.peer().createPeerConnection(BOOTSTRAP_NODE_ADDRESS, 500);
|
||||
FutureDirect futureDirect = peer1DHT.peer().sendDirect(futurePeerConnection).object("hallo").start();
|
||||
futureDirect.awaitUninterruptibly();
|
||||
assertTrue(futureDirect.isSuccess());
|
||||
|
||||
// server node does not reply
|
||||
// assertEquals("pong", futureDirect.object());
|
||||
}
|
||||
|
||||
private Peer bootstrapDirectConnection(int clientPort) {
|
||||
Peer peer = null;
|
||||
try {
|
||||
/* Number160 peerId = Number160.createHash(UUID.randomUUID().toString());
|
||||
PeerMapConfiguration pmc = new PeerMapConfiguration(peerId).peerNoVerification();
|
||||
PeerMap pm = new PeerMap(pmc);
|
||||
ChannelClientConfiguration cc = PeerBuilder.createDefaultChannelClientConfiguration();
|
||||
cc.maxPermitsTCP(100);
|
||||
cc.maxPermitsUDP(100);
|
||||
peer = new PeerBuilder(peerId).bindings(getBindings()).channelClientConfiguration(cc).peerMap(pm)
|
||||
.ports(clientPort).start();*/
|
||||
|
||||
Number160 peerId = Number160.createHash(UUID.randomUUID().toString());
|
||||
peer = new PeerBuilder(peerId).bindings(getBindings())
|
||||
.ports(clientPort).start();
|
||||
|
||||
FutureDiscover futureDiscover = peer.discover().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
|
||||
futureDiscover.awaitUninterruptibly();
|
||||
if (futureDiscover.isSuccess()) {
|
||||
log.info("Discover with direct connection successful. Address = " + futureDiscover.peerAddress());
|
||||
|
||||
FutureBootstrap futureBootstrap = peer.bootstrap().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
|
||||
futureBootstrap.awaitUninterruptibly();
|
||||
if (futureBootstrap.isSuccess()) {
|
||||
return peer;
|
||||
}
|
||||
else {
|
||||
log.warn("Bootstrap failed. Reason = " + futureBootstrap.failedReason());
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("Discover with direct connection failed. Reason = " + futureDiscover.failedReason());
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Discover with direct connection failed. Exception = " + e.getMessage());
|
||||
if (peer != null)
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Peer bootstrapWithPortForwarding(int clientPort) {
|
||||
Number160 peerId = Number160.createHash(UUID.randomUUID().toString());
|
||||
Peer peer = null;
|
||||
try {
|
||||
if (FORCED_CONNECTION_TYPE == ConnectionType.MANUAL_PORT_FORWARDING ||
|
||||
resolvedConnectionType == ConnectionType.MANUAL_PORT_FORWARDING) {
|
||||
peer = new PeerBuilder(peerId).bindings(getBindings())
|
||||
.behindFirewall()
|
||||
.tcpPortForwarding(clientPort)
|
||||
.udpPortForwarding(clientPort)
|
||||
.ports(clientPort)
|
||||
.start();
|
||||
}
|
||||
else {
|
||||
peer = new PeerBuilder(peerId).bindings(getBindings())
|
||||
.behindFirewall()
|
||||
.ports(clientPort)
|
||||
.start();
|
||||
}
|
||||
|
||||
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
|
||||
FutureDiscover futureDiscover = peer.discover().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
|
||||
FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover);
|
||||
futureNAT.awaitUninterruptibly();
|
||||
if (futureNAT.isSuccess()) {
|
||||
log.info("Automatic port forwarding is setup. Now we do a futureDiscover again. Address = " +
|
||||
futureNAT.peerAddress());
|
||||
futureDiscover = peer.discover().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
|
||||
futureDiscover.awaitUninterruptibly();
|
||||
if (futureDiscover.isSuccess()) {
|
||||
log.info("Discover with automatic port forwarding was successful. Address = " + futureDiscover
|
||||
.peerAddress());
|
||||
|
||||
FutureBootstrap futureBootstrap = peer.bootstrap().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
|
||||
futureBootstrap.awaitUninterruptibly();
|
||||
if (futureBootstrap.isSuccess()) {
|
||||
return peer;
|
||||
}
|
||||
else {
|
||||
log.warn("Bootstrap failed. Reason = " + futureBootstrap.failedReason());
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("Discover with automatic port forwarding failed. Reason = " + futureDiscover
|
||||
.failedReason());
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("StartSetupPortforwarding failed. Reason = " + futureNAT
|
||||
.failedReason());
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Discover with automatic port forwarding failed. Exception = " + e.getMessage());
|
||||
if (peer != null)
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Peer bootstrapInRelayMode(int clientPort) {
|
||||
Number160 peerId = Number160.createHash(UUID.randomUUID().toString());
|
||||
Peer peer = null;
|
||||
try {
|
||||
peer = new PeerBuilder(peerId).bindings(getBindings()).behindFirewall()
|
||||
.ports(clientPort).start();
|
||||
|
||||
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
|
||||
FutureDiscover futureDiscover = peer.discover().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
|
||||
FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover);
|
||||
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(new TCPRelayClientConfig(), futureDiscover, futureNAT);
|
||||
futureRelayNAT.awaitUninterruptibly();
|
||||
if (futureRelayNAT.isSuccess()) {
|
||||
log.info("Bootstrap using relay was successful. Address = " + peer.peerAddress());
|
||||
|
||||
FutureBootstrap futureBootstrap = peer.bootstrap().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
|
||||
futureBootstrap.awaitUninterruptibly();
|
||||
if (futureBootstrap.isSuccess()) {
|
||||
return peer;
|
||||
}
|
||||
else {
|
||||
log.warn("Bootstrap failed. Reason = " + futureBootstrap.failedReason());
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.error("Bootstrap using relay failed " + futureRelayNAT.failedReason());
|
||||
futureRelayNAT.shutdown();
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Bootstrap using relay failed. Exception " + e.getMessage());
|
||||
if (peer != null)
|
||||
peer.shutdown().awaitUninterruptibly();
|
||||
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Peer bootstrapInUnknownMode(int clientPort) {
|
||||
resolvedConnectionType = ConnectionType.DIRECT;
|
||||
Peer peer = bootstrapDirectConnection(clientPort);
|
||||
if (peer != null)
|
||||
return peer;
|
||||
|
||||
resolvedConnectionType = ConnectionType.MANUAL_PORT_FORWARDING;
|
||||
peer = bootstrapWithPortForwarding(clientPort);
|
||||
if (peer != null)
|
||||
return peer;
|
||||
|
||||
resolvedConnectionType = ConnectionType.AUTO_PORT_FORWARDING;
|
||||
peer = bootstrapWithPortForwarding(clientPort);
|
||||
if (peer != null)
|
||||
return peer;
|
||||
|
||||
resolvedConnectionType = ConnectionType.RELAY;
|
||||
peer = bootstrapInRelayMode(clientPort);
|
||||
if (peer != null)
|
||||
return peer;
|
||||
else
|
||||
log.error("Bootstrapping in all modes failed. Is bootstrap node " + BOOTSTRAP_NODE + "running?");
|
||||
|
||||
resolvedConnectionType = null;
|
||||
return peer;
|
||||
}
|
||||
|
||||
private PeerDHT getDHTPeer(int clientPort) {
|
||||
Peer peer;
|
||||
if (FORCED_CONNECTION_TYPE == ConnectionType.DIRECT) {
|
||||
peer = bootstrapDirectConnection(clientPort);
|
||||
}
|
||||
else if (FORCED_CONNECTION_TYPE == ConnectionType.AUTO_PORT_FORWARDING) {
|
||||
peer = bootstrapWithPortForwarding(clientPort);
|
||||
}
|
||||
else if (FORCED_CONNECTION_TYPE == ConnectionType.RELAY) {
|
||||
peer = bootstrapInRelayMode(clientPort);
|
||||
}
|
||||
else {
|
||||
peer = bootstrapInUnknownMode(clientPort);
|
||||
}
|
||||
|
||||
if (peer == null)
|
||||
Assert.fail("Bootstrapping failed." +
|
||||
" forcedConnectionType= " + FORCED_CONNECTION_TYPE +
|
||||
" resolvedConnectionType= " + resolvedConnectionType + "." +
|
||||
" Is bootstrap node " + BOOTSTRAP_NODE + "running?");
|
||||
|
||||
return new PeerBuilderDHT(peer).start();
|
||||
}
|
||||
|
||||
private Bindings getBindings() {
|
||||
Bindings bindings = new Bindings();
|
||||
bindings.addProtocol(StandardProtocolFamily.INET);
|
||||
return bindings;
|
||||
}
|
||||
}
|
61
core/src/test/java/io/bitsquare/network/NodeTests.java
Normal file
61
core/src/test/java/io/bitsquare/network/NodeTests.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.network;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class NodeTests {
|
||||
|
||||
@Test
|
||||
public void testEqualsAndHashCode() {
|
||||
Node node1a = Node.at("bitsquare1.example.com", "203.0.113.1");
|
||||
Node node1b = Node.at("bitsquare1.example.com", "203.0.113.1");
|
||||
|
||||
assertThat(node1a, equalTo(node1a));
|
||||
|
||||
assertThat(node1a, equalTo(node1b));
|
||||
assertThat(node1b, equalTo(node1a));
|
||||
|
||||
assertThat(node1a, not((Object) equalTo(null)));
|
||||
assertThat(node1a, not((Object) equalTo("not a node")));
|
||||
|
||||
assertThat(node1a, not(equalTo(Node.at("bitsquare2.example.com", node1a.getIp()))));
|
||||
assertThat(node1a, not(equalTo(Node.at(node1a.getName(), "203.0.113.2"))));
|
||||
assertThat(node1a, not(equalTo(Node.at(node1a.getName(), node1a.getIp(), Node.DEFAULT_PORT + 1))));
|
||||
|
||||
Node node2 = Node.at("bitsquare2.example.com", "203.0.113.2");
|
||||
assertThat(node1a.hashCode(), equalTo(node1b.hashCode()));
|
||||
assertThat(node1a.hashCode(), not(equalTo(node2.hashCode())));
|
||||
|
||||
assertThat(node1a.getPort(), equalTo(Node.DEFAULT_PORT));
|
||||
|
||||
Node node3a = Node.at("bitsquare3.example.com", "203.0.113.3", 1234);
|
||||
Node node3b = Node.at("bitsquare3.example.com", "203.0.113.3", "1234");
|
||||
|
||||
assertThat(node3a, equalTo(node3b));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
Node node = Node.at("bitsquare1.example.com", "203.0.113.1", 5001);
|
||||
assertThat(node.toString(), equalTo("Node{name=bitsquare1.example.com, ip=203.0.113.1, port=5001}"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.network.tomp2p;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.tomp2p.connection.Ports;
|
||||
import net.tomp2p.dht.FutureGet;
|
||||
import net.tomp2p.dht.FuturePut;
|
||||
import net.tomp2p.dht.FutureRemove;
|
||||
import net.tomp2p.dht.PeerBuilderDHT;
|
||||
import net.tomp2p.dht.PeerDHT;
|
||||
import net.tomp2p.dht.UtilsDHT2;
|
||||
import net.tomp2p.futures.FutureDirect;
|
||||
import net.tomp2p.p2p.PeerBuilder;
|
||||
import net.tomp2p.peers.Number160;
|
||||
import net.tomp2p.peers.PeerAddress;
|
||||
import net.tomp2p.rpc.ObjectDataReply;
|
||||
import net.tomp2p.storage.Data;
|
||||
import net.tomp2p.utils.Utils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
// TODO Reactivate tests when TomP2PNode is using original code again. we deactivated the security features atm.
|
||||
// cause IOException: Not listening to anything. Maybe your binding information is wrong.
|
||||
// investigate what has broken it, probably from update to latest head
|
||||
@Ignore
|
||||
public class TomP2PNodeTest {
|
||||
|
||||
final private static Random rnd = new Random(42L);
|
||||
|
||||
@Test
|
||||
public void testSendData() throws Exception {
|
||||
PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, new Ports().tcpPort());
|
||||
PeerDHT master = peers[0];
|
||||
PeerDHT client = peers[1];
|
||||
PeerDHT otherPeer = peers[2];
|
||||
UtilsDHT2.perfectRouting(peers);
|
||||
|
||||
|
||||
for (final PeerDHT peer : peers) {
|
||||
peer.peer().objectDataReply(new ObjectDataReply() {
|
||||
@Override
|
||||
public Object reply(PeerAddress sender, Object request) throws Exception {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
|
||||
keyGen.initialize(1024);
|
||||
KeyPair keyPairClient = keyGen.genKeyPair();
|
||||
KeyPair keyPairOtherPeer = keyGen.genKeyPair();
|
||||
|
||||
TomP2PNode node;
|
||||
Number160 locationKey;
|
||||
Object object;
|
||||
FutureDirect futureDirect;
|
||||
|
||||
node = new TomP2PNode(keyPairClient, client);
|
||||
object = "clients data";
|
||||
futureDirect = node.sendData(otherPeer.peerAddress(), object);
|
||||
futureDirect.awaitUninterruptibly();
|
||||
|
||||
assertTrue(futureDirect.isSuccess());
|
||||
// we return true from objectDataReply
|
||||
assertTrue((Boolean) futureDirect.object());
|
||||
|
||||
master.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProtectedPutGet() throws Exception {
|
||||
PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, new Ports().tcpPort());
|
||||
PeerDHT master = peers[0];
|
||||
PeerDHT client = peers[1];
|
||||
PeerDHT otherPeer = peers[2];
|
||||
UtilsDHT2.perfectRouting(peers);
|
||||
|
||||
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
|
||||
keyGen.initialize(1024);
|
||||
KeyPair keyPairClient = keyGen.genKeyPair();
|
||||
KeyPair keyPairOtherPeer = keyGen.genKeyPair();
|
||||
|
||||
TomP2PNode node;
|
||||
Number160 locationKey;
|
||||
Data data;
|
||||
FuturePut futurePut;
|
||||
FutureGet futureGet;
|
||||
|
||||
// otherPeer tries to squat clients location store
|
||||
// he can do it but as he has not the domain key of the client he cannot do any harm
|
||||
// he only can store und that path: locationKey.otherPeerDomainKey.data
|
||||
node = new TomP2PNode(keyPairOtherPeer, otherPeer);
|
||||
locationKey = Number160.createHash("clients location");
|
||||
data = new Data("otherPeer data");
|
||||
futurePut = node.putDomainProtectedData(locationKey, data);
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertTrue(futurePut.isSuccess());
|
||||
|
||||
futureGet = node.getDomainProtectedData(locationKey, keyPairOtherPeer.getPublic());
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertEquals("otherPeer data", futureGet.data().object());
|
||||
|
||||
// client store his data und his domainkey, no problem with previous occupied
|
||||
// he only can store und that path: locationKey.clientDomainKey.data
|
||||
node = new TomP2PNode(keyPairClient, client);
|
||||
locationKey = Number160.createHash("clients location");
|
||||
data = new Data("client data");
|
||||
futurePut = node.putDomainProtectedData(locationKey, data);
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertTrue(futurePut.isSuccess());
|
||||
|
||||
futureGet = node.getDomainProtectedData(locationKey, keyPairClient.getPublic());
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertEquals("client data", futureGet.data().object());
|
||||
|
||||
// also other peers can read that data if they know the public key of the client
|
||||
node = new TomP2PNode(keyPairOtherPeer, otherPeer);
|
||||
futureGet = node.getDomainProtectedData(locationKey, keyPairClient.getPublic());
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertEquals("client data", futureGet.data().object());
|
||||
|
||||
|
||||
// other peer try to use pub key of other peer as domain key hash.
|
||||
// must fail as he don't have the full key pair (private key of client missing)
|
||||
locationKey = Number160.createHash("clients location");
|
||||
data = new Data("otherPeer data hack");
|
||||
|
||||
data.protectEntry(keyPairOtherPeer);
|
||||
// he use the pub key from the client
|
||||
final Number160 keyHash = Utils.makeSHAHash(keyPairClient.getPublic().getEncoded());
|
||||
futurePut = otherPeer.put(locationKey).data(data).keyPair(keyPairOtherPeer).domainKey(keyHash)
|
||||
.protectDomain().start();
|
||||
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertFalse(futurePut.isSuccess());
|
||||
|
||||
// he can read his prev. stored data
|
||||
node = new TomP2PNode(keyPairOtherPeer, otherPeer);
|
||||
futureGet = node.getDomainProtectedData(locationKey, keyPairOtherPeer.getPublic());
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertEquals("otherPeer data", futureGet.data().object());
|
||||
|
||||
// he can read clients data
|
||||
futureGet = node.getDomainProtectedData(locationKey, keyPairClient.getPublic());
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
assertEquals("client data", futureGet.data().object());
|
||||
|
||||
master.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeEntryProtectionKey() throws Exception {
|
||||
KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
|
||||
|
||||
KeyPair keyPair1 = gen.generateKeyPair();
|
||||
KeyPair keyPair2 = gen.generateKeyPair();
|
||||
PeerDHT p1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(1)).ports(4838)
|
||||
.keyPair(keyPair1).start()).start();
|
||||
PeerDHT p2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash(2)).ports(4839)
|
||||
.keyPair(keyPair2).start()).start();
|
||||
|
||||
p2.peer().bootstrap().peerAddress(p1.peerAddress()).start().awaitUninterruptibly();
|
||||
p1.peer().bootstrap().peerAddress(p2.peerAddress()).start().awaitUninterruptibly();
|
||||
|
||||
Data data = new Data("test").protectEntry(keyPair1);
|
||||
FuturePut fp1 = p1.put(Number160.createHash("key1")).sign().data(data).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fp1.isSuccess());
|
||||
FuturePut fp2 = p2.put(Number160.createHash("key1")).data(data).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(!fp2.isSuccess());
|
||||
|
||||
Data data2 = new Data().protectEntry(keyPair2);
|
||||
data2.publicKey(keyPair2.getPublic());
|
||||
FuturePut fp3 =
|
||||
p1.put(Number160.createHash("key1")).sign().putMeta().data(data2).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fp3.isSuccess());
|
||||
|
||||
FuturePut fp4 = p2.put(Number160.createHash("key1")).sign().data(data).start().awaitUninterruptibly();
|
||||
Assert.assertTrue(fp4.isSuccess());
|
||||
|
||||
p1.shutdown().awaitUninterruptibly();
|
||||
p2.shutdown().awaitUninterruptibly();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAddToListGetList() throws Exception {
|
||||
|
||||
PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, new Ports().tcpPort());
|
||||
PeerDHT master = peers[0];
|
||||
PeerDHT client = peers[1];
|
||||
PeerDHT otherPeer = peers[2];
|
||||
UtilsDHT2.perfectRouting(peers);
|
||||
|
||||
TomP2PNode node;
|
||||
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
|
||||
keyGen.initialize(1024);
|
||||
KeyPair keyPairClient = keyGen.genKeyPair();
|
||||
KeyPair keyPairOtherPeer = keyGen.genKeyPair();
|
||||
|
||||
Number160 locationKey;
|
||||
Data data;
|
||||
FuturePut futurePut;
|
||||
FutureGet futureGet;
|
||||
|
||||
// client add a value
|
||||
|
||||
KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
|
||||
KeyPair keyPair1 = gen.generateKeyPair();
|
||||
keyPairClient = keyPair1;
|
||||
|
||||
node = new TomP2PNode(keyPairClient, client);
|
||||
locationKey = Number160.createHash("add to list clients location");
|
||||
data = new Data("add to list client data1");
|
||||
Data data_1 = data;
|
||||
futurePut = node.addProtectedData(locationKey, data);
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertTrue(futurePut.isSuccess());
|
||||
|
||||
data = new Data("add to list client data2");
|
||||
Data data_2 = data;
|
||||
futurePut = node.addProtectedData(locationKey, data);
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertTrue(futurePut.isSuccess());
|
||||
|
||||
futureGet = node.getDataMap(locationKey);
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
boolean foundData1 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data1");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
boolean foundData2 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data2");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
assertTrue(foundData1);
|
||||
assertTrue(foundData2);
|
||||
assertEquals(2, futureGet.dataMap().values().size());
|
||||
|
||||
|
||||
// other peer tried to overwrite that entry
|
||||
// but will not succeed, instead he will add a new entry.
|
||||
// TODO investigate why it is not possible to overwrite the entry with that method
|
||||
// The protection entry with the key does not make any difference as also the client himself cannot overwrite
|
||||
// any entry
|
||||
// http://tomp2p.net/doc/P2P-with-TomP2P-1.pdf
|
||||
// "add(location_key, value) is translated to put(location_key, hash(value), value)"
|
||||
|
||||
// fake content key with content key from previous clients entry
|
||||
Number160 contentKey = Number160.createHash("add to list client data1");
|
||||
|
||||
data = new Data("add to list other peer data HACK!");
|
||||
data.protectEntry(keyPairOtherPeer); // also with client key it does not work...
|
||||
futurePut = otherPeer.put(locationKey).data(contentKey, data).keyPair(keyPairOtherPeer).start();
|
||||
futurePut.awaitUninterruptibly();
|
||||
assertTrue(futurePut.isSuccess());
|
||||
|
||||
node = new TomP2PNode(keyPairOtherPeer, otherPeer);
|
||||
futureGet = node.getDataMap(locationKey);
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
|
||||
foundData1 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data1");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
foundData2 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data2");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
boolean foundData3 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list other peer data HACK!");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
assertTrue(foundData1);
|
||||
assertTrue(foundData2);
|
||||
assertTrue(foundData3);
|
||||
assertEquals(3, futureGet.dataMap().values().size());
|
||||
|
||||
|
||||
// client removes his entry -> OK
|
||||
node = new TomP2PNode(keyPairClient, client);
|
||||
FutureRemove futureRemove = node.removeFromDataMap(locationKey, data_1);
|
||||
futureRemove.awaitUninterruptibly();
|
||||
|
||||
// We don't test futureRemove.isSuccess() as this API does not fit well to that operation,
|
||||
// it might change in future to something like foundAndRemoved and notFound
|
||||
// See discussion at: https://github.com/tomp2p/TomP2P/issues/57#issuecomment-62069840
|
||||
|
||||
|
||||
futureGet = node.getDataMap(locationKey);
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
|
||||
foundData1 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data1");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
foundData2 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data2");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
foundData3 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list other peer data HACK!");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
assertFalse(foundData1);
|
||||
assertTrue(foundData2);
|
||||
assertTrue(foundData3);
|
||||
assertEquals(2, futureGet.dataMap().values().size());
|
||||
|
||||
|
||||
// otherPeer tries to removes client entry -> FAIL
|
||||
node = new TomP2PNode(keyPairOtherPeer, otherPeer);
|
||||
futureRemove = node.removeFromDataMap(locationKey, data_2);
|
||||
futureRemove.awaitUninterruptibly();
|
||||
assertFalse(futureRemove.isSuccess());
|
||||
|
||||
futureGet = node.getDataMap(locationKey);
|
||||
futureGet.awaitUninterruptibly();
|
||||
assertTrue(futureGet.isSuccess());
|
||||
|
||||
foundData1 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data1");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
foundData2 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list client data2");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
foundData3 = futureGet.dataMap().values().stream().anyMatch(data1 -> {
|
||||
try {
|
||||
return data1.object().equals("add to list other peer data HACK!");
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
assertFalse(foundData1);
|
||||
assertTrue(foundData2);
|
||||
assertTrue(foundData3);
|
||||
assertEquals(2, futureGet.dataMap().values().size());
|
||||
|
||||
master.shutdown();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.network.tomp2p;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TomP2PPeerTest {
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
TomP2PPeer peer = new TomP2PPeer(null);
|
||||
assertThat(peer.toString(), equalTo("TomP2PPeer{peerAddress=null}"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.placeoffer;
|
||||
|
||||
import io.bitsquare.arbitrator.Arbitrator;
|
||||
import io.bitsquare.bank.BankAccountType;
|
||||
import io.bitsquare.btc.BitcoinNetwork;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.btc.UserAgent;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.locale.CountryUtil;
|
||||
import io.bitsquare.locale.LanguageUtil;
|
||||
import io.bitsquare.network.BootstrapState;
|
||||
import io.bitsquare.network.Node;
|
||||
import io.bitsquare.network.tomp2p.BootstrappedPeerBuilder;
|
||||
import io.bitsquare.network.tomp2p.TomP2PNode;
|
||||
import io.bitsquare.offer.Direction;
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.offer.OfferBookService;
|
||||
import io.bitsquare.offer.tomp2p.TomP2POfferBookService;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.tomp2p.TomP2PTradeMessageService;
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.util.DSAKeyUtil;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.utils.Threading;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Currency;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
* That test is ignored for automated testing as it needs custom setup.
|
||||
* <p/>
|
||||
* It uses RegTest mode of Bitcoin network and localhost TomP2P network.
|
||||
* <p/>
|
||||
* 1. Need a first run to get the wallet receiving address.
|
||||
* 2. Fund that from regtest Bitcoin Core client.
|
||||
* 3. Create a block on regtest Bitcoin Core (setgenerate true) to get the balance.
|
||||
* 4. Start BootstrapNodeMain at localhost with program args: --node.name localhost
|
||||
*/
|
||||
@Ignore
|
||||
public class PlaceOfferProtocolTest {
|
||||
private static final Logger log = LoggerFactory.getLogger(PlaceOfferProtocolTest.class);
|
||||
|
||||
private WalletService walletService;
|
||||
private TradeMessageService tradeMessageService;
|
||||
private OfferBookService offerBookService;
|
||||
private final File dir = new File("./temp");
|
||||
private final static String OFFER_ID = "offerID";
|
||||
private Address address;
|
||||
private TomP2PNode tomP2PNode;
|
||||
private BootstrappedPeerBuilder bootstrappedPeerBuilder;
|
||||
|
||||
@Before
|
||||
public void setup() throws InterruptedException {
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
dir.mkdirs();
|
||||
|
||||
Persistence persistence = new Persistence(dir, "prefs");
|
||||
persistence.init();
|
||||
|
||||
// messageService
|
||||
Node bootstrapNode = Node.at("localhost", "127.0.0.1");
|
||||
User user = new User();
|
||||
user.applyPersistedUser(null);
|
||||
bootstrappedPeerBuilder = new BootstrappedPeerBuilder(Node.DEFAULT_PORT, false, bootstrapNode, "<unspecified>");
|
||||
tomP2PNode = new TomP2PNode(bootstrappedPeerBuilder);
|
||||
tradeMessageService = new TomP2PTradeMessageService(user, tomP2PNode);
|
||||
|
||||
Observable<BootstrapState> messageObservable = tomP2PNode.bootstrap(user.getMessageKeyPair(), tradeMessageService);
|
||||
messageObservable.publish();
|
||||
messageObservable.subscribe(
|
||||
state -> log.trace("state changed: " + state),
|
||||
error -> {
|
||||
log.error(error.toString());
|
||||
},
|
||||
() -> {
|
||||
log.trace("message completed");
|
||||
|
||||
offerBookService = new TomP2POfferBookService(tomP2PNode);
|
||||
offerBookService.setExecutor(Threading.SAME_THREAD);
|
||||
}
|
||||
);
|
||||
bootstrappedPeerBuilder.start();
|
||||
|
||||
// WalletService
|
||||
walletService = new WalletService(BitcoinNetwork.REGTEST,
|
||||
new FeePolicy(BitcoinNetwork.REGTEST),
|
||||
null,
|
||||
persistence,
|
||||
new UserAgent("", ""),
|
||||
dir,
|
||||
"Tests"
|
||||
);
|
||||
|
||||
Observable<Object> walletServiceObservable = walletService.initialize(Threading.SAME_THREAD);
|
||||
walletServiceObservable.subscribe(
|
||||
next -> {
|
||||
// log.trace("wallet next");
|
||||
},
|
||||
error -> {
|
||||
log.trace("wallet error");
|
||||
},
|
||||
() -> {
|
||||
log.trace("wallet complete");
|
||||
});
|
||||
|
||||
Observable<?> allTasks = Observable.merge(messageObservable, walletServiceObservable);
|
||||
allTasks.subscribe(
|
||||
next -> {
|
||||
//log.trace("next");
|
||||
},
|
||||
error -> log.error(error.toString()),
|
||||
() -> {
|
||||
log.trace("wallet completed");
|
||||
// 1. Use that address for funding the trading wallet
|
||||
address = walletService.getAddressInfoByTradeID(OFFER_ID).getAddress();
|
||||
log.info("address for funding wallet = " + address.toString());//muoTvFHJmQwPKYoA8Fr7t87UCSfZM4fciG
|
||||
log.info("Balance = " + walletService.getBalanceForAddress(address));
|
||||
countDownLatch.countDown();
|
||||
});
|
||||
|
||||
countDownLatch.await();
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutDown() throws IOException, InterruptedException {
|
||||
walletService.shutDown();
|
||||
bootstrappedPeerBuilder.shutDown();
|
||||
}
|
||||
|
||||
/* @Test
|
||||
public void validateOfferTest() throws InterruptedException {
|
||||
try {
|
||||
Offer offer = getOffer();
|
||||
getCreateOfferCoordinator(offer).validateOffer();
|
||||
assertTrue(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createOfferFeeTxTest() throws InterruptedException {
|
||||
try {
|
||||
Offer offer = getOffer();
|
||||
Transaction transaction = getCreateOfferCoordinator(offer).createOfferFeeTx();
|
||||
assertNotNull(transaction);
|
||||
} catch (Exception e) {
|
||||
log.info("address for funding wallet = " + address.toString());
|
||||
log.info("Balance = " + walletService.getBalanceForAddress(address));
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void broadcastCreateOfferFeeTxTest() throws InterruptedException {
|
||||
try {
|
||||
log.info("Balance pre = " + walletService.getBalanceForAddress(address));
|
||||
Offer offer = getOffer();
|
||||
TransactionResultHandler resultHandler = transaction -> assertNotNull(transaction);
|
||||
FaultHandler faultHandler = (message, throwable) -> {
|
||||
log.error(message);
|
||||
throwable.printStackTrace();
|
||||
fail(throwable.getMessage());
|
||||
};
|
||||
PlaceOfferProtocol placeOfferProtocol = getCreateOfferCoordinator(offer);
|
||||
Transaction transaction = placeOfferProtocol.createOfferFeeTx();
|
||||
placeOfferProtocol.broadcastCreateOfferFeeTx(transaction, resultHandler, faultHandler);
|
||||
log.info("Balance post = " + walletService.getBalanceForAddress(address));
|
||||
|
||||
} catch (Exception e) {
|
||||
log.info("address for funding wallet = " + address.toString());
|
||||
log.info("Balance = " + walletService.getBalanceForAddress(address));
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addOfferTest() throws InterruptedException {
|
||||
CountDownLatch countDownLatch = new CountDownLatch(2);
|
||||
try {
|
||||
Offer offer = getOffer();
|
||||
offerBookService.addListener(new OfferBookService.Listener() {
|
||||
@Override
|
||||
public void onOfferAdded(Offer offer1) {
|
||||
assertEquals("Offer matching", offer.getId(), offer1.getId());
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffersReceived(List<Offer> offers) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOfferRemoved(Offer offer) {
|
||||
}
|
||||
});
|
||||
|
||||
TransactionResultHandler resultHandler = transaction -> {
|
||||
assertNotNull(transaction);
|
||||
countDownLatch.countDown();
|
||||
};
|
||||
FaultHandler faultHandler = (message, throwable) -> {
|
||||
log.error(message);
|
||||
throwable.printStackTrace();
|
||||
fail(throwable.getMessage());
|
||||
countDownLatch.countDown();
|
||||
countDownLatch.countDown();
|
||||
};
|
||||
PlaceOfferProtocol placeOfferProtocol = getPlaceOfferProtocol(offer, resultHandler, faultHandler);
|
||||
Transaction transaction = placeOfferProtocol.createOfferFeeTx();
|
||||
placeOfferProtocol.addOffer(transaction);
|
||||
countDownLatch.await();
|
||||
log.info("Finished");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
countDownLatch.countDown();
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void placeOfferTest() throws InterruptedException {
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
TransactionResultHandler resultHandler = transaction -> {
|
||||
assertNotNull(transaction);
|
||||
countDownLatch.countDown();
|
||||
};
|
||||
FaultHandler faultHandler = (message, throwable) -> {
|
||||
log.error(message);
|
||||
throwable.printStackTrace();
|
||||
fail(throwable.getMessage());
|
||||
countDownLatch.countDown();
|
||||
countDownLatch.countDown();
|
||||
};
|
||||
PlaceOfferProtocol placeOfferProtocol = getPlaceOfferProtocol(getOffer(), resultHandler, faultHandler);
|
||||
placeOfferProtocol.placeOffer();
|
||||
countDownLatch.await();
|
||||
}
|
||||
|
||||
|
||||
private PlaceOfferProtocol getCreateOfferCoordinator(Offer offer) throws InterruptedException {
|
||||
TransactionResultHandler resultHandler = transaction -> log.debug("result transaction=" + transaction.toString());
|
||||
FaultHandler faultHandler = (message, throwable) -> {
|
||||
log.error(message);
|
||||
throwable.printStackTrace();
|
||||
log.info("Balance = " + walletService.getBalanceForAddress(walletService.getAddressInfoByTradeID(OFFER_ID).getAddress()));
|
||||
};
|
||||
return getPlaceOfferProtocol(offer, resultHandler, faultHandler);
|
||||
}
|
||||
|
||||
private PlaceOfferProtocol getPlaceOfferProtocol(Offer offer, TransactionResultHandler resultHandler, FaultHandler faultHandler) throws
|
||||
InterruptedException {
|
||||
return new PlaceOfferProtocol(offer,
|
||||
walletService,
|
||||
offerBookService,
|
||||
resultHandler,
|
||||
faultHandler);
|
||||
}*/
|
||||
|
||||
private Offer getOffer() {
|
||||
return new Offer(OFFER_ID,
|
||||
DSAKeyUtil.generateKeyPair().getPublic(),
|
||||
Direction.BUY,
|
||||
100L,
|
||||
Coin.CENT,
|
||||
Coin.CENT,
|
||||
BankAccountType.INTERNATIONAL,
|
||||
Currency.getInstance("EUR"),
|
||||
CountryUtil.getDefaultCountry(),
|
||||
"bankAccountUID",
|
||||
Arrays.asList(new Arbitrator()),
|
||||
Coin.CENT,
|
||||
Arrays.asList(CountryUtil.getDefaultCountry()),
|
||||
Arrays.asList(LanguageUtil.getDefaultLanguageLocale())
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.placeoffer;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TaskRunner {
|
||||
private static final Logger log = LoggerFactory.getLogger(TaskRunner.class);
|
||||
|
||||
private Queue<Class> tasks;
|
||||
private SharedModel sharedModel = new SharedModel();
|
||||
private FaultHandler faultHandler;
|
||||
private ResultHandler taskCompleted;
|
||||
private final boolean[] failed = {false};
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
// Task1.run();
|
||||
//Task2.run();
|
||||
|
||||
tasks = new LinkedBlockingQueue<>();
|
||||
tasks.add(Task1.class);
|
||||
tasks.add(Task2.class);
|
||||
|
||||
faultHandler = (throwable) -> {
|
||||
log.debug(throwable.getMessage());
|
||||
failed[0] = true;
|
||||
};
|
||||
taskCompleted = () -> {
|
||||
next();
|
||||
};
|
||||
next();
|
||||
/* ResultHandler handleResult = () -> {
|
||||
Class task = tasks.poll();
|
||||
try {
|
||||
if (!failed[0])
|
||||
((Task) task.newInstance()).run(sharedModel, taskCompleted, faultHandler);
|
||||
} catch (InstantiationException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (IllegalAccessException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
};*/
|
||||
|
||||
|
||||
|
||||
/* tasks.stream().forEach((e) -> {
|
||||
try {
|
||||
((Task) e.newInstance()).run(sharedModel, faultHandler);
|
||||
} catch (InstantiationException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (IllegalAccessException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
private void next() {
|
||||
Class task = tasks.poll();
|
||||
if (task != null) {
|
||||
try {
|
||||
if (!failed[0])
|
||||
((Task) task.newInstance()).run(sharedModel, taskCompleted, faultHandler);
|
||||
} catch (InstantiationException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (IllegalAccessException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface ResultHandler {
|
||||
void handleResult();
|
||||
}
|
||||
|
||||
interface FaultHandler {
|
||||
void handleFault(Throwable throwable);
|
||||
}
|
||||
|
||||
class SharedModel {
|
||||
public int data = 42;
|
||||
}
|
||||
|
||||
class Task {
|
||||
|
||||
protected void run(SharedModel sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Task1 extends Task {
|
||||
private static final Logger log = LoggerFactory.getLogger(Task1.class);
|
||||
|
||||
@Override
|
||||
public void run(SharedModel sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
log.debug("run " + Task1.class);
|
||||
log.debug("data " + sharedModel.data);
|
||||
// faultHandler.handleFault(new Exception("test"));
|
||||
sharedModel.data++;
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
}
|
||||
|
||||
class Task2 extends Task {
|
||||
private static final Logger log = LoggerFactory.getLogger(Task2.class);
|
||||
|
||||
@Override
|
||||
public void run(SharedModel sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
log.debug("run " + Task2.class);
|
||||
log.debug("data " + sharedModel.data);
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
}
|
37
core/src/test/java/io/bitsquare/util/Repeat.java
Normal file
37
core/src/test/java/io/bitsquare/util/Repeat.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.util;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Method-level annotation to be used in connection with {@link RepeatRule} to cause a
|
||||
* given {@link org.junit.Test} method to be repeated a specified number of times.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Repeat {
|
||||
|
||||
/**
|
||||
* Specifies the number of times to repeat the annotated {@link org.junit.Test}.
|
||||
*/
|
||||
int value();
|
||||
}
|
57
core/src/test/java/io/bitsquare/util/RepeatRule.java
Normal file
57
core/src/test/java/io/bitsquare/util/RepeatRule.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.util;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
|
||||
/**
|
||||
* @see {@link Repeat}
|
||||
*/
|
||||
public class RepeatRule implements TestRule {
|
||||
|
||||
private static class RepeatStatement extends Statement {
|
||||
|
||||
private final int times;
|
||||
private final Statement statement;
|
||||
|
||||
private RepeatStatement(int times, Statement statement) {
|
||||
this.times = times;
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
for (int i = 0; i < times; i++) {
|
||||
statement.evaluate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement statement, Description description) {
|
||||
Statement result = statement;
|
||||
Repeat repeat = description.getAnnotation(Repeat.class);
|
||||
if (repeat != null) {
|
||||
int times = repeat.value();
|
||||
result = new RepeatStatement(times, statement);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
68
core/src/test/java/io/bitsquare/util/RepeatRuleTests.java
Normal file
68
core/src/test/java/io/bitsquare/util/RepeatRuleTests.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.util;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class RepeatRuleTests {
|
||||
|
||||
private static final int EXPECTED_COUNT = 10;
|
||||
private static int ACTUAL_BEFORE_COUNT;
|
||||
private static int ACTUAL_TEST_COUNT;
|
||||
private static int ACTUAL_AFTER_COUNT;
|
||||
|
||||
public @Rule RepeatRule repeatRule = new RepeatRule();
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeTests() {
|
||||
ACTUAL_BEFORE_COUNT = 0;
|
||||
ACTUAL_TEST_COUNT = 0;
|
||||
ACTUAL_AFTER_COUNT = 0;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ACTUAL_BEFORE_COUNT++;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Repeat(EXPECTED_COUNT)
|
||||
public void shouldBeRepeated() {
|
||||
ACTUAL_TEST_COUNT++;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ACTUAL_AFTER_COUNT++;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterTests() {
|
||||
assertThat(ACTUAL_BEFORE_COUNT, equalTo(EXPECTED_COUNT));
|
||||
assertThat(ACTUAL_TEST_COUNT, equalTo(EXPECTED_COUNT));
|
||||
assertThat(ACTUAL_AFTER_COUNT, equalTo(EXPECTED_COUNT));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<!--
|
||||
~ This file is part of Bitsquare.
|
||||
~
|
||||
~ Bitsquare is free software: you can redistribute it and/or modify it
|
||||
~ under the terms of the GNU Affero General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or (at
|
||||
~ your option) any later version.
|
||||
~
|
||||
~ Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
~ License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Affero General Public License
|
||||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<?import javafx.scene.layout.*?>
|
||||
<AnchorPane xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
</AnchorPane>
|
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
~ This file is part of Bitsquare.
|
||||
~
|
||||
~ Bitsquare is free software: you can redistribute it and/or modify it
|
||||
~ under the terms of the GNU Affero General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or (at
|
||||
~ your option) any later version.
|
||||
~
|
||||
~ Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
~ License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Affero General Public License
|
||||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import javafx.scene.layout.*?>
|
||||
<AnchorPane fx:id="root" fx:controller="io.bitsquare.viewfx.view.fxml.FxmlViewLoaderTests$MissingFxmlViewAnnotation"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
</AnchorPane>
|
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
~ This file is part of Bitsquare.
|
||||
~
|
||||
~ Bitsquare is free software: you can redistribute it and/or modify it
|
||||
~ under the terms of the GNU Affero General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or (at
|
||||
~ your option) any later version.
|
||||
~
|
||||
~ Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
~ License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU Affero General Public License
|
||||
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<?import javafx.scene.layout.*?>
|
||||
<AnchorPane fx:id="root" fx:controller="io.bitsquare.viewfx.view.fxml.FxmlViewLoaderTests$WellFormed"
|
||||
xmlns:fx="http://javafx.com/fxml">
|
||||
</AnchorPane>
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.viewfx.view.fxml;
|
||||
|
||||
import io.bitsquare.viewfx.ViewfxException;
|
||||
import io.bitsquare.viewfx.view.FxmlView;
|
||||
import io.bitsquare.viewfx.view.View;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import io.bitsquare.viewfx.view.ViewFactory;
|
||||
import io.bitsquare.viewfx.view.ViewLoader;
|
||||
import io.bitsquare.viewfx.view.AbstractView;
|
||||
|
||||
import javafx.fxml.LoadException;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class FxmlViewLoaderTests {
|
||||
|
||||
private ViewLoader viewLoader;
|
||||
private ViewFactory viewFactory;
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
viewFactory = mock(ViewFactory.class);
|
||||
ResourceBundle resourceBundle = mock(ResourceBundle.class);
|
||||
viewLoader = new FxmlViewLoader(viewFactory, resourceBundle);
|
||||
}
|
||||
|
||||
|
||||
@FxmlView
|
||||
static class WellFormed extends AbstractView {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wellFormedFxmlFileShouldSucceed() {
|
||||
given(viewFactory.call(WellFormed.class)).willReturn(new WellFormed());
|
||||
View view = viewLoader.load(WellFormed.class);
|
||||
assertThat(view, instanceOf(WellFormed.class));
|
||||
}
|
||||
|
||||
|
||||
@FxmlView
|
||||
static class MissingFxController extends AbstractView {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fxmlFileMissingFxControllerAttributeShouldThrow() {
|
||||
thrown.expect(ViewfxException.class);
|
||||
thrown.expectMessage("Does it declare an fx:controller attribute?");
|
||||
viewLoader.load(MissingFxController.class);
|
||||
}
|
||||
|
||||
|
||||
static class MissingFxmlViewAnnotation extends AbstractView {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fxmlViewAnnotationShouldBeOptional() {
|
||||
given(viewFactory.call(MissingFxmlViewAnnotation.class)).willReturn(new MissingFxmlViewAnnotation());
|
||||
View view = viewLoader.load(MissingFxmlViewAnnotation.class);
|
||||
assertThat(view, instanceOf(MissingFxmlViewAnnotation.class));
|
||||
}
|
||||
|
||||
|
||||
@FxmlView
|
||||
static class Malformed extends AbstractView {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void malformedFxmlFileShouldThrow() {
|
||||
thrown.expect(ViewfxException.class);
|
||||
thrown.expectMessage("Failed to load view from FXML file");
|
||||
thrown.expectCause(instanceOf(LoadException.class));
|
||||
viewLoader.load(Malformed.class);
|
||||
}
|
||||
|
||||
|
||||
@FxmlView
|
||||
static class MissingFxmlFile extends AbstractView {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingFxmlFileShouldThrow() {
|
||||
thrown.expect(ViewfxException.class);
|
||||
thrown.expectMessage("Does it exist?");
|
||||
viewLoader.load(MissingFxmlFile.class);
|
||||
}
|
||||
|
||||
|
||||
@FxmlView(location = "unconventionally/located.fxml")
|
||||
static class CustomLocation extends AbstractView {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customFxmlFileLocationShouldOverrideDefaultConvention() {
|
||||
thrown.expect(ViewfxException.class);
|
||||
thrown.expectMessage("Failed to load view class");
|
||||
thrown.expectMessage("CustomLocation");
|
||||
thrown.expectMessage("[unconventionally/located.fxml] could not be loaded");
|
||||
viewLoader.load(CustomLocation.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.viewfx.view.support;
|
||||
|
||||
import io.bitsquare.viewfx.view.AbstractView;
|
||||
import io.bitsquare.viewfx.view.CachingViewLoader;
|
||||
import io.bitsquare.viewfx.view.ViewLoader;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class CachingViewLoaderTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ViewLoader delegateViewLoader = mock(ViewLoader.class);
|
||||
|
||||
ViewLoader cachingViewLoader = new CachingViewLoader(delegateViewLoader);
|
||||
|
||||
cachingViewLoader.load(TestView1.class);
|
||||
cachingViewLoader.load(TestView1.class);
|
||||
cachingViewLoader.load(TestView2.class);
|
||||
|
||||
then(delegateViewLoader).should(times(1)).load(TestView1.class);
|
||||
then(delegateViewLoader).should(times(1)).load(TestView2.class);
|
||||
then(delegateViewLoader).should(times(0)).load(TestView3.class);
|
||||
}
|
||||
|
||||
|
||||
static class TestView1 extends AbstractView {
|
||||
}
|
||||
|
||||
static class TestView2 extends AbstractView {
|
||||
}
|
||||
|
||||
static class TestView3 extends AbstractView {
|
||||
}
|
||||
}
|
368
core/src/test/java/net/tomp2p/dht/UtilsDHT2.java
Normal file
368
core/src/test/java/net/tomp2p/dht/UtilsDHT2.java
Normal file
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* Copyright 2012 Thomas Bocek
|
||||
*
|
||||
* 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 net.tomp2p.dht;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Random;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.tomp2p.connection.Bindings;
|
||||
import net.tomp2p.futures.FutureBootstrap;
|
||||
import net.tomp2p.futures.FutureDiscover;
|
||||
import net.tomp2p.message.Message;
|
||||
import net.tomp2p.message.Message.Type;
|
||||
import net.tomp2p.p2p.AutomaticFuture;
|
||||
import net.tomp2p.p2p.Peer;
|
||||
import net.tomp2p.p2p.PeerBuilder;
|
||||
import net.tomp2p.peers.Number160;
|
||||
import net.tomp2p.peers.PeerAddress;
|
||||
import net.tomp2p.peers.PeerMap;
|
||||
import net.tomp2p.peers.PeerMapConfiguration;
|
||||
import net.tomp2p.peers.PeerSocketAddress;
|
||||
|
||||
public class UtilsDHT2 {
|
||||
/**
|
||||
* Used to make the testcases predictable. Used as an input for {@link Random}.
|
||||
*/
|
||||
public static final long THE_ANSWER = 42L;
|
||||
|
||||
/**
|
||||
* Having two peers in a network, the seed needs to be different, otherwise we create a peer with the same id twice.
|
||||
*/
|
||||
public static final long THE_ANSWER2 = 43L;
|
||||
|
||||
public static Message createDummyMessage() throws UnknownHostException {
|
||||
return createDummyMessage(false, false);
|
||||
}
|
||||
|
||||
public static Message createDummyMessage(boolean firewallUDP, boolean firewallTCP)
|
||||
throws UnknownHostException {
|
||||
return createDummyMessage(new Number160("0x4321"), "127.0.0.1", 8001, 8002, new Number160("0x1234"),
|
||||
"127.0.0.1", 8003, 8004, (byte) 0, Type.REQUEST_1, firewallUDP, firewallTCP);
|
||||
}
|
||||
|
||||
public static PeerAddress createAddress(Number160 id) throws UnknownHostException {
|
||||
return createAddress(id, "127.0.0.1", 8005, 8006, false, false);
|
||||
}
|
||||
|
||||
public static PeerAddress createAddress() throws UnknownHostException {
|
||||
return createAddress(new Number160("0x5678"), "127.0.0.1", 8005, 8006, false, false);
|
||||
}
|
||||
|
||||
public static PeerAddress createAddress(int id) throws UnknownHostException {
|
||||
return createAddress(new Number160(id), "127.0.0.1", 8005, 8006, false, false);
|
||||
}
|
||||
|
||||
public static PeerAddress createAddress(String id) throws UnknownHostException {
|
||||
return createAddress(new Number160(id), "127.0.0.1", 8005, 8006, false, false);
|
||||
}
|
||||
|
||||
public static PeerAddress createAddress(Number160 idSender, String inetSender, int tcpPortSender,
|
||||
int udpPortSender, boolean firewallUDP, boolean firewallTCP) throws UnknownHostException {
|
||||
InetAddress inetSend = InetAddress.getByName(inetSender);
|
||||
PeerSocketAddress peerSocketAddress = new PeerSocketAddress(inetSend, tcpPortSender, udpPortSender);
|
||||
PeerAddress n1 = new PeerAddress(idSender, peerSocketAddress, firewallTCP, firewallUDP, false, false, false,
|
||||
PeerAddress.EMPTY_PEER_SOCKET_ADDRESSES);
|
||||
return n1;
|
||||
}
|
||||
|
||||
public static Message createDummyMessage(Number160 idSender, String inetSender, int tcpPortSendor,
|
||||
int udpPortSender, Number160 idRecipien, String inetRecipient, int tcpPortRecipient,
|
||||
int udpPortRecipient, byte command, Type type, boolean firewallUDP, boolean firewallTCP)
|
||||
throws UnknownHostException {
|
||||
Message message = new Message();
|
||||
PeerAddress n1 = createAddress(idSender, inetSender, tcpPortSendor, udpPortSender, firewallUDP,
|
||||
firewallTCP);
|
||||
message.sender(n1);
|
||||
//
|
||||
PeerAddress n2 = createAddress(idRecipien, inetRecipient, tcpPortRecipient, udpPortRecipient,
|
||||
firewallUDP, firewallTCP);
|
||||
message.recipient(n2);
|
||||
message.type(type);
|
||||
message.command(command);
|
||||
return message;
|
||||
}
|
||||
|
||||
public static PeerDHT[] createNodes(int nrOfPeers, Random rnd, int port) throws Exception {
|
||||
return createNodes(nrOfPeers, rnd, port, null);
|
||||
}
|
||||
|
||||
public static PeerDHT[] createNodes(int nrOfPeers, Random rnd, int port, AutomaticFuture automaticFuture)
|
||||
throws Exception {
|
||||
return createNodes(nrOfPeers, rnd, port, automaticFuture, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates peers for testing. The first peer (peer[0]) will be used as the master. This means that shutting down
|
||||
* peer[0] will shut down all other peers
|
||||
*
|
||||
* @param nrOfPeers
|
||||
* The number of peers to create including the master
|
||||
* @param rnd
|
||||
* The random object to create random peer IDs
|
||||
* @param port
|
||||
* The port where the master peer will listen to
|
||||
* @return All the peers, with the master peer at position 0 -> peer[0]
|
||||
* @throws Exception
|
||||
* If the creation of nodes fail.
|
||||
*/
|
||||
public static PeerDHT[] createNodes(int nrOfPeers, Random rnd, int port, AutomaticFuture automaticFuture,
|
||||
boolean maintenance) throws Exception {
|
||||
if (nrOfPeers < 1) {
|
||||
throw new IllegalArgumentException("Cannot create less than 1 peer");
|
||||
}
|
||||
Bindings bindings = new Bindings();
|
||||
PeerDHT[] peers = new PeerDHT[nrOfPeers];
|
||||
final Peer master;
|
||||
if (automaticFuture != null) {
|
||||
Number160 peerId = new Number160(rnd);
|
||||
PeerMap peerMap = new PeerMap(new PeerMapConfiguration(peerId));
|
||||
master = new PeerBuilder(peerId)
|
||||
.ports(port).enableMaintenance(maintenance)
|
||||
.bindings(bindings).peerMap(peerMap).start().addAutomaticFuture(automaticFuture);
|
||||
peers[0] = new PeerBuilderDHT(master).start();
|
||||
|
||||
}
|
||||
else {
|
||||
Number160 peerId = new Number160(rnd);
|
||||
PeerMap peerMap = new PeerMap(new PeerMapConfiguration(peerId));
|
||||
master = new PeerBuilder(peerId).enableMaintenance(maintenance).bindings(bindings)
|
||||
.peerMap(peerMap).ports(port).start();
|
||||
peers[0] = new PeerBuilderDHT(master).start();
|
||||
}
|
||||
|
||||
for (int i = 1; i < nrOfPeers; i++) {
|
||||
if (automaticFuture != null) {
|
||||
Number160 peerId = new Number160(rnd);
|
||||
PeerMap peerMap = new PeerMap(new PeerMapConfiguration(peerId));
|
||||
Peer peer = new PeerBuilder(peerId)
|
||||
.masterPeer(master)
|
||||
.enableMaintenance(maintenance).enableMaintenance(maintenance).peerMap(peerMap).bindings(bindings).start().addAutomaticFuture
|
||||
(automaticFuture);
|
||||
peers[i] = new PeerBuilderDHT(peer).start();
|
||||
}
|
||||
else {
|
||||
Number160 peerId = new Number160(rnd);
|
||||
PeerMap peerMap = new PeerMap(new PeerMapConfiguration(peerId).peerNoVerification());
|
||||
Peer peer = new PeerBuilder(peerId).enableMaintenance(maintenance)
|
||||
.bindings(bindings).peerMap(peerMap).masterPeer(master)
|
||||
.start();
|
||||
peers[i] = new PeerBuilderDHT(peer).start();
|
||||
}
|
||||
}
|
||||
System.err.println("peers created.");
|
||||
return peers;
|
||||
}
|
||||
|
||||
public static Peer[] createRealNodes(int nrOfPeers, Random rnd, int startPort,
|
||||
AutomaticFuture automaticFuture) throws Exception {
|
||||
if (nrOfPeers < 1) {
|
||||
throw new IllegalArgumentException("Cannot create less than 1 peer");
|
||||
}
|
||||
Peer[] peers = new Peer[nrOfPeers];
|
||||
for (int i = 0; i < nrOfPeers; i++) {
|
||||
peers[i] = new PeerBuilder(new Number160(rnd))
|
||||
.ports(startPort + i).start().addAutomaticFuture(automaticFuture);
|
||||
}
|
||||
System.err.println("real peers created.");
|
||||
return peers;
|
||||
}
|
||||
|
||||
public static Peer[] createNonMaintenanceNodes(int nrOfPeers, Random rnd, int port) throws IOException {
|
||||
if (nrOfPeers < 1) {
|
||||
throw new IllegalArgumentException("Cannot create less than 1 peer");
|
||||
}
|
||||
Peer[] peers = new Peer[nrOfPeers];
|
||||
peers[0] = new PeerBuilder(new Number160(rnd)).enableMaintenance(false).ports(port).start();
|
||||
for (int i = 1; i < nrOfPeers; i++) {
|
||||
peers[i] = new PeerBuilder(new Number160(rnd)).enableMaintenance(false).masterPeer(peers[0])
|
||||
.start();
|
||||
}
|
||||
System.err.println("non-maintenance peers created.");
|
||||
return peers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perfect routing, where each neighbor has contacted each other. This means that for small number of peers, every
|
||||
* peer knows every other peer.
|
||||
*
|
||||
* @param peers
|
||||
* The peers taking part in the p2p network.
|
||||
*/
|
||||
public static void perfectRouting(PeerDHT... peers) {
|
||||
for (int i = 0; i < peers.length; i++) {
|
||||
for (int j = 0; j < peers.length; j++)
|
||||
peers[i].peer().peerBean().peerMap().peerFound(peers[j].peer().peerAddress(), null, null, null);
|
||||
}
|
||||
System.err.println("perfect routing done.");
|
||||
}
|
||||
|
||||
public static void perfectRoutingIndirect(PeerDHT... peers) {
|
||||
for (int i = 0; i < peers.length; i++) {
|
||||
for (int j = 0; j < peers.length; j++)
|
||||
peers[i].peerBean().peerMap().peerFound(peers[j].peerAddress(), peers[j].peerAddress(), null, null);
|
||||
}
|
||||
System.err.println("perfect routing done.");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
createTempDirectory();
|
||||
}
|
||||
|
||||
private static final int TEMP_DIR_ATTEMPTS = 10000;
|
||||
|
||||
public static File createTempDirectory() throws IOException {
|
||||
File baseDir = new File(System.getProperty("java.io.tmpdir"));
|
||||
String baseName = System.currentTimeMillis() + "-";
|
||||
|
||||
for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
|
||||
File tempDir = new File(baseDir, baseName + counter);
|
||||
if (tempDir.mkdir()) {
|
||||
return tempDir;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Failed to create directory within " + TEMP_DIR_ATTEMPTS
|
||||
+ " attempts (tried " + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
|
||||
}
|
||||
|
||||
public static Peer[] createAndAttachNodes(int nr, int port, Random rnd) throws Exception {
|
||||
Peer[] peers = new Peer[nr];
|
||||
for (int i = 0; i < nr; i++) {
|
||||
if (i == 0) {
|
||||
peers[0] = new PeerBuilder(new Number160(rnd)).ports(port).start();
|
||||
}
|
||||
else {
|
||||
peers[i] = new PeerBuilder(new Number160(rnd)).masterPeer(peers[0]).start();
|
||||
}
|
||||
}
|
||||
return peers;
|
||||
}
|
||||
|
||||
public static void bootstrap(Peer[] peers) {
|
||||
List<FutureBootstrap> futures1 = new ArrayList<FutureBootstrap>();
|
||||
List<FutureDiscover> futures2 = new ArrayList<FutureDiscover>();
|
||||
for (int i = 1; i < peers.length; i++) {
|
||||
FutureDiscover tmp = peers[i].discover().peerAddress(peers[0].peerAddress()).start();
|
||||
futures2.add(tmp);
|
||||
}
|
||||
for (FutureDiscover future : futures2) {
|
||||
future.awaitUninterruptibly();
|
||||
}
|
||||
for (int i = 1; i < peers.length; i++) {
|
||||
FutureBootstrap tmp = peers[i].bootstrap().peerAddress(peers[0].peerAddress()).start();
|
||||
futures1.add(tmp);
|
||||
}
|
||||
for (int i = 1; i < peers.length; i++) {
|
||||
FutureBootstrap tmp = peers[0].bootstrap().peerAddress(peers[i].peerAddress()).start();
|
||||
futures1.add(tmp);
|
||||
}
|
||||
for (FutureBootstrap future : futures1)
|
||||
future.awaitUninterruptibly();
|
||||
}
|
||||
|
||||
public static void routing(Number160 key, Peer[] peers, int start) {
|
||||
System.out.println("routing: searching for key " + key);
|
||||
NavigableSet<PeerAddress> pa1 = new TreeSet<PeerAddress>(PeerMap.createXORAddressComparator(key));
|
||||
NavigableSet<PeerAddress> queried = new TreeSet<PeerAddress>(PeerMap.createXORAddressComparator(key));
|
||||
Number160 result = Number160.ZERO;
|
||||
Number160 resultPeer = new Number160("0xd75d1a3d57841fbc9e2a3d175d6a35dc2e15b9f");
|
||||
int round = 0;
|
||||
while (!resultPeer.equals(result)) {
|
||||
System.out.println("round " + round);
|
||||
round++;
|
||||
pa1.addAll(peers[start].peerBean().peerMap().all());
|
||||
queried.add(peers[start].peerAddress());
|
||||
System.out.println("closest so far: " + queried.first());
|
||||
PeerAddress next = pa1.pollFirst();
|
||||
while (queried.contains(next)) {
|
||||
next = pa1.pollFirst();
|
||||
}
|
||||
result = next.peerId();
|
||||
start = findNr(next.peerId().toString(), peers);
|
||||
}
|
||||
}
|
||||
|
||||
public static void findInMap(PeerAddress key, Peer[] peers) {
|
||||
for (int i = 0; i < peers.length; i++) {
|
||||
if (peers[i].peerBean().peerMap().contains(key)) {
|
||||
System.out.println("Peer " + i + " with the id " + peers[i].peerID() + " knows the peer "
|
||||
+ key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int findNr(String string, Peer[] peers) {
|
||||
for (int i = 0; i < peers.length; i++) {
|
||||
if (peers[i].peerID().equals(new Number160(string))) {
|
||||
System.out.println("we found the number " + i + " for peer with id " + string);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static Peer find(String string, Peer[] peers) {
|
||||
for (int i = 0; i < peers.length; i++) {
|
||||
if (peers[i].peerID().equals(new Number160(string))) {
|
||||
System.out.println("!!we found the number " + i + " for peer with id " + string);
|
||||
return peers[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void exec(String cmd) throws Exception {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
p.waitFor();
|
||||
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
String line = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
System.out.println(line);
|
||||
}
|
||||
br.close();
|
||||
}
|
||||
|
||||
public static PeerAddress createAddressIP(String inet) throws UnknownHostException {
|
||||
return createAddress(Number160.createHash(inet), inet, 8005, 8006, false, false);
|
||||
}
|
||||
|
||||
public static PeerAddress[] createDummyAddress(int size, int portTCP, int portUDP) throws UnknownHostException {
|
||||
PeerAddress[] pa = new PeerAddress[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
pa[i] = createAddress(i + 1, portTCP, portUDP);
|
||||
}
|
||||
return pa;
|
||||
}
|
||||
|
||||
public static PeerAddress createAddress(int iid, int portTCP, int portUDP) throws UnknownHostException {
|
||||
Number160 id = new Number160(iid);
|
||||
InetAddress address = InetAddress.getByName("127.0.0.1");
|
||||
return new PeerAddress(id, address, portTCP, portUDP);
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue