<commit_before>require 'spec_helper'

module Bosh::Director::DeploymentPlan
  describe PlacementPlanner::StaticIpsAvailabilityZonePicker do
    include Bosh::Director::IpUtil

    subject(:zone_picker) { PlacementPlanner::StaticIpsAvailabilityZonePicker.new(instance_plan_factory, network_planner, job.networks, 'fake-job', availability_zones, logger) }
    let(:network_planner) { NetworkPlanner::Planner.new(logger) }
    let(:network_reservation_repository) { BD::DeploymentPlan::NetworkReservationRepository.new(planner, logger) }
    let(:planner) { planner_factory.create_from_manifest(manifest_hash, cloud_config_model, nil, {}) }
    let(:instance_plan_factory) { InstancePlanFactory.new(instance_repo, {}, SkipDrain.new(true), index_assigner, network_reservation_repository) }
    let(:index_assigner) { PlacementPlanner::IndexAssigner.new(deployment_model) }
    let!(:deployment_model) { Bosh::Director::Models::Deployment.make(manifest: YAML.dump(manifest_hash), name: manifest_hash['name']) }
    let(:instance_repo) { Bosh::Director::DeploymentPlan::InstanceRepository.new(network_reservation_repository, logger) }
    def make_subnet_spec(range, static_ips, zone_names)
      spec = {
        'range' => range,
        'gateway' => NetAddr::CIDR.create(range)[1].ip,
        'dns' => ['8.8.8.8'],
        'static' => static_ips,
        'reserved' => [],
        'cloud_properties' => {},
      }
      spec['azs'] = zone_names if zone_names
      spec
    end
    let(:networks_spec) do
      [
        {'name' => 'a',
          'subnets' => [
            make_subnet_spec('192.168.1.0/24', ['192.168.1.10 - 192.168.1.14'], ['zone1']),
            make_subnet_spec('192.168.2.0/24', ['192.168.2.10 - 192.168.2.14'], ['zone2']),
          ]
        },
        {'name' => 'b',
          'subnets' => [
            make_subnet_spec('10.10.1.0/24', ['10.10.1.10 - 10.10.1.14'], ['zone1']),
            make_subnet_spec('10.10.2.0/24', ['10.10.2.10 - 10.10.2.14'], ['zone2']),
          ]
        }
      ]
    end

    let(:cloud_config_hash) do
      {
        'networks' => networks_spec,
        'compilation' => {'workers' => 1, 'network' => 'a', 'cloud_properties' => {}, 'az' => cloud_config_availability_zones.first['name']},
        'resource_pools' => [
          {
            'name' => 'a',
            'size' => 3,
            'cloud_properties' => {},
            'network' => 'a',
            'stemcell' => {'name' => 'ubuntu-stemcell', 'version' => '1'}
          }
        ],
        'azs' => cloud_config_availability_zones}
    end
    let(:cloud_config_availability_zones) do
      [
        {'name' => 'zone1', 'cloud_properties' => {:foo => 'bar'}},
        {'name' => 'zone2', 'cloud_properties' => {:foo => 'baz'}}
      ]
    end
    let(:manifest_hash) do
      {
        'name' => 'simple',
        'director_uuid' => 'deadbeef',
        'releases' => [{'name' => 'bosh-release', 'version' => '0.1-dev'}],
        'update' => {'canaries' => 2, 'canary_watch_time' => 4000, 'max_in_flight' => 1, 'update_watch_time' => 20},
        'jobs' => [
          {
            'name' => 'fake-job',
            'templates' => [{'name' => 'foobar'}],
            'resource_pool' => 'a',
            'instances' => desired_instance_count,
            'networks' => job_networks,
            'properties' => {},
            'azs' => job_availability_zones
          }
        ]
      }
    end
    let(:job_availability_zones) { ['zone1', 'zone2'] }
    let(:deployment_manifest_migrator) { instance_double(ManifestMigrator) }
    let(:planner_factory) { PlannerFactory.new(deployment_manifest_migrator, manifest_validator, deployment_repo, logger) }
    let(:manifest_validator) { Bosh::Director::DeploymentPlan::ManifestValidator.new }
    let(:deployment_repo) { DeploymentRepo.new }
    let(:event_log) { Bosh::Director::EventLog::Log.new(StringIO.new('')) }
    let(:cloud_config_model) { Bosh::Director::Models::CloudConfig.make(manifest: cloud_config_hash) }
    let(:manifest) { Bosh::Director::Manifest.new(manifest_hash, cloud_config_hash) }
    let(:planner) { planner_factory.create_from_manifest(manifest, cloud_config_model, {}) }
    let(:job) { planner.jobs.first }
    let(:job_networks) { [{'name' => 'a', 'static_ips' => static_ips}] }
    let(:desired_instances) { [].tap { |a| desired_instance_count.times { a << new_desired_instance } } }
    let(:desired_instance_count) { 3 }

    let(:instance_plans) { zone_picker.place_and_match_in(desired_instances, existing_instances) }
    let(:availability_zones) { job.availability_zones }
    let(:new_instance_plans) { instance_plans.select(&:new?) }
    let(:existing_instance_plans) { instance_plans.reject(&:new?).reject(&:obsolete?) }
    let(:obsolete_instance_plans) { instance_plans.select(&:obsolete?) }

    before do
      fake_job
      allow(deployment_manifest_migrator).to receive(:migrate) { |deployment_manifest, cloud_config| [deployment_manifest, cloud_config] }
    end

    describe '#place_and_match_in' do
      context 'with no existing instances' do
        let(:existing_instances) { [] }
        let(:static_ips) { ['192.168.1.10 - 192.168.1.12'] }<commit_msg>Fixes unit test failures in static_ips_availability_zone_picker_spec<commit_after>require 'spec_helper'

module Bosh::Director::DeploymentPlan
  describe PlacementPlanner::StaticIpsAvailabilityZonePicker do
    include Bosh::Director::IpUtil

    subject(:zone_picker) { PlacementPlanner::StaticIpsAvailabilityZonePicker.new(instance_plan_factory, network_planner, job.networks, 'fake-job', availability_zones, logger) }
    let(:network_planner) { NetworkPlanner::Planner.new(logger) }
    let(:network_reservation_repository) { BD::DeploymentPlan::NetworkReservationRepository.new(planner, logger) }
    let(:planner) { planner_factory.create_from_manifest(manifest_hash, cloud_config_model, nil, {}) }
    let(:instance_plan_factory) { InstancePlanFactory.new(instance_repo, {}, SkipDrain.new(true), index_assigner, network_reservation_repository) }
    let(:index_assigner) { PlacementPlanner::IndexAssigner.new(deployment_model) }
    let!(:deployment_model) { Bosh::Director::Models::Deployment.make(manifest: YAML.dump(manifest_hash), name: manifest_hash['name']) }
    let(:instance_repo) { Bosh::Director::DeploymentPlan::InstanceRepository.new(network_reservation_repository, logger) }
    def make_subnet_spec(range, static_ips, zone_names)
      spec = {
        'range' => range,
        'gateway' => NetAddr::CIDR.create(range)[1].ip,
        'dns' => ['8.8.8.8'],
        'static' => static_ips,
        'reserved' => [],
        'cloud_properties' => {},
      }
      spec['azs'] = zone_names if zone_names
      spec
    end
    let(:networks_spec) do
      [
        {'name' => 'a',
          'subnets' => [
            make_subnet_spec('192.168.1.0/24', ['192.168.1.10 - 192.168.1.14'], ['zone1']),
            make_subnet_spec('192.168.2.0/24', ['192.168.2.10 - 192.168.2.14'], ['zone2']),
          ]
        },
        {'name' => 'b',
          'subnets' => [
            make_subnet_spec('10.10.1.0/24', ['10.10.1.10 - 10.10.1.14'], ['zone1']),
            make_subnet_spec('10.10.2.0/24', ['10.10.2.10 - 10.10.2.14'], ['zone2']),
          ]
        }
      ]
    end

    let(:cloud_config_hash) do
      {
        'networks' => networks_spec,
        'compilation' => {'workers' => 1, 'network' => 'a', 'cloud_properties' => {}, 'az' => cloud_config_availability_zones.first['name']},
        'resource_pools' => [
          {
            'name' => 'a',
            'size' => 3,
            'cloud_properties' => {},
            'network' => 'a',
            'stemcell' => {'name' => 'ubuntu-stemcell', 'version' => '1'}
          }
        ],
        'azs' => cloud_config_availability_zones}
    end
    let(:cloud_config_availability_zones) do
      [
        {'name' => 'zone1', 'cloud_properties' => {:foo => 'bar'}},
        {'name' => 'zone2', 'cloud_properties' => {:foo => 'baz'}}
      ]
    end
    let(:manifest_hash) do
      {
        'name' => 'simple',
        'director_uuid' => 'deadbeef',
        'releases' => [{'name' => 'bosh-release', 'version' => '0.1-dev'}],
        'update' => {'canaries' => 2, 'canary_watch_time' => 4000, 'max_in_flight' => 1, 'update_watch_time' => 20},
        'jobs' => [
          {
            'name' => 'fake-job',
            'templates' => [{'name' => 'foobar'}],
            'resource_pool' => 'a',
            'instances' => desired_instance_count,
            'networks' => job_networks,
            'properties' => {},
            'azs' => job_availability_zones
          }
        ]
      }
    end
    let(:job_availability_zones) { ['zone1', 'zone2'] }
    let(:deployment_manifest_migrator) { instance_double(ManifestMigrator) }
    let(:planner_factory) { PlannerFactory.new(deployment_manifest_migrator, manifest_validator, deployment_repo, logger) }
    let(:manifest_validator) { Bosh::Director::DeploymentPlan::ManifestValidator.new }
    let(:deployment_repo) { DeploymentRepo.new }
    let(:event_log) { Bosh::Director::EventLog::Log.new(StringIO.new('')) }
    let(:cloud_config_model) { Bosh::Director::Models::CloudConfig.make(manifest: cloud_config_hash) }
    let(:manifest) { Bosh::Director::Manifest.new(manifest_hash, cloud_config_hash) }
    let(:planner) { planner_factory.create_from_manifest(manifest, cloud_config_model, nil, {}) }
    let(:job) { planner.jobs.first }
    let(:job_networks) { [{'name' => 'a', 'static_ips' => static_ips}] }
    let(:desired_instances) { [].tap { |a| desired_instance_count.times { a << new_desired_instance } } }
    let(:desired_instance_count) { 3 }

    let(:instance_plans) { zone_picker.place_and_match_in(desired_instances, existing_instances) }
    let(:availability_zones) { job.availability_zones }
    let(:new_instance_plans) { instance_plans.select(&:new?) }
    let(:existing_instance_plans) { instance_plans.reject(&:new?).reject(&:obsolete?) }
    let(:obsolete_instance_plans) { instance_plans.select(&:obsolete?) }

    before do
      fake_job
      allow(deployment_manifest_migrator).to receive(:migrate) { |deployment_manifest, cloud_config| [deployment_manifest, cloud_config] }
    end

    describe '#place_and_match_in' do
      context 'with no existing instances' do
        let(:existing_instances) { [] }
        let(:static_ips) { ['192.168.1.10 - 192.168.1.12'] }
{'fraction_non_alphanumeric': 0.16692263390286044, 'fraction_numerical': 0.027836436936072184, 'mean_word_length': 3.3035935563816605, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 30, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3962325', 'n_tokens_mistral': 3690, 'n_tokens_neox': 3454, 'n_words': 480}