<commit_before>
#include <torch/torch.h>
#include <vector>

std::vector<at::Tensor> cpu_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x);

std::vector<at::Tensor> cpu_bi_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x);

float sigmoidf(float x);
float reluf(float x);
float seluf(float x);
float apply_activation(int64_t type, float x);

/* Implementation starts here */

#define CHECK_CONTIGUOUS(x) AT_ASSERTM(x.is_contiguous(), #x " must be contiguous")
#define CHECK_FLOAT(x) AT_ASSERTM(x.type().scalarType() == at::ScalarType::Float, #x " must be float")

std::vector<at::Tensor> cpu_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,  // U is [length, batch_size, hidden_size*k]
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x) {

    CHECK_FLOAT(U);
    CHECK_CONTIGUOUS(U);
    CHECK_CONTIGUOUS(x);
    CHECK_CONTIGUOUS(weight_c);
    CHECK_CONTIGUOUS(bias);
    CHECK_CONTIGUOUS(c_init);
    CHECK_CONTIGUOUS(mask_pad);

    const int ncols = batch_size * hidden_size;
    const int ncols_u = batch_size * hidden_size * k;

    // pointers to parameters
    const float* forget_w_ptr = weight_c.data<float>();
    const float* reset_w_ptr = forget_w_ptr + hidden_size;
    const float* forget_b_ptr = bias.data<float>();
    const float* reset_b_ptr = forget_b_ptr + hidden_size;
    const float* U_ptr = U.data<float>();
    const float* x_ptr = x.data<float>();
    const float* pad_ptr = (mask_pad.numel() == 0) ? NULL :
                                    mask_pad.data<float>();

    auto h = at::zeros({length, batch_size, hidden_size}, U.options());
    auto c = c_init.clone();
    auto h_ptr = h.data<float>();
    auto c_ptr = c.data<float>();

    for (int l = 0; l < length; l++) {
        for (int i = 0; i < batch_size; i++) {
            // skip pad tokens
            if (pad_ptr && pad_ptr[l*batch_size]) continue;
            for (int j = 0; j < hidden_size; j++) {
                const int offset = i*hidden_size+j;

                // U[l,i,j,*]
                const float* u = U_ptr + l*ncols_u + offset*k;
                const float u0 = u[0];
                const float u1 = u[1];
                const float u2 = u[2];

                const float fw = forget_w_ptr[j];
                const float rw = reset_w_ptr[j];
                const float fb = forget_b_ptr[j];
                const float rb = reset_b_ptr[j];

                const float prev_c = c_ptr[offset];

                // forget gate
                const float fg = sigmoidf(u1 + fw*prev_c + fb);
                // reset gate
                const float rg = sigmoidf(u2 + rw*prev_c + rb);

                const float c_val = (prev_c - u0) * fg + u0; // prev_c * fg + u0 * (1 - fg);
                const float gc_val = apply_activation(activation_type, c_val);

                const float x_val = has_skip_term ? ((k == 4) ? u[3] : x_ptr[l*ncols + offset]*scale_x) : 0;
                const float h_val = (gc_val - x_val) * rg + x_val; // gc_val * rg + x_val * (1 - rg);

                h_ptr[l*ncols + offset] = h_val;
                c_ptr[offset] = c_val;
            }
        }
    }
    return {h, c};
}

std::vector<at::Tensor> cpu_bi_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,  // U is [length, batch_size, 2*hidden_size*k]
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x) {

    CHECK_FLOAT(U);
    CHECK_CONTIGUOUS(U);
    CHECK_CONTIGUOUS(x);
    CHECK_CONTIGUOUS(weight_c);
    CHECK_CONTIGUOUS(bias);
    CHECK_CONTIGUOUS(c_init);
    CHECK_CONTIGUOUS(mask_pad);

    const int ncols = batch_size * hidden_size * 2;
    const int ncols_u = batch_size * hidden_size * 2 * k;

    // pointers to parameters
    const float* forget_w_ptr = weight_c.data<float>();
    const float* reset_w_ptr = forget_w_ptr + hidden_size*2;
    const float* forget_b_ptr = bias.data<float>();
    const float* reset_b_ptr = forget_b_ptr + hidden_size*2;
    const float* U_ptr = U.data<float>();
    const float* x_ptr = x.data<float>();
    const float* pad_ptr = (mask_pad.numel() == 0) ? NULL :
                                    mask_pad.data<float>();

    auto h = at::zeros({length, batch_size, hidden_size*2}, U.options());
    auto c = c_init.clone();
    auto h_ptr = h.data<float>();
    auto c_ptr = c.data<float>();

    for (int l = 0; l < length; l++) {
        for (int i = 0; i < batch_size; i++) {
            for (int j = 0; j < hidden_size*2; j++) {
                // skip pad tokens
                int l_ = (j < hidden_size) ? l : (length - l - 1);
                if (pad_ptr && pad_ptr[l_*batch_size]) continue;

                const int offset = i*hidden_size*2+j;

                // U[l_,i,j,*]
                const float* u = U_ptr + l_*ncols_u + offset*k;
                const float u0 = u[0];
                const float u1 = u[1];
                const float u2 = u[2];

                const float fw = forget_w_ptr[j];
                const float rw = reset_w_ptr[j];
                const float fb = forget_b_ptr[j];
                const float rb = reset_b_ptr[j];

                const float prev_c = c_ptr[offset];

                // forget gate
                const float fg = sigmoidf(u1 + fw*prev_c + fb);
                // reset gate
                const float rg = sigmoidf(u2 + rw*prev_c + rb);

                const float c_val = (prev_c - u0) * fg + u0; // prev_c * fg + u0 * (1 - fg);
                const float gc_val = apply_activation(activation_type, c_val);

                const float x_val = has_skip_term ? ((k == 4) ? u[3] : x_ptr[l_*ncols + offset]*scale_x) : 0;
                const float h_val = (gc_val - x_val) * rg + x_val; // gc_val * rg + x_val * (1 - rg);

                h_ptr[l_*ncols + offset] = h_val;
                c_ptr[offset] = c_val;
            }
        }
    }
    return {h, c};
}

inline float sigmoidf(float x) {
    return 1.f / (1.f + expf(-x));
}

inline float reluf(float x) {
    return (x > 0.f) ? x : 0.f;
}

inline float seluf(float x) {
    return 1.0507009873554804934193349852946f * (
        (x > 0.f) ? x : 1.6732632423543772848170429916717f * (expf(x)-1.f)
    );
}

inline float apply_activation(int64_t type, float x) {
    switch (type) {
        case 0:
            return x;
        case 1:
            return tanhf(x);
        case 2:
            return reluf(x);
        case 3:
            return seluf(x);
    }
    return x;
}

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
  m.def("cpu_forward", &cpu_forward, "SRU forward (CPU version)");
  m.def("cpu_bi_forward", &cpu_bi_forward, "SRU bidirectional forward (CPU version)");
}
<commit_msg>add comments<commit_after>
#include <torch/torch.h>
#include <vector>

//  unidirectional forward()
std::vector<at::Tensor> cpu_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x);
//  k: the number of sub-matrices in grouped multiplication
//  U: the result of grouped multiplication
//  The size of U is [length, batch_size, hidden_size, k]

//  bidirectional forward()
std::vector<at::Tensor> cpu_bi_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x);
//  k: the number of sub-matrices in grouped multiplication
//  U: the result of grouped multiplication
//  The size of U is [length, batch_size, 2*hidden_size, k]

float sigmoidf(float x);
float reluf(float x);
float seluf(float x);
float apply_activation(int64_t type, float x);

/* Implementation starts here */

#define CHECK_CONTIGUOUS(x) AT_ASSERTM(x.is_contiguous(), #x " must be contiguous")
#define CHECK_FLOAT(x) AT_ASSERTM(x.type().scalarType() == at::ScalarType::Float, #x " must be float")

std::vector<at::Tensor> cpu_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,  // U is [length, batch_size, hidden_size*k]
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x) {

    CHECK_FLOAT(U);
    CHECK_CONTIGUOUS(U);
    CHECK_CONTIGUOUS(x);
    CHECK_CONTIGUOUS(weight_c);
    CHECK_CONTIGUOUS(bias);
    CHECK_CONTIGUOUS(c_init);
    CHECK_CONTIGUOUS(mask_pad);

    const int ncols = batch_size * hidden_size;
    const int ncols_u = batch_size * hidden_size * k;

    // pointers to parameters
    const float* forget_w_ptr = weight_c.data<float>();
    const float* reset_w_ptr = forget_w_ptr + hidden_size;
    const float* forget_b_ptr = bias.data<float>();
    const float* reset_b_ptr = forget_b_ptr + hidden_size;
    const float* U_ptr = U.data<float>();
    const float* x_ptr = x.data<float>();
    const float* pad_ptr = (mask_pad.numel() == 0) ? NULL :
                                    mask_pad.data<float>();

    auto h = at::zeros({length, batch_size, hidden_size}, U.options());
    auto c = c_init.clone();
    auto h_ptr = h.data<float>();
    auto c_ptr = c.data<float>();

    for (int l = 0; l < length; l++) {
        for (int i = 0; i < batch_size; i++) {
            // skip pad tokens
            if (pad_ptr && pad_ptr[l*batch_size]) continue;
            for (int j = 0; j < hidden_size; j++) {
                const int offset = i*hidden_size+j;

                // U[l,i,j,*]
                const float* u = U_ptr + l*ncols_u + offset*k;
                const float u0 = u[0];
                const float u1 = u[1];
                const float u2 = u[2];

                const float fw = forget_w_ptr[j];
                const float rw = reset_w_ptr[j];
                const float fb = forget_b_ptr[j];
                const float rb = reset_b_ptr[j];

                const float prev_c = c_ptr[offset];

                // forget gate
                const float fg = sigmoidf(u1 + fw*prev_c + fb);
                // reset gate
                const float rg = sigmoidf(u2 + rw*prev_c + rb);

                const float c_val = (prev_c - u0) * fg + u0; // prev_c * fg + u0 * (1 - fg);
                const float gc_val = apply_activation(activation_type, c_val);

                const float x_val = has_skip_term ? ((k == 4) ? u[3] : x_ptr[l*ncols + offset]*scale_x) : 0;
                const float h_val = (gc_val - x_val) * rg + x_val; // gc_val * rg + x_val * (1 - rg);

                h_ptr[l*ncols + offset] = h_val;
                c_ptr[offset] = c_val;
            }
        }
    }
    return {h, c};
}

std::vector<at::Tensor> cpu_bi_forward(
        const at::Tensor & U,
        const at::Tensor & x,
        const at::Tensor & weight_c,
        const at::Tensor & bias,
        const at::Tensor & c_init,
        const at::Tensor & mask_pad,
        const int64_t length,
        const int64_t batch_size,
        const int64_t hidden_size,
        const int64_t k,  // U is [length, batch_size, 2*hidden_size*k]
        const int64_t activation_type,
        const bool has_skip_term,
        const double scale_x) {

    CHECK_FLOAT(U);
    CHECK_CONTIGUOUS(U);
    CHECK_CONTIGUOUS(x);
    CHECK_CONTIGUOUS(weight_c);
    CHECK_CONTIGUOUS(bias);
    CHECK_CONTIGUOUS(c_init);
    CHECK_CONTIGUOUS(mask_pad);

    const int ncols = batch_size * hidden_size * 2;
    const int ncols_u = batch_size * hidden_size * 2 * k;

    // pointers to parameters
    const float* forget_w_ptr = weight_c.data<float>();
    const float* reset_w_ptr = forget_w_ptr + hidden_size*2;
    const float* forget_b_ptr = bias.data<float>();
    const float* reset_b_ptr = forget_b_ptr + hidden_size*2;
    const float* U_ptr = U.data<float>();
    const float* x_ptr = x.data<float>();
    const float* pad_ptr = (mask_pad.numel() == 0) ? NULL :
                                    mask_pad.data<float>();

    auto h = at::zeros({length, batch_size, hidden_size*2}, U.options());
    auto c = c_init.clone();
    auto h_ptr = h.data<float>();
    auto c_ptr = c.data<float>();

    for (int l = 0; l < length; l++) {
        for (int i = 0; i < batch_size; i++) {
            for (int j = 0; j < hidden_size*2; j++) {
                // skip pad tokens
                int l_ = (j < hidden_size) ? l : (length - l - 1);
                if (pad_ptr && pad_ptr[l_*batch_size]) continue;

                const int offset = i*hidden_size*2+j;

                // U[l_,i,j,*]
                const float* u = U_ptr + l_*ncols_u + offset*k;
                const float u0 = u[0];
                const float u1 = u[1];
                const float u2 = u[2];

                const float fw = forget_w_ptr[j];
                const float rw = reset_w_ptr[j];
                const float fb = forget_b_ptr[j];
                const float rb = reset_b_ptr[j];

                const float prev_c = c_ptr[offset];

                // forget gate
                const float fg = sigmoidf(u1 + fw*prev_c + fb);
                // reset gate
                const float rg = sigmoidf(u2 + rw*prev_c + rb);

                const float c_val = (prev_c - u0) * fg + u0; // prev_c * fg + u0 * (1 - fg);
                const float gc_val = apply_activation(activation_type, c_val);

                const float x_val = has_skip_term ? ((k == 4) ? u[3] : x_ptr[l_*ncols + offset]*scale_x) : 0;
                const float h_val = (gc_val - x_val) * rg + x_val; // gc_val * rg + x_val * (1 - rg);

                h_ptr[l_*ncols + offset] = h_val;
                c_ptr[offset] = c_val;
            }
        }
    }
    return {h, c};
}

inline float sigmoidf(float x) {
    return 1.f / (1.f + expf(-x));
}

inline float reluf(float x) {
    return (x > 0.f) ? x : 0.f;
}

inline float seluf(float x) {
    return 1.0507009873554804934193349852946f * (
        (x > 0.f) ? x : 1.6732632423543772848170429916717f * (expf(x)-1.f)
    );
}

inline float apply_activation(int64_t type, float x) {
    switch (type) {
        case 0:
            return x;
        case 1:
            return tanhf(x);
        case 2:
            return reluf(x);
        case 3:
            return seluf(x);
    }
    return x;
}

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
  m.def("cpu_forward", &cpu_forward, "SRU forward (CPU version)");
  m.def("cpu_bi_forward", &cpu_bi_forward, "SRU bidirectional forward (CPU version)");
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <kernel/context.hpp>
#include <cstdint>

extern "C" void __context_switch(uintptr_t stack);

static Context::context_func destination;
extern "C"
void __context_switch_delegate()
{
  destination();
}

void Context::jump(void* location, context_func func)
{
  // store so we can call it later
  destination = func;
  assert(destination);
  // switch to stack from @location
  __context_switch((uintptr_t) location);
}

void Context::create(unsigned stack_size, context_func func)
{
  // store so we can call it later
  destination = func;
  assert(destination);
  // create and switch to new stack
  char* stack_mem = new char[stack_size];
  assert(stack_mem);
  uintptr_t start = (uintptr_t) (stack_mem+stack_size) & ~0xF;
  __context_switch(start);
  delete[] stack_mem;
}
<commit_msg>context: Remove unnecessary checks, add comment<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// 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 <kernel/context.hpp>
#include <cstdint>

extern "C" void __context_switch(uintptr_t stack);

static Context::context_func destination;
extern "C"
void __context_switch_delegate()
{
  destination();
}

void Context::jump(void* location, context_func func)
{
  // store so we can call it later
  destination = func;
  // switch to stack from @location
  __context_switch((uintptr_t) location);
}

void Context::create(unsigned stack_size, context_func func)
{
  // store so we can call it later
  destination = func;
  // create and switch to new stack
  char* stack_mem = new char[stack_size];
  assert(stack_mem);
  // aligned to 16 byte boundary
  uintptr_t start = (uintptr_t) (stack_mem+stack_size) & ~0xF;
  __context_switch(start);
  delete[] stack_mem;
}
<|endoftext|>


<commit_before>// Copyright 2013 Tanel Lebedev

#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "./kopsik_api.h"
#include "./https_client.h"

#include "Poco/FileStream.h"
#include "Poco/File.h"

#define TESTDB "test.db"
#define ERRLEN 1024

namespace kopsik {

    class MockHTTPSClient : public HTTPSClient {
    public:
        MockHTTPSClient() : HTTPSClient("https://localhost:8088") {}
        MOCK_METHOD0(ListenToWebsocket, kopsik::error());
        MOCK_METHOD5(PostJSON, kopsik::error(
            std::string relative_url,
            std::string json,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
        MOCK_METHOD4(GetJSON, kopsik::error(
            std::string relative_url,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
    };

    TEST(KopsikApiTest, kopsik_context_init) {
        KopsikContext *ctx = kopsik_context_init();
        ASSERT_TRUE(ctx);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_version) {
        int major = 0;
        int minor = 0;
        int patch = 0;
        kopsik_version(&major, &minor, &patch);
        ASSERT_TRUE(major || minor || patch);
    }

    TEST(KopsikApiTest, kopsik_set_proxy) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_proxy(ctx, "localhost", 8000, "johnsmith", "secret");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_set_db_path) {
        KopsikContext *ctx = kopsik_context_init();
        {
            Poco::File f(TESTDB);
            if (f.exists()) f.remove(false);
        }
        kopsik_set_db_path(ctx, TESTDB);
        kopsik_context_clear(ctx);
        Poco::File f(TESTDB);
        ASSERT_TRUE(f.exists());
    }

    TEST(KopsikApiTest, kopsik_set_log_path) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_log_path(ctx, "test.log");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_user_init) {
        KopsikUser *user = kopsik_user_init();
        ASSERT_TRUE(user);
        kopsik_user_clear(user);
    }

    TEST(KopsikApiTest, kopsik_set_api_token) {
        KopsikContext *ctx = kopsik_context_init();
        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_set_api_token(ctx, err, ERRLEN, "token"));
        const int kMaxStrLen = 10;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("token", std::string(str));
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_lifecycle) {
        KopsikContext *ctx = kopsik_context_init();

        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);

        kopsik::HTTPSClient *client =
            reinterpret_cast<HTTPSClient *>(ctx->https_client);
        delete client;
        MockHTTPSClient *mock_client = new MockHTTPSClient();
        ctx->https_client = mock_client;

        Poco::FileStream fis("testdata/me.json", std::ios::binary);
        std::stringstream ss;
        ss << fis.rdbuf();
        fis.close();
        std::string json = ss.str();

        // Login
        EXPECT_CALL(*mock_client, GetJSON(
            std::string("/api/v8/me?app_name=kopsik&with_related_data=true"),
            std::string("foo@bar.com"),
            std::string("secret"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<3>(json),
            testing::Return("")));
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_login(
            ctx,
            err, ERRLEN,
            "foo@bar.com", "secret"));

        // We should have the API token now
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("30eb0ae954b536d2f6628f7fec47beb6", std::string(str));

        // We should have current user now
        KopsikUser *user = kopsik_user_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_current_user(ctx, err, ERRLEN, user));
        ASSERT_EQ((unsigned int)10471231, user->ID);
        ASSERT_EQ(std::string("John Smith"), std::string(user->Fullname));
        kopsik_user_clear(user);

        // Count time entry items before start. It should be 3, since
        // there are 3 time entries in the me.json file we're using:
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_EQ((unsigned int)3, list->Length);
        int number_of_items = list->Length;
        kopsik_time_entry_view_item_list_clear(list);

        // Start tracking
        KopsikTimeEntryViewItem *item = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_start(ctx, err, ERRLEN, "Test", item));
        ASSERT_EQ(std::string("Test"), std::string(item->Description));
        kopsik_time_entry_view_item_clear(item);

        // We should now have a running time entry
        int is_tracking = 0;
        KopsikTimeEntryViewItem *running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_TRUE(is_tracking);
        ASSERT_GT(0, running->DurationInSeconds);
        ASSERT_EQ(std::string("Test"), std::string(running->Description));
        ASSERT_FALSE(running->Project);
        ASSERT_TRUE(running->Duration);
        ASSERT_FALSE(running->Color);
        ASSERT_TRUE(running->GUID);
        std::string GUID(running->GUID);
        kopsik_time_entry_view_item_clear(running);

        // The running time entry should *not* be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 0, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // Stop the time entry
        KopsikTimeEntryViewItem *stopped = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_stop(ctx, err, ERRLEN, stopped));
        ASSERT_EQ(std::string("Test"), std::string(stopped->Description));
        std::string dirty_guid(stopped->GUID);
        kopsik_time_entry_view_item_clear(stopped);

        // Now the stopped time entry should be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 1, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // We should no longer get a running time entry from API.
        is_tracking = 0;
        running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_FALSE(is_tracking);
        kopsik_time_entry_view_item_clear(running);

        // We started and stopped one time entry.
        // This means we should have one dirty model now.
        KopsikPushableModelStats stats;
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Push changes
        std::stringstream response_body;
        response_body
            << "["
            << "{"
            << "\"status\": 200,"
            << "\"guid\": \"" << dirty_guid << "\","
            << "\"content_type\": \"application/json\","
            << "\"body\": \""
                << "{\"data\": {\"id\": 123456789, \"ui_modified_at\": "
                << time(0) << "}}\""
            << "}"
            << "]";
        std::string response_json = response_body.str();
        EXPECT_CALL(*mock_client, PostJSON(
            std::string("/api/v8/batch_updates"),
            testing::An<std::string>(),
            std::string("30eb0ae954b536d2f6628f7fec47beb6"),
            std::string("api_token"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<4>(response_json),
            testing::Return("")));

        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_push(
            ctx, err, ERRLEN));

        // Check that no dirty models are left.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)0, stats.TimeEntries);

        // Continue the time entry we created in the start.
        KopsikTimeEntryViewItem *continued =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_continue(
            ctx, err, ERRLEN, GUID.c_str(), continued));
        ASSERT_NE(std::string(GUID), std::string(continued->GUID));
        ASSERT_FALSE(std::string(continued->Duration).empty());
        ASSERT_GT(0, continued->DurationInSeconds);
        kopsik_time_entry_view_item_clear(continued);

        // We should now once again have a dirty model.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Get time entry view using GUID
        int was_found = 0;
        KopsikTimeEntryViewItem *found = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, dirty_guid.c_str(), found, &was_found));
        ASSERT_EQ(dirty_guid, std::string(found->GUID));
        ASSERT_TRUE(was_found);
        kopsik_time_entry_view_item_clear(found);

        // Ask for a non-existant time entry
        KopsikTimeEntryViewItem *nonexistant =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, "bad guid", nonexistant, &was_found));
        ASSERT_FALSE(nonexistant->GUID);
        ASSERT_FALSE(was_found);
        kopsik_time_entry_view_item_clear(nonexistant);

        // Delete the time entry we created in the start.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_delete_time_entry(
            ctx, err, ERRLEN, GUID.c_str()));

        // We shouldnt be able to retrieve this time entry now in list.
        KopsikTimeEntryViewItemList *visible =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, visible));
        for (unsigned int i = 0; i < visible->Length; i++) {
            KopsikTimeEntryViewItem *n = visible->ViewItems[i];
            ASSERT_FALSE(std::string(n->GUID) == GUID);
        }
        kopsik_time_entry_view_item_list_clear(visible);

        // Log out
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_logout(ctx, err, ERRLEN));

        // Check that we have no API token after user logged out.
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("", std::string(str));

        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_init) {
        KopsikTimeEntryViewItem *te = kopsik_time_entry_view_item_init();
        ASSERT_TRUE(te);
        kopsik_time_entry_view_item_clear(te);
    }

    TEST(KopsikApiTest, kopsik_format_duration_in_seconds) {
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        kopsik_format_duration_in_seconds(10, str, kMaxStrLen);
        ASSERT_EQ("00:00:10", std::string(str));
        kopsik_format_duration_in_seconds(60, str, kMaxStrLen);
        ASSERT_EQ("00:01:00", std::string(str));
        kopsik_format_duration_in_seconds(65, str, kMaxStrLen);
        ASSERT_EQ("00:01:05", std::string(str));
        kopsik_format_duration_in_seconds(3600, str, kMaxStrLen);
        ASSERT_EQ("01:00:00", std::string(str));
        kopsik_format_duration_in_seconds(5400, str, kMaxStrLen);
        ASSERT_EQ("01:30:00", std::string(str));
        kopsik_format_duration_in_seconds(5410, str, kMaxStrLen);
        ASSERT_EQ("01:30:10", std::string(str));
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_list_init) {
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_TRUE(list);
        kopsik_time_entry_view_item_list_clear(list);
    }

}  // namespace kopsik
<commit_msg>Change mock port number<commit_after>// Copyright 2013 Tanel Lebedev

#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "./kopsik_api.h"
#include "./https_client.h"

#include "Poco/FileStream.h"
#include "Poco/File.h"

#define TESTDB "test.db"
#define ERRLEN 1024

namespace kopsik {

    class MockHTTPSClient : public HTTPSClient {
    public:
        MockHTTPSClient() : HTTPSClient("https://localhost:8080") {}
        MOCK_METHOD0(ListenToWebsocket, kopsik::error());
        MOCK_METHOD5(PostJSON, kopsik::error(
            std::string relative_url,
            std::string json,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
        MOCK_METHOD4(GetJSON, kopsik::error(
            std::string relative_url,
            std::string basic_auth_username,
            std::string basic_auth_password,
            std::string *response_body));
    };

    TEST(KopsikApiTest, kopsik_context_init) {
        KopsikContext *ctx = kopsik_context_init();
        ASSERT_TRUE(ctx);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_version) {
        int major = 0;
        int minor = 0;
        int patch = 0;
        kopsik_version(&major, &minor, &patch);
        ASSERT_TRUE(major || minor || patch);
    }

    TEST(KopsikApiTest, kopsik_set_proxy) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_proxy(ctx, "localhost", 8000, "johnsmith", "secret");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_set_db_path) {
        KopsikContext *ctx = kopsik_context_init();
        {
            Poco::File f(TESTDB);
            if (f.exists()) f.remove(false);
        }
        kopsik_set_db_path(ctx, TESTDB);
        kopsik_context_clear(ctx);
        Poco::File f(TESTDB);
        ASSERT_TRUE(f.exists());
    }

    TEST(KopsikApiTest, kopsik_set_log_path) {
        KopsikContext *ctx = kopsik_context_init();
        kopsik_set_log_path(ctx, "test.log");
        ASSERT_TRUE(true);
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_user_init) {
        KopsikUser *user = kopsik_user_init();
        ASSERT_TRUE(user);
        kopsik_user_clear(user);
    }

    TEST(KopsikApiTest, kopsik_set_api_token) {
        KopsikContext *ctx = kopsik_context_init();
        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_set_api_token(ctx, err, ERRLEN, "token"));
        const int kMaxStrLen = 10;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("token", std::string(str));
        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_lifecycle) {
        KopsikContext *ctx = kopsik_context_init();

        Poco::File f(TESTDB);
        if (f.exists()) f.remove(false);
        kopsik_set_db_path(ctx, TESTDB);

        kopsik::HTTPSClient *client =
            reinterpret_cast<HTTPSClient *>(ctx->https_client);
        delete client;
        MockHTTPSClient *mock_client = new MockHTTPSClient();
        ctx->https_client = mock_client;

        Poco::FileStream fis("testdata/me.json", std::ios::binary);
        std::stringstream ss;
        ss << fis.rdbuf();
        fis.close();
        std::string json = ss.str();

        // Login
        EXPECT_CALL(*mock_client, GetJSON(
            std::string("/api/v8/me?app_name=kopsik&with_related_data=true"),
            std::string("foo@bar.com"),
            std::string("secret"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<3>(json),
            testing::Return("")));
        char err[ERRLEN];
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_login(
            ctx,
            err, ERRLEN,
            "foo@bar.com", "secret"));

        // We should have the API token now
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("30eb0ae954b536d2f6628f7fec47beb6", std::string(str));

        // We should have current user now
        KopsikUser *user = kopsik_user_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_current_user(ctx, err, ERRLEN, user));
        ASSERT_EQ((unsigned int)10471231, user->ID);
        ASSERT_EQ(std::string("John Smith"), std::string(user->Fullname));
        kopsik_user_clear(user);

        // Count time entry items before start. It should be 3, since
        // there are 3 time entries in the me.json file we're using:
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_EQ((unsigned int)3, list->Length);
        int number_of_items = list->Length;
        kopsik_time_entry_view_item_list_clear(list);

        // Start tracking
        KopsikTimeEntryViewItem *item = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_start(ctx, err, ERRLEN, "Test", item));
        ASSERT_EQ(std::string("Test"), std::string(item->Description));
        kopsik_time_entry_view_item_clear(item);

        // We should now have a running time entry
        int is_tracking = 0;
        KopsikTimeEntryViewItem *running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_TRUE(is_tracking);
        ASSERT_GT(0, running->DurationInSeconds);
        ASSERT_EQ(std::string("Test"), std::string(running->Description));
        ASSERT_FALSE(running->Project);
        ASSERT_TRUE(running->Duration);
        ASSERT_FALSE(running->Color);
        ASSERT_TRUE(running->GUID);
        std::string GUID(running->GUID);
        kopsik_time_entry_view_item_clear(running);

        // The running time entry should *not* be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 0, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // Stop the time entry
        KopsikTimeEntryViewItem *stopped = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_stop(ctx, err, ERRLEN, stopped));
        ASSERT_EQ(std::string("Test"), std::string(stopped->Description));
        std::string dirty_guid(stopped->GUID);
        kopsik_time_entry_view_item_clear(stopped);

        // Now the stopped time entry should be listed
        // among time entry view items.
        list = kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, list));
        ASSERT_TRUE(list);
        ASSERT_EQ((unsigned int)number_of_items + 1, list->Length);
        kopsik_time_entry_view_item_list_clear(list);

        // We should no longer get a running time entry from API.
        is_tracking = 0;
        running = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_running_time_entry_view_item(
            ctx, err, ERRLEN, running, &is_tracking));
        ASSERT_FALSE(is_tracking);
        kopsik_time_entry_view_item_clear(running);

        // We started and stopped one time entry.
        // This means we should have one dirty model now.
        KopsikPushableModelStats stats;
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Push changes
        std::stringstream response_body;
        response_body
            << "["
            << "{"
            << "\"status\": 200,"
            << "\"guid\": \"" << dirty_guid << "\","
            << "\"content_type\": \"application/json\","
            << "\"body\": \""
                << "{\"data\": {\"id\": 123456789, \"ui_modified_at\": "
                << time(0) << "}}\""
            << "}"
            << "]";
        std::string response_json = response_body.str();
        EXPECT_CALL(*mock_client, PostJSON(
            std::string("/api/v8/batch_updates"),
            testing::An<std::string>(),
            std::string("30eb0ae954b536d2f6628f7fec47beb6"),
            std::string("api_token"),
            testing::_))
        .WillOnce(testing::DoAll(
            testing::SetArgPointee<4>(response_json),
            testing::Return("")));

        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_push(
            ctx, err, ERRLEN));

        // Check that no dirty models are left.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)0, stats.TimeEntries);

        // Continue the time entry we created in the start.
        KopsikTimeEntryViewItem *continued =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_continue(
            ctx, err, ERRLEN, GUID.c_str(), continued));
        ASSERT_NE(std::string(GUID), std::string(continued->GUID));
        ASSERT_FALSE(std::string(continued->Duration).empty());
        ASSERT_GT(0, continued->DurationInSeconds);
        kopsik_time_entry_view_item_clear(continued);

        // We should now once again have a dirty model.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_pushable_models(
            ctx, err, ERRLEN, &stats));
        ASSERT_EQ((unsigned int)1, stats.TimeEntries);

        // Get time entry view using GUID
        int was_found = 0;
        KopsikTimeEntryViewItem *found = kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, dirty_guid.c_str(), found, &was_found));
        ASSERT_EQ(dirty_guid, std::string(found->GUID));
        ASSERT_TRUE(was_found);
        kopsik_time_entry_view_item_clear(found);

        // Ask for a non-existant time entry
        KopsikTimeEntryViewItem *nonexistant =
            kopsik_time_entry_view_item_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_item_by_guid(
            ctx, err, ERRLEN, "bad guid", nonexistant, &was_found));
        ASSERT_FALSE(nonexistant->GUID);
        ASSERT_FALSE(was_found);
        kopsik_time_entry_view_item_clear(nonexistant);

        // Delete the time entry we created in the start.
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_delete_time_entry(
            ctx, err, ERRLEN, GUID.c_str()));

        // We shouldnt be able to retrieve this time entry now in list.
        KopsikTimeEntryViewItemList *visible =
            kopsik_time_entry_view_item_list_init();
        ASSERT_EQ(KOPSIK_API_SUCCESS, kopsik_time_entry_view_items(
            ctx, err, ERRLEN, visible));
        for (unsigned int i = 0; i < visible->Length; i++) {
            KopsikTimeEntryViewItem *n = visible->ViewItems[i];
            ASSERT_FALSE(std::string(n->GUID) == GUID);
        }
        kopsik_time_entry_view_item_list_clear(visible);

        // Log out
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_logout(ctx, err, ERRLEN));

        // Check that we have no API token after user logged out.
        ASSERT_EQ(KOPSIK_API_SUCCESS,
            kopsik_get_api_token(ctx, err, ERRLEN, str, kMaxStrLen));
        ASSERT_EQ("", std::string(str));

        kopsik_context_clear(ctx);
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_init) {
        KopsikTimeEntryViewItem *te = kopsik_time_entry_view_item_init();
        ASSERT_TRUE(te);
        kopsik_time_entry_view_item_clear(te);
    }

    TEST(KopsikApiTest, kopsik_format_duration_in_seconds) {
        const int kMaxStrLen = 100;
        char str[kMaxStrLen];
        kopsik_format_duration_in_seconds(10, str, kMaxStrLen);
        ASSERT_EQ("00:00:10", std::string(str));
        kopsik_format_duration_in_seconds(60, str, kMaxStrLen);
        ASSERT_EQ("00:01:00", std::string(str));
        kopsik_format_duration_in_seconds(65, str, kMaxStrLen);
        ASSERT_EQ("00:01:05", std::string(str));
        kopsik_format_duration_in_seconds(3600, str, kMaxStrLen);
        ASSERT_EQ("01:00:00", std::string(str));
        kopsik_format_duration_in_seconds(5400, str, kMaxStrLen);
        ASSERT_EQ("01:30:00", std::string(str));
        kopsik_format_duration_in_seconds(5410, str, kMaxStrLen);
        ASSERT_EQ("01:30:10", std::string(str));
    }

    TEST(KopsikApiTest, kopsik_time_entry_view_item_list_init) {
        KopsikTimeEntryViewItemList *list =
            kopsik_time_entry_view_item_list_init();
        ASSERT_TRUE(list);
        kopsik_time_entry_view_item_list_clear(list);
    }

}  // namespace kopsik
<|endoftext|>


<commit_before>//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is
//  defined.  If we have valgrind.h but valgrind isn't running, its macros are
//  no-ops.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Valgrind.h"
#include "llvm/Config/config.h"

#if HAVE_VALGRIND_VALGRIND_H
#include <valgrind/valgrind.h>

static bool InitNotUnderValgrind() {
  return !RUNNING_ON_VALGRIND;
}

// This bool is negated from what we'd expect because code may run before it
// gets initialized.  If that happens, it will appear to be 0 (false), and we
// want that to cause the rest of the code in this file to run the
// Valgrind-provided macros.
static const bool NotUnderValgrind = InitNotUnderValgrind();

bool llvm::sys::RunningOnValgrind() {
  if (NotUnderValgrind)
    return false;
  return RUNNING_ON_VALGRIND;
}

void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
  if (NotUnderValgrind)
    return;

  VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
}

#else  // !HAVE_VALGRIND_VALGRIND_H

bool llvm::sys::RunningOnValgrind() {
  return false;
}

void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
}

#endif  // !HAVE_VALGRIND_VALGRIND_H
<commit_msg>Supress gcc-4.5 warning about the result not being used.<commit_after>//===-- Valgrind.cpp - Implement Valgrind communication ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Defines Valgrind communication methods, if HAVE_VALGRIND_VALGRIND_H is
//  defined.  If we have valgrind.h but valgrind isn't running, its macros are
//  no-ops.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Valgrind.h"
#include "llvm/Config/config.h"

#if HAVE_VALGRIND_VALGRIND_H
#include <valgrind/valgrind.h>

static bool InitNotUnderValgrind() {
  return !RUNNING_ON_VALGRIND;
}

// This bool is negated from what we'd expect because code may run before it
// gets initialized.  If that happens, it will appear to be 0 (false), and we
// want that to cause the rest of the code in this file to run the
// Valgrind-provided macros.
static const bool NotUnderValgrind = InitNotUnderValgrind();

bool llvm::sys::RunningOnValgrind() {
  if (NotUnderValgrind)
    return false;
  return RUNNING_ON_VALGRIND;
}

void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
  if (NotUnderValgrind)
    return;

  (void)VALGRIND_DISCARD_TRANSLATIONS(Addr, Len);
}

#else  // !HAVE_VALGRIND_VALGRIND_H

bool llvm::sys::RunningOnValgrind() {
  return false;
}

void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
}

#endif  // !HAVE_VALGRIND_VALGRIND_H
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/notifications/desktop_notifications_unittest.h"

#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
#include "content/public/common/show_desktop_notification_params.h"

#if defined(USE_AURA)
#include "ash/shell.h"
#include "chrome/browser/chromeos/notifications/balloon_collection_impl_aura.h"
#include "ui/aura/root_window.h"
#else
#include "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
#endif

#if defined(USE_AURA)
typedef class chromeos::BalloonCollectionImplAura BalloonCollectionImplType;
#else
typedef class chromeos::BalloonCollectionImpl BalloonCollectionImplType;
#endif

using content::BrowserThread;

namespace chromeos {

// static
std::string DesktopNotificationsTest::log_output_;

class BalloonViewImpl;

#if !defined(USE_AURA)
class MockNotificationUI : public BalloonCollectionImplType::NotificationUI {
 public:
  virtual void Add(Balloon* balloon) {}
  virtual bool Update(Balloon* balloon) { return false; }
  virtual void Remove(Balloon* balloon) {}
  virtual void Show(Balloon* balloon) {}
  virtual void ResizeNotification(Balloon* balloon,
                                  const gfx::Size& size) {}
  virtual void SetActiveView(BalloonViewImpl* view) {}
};
#endif

// Test version of the balloon collection which counts the number
// of notifications that are added to it.
class MockBalloonCollection : public BalloonCollectionImplType {
 public:
  MockBalloonCollection() {
#if !defined(USE_AURA)
    set_notification_ui(new MockNotificationUI());
#endif
  }
  virtual ~MockBalloonCollection() {};

  // BalloonCollectionImplType overrides
  virtual void Add(const Notification& notification, Profile* profile) OVERRIDE;
  virtual Balloon* MakeBalloon(const Notification& notification,
                               Profile* profile) OVERRIDE;
  virtual void OnBalloonClosed(Balloon* source) OVERRIDE;

  // Number of balloons being shown.
  std::set<Balloon*>& balloons() { return balloons_; }
  int count() const { return balloons_.size(); }

 private:
  std::set<Balloon*> balloons_;
};

void MockBalloonCollection::Add(const Notification& notification,
                                Profile* profile) {
  // Swap in a logging proxy for the purpose of logging calls that
  // would be made into javascript, then pass this down to the
  // balloon collection.
  typedef LoggingNotificationDelegate<DesktopNotificationsTest>
      LoggingNotificationProxy;
  Notification test_notification(
      notification.origin_url(),
      notification.content_url(),
      notification.display_source(),
      notification.replace_id(),
      new LoggingNotificationProxy(notification.notification_id()));
  BalloonCollectionImplType::Add(test_notification, profile);
}

Balloon* MockBalloonCollection::MakeBalloon(const Notification& notification,
                                            Profile* profile) {
  // Start with a normal balloon but mock out the view.
  Balloon* balloon =
      BalloonCollectionImplType::MakeBalloon(notification, profile);
  balloon->set_view(new MockBalloonView(balloon));
  balloons_.insert(balloon);
  return balloon;
}

void MockBalloonCollection::OnBalloonClosed(Balloon* source) {
  balloons_.erase(source);
  BalloonCollectionImplType::OnBalloonClosed(source);
}

// DesktopNotificationsTest

DesktopNotificationsTest::DesktopNotificationsTest()
    : ui_thread_(BrowserThread::UI, &message_loop_) {
}

DesktopNotificationsTest::~DesktopNotificationsTest() {
}

void DesktopNotificationsTest::SetUp() {
#if defined(USE_AURA)
  // Make sure a root window has been instantiated.
  ash::Shell::GetRootWindow();
#endif
  browser::RegisterLocalState(&local_state_);
  profile_.reset(new TestingProfile());
  balloon_collection_ = new MockBalloonCollection();
  ui_manager_.reset(NotificationUIManager::Create(&local_state_,
                                                  balloon_collection_));
  service_.reset(new DesktopNotificationService(profile(), ui_manager_.get()));
  log_output_.clear();
}

void DesktopNotificationsTest::TearDown() {
  service_.reset(NULL);
  ui_manager_.reset(NULL);
  profile_.reset(NULL);
}

content::ShowDesktopNotificationHostMsgParams
DesktopNotificationsTest::StandardTestNotification() {
  content::ShowDesktopNotificationHostMsgParams params;
  params.notification_id = 0;
  params.origin = GURL("http://www.google.com");
  params.is_html = false;
  params.icon_url = GURL("/icon.png");
  params.title = ASCIIToUTF16("Title");
  params.body = ASCIIToUTF16("Text");
  params.direction = WebKit::WebTextDirectionDefault;
  return params;
}

TEST_F(DesktopNotificationsTest, TestShow) {
  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.notification_id = 1;
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, 0, 0, DesktopNotificationService::PageNotification));

  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());

  content::ShowDesktopNotificationHostMsgParams params2;
  params2.origin = GURL("http://www.google.com");
  params2.is_html = true;
  params2.contents_url = GURL("http://www.google.com/notification.html");
  params2.notification_id = 2;

  EXPECT_TRUE(service_->ShowDesktopNotification(
      params2, 0, 0, DesktopNotificationService::PageNotification));
  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(2, balloon_collection_->count());

  EXPECT_EQ("notification displayed\n"
            "notification displayed\n",
            log_output_);
}

TEST_F(DesktopNotificationsTest, TestClose) {
  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.notification_id = 1;

  // Request a notification; should open a balloon.
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, 0, 0, DesktopNotificationService::PageNotification));
  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());

  // Close all the open balloons.
  std::set<Balloon*> balloons = balloon_collection_->balloons();
  std::set<Balloon*>::iterator iter;
  for (iter = balloons.begin(); iter != balloons.end(); ++iter) {
    (*iter)->OnClose(true);
  }

  // Verify that the balloon collection is now empty.
  EXPECT_EQ(0, balloon_collection_->count());

  EXPECT_EQ("notification displayed\n"
            "notification closed by user\n",
            log_output_);
}

TEST_F(DesktopNotificationsTest, TestCancel) {
  int process_id = 0;
  int route_id = 0;
  int notification_id = 1;

  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.notification_id = notification_id;

  // Request a notification; should open a balloon.
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, process_id, route_id,
      DesktopNotificationService::PageNotification));
  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());

  // Cancel the same notification
  service_->CancelDesktopNotification(process_id,
                                      route_id,
                                      notification_id);
  MessageLoopForUI::current()->RunAllPending();
  // Verify that the balloon collection is now empty.
  EXPECT_EQ(0, balloon_collection_->count());

  EXPECT_EQ("notification displayed\n"
            "notification closed by script\n",
            log_output_);
}

TEST_F(DesktopNotificationsTest, TestManyNotifications) {
  int process_id = 0;
  int route_id = 0;

  // Request lots of identical notifications.
#if defined(USE_AURA)
  // Aura is using the non-chromeos notification system which has a limit
  // of 4 visible toasts.
  const int kLotsOfToasts = 4;
#else
  const int kLotsOfToasts = 20;
#endif
  for (int id = 1; id <= kLotsOfToasts; ++id) {
    SCOPED_TRACE(base::StringPrintf("Creation loop: id=%d", id));
    content::ShowDesktopNotificationHostMsgParams params =
        StandardTestNotification();
    params.notification_id = id;
    EXPECT_TRUE(service_->ShowDesktopNotification(
        params, process_id, route_id,
        DesktopNotificationService::PageNotification));
  }
  MessageLoopForUI::current()->RunAllPending();

  // Build up an expected log of what should be happening.
  std::string expected_log;
  for (int i = 0; i < kLotsOfToasts; ++i) {
    expected_log.append("notification displayed\n");
  }

  EXPECT_EQ(kLotsOfToasts, balloon_collection_->count());
  EXPECT_EQ(expected_log, log_output_);

  // Cancel half of the notifications from the start
  int id;
  int cancelled = kLotsOfToasts / 2;
  for (id = 1;
       id <= cancelled;
       ++id) {
    SCOPED_TRACE(base::StringPrintf("Cancel half of notifications: id=%d", id));
    service_->CancelDesktopNotification(process_id, route_id, id);
    MessageLoopForUI::current()->RunAllPending();
    expected_log.append("notification closed by script\n");
    EXPECT_EQ(kLotsOfToasts - id,
              balloon_collection_->count());
    EXPECT_EQ(expected_log, log_output_);
  }

  // Now cancel the rest.  It should empty the balloon space.
  for (; id <= kLotsOfToasts; ++id) {
    SCOPED_TRACE(base::StringPrintf("Cancel loop: id=%d", id));
    service_->CancelDesktopNotification(process_id, route_id, id);
    expected_log.append("notification closed by script\n");
    MessageLoopForUI::current()->RunAllPending();
    EXPECT_EQ(expected_log, log_output_);
  }

  // Verify that the balloon collection is now empty.
  EXPECT_EQ(0, balloon_collection_->count());
}

TEST_F(DesktopNotificationsTest, TestEarlyDestruction) {
  // Create some toasts and then prematurely delete the notification service,
  // just to make sure nothing crashes/leaks.
  for (int id = 0; id <= 3; ++id) {
    SCOPED_TRACE(base::StringPrintf("Show Text loop: id=%d", id));

    EXPECT_TRUE(service_->ShowDesktopNotification(
        StandardTestNotification(), 0, 0,
        DesktopNotificationService::PageNotification));
  }
  service_.reset(NULL);
}

TEST_F(DesktopNotificationsTest, TestUserInputEscaping) {
  // Create a test script with some HTML; assert that it doesn't get into the
  // data:// URL that's produced for the balloon.
  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.title = ASCIIToUTF16("<script>window.alert('uh oh');</script>");
  params.body = ASCIIToUTF16("<i>this text is in italics</i>");
  params.notification_id = 1;
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, 0, 0, DesktopNotificationService::PageNotification));

  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());
  Balloon* balloon = (*balloon_collection_->balloons().begin());
  GURL data_url = balloon->notification().content_url();
  EXPECT_EQ(std::string::npos, data_url.spec().find("<script>"));
  EXPECT_EQ(std::string::npos, data_url.spec().find("<i>"));
}

}  // namespace chromeos
<commit_msg>Fix unit_tests on cros. Looks like I forgot another instance of CreateInstance()<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/notifications/desktop_notifications_unittest.h"

#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
#include "content/public/common/show_desktop_notification_params.h"

#if defined(USE_AURA)
#include "ash/shell.h"
#include "chrome/browser/chromeos/notifications/balloon_collection_impl_aura.h"
#include "ui/aura/root_window.h"
#else
#include "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
#endif

#if defined(USE_AURA)
typedef class chromeos::BalloonCollectionImplAura BalloonCollectionImplType;
#else
typedef class chromeos::BalloonCollectionImpl BalloonCollectionImplType;
#endif

using content::BrowserThread;

namespace chromeos {

// static
std::string DesktopNotificationsTest::log_output_;

class BalloonViewImpl;

#if !defined(USE_AURA)
class MockNotificationUI : public BalloonCollectionImplType::NotificationUI {
 public:
  virtual void Add(Balloon* balloon) {}
  virtual bool Update(Balloon* balloon) { return false; }
  virtual void Remove(Balloon* balloon) {}
  virtual void Show(Balloon* balloon) {}
  virtual void ResizeNotification(Balloon* balloon,
                                  const gfx::Size& size) {}
  virtual void SetActiveView(BalloonViewImpl* view) {}
};
#endif

// Test version of the balloon collection which counts the number
// of notifications that are added to it.
class MockBalloonCollection : public BalloonCollectionImplType {
 public:
  MockBalloonCollection() {
#if !defined(USE_AURA)
    set_notification_ui(new MockNotificationUI());
#endif
  }
  virtual ~MockBalloonCollection() {};

  // BalloonCollectionImplType overrides
  virtual void Add(const Notification& notification, Profile* profile) OVERRIDE;
  virtual Balloon* MakeBalloon(const Notification& notification,
                               Profile* profile) OVERRIDE;
  virtual void OnBalloonClosed(Balloon* source) OVERRIDE;

  // Number of balloons being shown.
  std::set<Balloon*>& balloons() { return balloons_; }
  int count() const { return balloons_.size(); }

 private:
  std::set<Balloon*> balloons_;
};

void MockBalloonCollection::Add(const Notification& notification,
                                Profile* profile) {
  // Swap in a logging proxy for the purpose of logging calls that
  // would be made into javascript, then pass this down to the
  // balloon collection.
  typedef LoggingNotificationDelegate<DesktopNotificationsTest>
      LoggingNotificationProxy;
  Notification test_notification(
      notification.origin_url(),
      notification.content_url(),
      notification.display_source(),
      notification.replace_id(),
      new LoggingNotificationProxy(notification.notification_id()));
  BalloonCollectionImplType::Add(test_notification, profile);
}

Balloon* MockBalloonCollection::MakeBalloon(const Notification& notification,
                                            Profile* profile) {
  // Start with a normal balloon but mock out the view.
  Balloon* balloon =
      BalloonCollectionImplType::MakeBalloon(notification, profile);
  balloon->set_view(new MockBalloonView(balloon));
  balloons_.insert(balloon);
  return balloon;
}

void MockBalloonCollection::OnBalloonClosed(Balloon* source) {
  balloons_.erase(source);
  BalloonCollectionImplType::OnBalloonClosed(source);
}

// DesktopNotificationsTest

DesktopNotificationsTest::DesktopNotificationsTest()
    : ui_thread_(BrowserThread::UI, &message_loop_) {
}

DesktopNotificationsTest::~DesktopNotificationsTest() {
}

void DesktopNotificationsTest::SetUp() {
#if defined(USE_AURA)
  // Make sure a root window has been instantiated.
  ash::Shell::CreateInstance(NULL);
#endif
  browser::RegisterLocalState(&local_state_);
  profile_.reset(new TestingProfile());
  balloon_collection_ = new MockBalloonCollection();
  ui_manager_.reset(NotificationUIManager::Create(&local_state_,
                                                  balloon_collection_));
  service_.reset(new DesktopNotificationService(profile(), ui_manager_.get()));
  log_output_.clear();
}

void DesktopNotificationsTest::TearDown() {
  service_.reset(NULL);
  ui_manager_.reset(NULL);
  profile_.reset(NULL);
}

content::ShowDesktopNotificationHostMsgParams
DesktopNotificationsTest::StandardTestNotification() {
  content::ShowDesktopNotificationHostMsgParams params;
  params.notification_id = 0;
  params.origin = GURL("http://www.google.com");
  params.is_html = false;
  params.icon_url = GURL("/icon.png");
  params.title = ASCIIToUTF16("Title");
  params.body = ASCIIToUTF16("Text");
  params.direction = WebKit::WebTextDirectionDefault;
  return params;
}

TEST_F(DesktopNotificationsTest, TestShow) {
  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.notification_id = 1;
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, 0, 0, DesktopNotificationService::PageNotification));

  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());

  content::ShowDesktopNotificationHostMsgParams params2;
  params2.origin = GURL("http://www.google.com");
  params2.is_html = true;
  params2.contents_url = GURL("http://www.google.com/notification.html");
  params2.notification_id = 2;

  EXPECT_TRUE(service_->ShowDesktopNotification(
      params2, 0, 0, DesktopNotificationService::PageNotification));
  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(2, balloon_collection_->count());

  EXPECT_EQ("notification displayed\n"
            "notification displayed\n",
            log_output_);
}

TEST_F(DesktopNotificationsTest, TestClose) {
  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.notification_id = 1;

  // Request a notification; should open a balloon.
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, 0, 0, DesktopNotificationService::PageNotification));
  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());

  // Close all the open balloons.
  std::set<Balloon*> balloons = balloon_collection_->balloons();
  std::set<Balloon*>::iterator iter;
  for (iter = balloons.begin(); iter != balloons.end(); ++iter) {
    (*iter)->OnClose(true);
  }

  // Verify that the balloon collection is now empty.
  EXPECT_EQ(0, balloon_collection_->count());

  EXPECT_EQ("notification displayed\n"
            "notification closed by user\n",
            log_output_);
}

TEST_F(DesktopNotificationsTest, TestCancel) {
  int process_id = 0;
  int route_id = 0;
  int notification_id = 1;

  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.notification_id = notification_id;

  // Request a notification; should open a balloon.
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, process_id, route_id,
      DesktopNotificationService::PageNotification));
  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());

  // Cancel the same notification
  service_->CancelDesktopNotification(process_id,
                                      route_id,
                                      notification_id);
  MessageLoopForUI::current()->RunAllPending();
  // Verify that the balloon collection is now empty.
  EXPECT_EQ(0, balloon_collection_->count());

  EXPECT_EQ("notification displayed\n"
            "notification closed by script\n",
            log_output_);
}

TEST_F(DesktopNotificationsTest, TestManyNotifications) {
  int process_id = 0;
  int route_id = 0;

  // Request lots of identical notifications.
#if defined(USE_AURA)
  // Aura is using the non-chromeos notification system which has a limit
  // of 4 visible toasts.
  const int kLotsOfToasts = 4;
#else
  const int kLotsOfToasts = 20;
#endif
  for (int id = 1; id <= kLotsOfToasts; ++id) {
    SCOPED_TRACE(base::StringPrintf("Creation loop: id=%d", id));
    content::ShowDesktopNotificationHostMsgParams params =
        StandardTestNotification();
    params.notification_id = id;
    EXPECT_TRUE(service_->ShowDesktopNotification(
        params, process_id, route_id,
        DesktopNotificationService::PageNotification));
  }
  MessageLoopForUI::current()->RunAllPending();

  // Build up an expected log of what should be happening.
  std::string expected_log;
  for (int i = 0; i < kLotsOfToasts; ++i) {
    expected_log.append("notification displayed\n");
  }

  EXPECT_EQ(kLotsOfToasts, balloon_collection_->count());
  EXPECT_EQ(expected_log, log_output_);

  // Cancel half of the notifications from the start
  int id;
  int cancelled = kLotsOfToasts / 2;
  for (id = 1;
       id <= cancelled;
       ++id) {
    SCOPED_TRACE(base::StringPrintf("Cancel half of notifications: id=%d", id));
    service_->CancelDesktopNotification(process_id, route_id, id);
    MessageLoopForUI::current()->RunAllPending();
    expected_log.append("notification closed by script\n");
    EXPECT_EQ(kLotsOfToasts - id,
              balloon_collection_->count());
    EXPECT_EQ(expected_log, log_output_);
  }

  // Now cancel the rest.  It should empty the balloon space.
  for (; id <= kLotsOfToasts; ++id) {
    SCOPED_TRACE(base::StringPrintf("Cancel loop: id=%d", id));
    service_->CancelDesktopNotification(process_id, route_id, id);
    expected_log.append("notification closed by script\n");
    MessageLoopForUI::current()->RunAllPending();
    EXPECT_EQ(expected_log, log_output_);
  }

  // Verify that the balloon collection is now empty.
  EXPECT_EQ(0, balloon_collection_->count());
}

TEST_F(DesktopNotificationsTest, TestEarlyDestruction) {
  // Create some toasts and then prematurely delete the notification service,
  // just to make sure nothing crashes/leaks.
  for (int id = 0; id <= 3; ++id) {
    SCOPED_TRACE(base::StringPrintf("Show Text loop: id=%d", id));

    EXPECT_TRUE(service_->ShowDesktopNotification(
        StandardTestNotification(), 0, 0,
        DesktopNotificationService::PageNotification));
  }
  service_.reset(NULL);
}

TEST_F(DesktopNotificationsTest, TestUserInputEscaping) {
  // Create a test script with some HTML; assert that it doesn't get into the
  // data:// URL that's produced for the balloon.
  content::ShowDesktopNotificationHostMsgParams params =
      StandardTestNotification();
  params.title = ASCIIToUTF16("<script>window.alert('uh oh');</script>");
  params.body = ASCIIToUTF16("<i>this text is in italics</i>");
  params.notification_id = 1;
  EXPECT_TRUE(service_->ShowDesktopNotification(
      params, 0, 0, DesktopNotificationService::PageNotification));

  MessageLoopForUI::current()->RunAllPending();
  EXPECT_EQ(1, balloon_collection_->count());
  Balloon* balloon = (*balloon_collection_->balloons().begin());
  GURL data_url = balloon->notification().content_url();
  EXPECT_EQ(std::string::npos, data_url.spec().find("<script>"));
  EXPECT_EQ(std::string::npos, data_url.spec().find("<i>"));
}

}  // namespace chromeos
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libpagemaker project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <cstdio>

#include <libpagemaker/libpagemaker.h>

#include <boost/scoped_ptr.hpp>

#include "PMDCollector.h"
#include "PMDParser.h"
#include "libpagemaker_utils.h"

namespace libpagemaker
{

bool PMDocument::isSupported(librevenge::RVNGInputStream * /*input*/) try
{
  // TODO: Fix this.
  return true;
}
catch (...)
{
  return false;
}

bool PMDocument::parse(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter) try
{
  PMDCollector collector;
  PMD_DEBUG_MSG(("About to start parsing...\n"));
  boost::scoped_ptr<librevenge::RVNGInputStream>
  pmdStream(input->getSubStreamByName("PageMaker"));
  PMDParser(pmdStream.get(), &collector).parse();
  PMD_DEBUG_MSG(("About to start drawing...\n"));
  collector.draw(painter);
  return true;
}
catch (...)
{
  return false;
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>Document Is Supported ?<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libpagemaker project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <cstdio>

#include <libpagemaker/libpagemaker.h>

#include <boost/scoped_ptr.hpp>

#include "PMDCollector.h"
#include "PMDParser.h"
#include "libpagemaker_utils.h"

namespace libpagemaker
{

bool PMDocument::isSupported(librevenge::RVNGInputStream *input) try
{
  return input && input->isStructured() && input->existsSubStream("PageMaker");
}
catch (...)
{
  return false;
}

bool PMDocument::parse(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter) try
{
  PMDCollector collector;
  PMD_DEBUG_MSG(("About to start parsing...\n"));
  boost::scoped_ptr<librevenge::RVNGInputStream>
  pmdStream(input->getSubStreamByName("PageMaker"));
  PMDParser(pmdStream.get(), &collector).parse();
  PMD_DEBUG_MSG(("About to start drawing...\n"));
  collector.draw(painter);
  return true;
}
catch (...)
{
  return false;
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<|endoftext|>


<commit_before><commit_msg>Fix layout of the Connection Tab of the Origin Info Bubble.<commit_after><|endoftext|>


<commit_before>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  scene/file.cpp                                                                  */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// include i/f header

#include "scene/file.hpp"

// includes, system

#include <array>                      // std::array<>
#include <boost/algorithm/string.hpp> // boost::algorithm::to_lower
#include <boost/filesystem.hpp>       // boost::filesystem::*
#include <functional>                 // std::function<>
#include <map>                        // std::map<>
#include <tuple>                      // std::tuple<>

// includes, project

#include <scene/node/group.hpp>

#define UKACHULLDCS_USE_TRACE
#undef UKACHULLDCS_USE_TRACE
#include <support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  struct file_handler {

    typedef scene::node::group group;

    typedef std::function<group* (std::string const&)>         load_function_type;
    typedef std::function<bool   (std::string const&, group*)> save_function_type;

    load_function_type load;
    save_function_type save;

  };

  typedef std::map<std::string, file_handler> suffix_handler_map_type;

  class compare_suffixes {

  public:

    explicit compare_suffixes(std::string const& a)
      : s_(boost::algorithm::to_lower_copy(a))
    {
      TRACE_NEVER("scene::file::<unnamed>::compare_suffixes::compare_suffixes");
    }

    bool operator()(suffix_handler_map_type::value_type const& a) const
    {
      TRACE_NEVER("scene::file::<unnamed>::compare_suffixes::operator()");

      return s_ == boost::algorithm::to_lower_copy(a.first);
    }

  private:

    std::string const s_;

  };

  // functions, internal

  // kludge to get MSVC select any overload at all!
  inline scene::node::group*
  obj_load(std::string const& /* a */)
  {
    TRACE_NEVER("scene::file::<unnamed>::obj_load");

    return nullptr; /* scene::file::obj::load(a); */
  }

  inline bool
  obj_save(std::string const& /* a */, scene::node::group* /* b */)
  {
    TRACE_NEVER("scene::file::<unnamed>::obj_save");

    return false; /* scene::file::obj::save(a, b); */
  }

  suffix_handler_map_type
  initialize_suffix_handler_map()
  {
    TRACE("scene::file::<unnamed>::initialize_suffix_handler_map");

    suffix_handler_map_type result;

    typedef file_handler::load_function_type load_fun;
    typedef file_handler::save_function_type save_fun;

    static std::array<std::tuple<std::string, load_fun, save_fun>, 1> const suffixes = {
      {
        std::make_tuple(".obj", &obj_load, &obj_save),
      }
    };

    for (auto s : suffixes) {
      file_handler fh;

      fh.load = std::get<1>(s);
      fh.save = std::get<2>(s);

      std::string const ext(boost::algorithm::to_lower_copy(std::get<0>(s)));

      result[ext] = fh;
    }

    return result;
  }

  // variables, internal

  suffix_handler_map_type const suffix_handler_map(initialize_suffix_handler_map());

} // namespace {

namespace scene {

  namespace file {

    // variables, exported

    // functions, exported

    /* static */ node::group*
    handler::load(std::string const& fname, type)
    {
      TRACE("scene::file::handler::load");

      namespace bfs = boost::filesystem;

      node::group* result(nullptr);
      std::string  suffix(bfs::path(fname).extension().string());
      auto const   found (std::find_if(suffix_handler_map.begin(), suffix_handler_map.end(),
                                       compare_suffixes(suffix)));

      if (suffix_handler_map.end() != found) {
        result = found->second.load(fname);
      }

      return result;
    }

    /* static */ bool
    handler::save(std::string const& fname, node::group* root, type)
    {
      TRACE("scene::file::handler::save");

      namespace bfs = boost::filesystem;

      bool         result(false);
      std::string  suffix(bfs::path(fname).extension().string());
      auto const   found (std::find_if(suffix_handler_map.begin(), suffix_handler_map.end(),
                                       compare_suffixes(suffix)));

      if (suffix_handler_map.end() != found) {
        result = found->second.save(fname, root);
      }

      return result;
    }

  } // namespace file {

} // namespace scene {
<commit_msg>update<commit_after>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  scene/file.cpp                                                                  */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// include i/f header

#include "scene/file.hpp"

// includes, system

#include <array>                      // std::array<>
#include <boost/algorithm/string.hpp> // boost::algorithm::to_lower
#include <boost/filesystem.hpp>       // boost::filesystem::*
#include <functional>                 // std::function<>
#include <map>                        // std::map<>
#include <tuple>                      // std::tuple<>

// includes, project

#include <scene/node/group.hpp>

#define UKACHULLDCS_USE_TRACE
#undef UKACHULLDCS_USE_TRACE
#include <support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  struct file_handler {

    typedef scene::node::group group;

    typedef std::function<group* (std::string const&)>         load_function_type;
    typedef std::function<bool   (std::string const&, group*)> save_function_type;

    load_function_type load;
    save_function_type save;

  };

  typedef std::map<std::string, file_handler> suffix_handler_map_type;

  class compare_suffixes {

  public:

    explicit compare_suffixes(std::string const& a)
      : s_(boost::algorithm::to_lower_copy(a))
    {
      TRACE_NEVER("scene::file::<unnamed>::compare_suffixes::compare_suffixes");
    }

    bool operator()(suffix_handler_map_type::value_type const& a) const
    {
      TRACE_NEVER("scene::file::<unnamed>::compare_suffixes::operator()");

      return s_ == boost::algorithm::to_lower_copy(a.first);
    }

  private:

    std::string const s_;

  };

  // functions, internal

  // kludge to get MSVC select any overload at all!
  inline scene::node::group*
  obj_load(std::string const& /* a */)
  {
    TRACE_NEVER("scene::file::<unnamed>::obj_load");

    return nullptr; /* scene::file::obj::load(a); */
  }

  inline bool
  obj_save(std::string const& /* a */, scene::node::group* /* b */)
  {
    TRACE_NEVER("scene::file::<unnamed>::obj_save");

    return false; /* scene::file::obj::save(a, b); */
  }

  suffix_handler_map_type
  initialize_suffix_handler_map()
  {
    TRACE("scene::file::<unnamed>::initialize_suffix_handler_map");

    suffix_handler_map_type result;

    typedef file_handler::load_function_type load_fun;
    typedef file_handler::save_function_type save_fun;

    static std::array<std::tuple<std::string const, load_fun, save_fun>, 1> const suffixes = {
      {
        std::make_tuple(".obj", &obj_load, &obj_save),
      }
    };

    for (auto s : suffixes) {
      file_handler fh;

      fh.load = std::get<1>(s);
      fh.save = std::get<2>(s);

      std::string const ext(boost::algorithm::to_lower_copy(std::get<0>(s)));

      result[ext] = fh;
    }

    return result;
  }

  // variables, internal

  suffix_handler_map_type const suffix_handler_map(initialize_suffix_handler_map());

} // namespace {

namespace scene {

  namespace file {

    // variables, exported

    // functions, exported

    /* static */ node::group*
    handler::load(std::string const& fname, type)
    {
      TRACE("scene::file::handler::load");

      namespace bfs = boost::filesystem;

      node::group* result(nullptr);
      std::string  suffix(bfs::path(fname).extension().string());
      auto const   found (std::find_if(suffix_handler_map.begin(), suffix_handler_map.end(),
                                       compare_suffixes(suffix)));

      if (suffix_handler_map.end() != found) {
        result = found->second.load(fname);
      }

      return result;
    }

    /* static */ bool
    handler::save(std::string const& fname, node::group* root, type)
    {
      TRACE("scene::file::handler::save");

      namespace bfs = boost::filesystem;

      bool         result(false);
      std::string  suffix(bfs::path(fname).extension().string());
      auto const   found (std::find_if(suffix_handler_map.begin(), suffix_handler_map.end(),
                                       compare_suffixes(suffix)));

      if (suffix_handler_map.end() != found) {
        result = found->second.save(fname, root);
      }

      return result;
    }

  } // namespace file {

} // namespace scene {
<|endoftext|>


<commit_before>/*  -*- c++ -*-
    kmservertest.cpp

    This file is part of KMail, the KDE mail client.
    Copyright (c) 2001-2002 Michael Haeckel <haeckel@kde.org>
    Copyright (c) 2003 Marc Mutz <mutz@kde.org>

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

    KMail 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 this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config.h>

#include "kmservertest.h"

#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kurl.h>
#include <kio/scheduler.h>
#include <kio/slave.h>
#include <kio/job.h>
#include <kio/global.h>

//-----------------------------------------------------------------------------
KMServerTest::KMServerTest( const QString & protocol, const QString & host, int port )
  : QObject(),
    mProtocol( protocol ), mHost( host ),
    mSSL( false ), mJob( 0 ), mSlave( 0 )
{
  KIO::Scheduler::connect(
    SIGNAL(slaveError(KIO::Slave *, int, const QString &)),
    this, SLOT(slotSlaveResult(KIO::Slave *, int, const QString &)));

  if ( port == 993 || port == 995 || port == 465 )
    port = 0;

  startOffSlave( port );
}

//-----------------------------------------------------------------------------
KMServerTest::~KMServerTest()
{
  if (mJob) mJob->kill(TRUE);
}

KIO::MetaData KMServerTest::slaveConfig() const {
  KIO::MetaData md;
  md.insert( "nologin", "on" );
  return md;
}

void KMServerTest::startOffSlave( int port ) {
  KURL url;
  url.setProtocol( mSSL ? mProtocol + 's' : mProtocol );
  url.setHost( mHost );
  if ( port )
    url.setPort( port );

  mSlave = KIO::Scheduler::getConnectedSlave( url, slaveConfig() );
  if ( !mSlave ) {
    slotSlaveResult( 0, 1 );
    return;
  }
  connect( mSlave, SIGNAL(metaData(const KIO::MetaData&)),
	   SLOT(slotMetaData(const KIO::MetaData&)) );

  QByteArray packedArgs;
  QDataStream stream( packedArgs, IO_WriteOnly );

  stream << (int) 'c';

  mJob = KIO::special( url, packedArgs, false );
  KIO::Scheduler::assignJobToSlave( mSlave, mJob );
  connect( mJob, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)) );
  connect( mJob, SIGNAL(infoMessage(KIO::Job*,const QString&)),
	   SLOT(slotData(KIO::Job*,const QString&)) );
}

//-----------------------------------------------------------------------------
void KMServerTest::slotData(KIO::Job *, const QString &data)
{
  if ( mList.empty() )
    mList = QStringList::split(' ', data);
kdDebug(5006) << data << endl;
kdDebug(5006) << "count = " << mList.count() << endl;
}

void KMServerTest::slotMetaData( const KIO::MetaData & md ) {
  KIO::MetaData::const_iterator it = md.find( "PLAIN AUTH METHODS" );
  if ( it != md.end() )
    mAuthNone = it.data();
  it = md.find( "TLS AUTH METHODS" );
  if ( it != md.end() )
    mAuthTLS = it.data();
  it = md.find( "SSL AUTH METHODS" );
  if ( it != md.end() )
    mAuthSSL = it.data();
}

//-----------------------------------------------------------------------------
void KMServerTest::slotResult(KIO::Job *job)
{
  slotSlaveResult(mSlave, job->error());
}

//-----------------------------------------------------------------------------
void KMServerTest::slotSlaveResult(KIO::Slave *aSlave, int error,
  const QString &)
{
  if (aSlave != mSlave) return;
  if (error != KIO::ERR_SLAVE_DIED && mSlave)
  {
    KIO::Scheduler::disconnectSlave(mSlave);
    mSlave = 0;
  }
  if (!mSSL) {
    mSSL = true;
    if ( error )
      mList.clear();
    else
      mList.append("NORMAL-CONNECTION");
    startOffSlave();
  } else {
    mJob = 0;
    if (!error) mList.append("SSL");
    if (mList.isEmpty())
      KMessageBox::error(0, i18n("<qt>Could not connect to server <b>%1</b>.</qt>")
      .arg(mHost));
    emit capabilities(mList);
    emit capabilities(mList, mAuthNone, mAuthSSL, mAuthTLS);
  }
}

#include "kmservertest.moc"
<commit_msg>give the user a useful error message when the server test fails<commit_after>/*  -*- c++ -*-
    kmservertest.cpp

    This file is part of KMail, the KDE mail client.
    Copyright (c) 2001-2002 Michael Haeckel <haeckel@kde.org>
    Copyright (c) 2003 Marc Mutz <mutz@kde.org>

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

    KMail 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 this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config.h>

#include "kmservertest.h"

#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kurl.h>
#include <kio/scheduler.h>
#include <kio/slave.h>
#include <kio/job.h>
#include <kio/global.h>

//-----------------------------------------------------------------------------
KMServerTest::KMServerTest( const QString & protocol, const QString & host, int port )
  : QObject(),
    mProtocol( protocol ), mHost( host ),
    mSSL( false ), mJob( 0 ), mSlave( 0 )
{
  KIO::Scheduler::connect(
    SIGNAL(slaveError(KIO::Slave *, int, const QString &)),
    this, SLOT(slotSlaveResult(KIO::Slave *, int, const QString &)));

  if ( port == 993 || port == 995 || port == 465 )
    port = 0;

  startOffSlave( port );
}

//-----------------------------------------------------------------------------
KMServerTest::~KMServerTest()
{
  if (mJob) mJob->kill(TRUE);
}

KIO::MetaData KMServerTest::slaveConfig() const {
  KIO::MetaData md;
  md.insert( "nologin", "on" );
  return md;
}

void KMServerTest::startOffSlave( int port ) {
  KURL url;
  url.setProtocol( mSSL ? mProtocol + 's' : mProtocol );
  url.setHost( mHost );
  if ( port )
    url.setPort( port );

  mSlave = KIO::Scheduler::getConnectedSlave( url, slaveConfig() );
  if ( !mSlave ) {
    slotSlaveResult( 0, 1 );
    return;
  }
  connect( mSlave, SIGNAL(metaData(const KIO::MetaData&)),
	   SLOT(slotMetaData(const KIO::MetaData&)) );

  QByteArray packedArgs;
  QDataStream stream( packedArgs, IO_WriteOnly );

  stream << (int) 'c';

  mJob = KIO::special( url, packedArgs, false );
  KIO::Scheduler::assignJobToSlave( mSlave, mJob );
  connect( mJob, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)) );
  connect( mJob, SIGNAL(infoMessage(KIO::Job*,const QString&)),
	   SLOT(slotData(KIO::Job*,const QString&)) );
}

//-----------------------------------------------------------------------------
void KMServerTest::slotData(KIO::Job *, const QString &data)
{
  if ( mList.empty() )
    mList = QStringList::split(' ', data);
kdDebug(5006) << data << endl;
kdDebug(5006) << "count = " << mList.count() << endl;
}

void KMServerTest::slotMetaData( const KIO::MetaData & md ) {
  KIO::MetaData::const_iterator it = md.find( "PLAIN AUTH METHODS" );
  if ( it != md.end() )
    mAuthNone = it.data();
  it = md.find( "TLS AUTH METHODS" );
  if ( it != md.end() )
    mAuthTLS = it.data();
  it = md.find( "SSL AUTH METHODS" );
  if ( it != md.end() )
    mAuthSSL = it.data();
}

//-----------------------------------------------------------------------------
void KMServerTest::slotResult(KIO::Job *job)
{
  slotSlaveResult(mSlave, job->error());
}

//-----------------------------------------------------------------------------
void KMServerTest::slotSlaveResult(KIO::Slave *aSlave, int error,
  const QString &)
{
  if (aSlave != mSlave) return;
  if (error != KIO::ERR_SLAVE_DIED && mSlave)
  {
    KIO::Scheduler::disconnectSlave(mSlave);
    mSlave = 0;
  }
  if (!mSSL) {
    mSSL = true;
    if ( error )
      mList.clear();
    else
      mList.append("NORMAL-CONNECTION");
    startOffSlave();
  } else {
    if (error)
      mJob->showErrorDialog( 0L );

    mJob = 0;
    if (!error) mList.append("SSL");
    emit capabilities(mList);
    emit capabilities(mList, mAuthNone, mAuthSSL, mAuthTLS);
  }
}

#include "kmservertest.moc"
<|endoftext|>