예제 #1
0
async def test_install_all_tentacles_with_profile(clean):
    _enable_loggers()
    profile_path = os.path.join(commons_constants.USER_PROFILES_FOLDER, "many_traded_elements")
    assert not os.path.isfile(os.path.join(profile_path, commons_constants.PROFILE_CONFIG_FILE))
    tentacles_path = os.path.join("tests", "static", "tentacles_with_profile.zip")
    await fetch_and_extract_tentacles(TEMP_DIR, tentacles_path, None)
    worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH, False, None)
    worker.tentacles_path_or_url = tentacles_path
    worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    assert await worker.process() == 0

    # test installed files to ensure tentacles installation got well
    trading_mode_files_count = sum(1 for _ in os.walk(os.path.join(TENTACLES_PATH, "Trading", "Mode")))
    assert trading_mode_files_count == 5
    config_files = [f for f in os.walk(os.path.join(profile_path, TENTACLES_SPECIFIC_CONFIG_FOLDER))]
    config_files_count = len(config_files)
    assert config_files_count == 1
    assert "DailyTradingMode.json" in config_files[0][2]
    assert len(config_files[0][2]) == 18

    # test installed profile
    assert os.path.isfile(os.path.join(profile_path, commons_constants.PROFILE_CONFIG_FILE))
    assert os.path.isfile(os.path.join(profile_path, "default_profile.png"))
    assert os.path.isfile(os.path.join(profile_path, commons_constants.CONFIG_TENTACLES_FILE))
    assert os.path.isfile(os.path.join(profile_path, TENTACLES_SPECIFIC_CONFIG_FOLDER, "DailyTradingMode.json"))
    assert os.path.isfile(os.path.join(profile_path, TENTACLES_SPECIFIC_CONFIG_FOLDER, "TwitterNewsEvaluator.json"))
async def test_uninstall_all_tentacles(clean):
    _enable_loggers()
    tentacles_path = os.path.join("tests", "static", "tentacles.zip")
    await fetch_and_extract_tentacles(TEMP_DIR, tentacles_path, None)
    install_worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                   False, None)
    install_worker.tentacles_path_or_url = tentacles_path
    install_worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    assert await install_worker.process() == 0
    tentacles_files_count = sum(1 for _ in os.walk(TENTACLES_PATH))
    assert tentacles_files_count > 60

    uninstall_worker = UninstallWorker(None, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                       False, None)
    uninstall_worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    assert await uninstall_worker.process() == 0
    tentacles_files_count = sum(1 for _ in os.walk(TENTACLES_PATH))
    assert tentacles_files_count == 24
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH, "r") as config_f:
        assert json.load(config_f) == {
            'registered_tentacles': {},
            'tentacle_activation': {
                'Backtesting': {},
                'Evaluator': {},
                'Services': {},
                'Trading': {}
            }
        }
예제 #3
0
async def test_profiles_update(clean, fake_profiles):
    _enable_loggers()
    tentacles_path = os.path.join("tests", "static", "tentacles.zip")
    await fetch_and_extract_tentacles(TEMP_DIR, tentacles_path, None)
    worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH, False,
                           None)
    worker.tentacles_path_or_url = tentacles_path
    worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    # install all tentacles
    assert await worker.process() == 0

    # test tentacles setup config
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH) as config_f:
        ref_profile_config = json.load(config_f)

        # test profiles tentacles config
        with open(
                os.path.join(
                    commons_constants.USER_PROFILES_FOLDER,
                    commons_constants.DEFAULT_PROFILE,
                    commons_constants.CONFIG_TENTACLES_FILE)) as default_c:
            assert ref_profile_config == json.load(default_c)
        with open(
                os.path.join(
                    commons_constants.USER_PROFILES_FOLDER, OTHER_PROFILE,
                    commons_constants.CONFIG_TENTACLES_FILE)) as other_c:
            assert ref_profile_config == json.load(other_c)

    # test specific tentacles config
    default_profile_tentacles_config = os.path.join(
        commons_constants.USER_PROFILES_FOLDER,
        commons_constants.DEFAULT_PROFILE, TENTACLES_SPECIFIC_CONFIG_FOLDER)
    other_profile_tentacles_config = os.path.join(
        commons_constants.USER_PROFILES_FOLDER, OTHER_PROFILE,
        TENTACLES_SPECIFIC_CONFIG_FOLDER)
    for tentacle_config in os.scandir(
            os.path.join(
                os.path.split(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH)[0],
                TENTACLES_SPECIFIC_CONFIG_FOLDER)):
        with open(tentacle_config) as ref_config_file:
            ref_config = json.load(ref_config_file)
        with open(
                os.path.join(
                    default_profile_tentacles_config,
                    tentacle_config.name)) as default_profile_config_file:
            assert ref_config == json.load(default_profile_config_file)
        with open(
                os.path.join(
                    other_profile_tentacles_config,
                    tentacle_config.name)) as other_profile_config_file:
            assert ref_config == json.load(other_profile_config_file)
예제 #4
0
async def test_install_all_tentacles(clean):
    _enable_loggers()
    tentacles_path = os.path.join("tests", "static", "tentacles.zip")
    await fetch_and_extract_tentacles(TEMP_DIR, tentacles_path, None)
    worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH, False,
                           None)
    worker.tentacles_path_or_url = tentacles_path
    worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    assert await worker.process() == 0

    # test installed files
    trading_mode_files_count = sum(
        1 for _ in os.walk(os.path.join(TENTACLES_PATH, "Trading", "Mode")))
    assert trading_mode_files_count == 5
    config_files = [
        f for f in os.walk(USER_REFERENCE_TENTACLE_SPECIFIC_CONFIG_PATH)
    ]
    config_files_count = len(config_files)
    assert config_files_count == 1
    assert "DailyTradingMode.json" in config_files[0][2]
    assert len(config_files[0][2]) == 5

    # test tentacles config
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH, "r") as config_f:
        assert json.load(config_f) == {
            'registered_tentacles': {
                'OctoBot-Default-Tentacles': tentacles_path
            },
            'tentacle_activation': {
                'Backtesting': {
                    'GenericExchangeDataImporter': True
                },
                'Evaluator': {
                    'InstantFluctuationsEvaluator': True,
                    'OtherInstantFluctuationsEvaluator': False,
                    'OverallStateAnalyser': True,
                    'RedditForumEvaluator': False,
                    'SecondOtherInstantFluctuationsEvaluator': False,
                    'SimpleMixedStrategyEvaluator': True,
                    'TextAnalysis': True
                },
                'Services': {
                    'RedditService': True,
                    'RedditServiceFeed': True
                },
                'Trading': {
                    'DailyTradingMode': True
                }
            }
        }
예제 #5
0
async def test_uninstall_two_tentacles(clean):
    _enable_loggers()
    tentacles_path = os.path.join("tests", "static", "tentacles.zip")
    await fetch_and_extract_tentacles(TEMP_DIR, tentacles_path, None)
    install_worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                   False, None)
    install_worker.tentacles_path_or_url = tentacles_path
    install_worker.tentacles_setup_manager.default_tentacle_config \
        = os.path.join("tests", "static", "default_tentacle_config.json")
    assert await install_worker.process() == 0
    tentacles_files_count = sum(1 for _ in os.walk(TENTACLES_PATH))
    assert tentacles_files_count > 60

    uninstall_worker = UninstallWorker(None, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                       False, None)
    uninstall_worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    assert await uninstall_worker.process(
        ["instant_fluctuations_evaluator", "generic_exchange_importer"]) == 0
    tentacles_files_count = sum(1 for _ in os.walk(TENTACLES_PATH))
    assert tentacles_files_count < 60
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH, "r") as config_f:
        assert json.load(config_f) == {
            'installation_context': {
                'octobot_version': 'unknown'
            },
            'registered_tentacles': {
                'OctoBot-Default-Tentacles': tentacles_path
            },
            'tentacle_activation': {
                'Backtesting': {},
                'Evaluator': {
                    'OtherInstantFluctuationsEvaluator': False,
                    'OverallStateAnalyser': True,
                    'RedditForumEvaluator': False,
                    'SecondOtherInstantFluctuationsEvaluator': False,
                    'SimpleMixedStrategyEvaluator': True,
                    'TextAnalysis': True
                },
                'Services': {
                    'RedditService': True,
                    'RedditServiceFeed': True
                },
                'Trading': {
                    'DailyTradingMode': True
                }
            }
        }
예제 #6
0
async def test_update_all_tentacles(clean):
    _enable_loggers()
    await fetch_and_extract_tentacles(
        TEMP_DIR, path.join("tests", "static", "tentacles.zip"), None)
    install_worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                   False, None)
    install_worker.tentacles_setup_manager.default_tentacle_config = \
        path.join("tests", "static", "default_tentacle_config.json")
    await install_worker.process()
    rmtree(TEMP_DIR)
    await fetch_and_extract_tentacles(
        TEMP_DIR, path.join("tests", "static", "update_tentacles.zip"), None)
    update_worker = UpdateWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                 False, None)
    update_worker.tentacles_setup_manager.default_tentacle_config = \
        path.join("tests", "static", "default_tentacle_config.json")
    assert await update_worker.process() == 0

    # check updated versions
    factory = TentacleFactory(TENTACLES_PATH)
    from tentacles.Evaluator.RealTime import instant_fluctuations_evaluator
    ife_tentacle_data = await factory.create_and_load_tentacle_from_module(
        instant_fluctuations_evaluator)
    assert ife_tentacle_data.version == "1.3.0"
    import tentacles.Backtesting.importers.exchanges.generic_exchange_importer as gei
    gei_tentacle_data = await factory.create_and_load_tentacle_from_module(gei)
    # not updated because update version is "1.1.9"
    assert gei_tentacle_data.version == "1.2.0"
    import tentacles.Evaluator.Util.text_analysis
    ta_tentacle_data = await factory.create_and_load_tentacle_from_module(
        tentacles.Evaluator.Util.text_analysis)
    assert ta_tentacle_data.version == "1.3.0"
    import tentacles.Trading.Mode.daily_trading_mode as dtm
    dtm_tentacle_data = await factory.create_and_load_tentacle_from_module(dtm)
    assert dtm_tentacle_data.version == "1.3.0"
예제 #7
0
async def test_install_all_tentacles_fetching_requirements(clean):
    async with aiohttp.ClientSession() as session:
        _enable_loggers()
        await fetch_and_extract_tentacles(
            TEMP_DIR,
            os.path.join("tests", "static", "requirements_tentacles.zip"),
            None)
        worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                               False, session)
        worker.tentacles_setup_manager.default_tentacle_config = \
            os.path.join("tests", "static", "default_tentacle_config.json")
        assert await worker.process() == 0

    trading_mode_files_count = sum(
        1 for _ in os.walk(os.path.join(TENTACLES_PATH, "Trading", "Mode")))
    assert trading_mode_files_count == 5
    config_files = [
        f for f in os.walk(USER_REFERENCE_TENTACLE_SPECIFIC_CONFIG_PATH)
    ]
    config_files_count = len(config_files)
    assert config_files_count == 1
    # ensure fetched InstantFluctuationsEvaluator requirement
    assert "InstantFluctuationsEvaluator.json" in config_files[0][2]
    assert os.path.exists(
        os.path.join("tentacles", "Evaluator", "RealTime",
                     "instant_fluctuations_evaluator",
                     "instant_fluctuations.py"))
    assert len(config_files[0][2]) == 4
예제 #8
0
async def test_profiles_update(clean, fake_profiles):
    _enable_loggers()
    tentacles_path = os.path.join("tests", "static", "tentacles.zip")
    await fetch_and_extract_tentacles(TEMP_DIR, tentacles_path, None)
    install_worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                   False, None)
    install_worker.tentacles_path_or_url = tentacles_path
    install_worker.tentacles_setup_manager.default_tentacle_config \
        = os.path.join("tests", "static", "default_tentacle_config.json")
    assert await install_worker.process() == 0
    tentacles_files_count = sum(1 for _ in os.walk(TENTACLES_PATH))
    assert tentacles_files_count > 60

    ref_specific_tentacles_config = os.path.join(
        TENTACLES_PATH, TENTACLES_EVALUATOR_PATH,
        TENTACLES_EVALUATOR_REALTIME_PATH, "instant_fluctuations_evaluator",
        TENTACLE_CONFIG)
    with open(
            os.path.join(ref_specific_tentacles_config,
                         "InstantFluctuationsEvaluator.json")) as ref_conf:
        instant_fluct_config = json.load(ref_conf)

    uninstall_worker = UninstallWorker(None, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                       False, None)
    uninstall_worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    # uninstall 2 tentacles
    assert await uninstall_worker.process(
        ["instant_fluctuations_evaluator", "generic_exchange_importer"]) == 0

    # test tentacles setup config
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH) as config_f:
        ref_profile_config = json.load(config_f)

        # test profiles tentacles config
        with open(
                os.path.join(
                    commons_constants.USER_PROFILES_FOLDER,
                    commons_constants.DEFAULT_PROFILE,
                    commons_constants.CONFIG_TENTACLES_FILE)) as default_c:
            assert ref_profile_config == json.load(default_c)
        with open(
                os.path.join(
                    commons_constants.USER_PROFILES_FOLDER, OTHER_PROFILE,
                    commons_constants.CONFIG_TENTACLES_FILE)) as other_c:
            assert ref_profile_config == json.load(other_c)
예제 #9
0
async def test_install_all_tentacles_twice(clean):
    await fetch_and_extract_tentacles(TEMP_DIR, os.path.join("tests", "static", "tentacles.zip"), None)
    worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH, False, None)
    worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    assert await worker.process() == 0
    assert await worker.process() == 0
    trading_mode_files_count = sum(1 for _ in os.walk(os.path.join(TENTACLES_PATH, "Trading", "Mode")))
    assert trading_mode_files_count == 5
예제 #10
0
async def test_install_two_tentacles(clean):
    _enable_loggers()
    tentacles_path = os.path.join("tests", "static", "tentacles.zip")
    await fetch_and_extract_tentacles(TEMP_DIR, tentacles_path, None)
    worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH, False,
                           None)
    worker.tentacles_path_or_url = tentacles_path
    worker.tentacles_setup_manager.default_tentacle_config = \
        os.path.join("tests", "static", "default_tentacle_config.json")
    assert await worker.process(
        ["instant_fluctuations_evaluator", "generic_exchange_importer"]) == 0

    # test installed files
    trading_mode_files_count = sum(
        1 for _ in os.walk(os.path.join(TENTACLES_PATH, "Trading", "Mode")))
    assert trading_mode_files_count == 1
    backtesting_mode_files_count = sum(1 for _ in os.walk(
        os.path.join(TENTACLES_PATH, "Backtesting", "importers")))
    assert backtesting_mode_files_count == 7
    config_files = [
        f for f in os.walk(USER_REFERENCE_TENTACLE_SPECIFIC_CONFIG_PATH)
    ]
    config_files_count = len(config_files)
    assert config_files_count == 1
    assert "InstantFluctuationsEvaluator.json" in config_files[0][2]
    assert "DailyTradingMode.json" not in config_files[0][2]
    assert len(config_files[0][2]) == 1

    # test tentacles config
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH, "r") as config_f:
        ref_profile_config = json.load(config_f)
        assert ref_profile_config == {
            'registered_tentacles': {
                'OctoBot-Default-Tentacles': tentacles_path
            },
            'tentacle_activation': {
                'Backtesting': {
                    'GenericExchangeDataImporter': True
                },
                'Evaluator': {
                    'InstantFluctuationsEvaluator': True
                }
            }
        }
예제 #11
0
async def test_install_one_tentacle_with_requirement(clean):
    async with aiohttp.ClientSession() as session:
        _enable_loggers()
        await fetch_and_extract_tentacles(
            TEMP_DIR, os.path.join("tests", "static", "tentacles.zip"), None)
        worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                               False, session)
        worker.tentacles_setup_manager.default_tentacle_config = \
            os.path.join("tests", "static", "default_tentacle_config.json")
        assert await worker.process(["reddit_service_feed"]) == 0

    # test removed temporary requirements files
    assert not os.path.exists(TENTACLES_REQUIREMENTS_INSTALL_TEMP_DIR)

    # test installed files
    trading_mode_files_count = sum(
        1 for _ in os.walk(os.path.join(TENTACLES_PATH, "Trading", "Mode")))
    assert trading_mode_files_count == 1
    config_files = [
        f for f in os.walk(USER_REFERENCE_TENTACLE_SPECIFIC_CONFIG_PATH)
    ]
    assert len(config_files) == 1
    assert len(config_files[0][2]) == 0

    # test tentacles config
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH, "r") as config_f:
        assert json.load(config_f) == {
            'registered_tentacles': {
                'OctoBot-Default-Tentacles': UNKNOWN_TENTACLES_PACKAGE_LOCATION
            },
            'tentacle_activation': {
                'Services': {
                    'RedditService': True,
                    'RedditServiceFeed': True
                }
            }
        }
    assert os.path.exists(
        os.path.join("tentacles", "Services", "Services_bases",
                     "reddit_service", "reddit.py"))
예제 #12
0
async def test_update_two_tentacles(clean):
    _enable_loggers()
    await fetch_and_extract_tentacles(
        TEMP_DIR, path.join("tests", "static", "tentacles.zip"), None)
    install_worker = InstallWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                   False, None)
    install_worker.tentacles_setup_manager.default_tentacle_config = \
        path.join("tests", "static", "default_tentacle_config.json")
    await install_worker.process([
        "instant_fluctuations_evaluator", "generic_exchange_importer",
        "text_analysis"
    ])
    rmtree(TEMP_DIR)

    # edit instant_fluctuations_evaluator config to ensure file is not replaced
    config_path = path.join(USER_REFERENCE_TENTACLE_SPECIFIC_CONFIG_PATH,
                            "InstantFluctuationsEvaluator.json")
    with open(config_path, "r+") as config_f:
        new_content = f"{config_f.read()},"
        config_f.write(",")
    await fetch_and_extract_tentacles(
        TEMP_DIR, path.join("tests", "static", "update_tentacles.zip"), None)
    update_worker = UpdateWorker(TEMP_DIR, TENTACLES_PATH, DEFAULT_BOT_PATH,
                                 False, None)
    update_worker.tentacles_setup_manager.default_tentacle_config = \
        path.join("tests", "static", "default_tentacle_config.json")
    assert await update_worker.process(
        ["instant_fluctuations_evaluator", "generic_exchange_importer"]) == 0

    # ensure instant_fluctuations_evaluator file is not replaced
    with open(config_path, "r") as config_f:
        assert new_content == config_f.read()

    # test installed files
    trading_mode_files_count = sum(
        1 for _ in walk(path.join(TENTACLES_PATH, "Trading", "Mode")))
    assert trading_mode_files_count == 1
    backtesting_mode_files_count = sum(
        1 for _ in walk(path.join(TENTACLES_PATH, "Backtesting", "importers")))
    assert backtesting_mode_files_count == 7
    config_files = [
        f for f in walk(USER_REFERENCE_TENTACLE_SPECIFIC_CONFIG_PATH)
    ]
    config_files_count = len(config_files)
    assert config_files_count == 1
    assert "InstantFluctuationsEvaluator.json" in config_files[0][2]
    assert "DailyTradingMode.json" not in config_files[0][2]
    assert len(config_files[0][2]) == 1

    # test tentacles config
    with open(USER_REFERENCE_TENTACLE_CONFIG_FILE_PATH, "r") as config_f:
        assert json.load(config_f) == {
            'registered_tentacles': {
                'OctoBot-Default-Tentacles': UNKNOWN_TENTACLES_PACKAGE_LOCATION
            },
            'tentacle_activation': {
                'Backtesting': {
                    'GenericExchangeDataImporter': True
                },
                'Evaluator': {
                    'InstantFluctuationsEvaluator': True,
                    'TextAnalysis': True
                }
            }
        }

    # check updated versions
    factory = TentacleFactory("tentacles")
    from tentacles.Evaluator.RealTime import instant_fluctuations_evaluator
    ife_tentacle_data = await factory.create_and_load_tentacle_from_module(
        instant_fluctuations_evaluator)
    assert ife_tentacle_data.version == "1.3.0"
    # not updated because update version is "1.1.9"
    import tentacles.Backtesting.importers.exchanges.generic_exchange_importer as gei
    gei_tentacle_data = await factory.create_and_load_tentacle_from_module(gei)
    assert gei_tentacle_data.version == "1.2.0"
    import tentacles.Evaluator.Util.text_analysis
    ta_tentacle_data = await factory.create_and_load_tentacle_from_module(
        tentacles.Evaluator.Util.text_analysis)
    assert ta_tentacle_data.version == "1.2.0"
예제 #13
0
async def test_update_activation_configuration():
    _cleanup(False)
    await fetch_and_extract_tentacles(temp_dir,
                                      join("tests", "static", "tentacles.zip"),
                                      None)
    worker = InstallWorker(temp_dir, TENTACLES_PATH, DEFAULT_BOT_PATH, False,
                           None)
    worker.tentacles_setup_manager.default_tentacle_config = join(
        "tests", "static", "default_tentacle_config.json")
    assert await worker.process() == 0
    setup_config = get_tentacles_setup_config()
    default_activation = copy(get_tentacles_activation(setup_config))
    assert default_activation == {
        'Backtesting': {
            'GenericExchangeDataImporter': True
        },
        'Evaluator': {
            'InstantFluctuationsEvaluator': True,
            'OtherInstantFluctuationsEvaluator': False,
            'OverallStateAnalyser': True,
            'RedditForumEvaluator': False,
            'SecondOtherInstantFluctuationsEvaluator': False,
            'SimpleMixedStrategyEvaluator': True,
            'TextAnalysis': True
        },
        'Services': {
            'RedditService': True,
            'RedditServiceFeed': True
        },
        'Trading': {
            'DailyTradingMode': True
        }
    }
    # Did not add OtherTentacle since it is not in original activation
    assert update_activation_configuration(
        setup_config, {"OtherTentacle": True}, False) is False
    assert default_activation == get_tentacles_activation(setup_config)

    # No change
    assert update_activation_configuration(
        setup_config, {"InstantFluctuationsEvaluator": True}, False) is False
    assert default_activation == get_tentacles_activation(setup_config)

    # One change
    assert update_activation_configuration(
        setup_config, {"InstantFluctuationsEvaluator": False}, False) is True
    assert get_tentacles_activation(setup_config) == {
        'Backtesting': {
            'GenericExchangeDataImporter': True
        },
        'Evaluator': {
            'InstantFluctuationsEvaluator': False,
            'OtherInstantFluctuationsEvaluator': False,
            'OverallStateAnalyser': True,
            'RedditForumEvaluator': False,
            'SecondOtherInstantFluctuationsEvaluator': False,
            'SimpleMixedStrategyEvaluator': True,
            'TextAnalysis': True
        },
        'Services': {
            'RedditService': True,
            'RedditServiceFeed': True
        },
        'Trading': {
            'DailyTradingMode': True
        }
    }

    # Two changes
    assert update_activation_configuration(setup_config, {
        "InstantFluctuationsEvaluator": True,
        'RedditForumEvaluator': True
    }, False) is True
    assert get_tentacles_activation(setup_config) == {
        'Backtesting': {
            'GenericExchangeDataImporter': True
        },
        'Evaluator': {
            'InstantFluctuationsEvaluator': True,
            'OtherInstantFluctuationsEvaluator': False,
            'OverallStateAnalyser': True,
            'RedditForumEvaluator': True,
            'SecondOtherInstantFluctuationsEvaluator': False,
            'SimpleMixedStrategyEvaluator': True,
            'TextAnalysis': True
        },
        'Services': {
            'RedditService': True,
            'RedditServiceFeed': True
        },
        'Trading': {
            'DailyTradingMode': True
        }
    }

    # Two changes with deactivate others evaluators
    assert update_activation_configuration(setup_config, {
        "InstantFluctuationsEvaluator": True,
        'RedditForumEvaluator': True
    }, True) is False
    assert get_tentacles_activation(setup_config) == {
        'Backtesting': {
            'GenericExchangeDataImporter': True
        },
        'Evaluator': {
            'InstantFluctuationsEvaluator': True,
            'OtherInstantFluctuationsEvaluator': False,
            'OverallStateAnalyser': True,
            'RedditForumEvaluator': True,
            'SecondOtherInstantFluctuationsEvaluator': False,
            'SimpleMixedStrategyEvaluator': True,
            'TextAnalysis': True
        },
        'Services': {
            'RedditService': True,
            'RedditServiceFeed': True
        },
        'Trading': {
            'DailyTradingMode': True
        }
    }
    _cleanup()