<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once
#include "sstables/sstables.hh"
#include "sstables/compaction_manager.hh"
#include "cell_locking.hh"
#include "mutation_reader.hh"
#include "test/lib/sstable_utils.hh"
#include "test/lib/test_services.hh"
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/range/irange.hpp>

using namespace sstables;

class perf_sstable_test_env {
    test_env _env;

public:
    struct conf {
        unsigned partitions;
        unsigned key_size;
        unsigned num_columns;
        unsigned column_size;
        unsigned sstables;
        size_t buffer_size;
        sstring dir;
    };

private:
    sstring dir() {
        return _cfg.dir + "/" + to_sstring(this_shard_id());
    }

    sstring random_string(unsigned size) {
        sstring str = uninitialized_string(size_t(size));
        for (auto& b: str) {
            b = _distribution(_generator);
        }
        return str;
    }

    sstring random_key() {
        return random_string(_cfg.key_size);
    }

    sstring random_column() {
        return random_string(_cfg.column_size);
    }

    conf _cfg;
    schema_ptr s;
    std::default_random_engine _generator;
    std::uniform_int_distribution<char> _distribution;
    lw_shared_ptr<memtable> _mt;
    std::vector<shared_sstable> _sst;

    schema_ptr create_schema() {
        std::vector<schema::column> columns;

        for (unsigned i = 0; i < _cfg.num_columns; ++i) {
            columns.push_back(schema::column{ to_bytes(format("column{:04d}", i)), utf8_type });
        }

        schema_builder builder(make_shared_schema(generate_legacy_id("ks", "perf-test"), "ks", "perf-test",
            // partition key
            {{"name", utf8_type}},
            // clustering key
            {},
            // regular columns
            { columns },
            // static columns
            {},
            // regular column name type
            utf8_type,
            // comment
            "Perf tests"
        ));
        return builder.build(schema_builder::compact_storage::no);
    }

public:
    perf_sstable_test_env(conf cfg) : _cfg(std::move(cfg))
           , s(create_schema())
           , _distribution('@', '~')
           , _mt(make_lw_shared<memtable>(s))
    {}

    future<> stop() { return make_ready_future<>(); }

    future<> fill_memtable() {
        auto idx = boost::irange(0, int(_cfg.partitions / _cfg.sstables));
        auto local_keys = make_local_keys(int(_cfg.partitions / _cfg.sstables), s, _cfg.key_size);
        return do_for_each(idx.begin(), idx.end(), [this, local_keys = std::move(local_keys)] (auto iteration) {
            auto key = partition_key::from_deeply_exploded(*s, { local_keys.at(iteration) });
            auto mut = mutation(this->s, key);
            for (auto& cdef: this->s->regular_columns()) {
                mut.set_clustered_cell(clustering_key::make_empty(), cdef, atomic_cell::make_live(*utf8_type, 0, utf8_type->decompose(this->random_column())));
            }
            this->_mt->apply(std::move(mut));
            return make_ready_future<>();
        });
    }

    future<> load_sstables(unsigned iterations) {
        _sst.push_back(_env.make_sstable(s, this->dir(), 0, sstable::version_types::ka, sstable::format_types::big));
        return _sst.back()->load();
    }

    using clk = std::chrono::steady_clock;
    static auto now() {
        return clk::now();
    }

    // Mappers below
    future<double> flush_memtable(int idx) {
        return seastar::async([this, idx] {
            size_t partitions = _mt->partition_count();

            test_setup::create_empty_test_dir(dir()).get();
            auto sst = _env.make_sstable(s, dir(), idx, sstable::version_types::ka, sstable::format_types::big, _cfg.buffer_size);

            auto start = perf_sstable_test_env::now();
            write_memtable_to_sstable_for_test(*_mt, sst).get();
            auto end = perf_sstable_test_env::now();

            _mt->revert_flushed_memory();

            auto duration = std::chrono::duration<double>(end - start).count();
            return partitions / duration;
        });
    }

    future<double> compaction(int idx) {
        return test_setup::create_empty_test_dir(dir()).then([this, idx] {
            return seastar::async([this, idx] {
                auto sst_gen = [this, gen = make_lw_shared<unsigned>(idx)] () mutable {
                    return _env.make_sstable(s, dir(), (*gen)++, sstable::version_types::ka, sstable::format_types::big, _cfg.buffer_size);
                };

                std::vector<shared_sstable> ssts;
                for (auto i = 0u; i < _cfg.sstables; i++) {
                    auto sst = sst_gen();
                    write_memtable_to_sstable_for_test(*_mt, sst).get();
                    sst->open_data().get();
                    _mt->revert_flushed_memory();
                    ssts.push_back(std::move(sst));
                }

                cache_tracker tracker;
                cell_locker_stats cl_stats;
                auto cm = make_lw_shared<compaction_manager>();
                auto cf = make_lw_shared<column_family>(s, column_family_test_config(), column_family::no_commitlog(), *cm, cl_stats, tracker);

                auto start = perf_sstable_test_env::now();

                auto descriptor = sstables::compaction_descriptor(std::move(ssts), cf->get_sstable_set(), default_priority_class());
                descriptor.creator = [sst_gen = std::move(sst_gen)] (unsigned dummy) mutable {
                    return sst_gen();
                };
                descriptor.replacer = sstables::replacer_fn_no_op();
                auto ret = sstables::compact_sstables(std::move(descriptor), *cf).get0();
                auto end = perf_sstable_test_env::now();

                auto partitions_per_sstable = _cfg.partitions / _cfg.sstables;
                assert(ret.total_keys_written == partitions_per_sstable);

                auto duration = std::chrono::duration<double>(end - start).count();
                return ret.total_keys_written / duration;
            });
        });
    }

    future<double> read_all_indexes(int idx) {
        return do_with(test(_sst[0]), [] (auto& sst) {
            const auto start = perf_sstable_test_env::now();

            return sst.read_indexes().then([start] (const auto& indexes) {
                auto end = perf_sstable_test_env::now();
                auto duration = std::chrono::duration<double>(end - start).count();
                return indexes.size() / duration;
            });
        });
    }

    future<double> read_sequential_partitions(int idx) {
        return do_with(_sst[0]->read_rows_flat(s, tests::make_permit()), [this] (flat_mutation_reader& r) {
            auto start = perf_sstable_test_env::now();
            auto total = make_lw_shared<size_t>(0);
            auto done = make_lw_shared<bool>(false);
            return do_until([done] { return *done; }, [this, done, total, &r] {
                return read_mutation_from_flat_mutation_reader(r, db::no_timeout).then([this, done, total] (mutation_opt m) {
                    if (!m) {
                        *done = true;
                    } else {
                        auto row = m->partition().find_row(*s, clustering_key::make_empty());
                        if (!row || row->size() != _cfg.num_columns) {
                            throw std::invalid_argument("Invalid sstable found. Maybe you ran write mode with different num_columns settings?");
                        } else {
                            (*total)++;
                        }
                    }
                });
            }).then([total, start] {
                auto end = perf_sstable_test_env::now();
                auto duration = std::chrono::duration<double>(end - start).count();
                return *total / duration;
            });
        });
    }
};

// The function func should carry on with the test, and return the number of partitions processed.
// time_runs will then map reduce it, and return the aggregate partitions / sec for the whole system.
template <typename Func>
future<> time_runs(unsigned iterations, unsigned parallelism, distributed<perf_sstable_test_env>& dt, Func func) {
    using namespace boost::accumulators;
    auto acc = make_lw_shared<accumulator_set<double, features<tag::mean, tag::error_of<tag::mean>>>>();
    auto idx = boost::irange(0, int(iterations));
    return do_for_each(idx.begin(), idx.end(), [parallelism, acc, &dt, func] (auto iter) {
        auto idx = boost::irange(0, int(parallelism));
        return parallel_for_each(idx.begin(), idx.end(), [&dt, func, acc] (auto idx) {
            return dt.map_reduce(adder<double>(), func, std::move(idx)).then([acc] (double result) {
                auto& a = *acc;
                a(result);
                return make_ready_future<>();
            });
        });
    }).then([acc, iterations, parallelism] {
        std::cout << format("{:.2f}", mean(*acc)) << " +- " << format("{:.2f}", error_of<tag::mean>(*acc)) << " partitions / sec (" << iterations << " runs, " << parallelism << " concurrent ops)\n";
    });
}
<commit_msg>test: perf/perf_sstable.hh: prepare for asynchronously closed sstables_manager<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla 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.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once
#include "sstables/sstables.hh"
#include "sstables/compaction_manager.hh"
#include "cell_locking.hh"
#include "mutation_reader.hh"
#include "test/lib/sstable_utils.hh"
#include "test/lib/test_services.hh"
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/range/irange.hpp>

using namespace sstables;

class perf_sstable_test_env {
    test_env _env;

public:
    struct conf {
        unsigned partitions;
        unsigned key_size;
        unsigned num_columns;
        unsigned column_size;
        unsigned sstables;
        size_t buffer_size;
        sstring dir;
    };

private:
    sstring dir() {
        return _cfg.dir + "/" + to_sstring(this_shard_id());
    }

    sstring random_string(unsigned size) {
        sstring str = uninitialized_string(size_t(size));
        for (auto& b: str) {
            b = _distribution(_generator);
        }
        return str;
    }

    sstring random_key() {
        return random_string(_cfg.key_size);
    }

    sstring random_column() {
        return random_string(_cfg.column_size);
    }

    conf _cfg;
    schema_ptr s;
    std::default_random_engine _generator;
    std::uniform_int_distribution<char> _distribution;
    lw_shared_ptr<memtable> _mt;
    std::vector<shared_sstable> _sst;

    schema_ptr create_schema() {
        std::vector<schema::column> columns;

        for (unsigned i = 0; i < _cfg.num_columns; ++i) {
            columns.push_back(schema::column{ to_bytes(format("column{:04d}", i)), utf8_type });
        }

        schema_builder builder(make_shared_schema(generate_legacy_id("ks", "perf-test"), "ks", "perf-test",
            // partition key
            {{"name", utf8_type}},
            // clustering key
            {},
            // regular columns
            { columns },
            // static columns
            {},
            // regular column name type
            utf8_type,
            // comment
            "Perf tests"
        ));
        return builder.build(schema_builder::compact_storage::no);
    }

public:
    perf_sstable_test_env(conf cfg) : _cfg(std::move(cfg))
           , s(create_schema())
           , _distribution('@', '~')
           , _mt(make_lw_shared<memtable>(s))
    {}

    future<> stop() { return make_ready_future<>(); }

    future<> fill_memtable() {
        auto idx = boost::irange(0, int(_cfg.partitions / _cfg.sstables));
        auto local_keys = make_local_keys(int(_cfg.partitions / _cfg.sstables), s, _cfg.key_size);
        return do_for_each(idx.begin(), idx.end(), [this, local_keys = std::move(local_keys)] (auto iteration) {
            auto key = partition_key::from_deeply_exploded(*s, { local_keys.at(iteration) });
            auto mut = mutation(this->s, key);
            for (auto& cdef: this->s->regular_columns()) {
                mut.set_clustered_cell(clustering_key::make_empty(), cdef, atomic_cell::make_live(*utf8_type, 0, utf8_type->decompose(this->random_column())));
            }
            this->_mt->apply(std::move(mut));
            return make_ready_future<>();
        });
    }

    future<> load_sstables(unsigned iterations) {
        _sst.push_back(_env.make_sstable(s, this->dir(), 0, sstable::version_types::ka, sstable::format_types::big));
        return _sst.back()->load();
    }

    using clk = std::chrono::steady_clock;
    static auto now() {
        return clk::now();
    }

    // Mappers below
    future<double> flush_memtable(int idx) {
        return seastar::async([this, idx] {
            size_t partitions = _mt->partition_count();

            test_setup::create_empty_test_dir(dir()).get();
            auto sst = _env.make_sstable(s, dir(), idx, sstable::version_types::ka, sstable::format_types::big, _cfg.buffer_size);

            auto start = perf_sstable_test_env::now();
            write_memtable_to_sstable_for_test(*_mt, sst).get();
            auto end = perf_sstable_test_env::now();

            _mt->revert_flushed_memory();

            auto duration = std::chrono::duration<double>(end - start).count();
            return partitions / duration;
        });
    }

    future<double> compaction(int idx) {
        return test_setup::create_empty_test_dir(dir()).then([this, idx] {
            return sstables::test_env::do_with_async_returning<double>([this, idx] (sstables::test_env& env) {
                auto sst_gen = [this, gen = make_lw_shared<unsigned>(idx)] () mutable {
                    return _env.make_sstable(s, dir(), (*gen)++, sstable::version_types::ka, sstable::format_types::big, _cfg.buffer_size);
                };

                std::vector<shared_sstable> ssts;
                for (auto i = 0u; i < _cfg.sstables; i++) {
                    auto sst = sst_gen();
                    write_memtable_to_sstable_for_test(*_mt, sst).get();
                    sst->open_data().get();
                    _mt->revert_flushed_memory();
                    ssts.push_back(std::move(sst));
                }

                cache_tracker tracker;
                cell_locker_stats cl_stats;
                auto cm = make_lw_shared<compaction_manager>();
                auto cf = make_lw_shared<column_family>(s, column_family_test_config(env.manager()), column_family::no_commitlog(), *cm, cl_stats, tracker);

                auto start = perf_sstable_test_env::now();

                auto descriptor = sstables::compaction_descriptor(std::move(ssts), cf->get_sstable_set(), default_priority_class());
                descriptor.creator = [sst_gen = std::move(sst_gen)] (unsigned dummy) mutable {
                    return sst_gen();
                };
                descriptor.replacer = sstables::replacer_fn_no_op();
                auto ret = sstables::compact_sstables(std::move(descriptor), *cf).get0();
                auto end = perf_sstable_test_env::now();

                auto partitions_per_sstable = _cfg.partitions / _cfg.sstables;
                assert(ret.total_keys_written == partitions_per_sstable);

                auto duration = std::chrono::duration<double>(end - start).count();
                return ret.total_keys_written / duration;
            });
        });
    }

    future<double> read_all_indexes(int idx) {
        return do_with(test(_sst[0]), [] (auto& sst) {
            const auto start = perf_sstable_test_env::now();

            return sst.read_indexes().then([start] (const auto& indexes) {
                auto end = perf_sstable_test_env::now();
                auto duration = std::chrono::duration<double>(end - start).count();
                return indexes.size() / duration;
            });
        });
    }

    future<double> read_sequential_partitions(int idx) {
        return do_with(_sst[0]->read_rows_flat(s, tests::make_permit()), [this] (flat_mutation_reader& r) {
            auto start = perf_sstable_test_env::now();
            auto total = make_lw_shared<size_t>(0);
            auto done = make_lw_shared<bool>(false);
            return do_until([done] { return *done; }, [this, done, total, &r] {
                return read_mutation_from_flat_mutation_reader(r, db::no_timeout).then([this, done, total] (mutation_opt m) {
                    if (!m) {
                        *done = true;
                    } else {
                        auto row = m->partition().find_row(*s, clustering_key::make_empty());
                        if (!row || row->size() != _cfg.num_columns) {
                            throw std::invalid_argument("Invalid sstable found. Maybe you ran write mode with different num_columns settings?");
                        } else {
                            (*total)++;
                        }
                    }
                });
            }).then([total, start] {
                auto end = perf_sstable_test_env::now();
                auto duration = std::chrono::duration<double>(end - start).count();
                return *total / duration;
            });
        });
    }
};

// The function func should carry on with the test, and return the number of partitions processed.
// time_runs will then map reduce it, and return the aggregate partitions / sec for the whole system.
template <typename Func>
future<> time_runs(unsigned iterations, unsigned parallelism, distributed<perf_sstable_test_env>& dt, Func func) {
    using namespace boost::accumulators;
    auto acc = make_lw_shared<accumulator_set<double, features<tag::mean, tag::error_of<tag::mean>>>>();
    auto idx = boost::irange(0, int(iterations));
    return do_for_each(idx.begin(), idx.end(), [parallelism, acc, &dt, func] (auto iter) {
        auto idx = boost::irange(0, int(parallelism));
        return parallel_for_each(idx.begin(), idx.end(), [&dt, func, acc] (auto idx) {
            return dt.map_reduce(adder<double>(), func, std::move(idx)).then([acc] (double result) {
                auto& a = *acc;
                a(result);
                return make_ready_future<>();
            });
        });
    }).then([acc, iterations, parallelism] {
        std::cout << format("{:.2f}", mean(*acc)) << " +- " << format("{:.2f}", error_of<tag::mean>(*acc)) << " partitions / sec (" << iterations << " runs, " << parallelism << " concurrent ops)\n";
    });
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

// PUBLIC API
#include <disir/disir.h>

#include "test_helper.h"

class StatusTest : public testing::Test
{
public:
    enum disir_status status;
    const char *status_string;

private:
    void SetUp()
    {
        status = DISIR_STATUS_OK;
    }
};

TEST_F (StatusTest, ok)
{
    status = DISIR_STATUS_OK;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "OK");
}

TEST_F (StatusTest, no_can_do)
{
    status = DISIR_STATUS_NO_CAN_DO;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NO CAN DO");
}

TEST_F (StatusTest, too_few_arguments)
{
    status = DISIR_STATUS_TOO_FEW_ARGUMENTS;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "TOO FEW ARGUMENTS");
}

TEST_F (StatusTest, context_in_wrong_state)
{
    status = DISIR_STATUS_CONTEXT_IN_WRONG_STATE;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONTEXT IN WRONG STATE");
}

TEST_F (StatusTest, wrong_context)
{
    status = DISIR_STATUS_WRONG_CONTEXT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "WRONG CONTEXT");
}

TEST_F (StatusTest, destroyed_context)
{
    status = DISIR_STATUS_DESTROYED_CONTEXT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "DESTROYED CONTEXT");
}

TEST_F (StatusTest, bad_context_object)
{
    status = DISIR_STATUS_BAD_CONTEXT_OBJECT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "BAD CONTEXT OBJECT");
}

TEST_F (StatusTest, invalid_context)
{
    status = DISIR_STATUS_INVALID_CONTEXT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "INVALID CONTEXT");
}

TEST_F (StatusTest, no_memory)
{
    status = DISIR_STATUS_NO_MEMORY;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NO MEMORY");
}

TEST_F (StatusTest, internal_error)
{
    status = DISIR_STATUS_INTERNAL_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "INTERNAL ERROR");
}

TEST_F (StatusTest, insufficient_resources)
{
    status = DISIR_STATUS_INSUFFICIENT_RESOURCES;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "INSUFFICIENT RESOURCES");
}

TEST_F (StatusTest, exists)
{
    status = DISIR_STATUS_EXISTS;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "EXISTS");
}

TEST_F (StatusTest, conflicting_semver)
{
    status = DISIR_STATUS_CONFLICTING_SEMVER;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONFLICTING SEMVER");
}

TEST_F (StatusTest, conflict)
{
    status = DISIR_STATUS_CONFLICT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONFLICT");
}

TEST_F (StatusTest, exhausted)
{
    status = DISIR_STATUS_EXHAUSTED;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "EXHAUSTED");
}

TEST_F (StatusTest, mold_missing)
{
    status =  DISIR_STATUS_MOLD_MISSING;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "MOLD MISSING");
}

TEST_F (StatusTest, wrong_value_type)
{
    status =  DISIR_STATUS_WRONG_VALUE_TYPE;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "WRONG VALUE TYPE");
}

TEST_F (StatusTest, not_exist)
{
    status =  DISIR_STATUS_NOT_EXIST;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NOT EXIST");
}

TEST_F (StatusTest, restriction_violated)
{
    status = DISIR_STATUS_RESTRICTION_VIOLATED;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "RESTRICTION VIOLATED");
}

TEST_F (StatusTest, elements_invalid)
{
    status = DISIR_STATUS_ELEMENTS_INVALID;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "ELEMENTS INVALID");
}

TEST_F (StatusTest, not_supported)
{
    status = DISIR_STATUS_NOT_SUPPORTED;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NOT SUPPORTED");
}

TEST_F (StatusTest, plugin_error)
{
    status = DISIR_STATUS_PLUGIN_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "PLUGIN ERROR");
}

TEST_F (StatusTest, load_error)
{
    status = DISIR_STATUS_LOAD_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "LOAD ERROR");
}

TEST_F (StatusTest, config_invalid)
{
    status = DISIR_STATUS_CONFIG_INVALID;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONFIG INVALID");
}

TEST_F (StatusTest, group_missing)
{
    status = DISIR_STATUS_GROUP_MISSING;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "GROUP MISSING");
}

TEST_F (StatusTest, permission_error)
{
    status = DISIR_STATUS_PERMISSION_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "PERMISSION ERROR");
}

TEST_F (StatusTest, fs_error)
{
    status = DISIR_STATUS_FS_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "FILESYSTEM ERROR");
}

TEST_F (StatusTest, default_missing)
{
    status = DISIR_STATUS_DEFAULT_MISSING;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "DEFAULT MISSING");
}

TEST_F (StatusTest, unknown)
{
    status = DISIR_STATUS_UNKNOWN;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "UNKNOWN");
}

<commit_msg>tests lib: add test for status FATAL_CONTEXT<commit_after>#include <gtest/gtest.h>

// PUBLIC API
#include <disir/disir.h>

#include "test_helper.h"

class StatusTest : public testing::Test
{
public:
    enum disir_status status;
    const char *status_string;

private:
    void SetUp()
    {
        status = DISIR_STATUS_OK;
    }
};

TEST_F (StatusTest, ok)
{
    status = DISIR_STATUS_OK;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "OK");
}

TEST_F (StatusTest, no_can_do)
{
    status = DISIR_STATUS_NO_CAN_DO;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NO CAN DO");
}

TEST_F (StatusTest, too_few_arguments)
{
    status = DISIR_STATUS_TOO_FEW_ARGUMENTS;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "TOO FEW ARGUMENTS");
}

TEST_F (StatusTest, context_in_wrong_state)
{
    status = DISIR_STATUS_CONTEXT_IN_WRONG_STATE;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONTEXT IN WRONG STATE");
}

TEST_F (StatusTest, wrong_context)
{
    status = DISIR_STATUS_WRONG_CONTEXT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "WRONG CONTEXT");
}

TEST_F (StatusTest, destroyed_context)
{
    status = DISIR_STATUS_DESTROYED_CONTEXT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "DESTROYED CONTEXT");
}

TEST_F (StatusTest, fatal_context)
{
    status = DISIR_STATUS_FATAL_CONTEXT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "FATAL CONTEXT");
}

TEST_F (StatusTest, bad_context_object)
{
    status = DISIR_STATUS_BAD_CONTEXT_OBJECT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "BAD CONTEXT OBJECT");
}

TEST_F (StatusTest, invalid_context)
{
    status = DISIR_STATUS_INVALID_CONTEXT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "INVALID CONTEXT");
}

TEST_F (StatusTest, no_memory)
{
    status = DISIR_STATUS_NO_MEMORY;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NO MEMORY");
}

TEST_F (StatusTest, internal_error)
{
    status = DISIR_STATUS_INTERNAL_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "INTERNAL ERROR");
}

TEST_F (StatusTest, insufficient_resources)
{
    status = DISIR_STATUS_INSUFFICIENT_RESOURCES;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "INSUFFICIENT RESOURCES");
}

TEST_F (StatusTest, exists)
{
    status = DISIR_STATUS_EXISTS;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "EXISTS");
}

TEST_F (StatusTest, conflicting_semver)
{
    status = DISIR_STATUS_CONFLICTING_SEMVER;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONFLICTING SEMVER");
}

TEST_F (StatusTest, conflict)
{
    status = DISIR_STATUS_CONFLICT;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONFLICT");
}

TEST_F (StatusTest, exhausted)
{
    status = DISIR_STATUS_EXHAUSTED;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "EXHAUSTED");
}

TEST_F (StatusTest, mold_missing)
{
    status =  DISIR_STATUS_MOLD_MISSING;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "MOLD MISSING");
}

TEST_F (StatusTest, wrong_value_type)
{
    status =  DISIR_STATUS_WRONG_VALUE_TYPE;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "WRONG VALUE TYPE");
}

TEST_F (StatusTest, not_exist)
{
    status =  DISIR_STATUS_NOT_EXIST;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NOT EXIST");
}

TEST_F (StatusTest, restriction_violated)
{
    status = DISIR_STATUS_RESTRICTION_VIOLATED;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "RESTRICTION VIOLATED");
}

TEST_F (StatusTest, elements_invalid)
{
    status = DISIR_STATUS_ELEMENTS_INVALID;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "ELEMENTS INVALID");
}

TEST_F (StatusTest, not_supported)
{
    status = DISIR_STATUS_NOT_SUPPORTED;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "NOT SUPPORTED");
}

TEST_F (StatusTest, plugin_error)
{
    status = DISIR_STATUS_PLUGIN_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "PLUGIN ERROR");
}

TEST_F (StatusTest, load_error)
{
    status = DISIR_STATUS_LOAD_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "LOAD ERROR");
}

TEST_F (StatusTest, config_invalid)
{
    status = DISIR_STATUS_CONFIG_INVALID;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "CONFIG INVALID");
}

TEST_F (StatusTest, group_missing)
{
    status = DISIR_STATUS_GROUP_MISSING;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "GROUP MISSING");
}

TEST_F (StatusTest, permission_error)
{
    status = DISIR_STATUS_PERMISSION_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "PERMISSION ERROR");
}

TEST_F (StatusTest, fs_error)
{
    status = DISIR_STATUS_FS_ERROR;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "FILESYSTEM ERROR");
}

TEST_F (StatusTest, default_missing)
{
    status = DISIR_STATUS_DEFAULT_MISSING;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "DEFAULT MISSING");
}

TEST_F (StatusTest, unknown)
{
    status = DISIR_STATUS_UNKNOWN;
    status_string = disir_status_string (status);
    ASSERT_STREQ (status_string, "UNKNOWN");
}

<|endoftext|>


<commit_before>
//--------------------------------------------------------------------------------------------------
void test_unit_task_result()
{
    TEST_FUNC;

    auto spTask = oqpi_tk::make_task("FibonacciReturnResult", fibonacci, gValue);
    oqpi_tk::schedule_task(spTask);
    std::cout << "Fibonacci(" << gValue << ") = " << spTask->waitForResult() << std::endl;
}

//--------------------------------------------------------------------------------------------------
void test_unit_task()
{
    TEST_FUNC;

    auto spTask = oqpi_tk::make_task("Fibonacci4x", oqpi::task_priority::normal, []
    {
        for (int i = 0; i < gTaskCount; ++i)
        {
            volatile auto a = 0ull;
            a += fibonacci(gValue+a);
        }
    });
    oqpi_tk::schedule_task(spTask).wait();
}

//--------------------------------------------------------------------------------------------------
void test_multiple_unit_tasks()
{
    TEST_FUNC;

    std::vector<oqpi::task_handle> handles(gTaskCount);
    for (auto i = 0; i < gTaskCount; ++i)
    {
        handles[i] = oqpi_tk::schedule_task("Fibonacci_" + std::to_string(i), fibonacci, gValue);
    }
    for (auto &h : handles)
    {
        h.wait();
    }
}

//--------------------------------------------------------------------------------------------------
void test_sequence_group()
{
    TEST_FUNC;

    auto spSeq = oqpi_tk::make_sequence_group<oqpi::task_type::waitable>("Sequence");
    for (auto i = 0; i < gTaskCount; ++i)
    {
        auto spTask = oqpi_tk::make_task_item("FibonacciSeq" + std::to_string(i), fibonacci, gValue);
        spSeq->addTask(spTask);
    }
    oqpi_tk::schedule_task(oqpi::task_handle(spSeq)).wait();
}

//--------------------------------------------------------------------------------------------------
void test_parallel_group()
{
    TEST_FUNC;

    auto spFork = oqpi_tk::make_parallel_group<oqpi::task_type::waitable>("Fork", oqpi::task_priority::normal, gTaskCount);
    for (auto i = 0; i < gTaskCount; ++i)
    {
        auto spTask = oqpi_tk::make_task_item("FibonacciFork" + std::to_string(i), fibonacci, gValue);
        spFork->addTask(spTask);
    }
    oqpi_tk::schedule_task(oqpi::task_handle(spFork)).wait();
}

//--------------------------------------------------------------------------------------------------
void test_sequence_of_parallel_groups()
{
    TEST_FUNC;

    auto spSeq = oqpi_tk::make_sequence_group<oqpi::task_type::waitable>("Sequence");
    for (auto i = 0; i < gTaskCount; ++i)
    {
        auto spFork = oqpi_tk::make_parallel_group<oqpi::task_type::fire_and_forget>("Fork" + std::to_string(i), oqpi::task_priority::normal, gTaskCount);
        for (auto j = 0; j < gTaskCount; ++j)
        {
            auto spTask = oqpi_tk::make_task_item("Fibonacci_" + std::to_string(i*10+j), oqpi::task_priority::normal, fibonacci, gValue);
            spFork->addTask(spTask);
        }
        spSeq->addTask(oqpi::task_handle(spFork));
    }
    oqpi_tk::schedule_task(oqpi::task_handle(spSeq)).wait();
}

//--------------------------------------------------------------------------------------------------
void test_scheduling()
{
    test_unit_task_result();

    test_unit_task();

    test_multiple_unit_tasks();

    test_sequence_group();

    test_parallel_group();

    test_sequence_of_parallel_groups();
}

//--------------------------------------------------------------------------------------------------
TEST_CASE("Scheduling (tasks, sequence groups, parallel groups).", "[scheduling]")
{
    // Does this make sense?
    CHECK_NOTHROW(test_scheduling());
}
<commit_msg>Removed comment<commit_after>
//--------------------------------------------------------------------------------------------------
void test_unit_task_result()
{
    TEST_FUNC;

    auto spTask = oqpi_tk::make_task("FibonacciReturnResult", fibonacci, gValue);
    oqpi_tk::schedule_task(spTask);
    std::cout << "Fibonacci(" << gValue << ") = " << spTask->waitForResult() << std::endl;
}

//--------------------------------------------------------------------------------------------------
void test_unit_task()
{
    TEST_FUNC;

    auto spTask = oqpi_tk::make_task("Fibonacci4x", oqpi::task_priority::normal, []
    {
        for (int i = 0; i < gTaskCount; ++i)
        {
            volatile auto a = 0ull;
            a += fibonacci(gValue+a);
        }
    });
    oqpi_tk::schedule_task(spTask).wait();
}

//--------------------------------------------------------------------------------------------------
void test_multiple_unit_tasks()
{
    TEST_FUNC;

    std::vector<oqpi::task_handle> handles(gTaskCount);
    for (auto i = 0; i < gTaskCount; ++i)
    {
        handles[i] = oqpi_tk::schedule_task("Fibonacci_" + std::to_string(i), fibonacci, gValue);
    }
    for (auto &h : handles)
    {
        h.wait();
    }
}

//--------------------------------------------------------------------------------------------------
void test_sequence_group()
{
    TEST_FUNC;

    auto spSeq = oqpi_tk::make_sequence_group<oqpi::task_type::waitable>("Sequence");
    for (auto i = 0; i < gTaskCount; ++i)
    {
        auto spTask = oqpi_tk::make_task_item("FibonacciSeq" + std::to_string(i), fibonacci, gValue);
        spSeq->addTask(spTask);
    }
    oqpi_tk::schedule_task(oqpi::task_handle(spSeq)).wait();
}

//--------------------------------------------------------------------------------------------------
void test_parallel_group()
{
    TEST_FUNC;

    auto spFork = oqpi_tk::make_parallel_group<oqpi::task_type::waitable>("Fork", oqpi::task_priority::normal, gTaskCount);
    for (auto i = 0; i < gTaskCount; ++i)
    {
        auto spTask = oqpi_tk::make_task_item("FibonacciFork" + std::to_string(i), fibonacci, gValue);
        spFork->addTask(spTask);
    }
    oqpi_tk::schedule_task(oqpi::task_handle(spFork)).wait();
}

//--------------------------------------------------------------------------------------------------
void test_sequence_of_parallel_groups()
{
    TEST_FUNC;

    auto spSeq = oqpi_tk::make_sequence_group<oqpi::task_type::waitable>("Sequence");
    for (auto i = 0; i < gTaskCount; ++i)
    {
        auto spFork = oqpi_tk::make_parallel_group<oqpi::task_type::fire_and_forget>("Fork" + std::to_string(i), oqpi::task_priority::normal, gTaskCount);
        for (auto j = 0; j < gTaskCount; ++j)
        {
            auto spTask = oqpi_tk::make_task_item("Fibonacci_" + std::to_string(i*10+j), oqpi::task_priority::normal, fibonacci, gValue);
            spFork->addTask(spTask);
        }
        spSeq->addTask(oqpi::task_handle(spFork));
    }
    oqpi_tk::schedule_task(oqpi::task_handle(spSeq)).wait();
}

//--------------------------------------------------------------------------------------------------
void test_scheduling()
{
    test_unit_task_result();

    test_unit_task();

    test_multiple_unit_tasks();

    test_sequence_group();

    test_parallel_group();

    test_sequence_of_parallel_groups();
}

//--------------------------------------------------------------------------------------------------
TEST_CASE("Scheduling (tasks, sequence groups, parallel groups).", "[scheduling]")
{
    CHECK_NOTHROW(test_scheduling());
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * tests/api/test_wordcount.cpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <c7a/api/dia_base.hpp>
#include <c7a/core/stage_builder.hpp>
#include <c7a/api/dia.hpp>
#include <c7a/api/context.hpp>
#include <tests/c7a_tests.hpp>

#include <vector>
#include <string>
#include <utility>

#include "gtest/gtest.h"

using namespace c7a::core;

TEST(WordCount, PreOP) {
    using c7a::Context;
    using WordPair = std::pair<std::string, int>;

    Context ctx;

    auto line_to_words = [](std::string line, std::function<void(WordPair)> emit) {
                             std::string word;
                             std::istringstream iss(line);
                             while (iss >> word) {
                                 WordPair wp = std::make_pair(word, 1);
                                 emit(wp);
                             }
                         };
    auto key = [](WordPair in) {
                   return in.first;
               };
    auto red_fn = [](WordPair in1, WordPair in2) {
                      WordPair wp = std::make_pair(in1.first, in1.second + in2.second);
                      return wp;
                  };

    auto lines = ReadFromFileSystem(
        ctx,
        g_workpath + "/inputs/wordcount.in",
        [](const std::string& line) {
            return line;
        });

    auto word_pairs = lines.FlatMap(line_to_words);

    auto red_words = word_pairs.ReduceBy(key).With(red_fn);

    std::vector<Stage> result;
    FindStages(red_words.get_node(), result);
    for (auto s : result)
    {
        s.Run();
    }
}

/******************************************************************************/
<commit_msg>use RunScope() in the wordcount test<commit_after>/*******************************************************************************
 * tests/api/test_wordcount.cpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#include <c7a/api/dia_base.hpp>
#include <c7a/core/stage_builder.hpp>
#include <c7a/api/dia.hpp>
#include <c7a/api/context.hpp>
#include <tests/c7a_tests.hpp>

#include <vector>
#include <string>
#include <utility>

#include "gtest/gtest.h"

using namespace c7a::core;

TEST(WordCount, PreOP) {
    using c7a::Context;
    using WordPair = std::pair<std::string, int>;

    Context ctx;

    auto line_to_words = [](std::string line, std::function<void(WordPair)> emit) {
                             std::string word;
                             std::istringstream iss(line);
                             while (iss >> word) {
                                 WordPair wp = std::make_pair(word, 1);
                                 emit(wp);
                             }
                         };
    auto key = [](WordPair in) {
                   return in.first;
               };
    auto red_fn = [](WordPair in1, WordPair in2) {
                      WordPair wp = std::make_pair(in1.first, in1.second + in2.second);
                      return wp;
                  };

    auto lines = ReadFromFileSystem(
        ctx,
        g_workpath + "/inputs/wordcount.in",
        [](const std::string& line) {
            return line;
        });

    auto word_pairs = lines.FlatMap(line_to_words);

    auto red_words = word_pairs.ReduceBy(key).With(red_fn);

    RunScope(red_words.get_node());
}

/******************************************************************************/
<|endoftext|>


<commit_before>// Copyright 2021 The Pigweed Authors
//
// 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
//
//     https://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.

#include "pw_system/init.h"

#include "pw_log/log.h"
#include "pw_rpc/echo_service_nanopb.h"
#include "pw_system/thread_options.h"
#include "pw_system_private/log.h"
#include "pw_system_private/rpc.h"
#include "pw_thread/detached_thread.h"

namespace pw::system {
namespace {
rpc::EchoService echo_service;
}  // namespace

void Init() {
  PW_LOG_INFO("System init");

  // Setup logging.
  const Status status = GetLogThread().OpenUnrequestedLogStream(
      kDefaultChannelId, GetRpcServer(), GetLogService());
  if (!status.ok()) {
    PW_LOG_ERROR("Error opening OpenUnrequestedLogStream %s", status.str());
  }

  PW_LOG_INFO("Registering RPC services");
  GetRpcServer().RegisterService(echo_service);
  GetRpcServer().RegisterService(GetLogService());

  PW_LOG_INFO("Starting threads");
  // Start threads.
  thread::DetachedThread(system::LogThreadOptions(), GetLogThread());
  thread::DetachedThread(system::RpcThreadOptions(), GetRpcDispatchThread());
}

}  // namespace pw::system
<commit_msg>pw_system: Reword log stream error message<commit_after>// Copyright 2021 The Pigweed Authors
//
// 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
//
//     https://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.

#include "pw_system/init.h"

#include "pw_log/log.h"
#include "pw_rpc/echo_service_nanopb.h"
#include "pw_system/thread_options.h"
#include "pw_system_private/log.h"
#include "pw_system_private/rpc.h"
#include "pw_thread/detached_thread.h"

namespace pw::system {
namespace {
rpc::EchoService echo_service;
}  // namespace

void Init() {
  PW_LOG_INFO("System init");

  // Setup logging.
  const Status status = GetLogThread().OpenUnrequestedLogStream(
      kDefaultChannelId, GetRpcServer(), GetLogService());
  if (!status.ok()) {
    PW_LOG_ERROR("Error opening unrequested log streams %d",
                 static_cast<int>(status.code()));
  }

  PW_LOG_INFO("Registering RPC services");
  GetRpcServer().RegisterService(echo_service);
  GetRpcServer().RegisterService(GetLogService());

  PW_LOG_INFO("Starting threads");
  // Start threads.
  thread::DetachedThread(system::LogThreadOptions(), GetLogThread());
  thread::DetachedThread(system::RpcThreadOptions(), GetRpcDispatchThread());
}

}  // namespace pw::system
<|endoftext|>


<commit_before>/*
 * Copyright 2019-present Facebook, Inc.
 *
 * 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.
 */

#include <folly/io/Cursor.h>
#include <folly/portability/GTest.h>
#include <thrift/lib/cpp/protocol/TProtocolException.h>
#include <thrift/lib/cpp2/protocol/BinaryProtocol.h>
#include <thrift/lib/cpp2/protocol/CompactProtocol.h>
#include <thrift/lib/cpp2/protocol/SimpleJSONProtocol.h>
#include <thrift/lib/cpp2/protocol/test/gen-cpp2/module_types.h>

namespace apache {
namespace thrift {
namespace test {

OneOfEach makeTestData1() {
  OneOfEach ooe;
  ooe.myBool = false;
  ooe.myMap = std::map<std::string, int64_t>(
      {{"key1", 14}, {"key2", 0}, {"key3", 1000}});
  ooe.myList = std::vector<std::string>{"good1", "good2", "good3"};
  return ooe;
}

OneOfEach makeTestData2() {
  OneOfEach ooe;
  ooe.myMap = std::map<std::string, int64_t>(
      {{"key1", 14}, {"key2", 0}, {"key3", 1000}});
  ooe.myList = std::vector<std::string>{"good1", "good2", "good3"};
  ooe.mySet = std::set<std::string>{"elem1", "elem2", "elem3"};
  SubStruct sub;
  sub.mySubI64 = 123456789;
  sub.mySubString = "substring";
  ooe.myStruct = sub;
  return ooe;
}

template <class ProtocolWriter, class ProtocolReader>
void testSkipMap() {
  OneOfEach ooe = makeTestData1();

  ProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  ProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different map types
  OneOfEach2 ooe2;
  EXPECT_NO_THROW(ooe2.read(&protocolReader));
  EXPECT_EQ(0, ooe2.myMap.size());
  EXPECT_EQ(ooe.myList, ooe2.myList);
}

template <class ProtocolWriter, class ProtocolReader>
void testSkipListAndSet() {
  OneOfEach ooe = makeTestData2();

  ProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  ProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different list/set types
  OneOfEach3 ooe3;
  EXPECT_NO_THROW(ooe3.read(&protocolReader));
  EXPECT_EQ(ooe.myMap, ooe3.myMap);
  EXPECT_EQ(0, ooe3.myList.size());
  EXPECT_EQ(0, ooe3.mySet.size());
  EXPECT_EQ(ooe.myStruct, ooe3.myStruct);
}

TEST(ContainerSkippingTest, BinaryProtocolSkipMap) {
  testSkipMap<BinaryProtocolWriter, BinaryProtocolReader>();
}

TEST(ContainerSkippingTest, CompactProtocolSkipMap) {
  testSkipMap<CompactProtocolWriter, CompactProtocolReader>();
}

TEST(ContainerSkippingTest, BinaryProtocolSkipListAndSet) {
  testSkipListAndSet<BinaryProtocolWriter, BinaryProtocolReader>();
}

TEST(ContainerSkippingTest, CompactProtocolSkipListAndSet) {
  testSkipListAndSet<CompactProtocolWriter, CompactProtocolReader>();
}

TEST(ContainerSkippingTest, SimpleJSONProtocolSkipMap) {
  OneOfEach ooe = makeTestData1();

  SimpleJSONProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  SimpleJSONProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different map types
  OneOfEach2 ooe2;
  EXPECT_THROW(ooe2.read(&protocolReader), TProtocolException);
}

TEST(ContainerSkippingTest, SimpleJSONProtocolSkipListAndSet) {
  OneOfEach ooe = makeTestData2();

  SimpleJSONProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  SimpleJSONProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different list/set types
  OneOfEach3 ooe3;
  EXPECT_THROW(ooe3.read(&protocolReader), TProtocolException);
}
} // namespace test
} // namespace thrift
} // namespace apache
<commit_msg>Fix typo affecting case-sensitive includes<commit_after>/*
 * Copyright 2019-present Facebook, Inc.
 *
 * 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.
 */

#include <folly/io/Cursor.h>
#include <folly/portability/GTest.h>
#include <thrift/lib/cpp/protocol/TProtocolException.h>
#include <thrift/lib/cpp2/protocol/BinaryProtocol.h>
#include <thrift/lib/cpp2/protocol/CompactProtocol.h>
#include <thrift/lib/cpp2/protocol/SimpleJSONProtocol.h>
#include <thrift/lib/cpp2/protocol/test/gen-cpp2/Module_types.h>

namespace apache {
namespace thrift {
namespace test {

OneOfEach makeTestData1() {
  OneOfEach ooe;
  ooe.myBool = false;
  ooe.myMap = std::map<std::string, int64_t>(
      {{"key1", 14}, {"key2", 0}, {"key3", 1000}});
  ooe.myList = std::vector<std::string>{"good1", "good2", "good3"};
  return ooe;
}

OneOfEach makeTestData2() {
  OneOfEach ooe;
  ooe.myMap = std::map<std::string, int64_t>(
      {{"key1", 14}, {"key2", 0}, {"key3", 1000}});
  ooe.myList = std::vector<std::string>{"good1", "good2", "good3"};
  ooe.mySet = std::set<std::string>{"elem1", "elem2", "elem3"};
  SubStruct sub;
  sub.mySubI64 = 123456789;
  sub.mySubString = "substring";
  ooe.myStruct = sub;
  return ooe;
}

template <class ProtocolWriter, class ProtocolReader>
void testSkipMap() {
  OneOfEach ooe = makeTestData1();

  ProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  ProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different map types
  OneOfEach2 ooe2;
  EXPECT_NO_THROW(ooe2.read(&protocolReader));
  EXPECT_EQ(0, ooe2.myMap.size());
  EXPECT_EQ(ooe.myList, ooe2.myList);
}

template <class ProtocolWriter, class ProtocolReader>
void testSkipListAndSet() {
  OneOfEach ooe = makeTestData2();

  ProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  ProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different list/set types
  OneOfEach3 ooe3;
  EXPECT_NO_THROW(ooe3.read(&protocolReader));
  EXPECT_EQ(ooe.myMap, ooe3.myMap);
  EXPECT_EQ(0, ooe3.myList.size());
  EXPECT_EQ(0, ooe3.mySet.size());
  EXPECT_EQ(ooe.myStruct, ooe3.myStruct);
}

TEST(ContainerSkippingTest, BinaryProtocolSkipMap) {
  testSkipMap<BinaryProtocolWriter, BinaryProtocolReader>();
}

TEST(ContainerSkippingTest, CompactProtocolSkipMap) {
  testSkipMap<CompactProtocolWriter, CompactProtocolReader>();
}

TEST(ContainerSkippingTest, BinaryProtocolSkipListAndSet) {
  testSkipListAndSet<BinaryProtocolWriter, BinaryProtocolReader>();
}

TEST(ContainerSkippingTest, CompactProtocolSkipListAndSet) {
  testSkipListAndSet<CompactProtocolWriter, CompactProtocolReader>();
}

TEST(ContainerSkippingTest, SimpleJSONProtocolSkipMap) {
  OneOfEach ooe = makeTestData1();

  SimpleJSONProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  SimpleJSONProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different map types
  OneOfEach2 ooe2;
  EXPECT_THROW(ooe2.read(&protocolReader), TProtocolException);
}

TEST(ContainerSkippingTest, SimpleJSONProtocolSkipListAndSet) {
  OneOfEach ooe = makeTestData2();

  SimpleJSONProtocolWriter protocolWriter;
  folly::IOBufQueue q;
  protocolWriter.setOutput(&q);
  ooe.write(&protocolWriter);

  SimpleJSONProtocolReader protocolReader;
  protocolReader.setInput(q.front());
  // Deserialize into a struct with different list/set types
  OneOfEach3 ooe3;
  EXPECT_THROW(ooe3.read(&protocolReader), TProtocolException);
}
} // namespace test
} // namespace thrift
} // namespace apache
<|endoftext|>


<commit_before>/* This file is part of the KDE project
   Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
   Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
   Copyright (C) 2001, 2005 Anders Lund <anders.lund@lund.tdcadsl.dk>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/
#include "kateviewspace.h"

#include <KTextEditor/SessionConfigInterface>
#include "kateviewspace.moc"

#include "katemainwindow.h"
#include "kateviewmanager.h"
#include "katedocmanager.h"
#include "kateapp.h"
#include "katesession.h"

#include <KLocale>
#include <KSqueezedTextLabel>
#include <KConfig>
#include <kdebug.h>
#include <KStringHandler>
#include <KVBox>

#include <QStackedWidget>
#include <QCursor>
#include <QMenu>
#include <QTimer>
#include <QEvent>
#include <QMouseEvent>

//BEGIN KateViewSpace
KateViewSpace::KateViewSpace( KateViewManager *viewManager,
                              QWidget* parent, const char* name )
    : KVBox(parent),
    m_viewManager( viewManager )
{
  setObjectName(name);

  stack = new QStackedWidget( this );
  stack->setFocus();
  stack->setSizePolicy (QSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));

  mStatusBar = new KateVSStatusBar(this);
  mIsActiveSpace = false;

  setMinimumWidth (mStatusBar->minimumWidth());
  m_group.clear();

  // connect signal to hide/show statusbar
  connect (m_viewManager->mainWindow(), SIGNAL(statusBarToggled ()), this, SLOT(statusBarToggled ()));

  // init the statusbar...
  statusBarToggled ();
}

KateViewSpace::~KateViewSpace()
{}

void KateViewSpace::statusBarToggled ()
{
  // show or hide the bar?
  if (m_viewManager->mainWindow()->showStatusBar())
    mStatusBar->show ();
  else
    mStatusBar->hide ();
}

void KateViewSpace::addView(KTextEditor::View* v, bool show)
{
  // restore the config of this view if possible
  if ( !m_group.isEmpty() )
  {
    QString fn = v->document()->url().prettyUrl();
    if ( ! fn.isEmpty() )
    {
      QString vgroup = QString("%1 %2").arg(m_group).arg(fn);

      KateSession::Ptr as = KateSessionManager::self()->activeSession ();
      if ( as->configRead() && as->configRead()->hasGroup( vgroup ) )
      {
        KConfigGroup cg( as->configRead(), vgroup );

        if (KTextEditor::SessionConfigInterface *iface = qobject_cast<KTextEditor::SessionConfigInterface *>(v))
          iface->readSessionConfig ( cg );
      }
    }
  }

  stack->addWidget(v);
  if (show)
  {
    mViewList.append(v);
    showView( v );
  }
  else
  {
    KTextEditor::View* c = (KTextEditor::View*)stack->currentWidget();
    mViewList.prepend( v );
    showView( c );
  }

  // signals for the statusbar
  connect(v, SIGNAL(cursorPositionChanged(KTextEditor::View *, const KTextEditor::Cursor&)), mStatusBar, SLOT(cursorPositionChanged(KTextEditor::View *)));
  connect(v, SIGNAL(viewModeChanged(KTextEditor::View *)), mStatusBar, SLOT(viewModeChanged(KTextEditor::View *)));
  connect(v, SIGNAL(selectionChanged (KTextEditor::View *)), mStatusBar, SLOT(selectionChanged (KTextEditor::View *)));
  connect(v, SIGNAL(informationMessage (KTextEditor::View *, const QString &)), mStatusBar, SLOT(informationMessage (KTextEditor::View *, const QString &)));
  connect(v->document(), SIGNAL(modifiedChanged(KTextEditor::Document *)), mStatusBar, SLOT(modifiedChanged()));
  connect(v->document(), SIGNAL(modifiedOnDisk(KTextEditor::Document *, bool, KTextEditor::ModificationInterface::ModifiedOnDiskReason)), mStatusBar, SLOT(modifiedChanged()) );
  connect(v->document(), SIGNAL(documentNameChanged(KTextEditor::Document *)), mStatusBar, SLOT(documentNameChanged()));
}

void KateViewSpace::removeView(KTextEditor::View* v)
{
  bool active = ( v == currentView() );

  mViewList.removeAt ( mViewList.indexOf ( v ) );
  stack->removeWidget (v);

  if ( ! active )
    return;

  // the last recently used viewspace is always at the end of the list
  if (!mViewList.isEmpty())
    showView(mViewList.last());
}

bool KateViewSpace::showView(KTextEditor::Document *document)
{
  QList<KTextEditor::View*>::const_iterator it = mViewList.constEnd();
  while( it != mViewList.constBegin() )
  {
    --it;
    if ((*it)->document() == document)
    {
      KTextEditor::View* kv = *it;

      // move view to end of list
      mViewList.removeAt( mViewList.indexOf(kv) );
      mViewList.append( kv );
      stack->setCurrentWidget( kv );
      kv->show();

      mStatusBar->updateStatus ();

      return true;
    }
  }
  return false;
}

KTextEditor::View* KateViewSpace::currentView()
{
  // stack->currentWidget() returns NULL, if stack.count() == 0,
  // i.e. if mViewList.isEmpty()
  return (KTextEditor::View*)stack->currentWidget();
}

bool KateViewSpace::isActiveSpace()
{
  return mIsActiveSpace;
}

void KateViewSpace::setActive( bool active, bool )
{
  mIsActiveSpace = active;

  // change the statusbar palette and make sure it gets updated
  QPalette pal( palette() );
  if ( ! active )
  {
    pal.setColor( QPalette::Window, pal.color(QPalette::Window).dark() );
    pal.setColor( QPalette::Light, pal.color(QPalette::Light).light() );
  }

  mStatusBar->setPalette( pal );
  mStatusBar->update();
}

bool KateViewSpace::event( QEvent *e )
{
  if ( e->type() == QEvent::PaletteChange )
  {
    setActive( mIsActiveSpace );
    return true;
  }
  return KVBox::event( e );
}

void KateViewSpace::saveConfig ( KConfigBase* config, int myIndex , const QString& viewConfGrp)
{
//   kDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")";
  QString groupname = QString(viewConfGrp + "-ViewSpace %1").arg( myIndex );

  KConfigGroup group (config, groupname);
  group.writeEntry ("Count", mViewList.count());

  if (currentView())
    group.writeEntry( "Active View", currentView()->document()->url().prettyUrl() );

  // Save file list, including cursor position in this instance.
  int idx = 0;
  for (QList<KTextEditor::View*>::iterator it = mViewList.begin();
       it != mViewList.end(); ++it)
  {
    if ( !(*it)->document()->url().isEmpty() )
    {
      group.writeEntry( QString("View %1").arg( idx ), (*it)->document()->url().prettyUrl() );

      // view config, group: "ViewSpace <n> url"
      QString vgroup = QString("%1 %2").arg(groupname).arg((*it)->document()->url().prettyUrl());
      KConfigGroup viewGroup( config, vgroup );

      if (KTextEditor::SessionConfigInterface *iface = qobject_cast<KTextEditor::SessionConfigInterface *>(*it))
        iface->writeSessionConfig( viewGroup );
    }

    ++idx;
  }
}

void KateViewSpace::restoreConfig ( KateViewManager *viewMan, const KConfigBase* config, const QString &groupname )
{
  KConfigGroup group (config, groupname);
  QString fn = group.readEntry( "Active View" );

  if ( !fn.isEmpty() )
  {
    KTextEditor::Document *doc = KateDocManager::self()->findDocument (KUrl(fn));

    if (doc)
    {
      // view config, group: "ViewSpace <n> url"
      QString vgroup = QString("%1 %2").arg(groupname).arg(fn);
      KConfigGroup configGroup( config, vgroup );

      viewMan->createView (doc);

      KTextEditor::View *v = viewMan->activeView ();

      if (KTextEditor::SessionConfigInterface *iface = qobject_cast<KTextEditor::SessionConfigInterface *>(v))
        iface->readSessionConfig( configGroup );
    }
  }

  if (mViewList.isEmpty())
    viewMan->createView (KateDocManager::self()->document(0));

  m_group = groupname; // used for restroing view configs later
}
//END KateViewSpace

//BEGIN KateVSStatusBar
KateVSStatusBar::KateVSStatusBar ( KateViewSpace *parent)
    : KStatusBar( parent),
    m_viewSpace( parent )
{
  QString lineColText = i18n(" Line: %1 Col: %2 ", KGlobal::locale()->formatNumber(4444, 0),
         KGlobal::locale()->formatNumber(44, 0));

  m_lineColLabel = new QLabel( this );
  m_lineColLabel->setMinimumWidth( m_lineColLabel->fontMetrics().width( lineColText ) );
  addWidget( m_lineColLabel, 0 );
  m_lineColLabel->installEventFilter( this );

  m_modifiedLabel = new QLabel( this );
  m_modifiedLabel->setFixedSize( 16, 16 );
  addWidget( m_modifiedLabel, 0 );
  m_modifiedLabel->setAlignment( Qt::AlignCenter );
  m_modifiedLabel->installEventFilter( this );

  m_insertModeLabel = new QLabel( i18n(" INS "), this );
  addWidget( m_insertModeLabel, 0 );
  m_insertModeLabel->setAlignment( Qt::AlignCenter );
  m_insertModeLabel->installEventFilter( this );

  m_selectModeLabel = new QLabel( i18n(" LINE "), this );
  addWidget( m_selectModeLabel, 0 );
  m_selectModeLabel->setAlignment( Qt::AlignCenter );
  m_selectModeLabel->installEventFilter( this );

  m_fileNameLabel = new KSqueezedTextLabel( this );
  addPermanentWidget( m_fileNameLabel, 1 );
  m_fileNameLabel->setMinimumSize( 0, 0 );
  m_fileNameLabel->setSizePolicy(QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed ));
  m_fileNameLabel->setAlignment( /*Qt::AlignRight*/Qt::AlignLeft );
  m_fileNameLabel->installEventFilter( this );

  installEventFilter( this );
  m_modPm = KIcon("modified").pixmap(16);
  m_modDiscPm = KIcon("modonhd").pixmap(16);
  m_modmodPm = KIcon("modmod").pixmap(16);
}

KateVSStatusBar::~KateVSStatusBar ()
{}

void KateVSStatusBar::showMenu()
{
  KXmlGuiWindow* mainWindow = static_cast<KXmlGuiWindow*>( window() );
  QMenu* menu = static_cast<QMenu*>( mainWindow->factory()->container("viewspace_popup", mainWindow ) );

  if (menu)
    menu->exec(QCursor::pos());
}

bool KateVSStatusBar::eventFilter(QObject*, QEvent *e)
{
  if (e->type() == QEvent::MouseButtonPress)
  {
    if ( m_viewSpace->currentView() )
      m_viewSpace->currentView()->setFocus();

    if ( ((QMouseEvent*)e)->button() == Qt::RightButton)
      showMenu();

    return true;
  }

  return false;
}

void KateVSStatusBar::updateStatus ()
{
  if (!m_viewSpace->currentView())
    return;

  KTextEditor::View* view = m_viewSpace->currentView();
  viewModeChanged (view);
  cursorPositionChanged (view);
  selectionChanged (view);
  modifiedChanged ();
  documentNameChanged ();
}

void KateVSStatusBar::viewModeChanged ( KTextEditor::View *view )
{
  if (view != m_viewSpace->currentView())
    return;

  m_insertModeLabel->setText( view->viewMode() );
}

void KateVSStatusBar::cursorPositionChanged ( KTextEditor::View *view )
{
  if (view != m_viewSpace->currentView())
    return;

  KTextEditor::Cursor position (view->cursorPositionVirtual());

  m_lineColLabel->setText(
    i18n(" Line: %1 Col: %2 ", KGlobal::locale()->formatNumber(position.line() + 1, 0),
         KGlobal::locale()->formatNumber(position.column() + 1, 0)) );
}

void KateVSStatusBar::selectionChanged (KTextEditor::View *view)
{
  if (view != m_viewSpace->currentView())
    return;

  m_selectModeLabel->setText( view->blockSelection() ? i18n(" BLOCK ") : i18n(" LINE ") );
}

void KateVSStatusBar::informationMessage (KTextEditor::View *view, const QString &message)
{
  if (view != m_viewSpace->currentView())
    return;

  m_fileNameLabel->setText( message );

  // timer to reset this after 4 seconds
  QTimer::singleShot(4000, this, SLOT(documentNameChanged()));
}

void KateVSStatusBar::modifiedChanged()
{
  KTextEditor::View *v = m_viewSpace->currentView();

  if ( v )
  {
    bool mod = v->document()->isModified();

    const KateDocumentInfo *info
    = KateDocManager::self()->documentInfo ( v->document() );

    bool modOnHD = info && info->modifiedOnDisc;

    m_modifiedLabel->setPixmap(
      mod ?
      info && modOnHD ?
      m_modmodPm :
  m_modPm :
      info && modOnHD ?
      m_modDiscPm :
      QPixmap()
    );
  }
}

void KateVSStatusBar::documentNameChanged ()
{
  KTextEditor::View *v = m_viewSpace->currentView();

  if ( v )
    m_fileNameLabel->setText( KStringHandler::lsqueeze(v->document()->documentName (), 64) );
}

//END KateVSStatusBar

// kate: space-indent on; indent-width 2; replace-tabs on;
<commit_msg>Fix resizing of Kate under Mac OS X.<commit_after>/* This file is part of the KDE project
   Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
   Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
   Copyright (C) 2001, 2005 Anders Lund <anders.lund@lund.tdcadsl.dk>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/
#include "kateviewspace.h"

#include <KTextEditor/SessionConfigInterface>
#include "kateviewspace.moc"

#include "katemainwindow.h"
#include "kateviewmanager.h"
#include "katedocmanager.h"
#include "kateapp.h"
#include "katesession.h"

#include <KLocale>
#include <KSqueezedTextLabel>
#include <KConfig>
#include <kdebug.h>
#include <KStringHandler>
#include <KVBox>

#include <QStackedWidget>
#include <QCursor>
#include <QMenu>
#include <QTimer>
#include <QEvent>
#include <QMouseEvent>
#include <QSizeGrip>

//BEGIN KateViewSpace
KateViewSpace::KateViewSpace( KateViewManager *viewManager,
                              QWidget* parent, const char* name )
    : KVBox(parent),
    m_viewManager( viewManager )
{
  setObjectName(name);

  stack = new QStackedWidget( this );
  stack->setFocus();
  stack->setSizePolicy (QSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));

  mStatusBar = new KateVSStatusBar(this);
  mIsActiveSpace = false;

  setMinimumWidth (mStatusBar->minimumWidth());
  m_group.clear();

  // connect signal to hide/show statusbar
  connect (m_viewManager->mainWindow(), SIGNAL(statusBarToggled ()), this, SLOT(statusBarToggled ()));

  // init the statusbar...
  statusBarToggled ();
}

KateViewSpace::~KateViewSpace()
{}

void KateViewSpace::statusBarToggled ()
{
  // show or hide the bar?
  if (m_viewManager->mainWindow()->showStatusBar())
    mStatusBar->show ();
  else
    mStatusBar->hide ();
}

void KateViewSpace::addView(KTextEditor::View* v, bool show)
{
  // restore the config of this view if possible
  if ( !m_group.isEmpty() )
  {
    QString fn = v->document()->url().prettyUrl();
    if ( ! fn.isEmpty() )
    {
      QString vgroup = QString("%1 %2").arg(m_group).arg(fn);

      KateSession::Ptr as = KateSessionManager::self()->activeSession ();
      if ( as->configRead() && as->configRead()->hasGroup( vgroup ) )
      {
        KConfigGroup cg( as->configRead(), vgroup );

        if (KTextEditor::SessionConfigInterface *iface = qobject_cast<KTextEditor::SessionConfigInterface *>(v))
          iface->readSessionConfig ( cg );
      }
    }
  }

  stack->addWidget(v);
  if (show)
  {
    mViewList.append(v);
    showView( v );
  }
  else
  {
    KTextEditor::View* c = (KTextEditor::View*)stack->currentWidget();
    mViewList.prepend( v );
    showView( c );
  }

  // signals for the statusbar
  connect(v, SIGNAL(cursorPositionChanged(KTextEditor::View *, const KTextEditor::Cursor&)), mStatusBar, SLOT(cursorPositionChanged(KTextEditor::View *)));
  connect(v, SIGNAL(viewModeChanged(KTextEditor::View *)), mStatusBar, SLOT(viewModeChanged(KTextEditor::View *)));
  connect(v, SIGNAL(selectionChanged (KTextEditor::View *)), mStatusBar, SLOT(selectionChanged (KTextEditor::View *)));
  connect(v, SIGNAL(informationMessage (KTextEditor::View *, const QString &)), mStatusBar, SLOT(informationMessage (KTextEditor::View *, const QString &)));
  connect(v->document(), SIGNAL(modifiedChanged(KTextEditor::Document *)), mStatusBar, SLOT(modifiedChanged()));
  connect(v->document(), SIGNAL(modifiedOnDisk(KTextEditor::Document *, bool, KTextEditor::ModificationInterface::ModifiedOnDiskReason)), mStatusBar, SLOT(modifiedChanged()) );
  connect(v->document(), SIGNAL(documentNameChanged(KTextEditor::Document *)), mStatusBar, SLOT(documentNameChanged()));
}

void KateViewSpace::removeView(KTextEditor::View* v)
{
  bool active = ( v == currentView() );

  mViewList.removeAt ( mViewList.indexOf ( v ) );
  stack->removeWidget (v);

  if ( ! active )
    return;

  // the last recently used viewspace is always at the end of the list
  if (!mViewList.isEmpty())
    showView(mViewList.last());
}

bool KateViewSpace::showView(KTextEditor::Document *document)
{
  QList<KTextEditor::View*>::const_iterator it = mViewList.constEnd();
  while( it != mViewList.constBegin() )
  {
    --it;
    if ((*it)->document() == document)
    {
      KTextEditor::View* kv = *it;

      // move view to end of list
      mViewList.removeAt( mViewList.indexOf(kv) );
      mViewList.append( kv );
      stack->setCurrentWidget( kv );
      kv->show();

      mStatusBar->updateStatus ();

      return true;
    }
  }
  return false;
}

KTextEditor::View* KateViewSpace::currentView()
{
  // stack->currentWidget() returns NULL, if stack.count() == 0,
  // i.e. if mViewList.isEmpty()
  return (KTextEditor::View*)stack->currentWidget();
}

bool KateViewSpace::isActiveSpace()
{
  return mIsActiveSpace;
}

void KateViewSpace::setActive( bool active, bool )
{
  mIsActiveSpace = active;

  // change the statusbar palette and make sure it gets updated
  QPalette pal( palette() );
  if ( ! active )
  {
    pal.setColor( QPalette::Window, pal.color(QPalette::Window).dark() );
    pal.setColor( QPalette::Light, pal.color(QPalette::Light).light() );
  }

  mStatusBar->setPalette( pal );
  mStatusBar->update();
}

bool KateViewSpace::event( QEvent *e )
{
  if ( e->type() == QEvent::PaletteChange )
  {
    setActive( mIsActiveSpace );
    return true;
  }
  return KVBox::event( e );
}

void KateViewSpace::saveConfig ( KConfigBase* config, int myIndex , const QString& viewConfGrp)
{
//   kDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")";
  QString groupname = QString(viewConfGrp + "-ViewSpace %1").arg( myIndex );

  KConfigGroup group (config, groupname);
  group.writeEntry ("Count", mViewList.count());

  if (currentView())
    group.writeEntry( "Active View", currentView()->document()->url().prettyUrl() );

  // Save file list, including cursor position in this instance.
  int idx = 0;
  for (QList<KTextEditor::View*>::iterator it = mViewList.begin();
       it != mViewList.end(); ++it)
  {
    if ( !(*it)->document()->url().isEmpty() )
    {
      group.writeEntry( QString("View %1").arg( idx ), (*it)->document()->url().prettyUrl() );

      // view config, group: "ViewSpace <n> url"
      QString vgroup = QString("%1 %2").arg(groupname).arg((*it)->document()->url().prettyUrl());
      KConfigGroup viewGroup( config, vgroup );

      if (KTextEditor::SessionConfigInterface *iface = qobject_cast<KTextEditor::SessionConfigInterface *>(*it))
        iface->writeSessionConfig( viewGroup );
    }

    ++idx;
  }
}

void KateViewSpace::restoreConfig ( KateViewManager *viewMan, const KConfigBase* config, const QString &groupname )
{
  KConfigGroup group (config, groupname);
  QString fn = group.readEntry( "Active View" );

  if ( !fn.isEmpty() )
  {
    KTextEditor::Document *doc = KateDocManager::self()->findDocument (KUrl(fn));

    if (doc)
    {
      // view config, group: "ViewSpace <n> url"
      QString vgroup = QString("%1 %2").arg(groupname).arg(fn);
      KConfigGroup configGroup( config, vgroup );

      viewMan->createView (doc);

      KTextEditor::View *v = viewMan->activeView ();

      if (KTextEditor::SessionConfigInterface *iface = qobject_cast<KTextEditor::SessionConfigInterface *>(v))
        iface->readSessionConfig( configGroup );
    }
  }

  if (mViewList.isEmpty())
    viewMan->createView (KateDocManager::self()->document(0));

  m_group = groupname; // used for restroing view configs later
}
//END KateViewSpace

//BEGIN KateVSStatusBar
KateVSStatusBar::KateVSStatusBar ( KateViewSpace *parent)
    : KStatusBar( parent),
    m_viewSpace( parent )
{
  QString lineColText = i18n(" Line: %1 Col: %2 ", KGlobal::locale()->formatNumber(4444, 0),
         KGlobal::locale()->formatNumber(44, 0));

  m_lineColLabel = new QLabel( this );
  m_lineColLabel->setMinimumWidth( m_lineColLabel->fontMetrics().width( lineColText ) );
  addWidget( m_lineColLabel, 0 );
  m_lineColLabel->installEventFilter( this );

  m_modifiedLabel = new QLabel( this );
  m_modifiedLabel->setFixedSize( 16, 16 );
  addWidget( m_modifiedLabel, 0 );
  m_modifiedLabel->setAlignment( Qt::AlignCenter );
  m_modifiedLabel->installEventFilter( this );

  m_insertModeLabel = new QLabel( i18n(" INS "), this );
  addWidget( m_insertModeLabel, 0 );
  m_insertModeLabel->setAlignment( Qt::AlignCenter );
  m_insertModeLabel->installEventFilter( this );

  m_selectModeLabel = new QLabel( i18n(" LINE "), this );
  addWidget( m_selectModeLabel, 0 );
  m_selectModeLabel->setAlignment( Qt::AlignCenter );
  m_selectModeLabel->installEventFilter( this );

  m_fileNameLabel = new KSqueezedTextLabel( this );
  addPermanentWidget( m_fileNameLabel, 1 );
  m_fileNameLabel->setMinimumSize( 0, 0 );
  m_fileNameLabel->setSizePolicy(QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed ));
  m_fileNameLabel->setAlignment( /*Qt::AlignRight*/Qt::AlignLeft );
  m_fileNameLabel->installEventFilter( this );

#ifdef Q_WS_MAC
  setSizeGripEnabled( false );
  addPermanentWidget( new QSizeGrip( this ) );
#endif

  installEventFilter( this );
  m_modPm = KIcon("modified").pixmap(16);
  m_modDiscPm = KIcon("modonhd").pixmap(16);
  m_modmodPm = KIcon("modmod").pixmap(16);
}

KateVSStatusBar::~KateVSStatusBar ()
{}

void KateVSStatusBar::showMenu()
{
  KXmlGuiWindow* mainWindow = static_cast<KXmlGuiWindow*>( window() );
  QMenu* menu = static_cast<QMenu*>( mainWindow->factory()->container("viewspace_popup", mainWindow ) );

  if (menu)
    menu->exec(QCursor::pos());
}

bool KateVSStatusBar::eventFilter(QObject*, QEvent *e)
{
  if (e->type() == QEvent::MouseButtonPress)
  {
    if ( m_viewSpace->currentView() )
      m_viewSpace->currentView()->setFocus();

    if ( ((QMouseEvent*)e)->button() == Qt::RightButton)
      showMenu();

    return true;
  }

  return false;
}

void KateVSStatusBar::updateStatus ()
{
  if (!m_viewSpace->currentView())
    return;

  KTextEditor::View* view = m_viewSpace->currentView();
  viewModeChanged (view);
  cursorPositionChanged (view);
  selectionChanged (view);
  modifiedChanged ();
  documentNameChanged ();
}

void KateVSStatusBar::viewModeChanged ( KTextEditor::View *view )
{
  if (view != m_viewSpace->currentView())
    return;

  m_insertModeLabel->setText( view->viewMode() );
}

void KateVSStatusBar::cursorPositionChanged ( KTextEditor::View *view )
{
  if (view != m_viewSpace->currentView())
    return;

  KTextEditor::Cursor position (view->cursorPositionVirtual());

  m_lineColLabel->setText(
    i18n(" Line: %1 Col: %2 ", KGlobal::locale()->formatNumber(position.line() + 1, 0),
         KGlobal::locale()->formatNumber(position.column() + 1, 0)) );
}

void KateVSStatusBar::selectionChanged (KTextEditor::View *view)
{
  if (view != m_viewSpace->currentView())
    return;

  m_selectModeLabel->setText( view->blockSelection() ? i18n(" BLOCK ") : i18n(" LINE ") );
}

void KateVSStatusBar::informationMessage (KTextEditor::View *view, const QString &message)
{
  if (view != m_viewSpace->currentView())
    return;

  m_fileNameLabel->setText( message );

  // timer to reset this after 4 seconds
  QTimer::singleShot(4000, this, SLOT(documentNameChanged()));
}

void KateVSStatusBar::modifiedChanged()
{
  KTextEditor::View *v = m_viewSpace->currentView();

  if ( v )
  {
    bool mod = v->document()->isModified();

    const KateDocumentInfo *info
    = KateDocManager::self()->documentInfo ( v->document() );

    bool modOnHD = info && info->modifiedOnDisc;

    m_modifiedLabel->setPixmap(
      mod ?
      info && modOnHD ?
      m_modmodPm :
  m_modPm :
      info && modOnHD ?
      m_modDiscPm :
      QPixmap()
    );
  }
}

void KateVSStatusBar::documentNameChanged ()
{
  KTextEditor::View *v = m_viewSpace->currentView();

  if ( v )
    m_fileNameLabel->setText( KStringHandler::lsqueeze(v->document()->documentName (), 64) );
}

//END KateVSStatusBar

// kate: space-indent on; indent-width 2; replace-tabs on;
<|endoftext|>


<commit_before><commit_msg>Cleanup: Formatting code<commit_after><|endoftext|>


<commit_before><commit_msg>type changed for sprintf<commit_after><|endoftext|>


<commit_before><commit_msg>[Game] Tiger is running!<commit_after><|endoftext|>


<commit_before><commit_msg>unbuffered mode for solaris<commit_after><|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2004  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library 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
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <iomanip>
#include <fstream>
#include <stdio.h>
#include <string.h>

// Local includes
#include "mesh.h"
#include "libmesh_config.h"
#include "medit_io.h"

// ------------------------------------------------------------
// MEDITIO  members
void MEDITIO::write (const std::string& fname)
{
  if (libMesh::processor_id() == 0)
    if (!this->binary())
      this->write_ascii  (fname);
}

void MEDITIO::write_nodal_data (const std::string& fname,
			      const std::vector<Number>& soln,
			      const std::vector<std::string>& names)
{
  if (libMesh::processor_id() == 0)
    if (!this->binary())
      this->write_ascii  (fname, &soln, &names);
}

void MEDITIO::write_ascii (const std::string& fname,
			   const std::vector<Number>* vec,
			   const std::vector<std::string>* solution_names)
{
  // Current lacks in implementation:
  //  (i)   only 3D meshes.
  //  (ii)  only QUAD4, TRI3, TET4 elements, others are omitted !
  //  (iii) no distinction between materials.
  //  (iv)  no vector output, just first scalar as output

  // assert three dimensions (should be extended later)
  assert (this->cmesh().mesh_dimension() == 3);

  // Open the output file stream
  std::ofstream out (fname.c_str());

  assert (out.good());

  // Get a reference to the mesh
  const MeshBase& mesh = this->cmesh();

  // Begin interfacing with the MEdit data file
  {
    // header:
    out << "MeshVersionFormatted  1\n";
    out << "Dimension  3\n";
    out << "# Mesh generated by libmesh\n\n";

    // write the nodes:
    out << "# Set of mesh vertices\n";
    out << "Vertices\n";
    out << mesh.n_nodes() << "\n";

    for (unsigned int v=0; v<mesh.n_nodes(); v++)
      out << mesh.point(v)(0) << " " << mesh.point(v)(1) << " " << mesh.point(v)(2) << " 0\n";
  }

  {
    // write the connectivity:
    out << "\n# Set of Polys\n\n";

    // count occurrences of output elements:
    int n_tri3  = 0;
    int n_quad4 = 0;
    int n_tet4  = 0;

    const_active_elem_iterator       it (mesh.elements_begin());
    const const_active_elem_iterator end(mesh.elements_end());

    for ( ; it != end; ++it) {
      if ((*it)->type() == TRI3)  n_tri3++;
      if ((*it)->type() == QUAD4) n_quad4++;
      if ((*it)->type() == QUAD9) n_quad4+=4; // (QUAD9 is written as 4 QUAD4.)
      if ((*it)->type() == TET4)  n_tet4++;
    } // for

    // First: write out TRI3 elements:
    out << "Triangles\n";
    out << n_tri3 << "\n";

    for (it=mesh.elements_begin() ; it != end; ++it)
      if ((*it)->type() == TRI3) {
	out << (*it)->node(0)+1  << " " << (*it)->node(1)+1  << " " << (*it)->node(2)+1  << " 0\n";
      } // if

    // Second: write out QUAD4 elements:
    out << "Quadrilaterals\n";
    out << n_quad4 << "\n";

    for (it=mesh.elements_begin() ; it != end; ++it)
      if ((*it)->type() == QUAD4) {
	out << (*it)->node(0)+1  << " "
	    << (*it)->node(1)+1  << " "
	    << (*it)->node(2)+1  << " "
	    << (*it)->node(3)+1  <<" 0\n";
      } // if
      else if ((*it)->type() == QUAD9) {
	out << (*it)->node(0)+1  << " "
	    << (*it)->node(4)+1  << " "
	    << (*it)->node(8)+1  << " "
	    << (*it)->node(7)+1  <<" 0\n";
	out << (*it)->node(7)+1  << " "
	    << (*it)->node(8)+1  << " "
	    << (*it)->node(6)+1  << " "
	    << (*it)->node(3)+1  <<" 0\n";
	out << (*it)->node(4)+1  << " "
	    << (*it)->node(1)+1  << " "
	    << (*it)->node(5)+1  << " "
	    << (*it)->node(8)+1  <<" 0\n";
	out << (*it)->node(8)+1  << " "
	    << (*it)->node(5)+1  << " "
	    << (*it)->node(2)+1  << " "
	    << (*it)->node(6)+1  <<" 0\n";
      } // if

    // Third: write out TET4 elements:
    out << "Tetrahedra\n";
    out << n_tet4 << "\n";

    for (it=mesh.elements_begin() ; it != end; ++it)
      if ((*it)->type() == TET4) {
	out << (*it)->node(0)+1  << " "
	    << (*it)->node(1)+1  << " "
	    << (*it)->node(2)+1  << " "
	    << (*it)->node(3)+1  <<" 0\n";
      } // if
  }
  // end of the out file
  out << std::endl << "# end of file" << std::endl;

  // optionally write the data
  if ((solution_names != NULL) &&
      (vec != NULL))
    {
      // Open the ".bb" file stream
      int idx = fname.find_last_of(".");
      string bbname = fname.substr(0,idx) + ".bb";

      std::ofstream bbout (bbname.c_str());
      assert (bbout.good());

      // Header: 3: 3D mesh, 1: scalar output, 2: node-indexed
      const unsigned int n_vars = solution_names->size();
      bbout << "3 1 " << mesh.n_nodes() << " 2\n";
      for (unsigned int n=0; n<mesh.n_nodes(); n++)
	bbout << std::setprecision(10) << (*vec)[n*n_vars + scalar_idx] << " ";
      bbout << "\n";
    } // endif
}

<commit_msg>Changed string to std::string in one place.<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2004  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library 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
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <iomanip>
#include <fstream>
#include <stdio.h>
#include <string.h>

// Local includes
#include "mesh.h"
#include "libmesh_config.h"
#include "medit_io.h"

// ------------------------------------------------------------
// MEDITIO  members
void MEDITIO::write (const std::string& fname)
{
  if (libMesh::processor_id() == 0)
    if (!this->binary())
      this->write_ascii  (fname);
}

void MEDITIO::write_nodal_data (const std::string& fname,
			      const std::vector<Number>& soln,
			      const std::vector<std::string>& names)
{
  if (libMesh::processor_id() == 0)
    if (!this->binary())
      this->write_ascii  (fname, &soln, &names);
}

void MEDITIO::write_ascii (const std::string& fname,
			   const std::vector<Number>* vec,
			   const std::vector<std::string>* solution_names)
{
  // Current lacks in implementation:
  //  (i)   only 3D meshes.
  //  (ii)  only QUAD4, TRI3, TET4 elements, others are omitted !
  //  (iii) no distinction between materials.
  //  (iv)  no vector output, just first scalar as output

  // assert three dimensions (should be extended later)
  assert (this->cmesh().mesh_dimension() == 3);

  // Open the output file stream
  std::ofstream out (fname.c_str());

  assert (out.good());

  // Get a reference to the mesh
  const MeshBase& mesh = this->cmesh();

  // Begin interfacing with the MEdit data file
  {
    // header:
    out << "MeshVersionFormatted  1\n";
    out << "Dimension  3\n";
    out << "# Mesh generated by libmesh\n\n";

    // write the nodes:
    out << "# Set of mesh vertices\n";
    out << "Vertices\n";
    out << mesh.n_nodes() << "\n";

    for (unsigned int v=0; v<mesh.n_nodes(); v++)
      out << mesh.point(v)(0) << " " << mesh.point(v)(1) << " " << mesh.point(v)(2) << " 0\n";
  }

  {
    // write the connectivity:
    out << "\n# Set of Polys\n\n";

    // count occurrences of output elements:
    int n_tri3  = 0;
    int n_quad4 = 0;
    int n_tet4  = 0;

    const_active_elem_iterator       it (mesh.elements_begin());
    const const_active_elem_iterator end(mesh.elements_end());

    for ( ; it != end; ++it) {
      if ((*it)->type() == TRI3)  n_tri3++;
      if ((*it)->type() == QUAD4) n_quad4++;
      if ((*it)->type() == QUAD9) n_quad4+=4; // (QUAD9 is written as 4 QUAD4.)
      if ((*it)->type() == TET4)  n_tet4++;
    } // for

    // First: write out TRI3 elements:
    out << "Triangles\n";
    out << n_tri3 << "\n";

    for (it=mesh.elements_begin() ; it != end; ++it)
      if ((*it)->type() == TRI3) {
	out << (*it)->node(0)+1  << " " << (*it)->node(1)+1  << " " << (*it)->node(2)+1  << " 0\n";
      } // if

    // Second: write out QUAD4 elements:
    out << "Quadrilaterals\n";
    out << n_quad4 << "\n";

    for (it=mesh.elements_begin() ; it != end; ++it)
      if ((*it)->type() == QUAD4) {
	out << (*it)->node(0)+1  << " "
	    << (*it)->node(1)+1  << " "
	    << (*it)->node(2)+1  << " "
	    << (*it)->node(3)+1  <<" 0\n";
      } // if
      else if ((*it)->type() == QUAD9) {
	out << (*it)->node(0)+1  << " "
	    << (*it)->node(4)+1  << " "
	    << (*it)->node(8)+1  << " "
	    << (*it)->node(7)+1  <<" 0\n";
	out << (*it)->node(7)+1  << " "
	    << (*it)->node(8)+1  << " "
	    << (*it)->node(6)+1  << " "
	    << (*it)->node(3)+1  <<" 0\n";
	out << (*it)->node(4)+1  << " "
	    << (*it)->node(1)+1  << " "
	    << (*it)->node(5)+1  << " "
	    << (*it)->node(8)+1  <<" 0\n";
	out << (*it)->node(8)+1  << " "
	    << (*it)->node(5)+1  << " "
	    << (*it)->node(2)+1  << " "
	    << (*it)->node(6)+1  <<" 0\n";
      } // if

    // Third: write out TET4 elements:
    out << "Tetrahedra\n";
    out << n_tet4 << "\n";

    for (it=mesh.elements_begin() ; it != end; ++it)
      if ((*it)->type() == TET4) {
	out << (*it)->node(0)+1  << " "
	    << (*it)->node(1)+1  << " "
	    << (*it)->node(2)+1  << " "
	    << (*it)->node(3)+1  <<" 0\n";
      } // if
  }
  // end of the out file
  out << std::endl << "# end of file" << std::endl;

  // optionally write the data
  if ((solution_names != NULL) &&
      (vec != NULL))
    {
      // Open the ".bb" file stream
      int idx = fname.find_last_of(".");
      std::string bbname = fname.substr(0,idx) + ".bb";

      std::ofstream bbout (bbname.c_str());
      assert (bbout.good());

      // Header: 3: 3D mesh, 1: scalar output, 2: node-indexed
      const unsigned int n_vars = solution_names->size();
      bbout << "3 1 " << mesh.n_nodes() << " 2\n";
      for (unsigned int n=0; n<mesh.n_nodes(); n++)
	bbout << std::setprecision(10) << (*vec)[n*n_vars + scalar_idx] << " ";
      bbout << "\n";
    } // endif
}

<|endoftext|>