1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <memory>
20 
21 #include <gtest/gtest.h>
22 
23 #include <jni.h>
24 #include <nativehelper/JniInvocation.h>
25 
26 namespace android {
27 
28 // Example test setup following googletest docs:
29 //
30 //   template <typename Provider>
31 //   class TemplatedTest : public JNITestBase<Provider> {
32 //      ...
33 //   }
34 //
35 //   typedef ::testing::Types<MockJNIProvider> Providers;
36 //   TYPED_TEST_CASE(TemplatedTest, Providers);
37 //
38 //   TYPED_TEST() {
39 //     // Test code. Use "this->" to access TemplatedTest members.
40 //   }
41 
42 
43 
44 // Provider is a concept that must follow this structure:
45 //
46 // class JNIProvider {
47 // public:
48 //    JNIProvider();
49 //
50 //    void SetUp();
51 //    JNIEnv* CreateJNIEnv();
52 //
53 //    void DestroyJNIEnv(JNIEnv* env);
54 //    void TearDown();
55 // }
56 
57 template <typename Provider, typename Test = ::testing::Test>
58 class JNITestBase : public Test {
59 protected:
60     JNITestBase() : provider_(), env_(nullptr), java_vm_(nullptr) {
61     }
62 
63     void SetUp() override {
64         Test::SetUp();
65         provider_.SetUp();
66         env_ = provider_.CreateJNIEnv();
67         ASSERT_TRUE(env_ != nullptr);
68     }
69 
70     void TearDown() override {
71         provider_->DestroyJNIEnv(env_);
72         provider_->TearDown();
73         Test::TearDown();
74     }
75 
76 protected:
77     Provider provider_;
78 
79     JNIEnv* env_;
80     JavaVM* java_vm_;
81 };
82 
83 // A mockable implementation of the Provider concept. It is the responsibility
84 // of the test to stub out any needed functions (all function pointers will be
85 // null initially).
86 //
87 // TODO: Consider googlemock.
88 class MockJNIProvider {
89 public:
90     MockJNIProvider() {
91     }
92 
93     void SetUp() {
94         // Nothing to here.
95     }
96 
97     // TODO: Spawn threads to allow more envs?
98     JNIEnv* CreateJNIEnv() {
99         return CreateMockedJNIEnv().release();
100     }
101 
102     void DestroyJNIEnv(JNIEnv* env) {
103         delete env->functions;
104         delete env;
105     }
106 
107     void TearDown() {
108         // Nothing to do here.
109     }
110 
111 protected:
112     std::unique_ptr<JNIEnv> CreateMockedJNIEnv() {
113         JNINativeInterface* inf = new JNINativeInterface();
114         memset(inf, 0, sizeof(JNINativeInterface));
115 
116         std::unique_ptr<JNIEnv> ret(new JNIEnv{0});
117         ret->functions = inf;
118 
119         return ret;
120     }
121 };
122 
123 }  // namespace android
124 
125