A Little Princess
by Frances Hodgson Burnett
Chapter 18: “I Tried Not to Be”
Additional Information
- Year Published: 1906
- Language: English
- Country of Origin: England
- Source: Burnett F. H. (1906). The Little Princess.London, England: Warne.
-
Readability:
- Flesch–Kincaid Level: 6.3
- Word Count: 4,019
- Genre: Adventure
- Keywords: 20th century literature, american literature, childrenõs literature
- ✎ Cite This
Downloads
It was pretty, comfortable Mrs. Carmichael who explained everything. She was sent for at once, and came across the square to take Sara into her warm arms and make clear to her all that had happened. The excitement of the totally unexpected discovery had been temporarily almost overpowering to Mr. Carrisford in his weak condition.
“Upon my word,” he said faintly to Mr. Carmichael, when it was suggested that the little girl should go into another room. “I feel as if I do not want to lose sight of her.”
“I will take care of her,” Janet said, “and mamma will come in a few minutes.” And it was Janet who led her away.
“We’re so glad you are found,” she said. “You don’t know how glad we are that you are found.”
Donald stood with his hands in his pockets, and gazed at Sara with reflecting and self-reproachful eyes.
“If I’d just asked what your name was when I gave you my sixpence,” he said, “you would have told me it was Sara Crewe, and then you would have been found in a minute.” Then Mrs. Carmichael came in. She looked very much moved, and suddenly took Sara in her arms and kissed her.
“You look bewildered, poor child,” she said. “And it is not to be wondered at.”
Sara could only think of one thing.
“Was he,” she said, with a glance toward the closed door of the library—”was he the wicked friend? Oh, do tell me!”
Mrs. Carmichael was crying as she kissed her again. She felt as if she ought to be kissed very often because she had not been kissed for so long.
“He was not wicked, my dear,” she answered. “He did not really lose your papa’s money. He only thought he had lost it; and because he loved him so much his grief made him so ill that for a time he was not in his right mind. He almost died of brain fever, and long before he began to recover your poor papa was dead.”
“And he did not know where to find me,” murmured Sara. “And I was so near.” Somehow, she could not forget that she had been so near.
“He believed you were in school in France,” Mrs. Carmichael explained. “And he was continually misled by false clues. He has looked for you everywhere. When he saw you pass by, looking so sad and neglected, he did not dream that you were his friend’s poor child; but because you were a little girl, too, he was sorry for you, and wanted to make you happier. And he told Ram Dass to climb into your attic window and try to make you comfortable.”
Sara gave a start of joy; her whole look changed.
“Did Ram Dass bring the things?” she cried out. “Did he tell Ram Dass to do it? Did he make the dream that came true?”
“Yes, my dear—yes! He is kind and good, and he was sorry for you, for little lost Sara Crewe’s sake.”
The library door opened and Mr. Carmichael appeared, calling Sara to him with a gesture.
“Mr. Carrisford is better already,” he said. “He wants you to come to him.”
Sara did not wait. When the Indian gentleman looked at her as she entered, he saw that her face was all alight.
She went and stood before his chair, with her hands clasped together against her breast.
“You sent the things to me,” she said, in a joyful emotional little voice, “the beautiful, beautiful things? You sent them!”
“Yes, poor, dear child, I did,” he answered her. He was weak and broken with long illness and trouble, but he looked at her with the look she remembered in her father’s eyes—that look of loving her and wanting to take her in his arms. It made her kneel down by him, just as she used to kneel by her father when they were the dearest friends and lovers in the world.
“Then it is you who are my friend,” she said; “it is you who are my friend!” And she dropped her face on his thin hand and kissed it again and again.
“The man will be himself again in three weeks,” Mr. Carmichael said aside to his wife. “Look at his face already.”
In fact, he did look changed. Here was the “Little Missus,” and he had new things to think of and plan for already. In the first place, there was Miss Minchin. She must be interviewed and told of the change which had taken place in the fortunes of her pupil.
Sara was not to return to the seminary at all. The Indian gentleman was very determined upon that point. She must remain where she was, and Mr. Carmichael should go and see Miss Minchin himself.
“I am glad I need not go back,” said Sara. “She will be very angry. She does not like me; though perhaps it is my fault, because I do not like her.”
But, oddly enough, Miss Minchin made it unnecessary for Mr. Carmichael to go to her, by actually coming in search of her pupil herself. She had wanted Sara for something, and on inquiry had heard an astonishing thing. One of the housemaids had seen her steal out of the area with something hidden under her cloak, and had also seen her go up the steps of the next door and enter the house.
“What does she mean!” cried Miss Minchin to Miss Amelia.
“I don’t know, I’m sure, sister,” answered Miss Amelia. “Unless she has made friends with him because he has lived in India.”
“It would be just like her to thrust herself upon him and try to gain his sympathies in some such impertinent fashion,” said Miss Minchin. “She must have been in the house for two hours. I will not allow such presumption. I shall go and inquire into the matter, and apologize for her intrusion.”
Sara was sitting on a footstool close to Mr. Carrisford’s knee, and listening to some of the many things he felt it necessary to try to explain to her, when Ram Dass announced the visitor’s arrival.
Sara rose involuntarily, and became rather pale; but Mr. Carrisford saw that she stood quietly, and showed none of the ordinary signs of child terror.
Miss Minchin entered the room with a sternly dignified manner. She was correctly and well dressed, and rigidly polite.
“I am sorry to disturb Mr. Carrisford,” she said; “but I have explanations to make. I am Miss Minchin, the proprietress of the Young Ladies’ Seminary next door.”
The Indian gentleman looked at her for a moment in silent scrutiny. He was a man who had naturally a rather hot temper, and he did not wish it to get too much the better of him.
“So you are Miss Minchin?” he said.
“I am, sir.”
“In that case,” the Indian gentleman replied, “you have arrived at the right time. My solicitor, Mr. Carmichael, was just on the point of going to see you.”
Mr. Carmichael bowed slightly, and Miiss Minchin looked from him to Mr. Carrisford in amazement.
“Your solicitor!” she said. “I do not understand. I have come here as a matter of duty. I have just discovered that you have been intruded upon through the forwardness of one of my pupils—a charity pupil. I came to explain that she intruded without my knowledge.” She turned upon Sara. “Go home at once,” she commanded indignantly. “You shall be severely punished. Go home at once.”
The Indian gentleman drew Sara to his side and patted her hand.
“She is not going.”
Miss Minchin felt rather as if she must be losing her senses.
“Not going!” she repeated.
“No,” said Mr. Carrisford.  Her home for the future will be with me.”
Miss Minchin fell back in amazed indignation.
“With you! With you sir! What does this mean?”
“Kindly explain the matter, Carmichael,” said the Indian gentleman; “and get it over as quickly as possible.” And he made Sara sit down again, and held her hands in his—which was another trick of her papa’s.
Then Mr. Carmichael explained—in the quiet, level-toned, steady manner of a man who knew his subject, and all its legal significance, which was a thing Miss Minchin understood as a business woman, and did not enjoy.
“Mr. Carrisford, madam,” he said, “was an intimate friend of the late Captain Crewe. He was his partner in certain large investments. The fortune which Captain Crewe supposed he had lost has been recovered, and is now in Mr. Carrisford’s hands.”
“The fortune!” cried Miss Minchin; and she really lost color as she uttered the exclamation. “Sara’s fortune!”
“It will be Sara’s fortune,” replied Mr. Carmichael, rather coldly. “It is Sara’s fortune now, in fact. Certain events have increased it enormously. The diamond mines have retrieved themselves.”
“The diamond mines!” Miss Minchin gasped out. If this was true, nothing so horrible, she felt, had ever happened to her since she was born.
“The diamond mines,” Mr. Carmichael repeated, and he could not help adding, with a rather sly, unlawyer-like smile, “There are not many princesses, Miss Minchin, who are richer than your little charity pupil, Sara Crewe, will be. Mr. Carrisford has been searching for her for nearly two years; he has found her at last, and he will keep her.”
After which he asked Miss Minchin to sit down while he explained matters to her fully, and went into such detail as was necessary to make it quite clear to her that Sara’s future was an assured one, and that what had seemed to be lost was to be restored to her tenfold; also, that she had in Mr. Carrisford a guardian as well as a friend.
Miss Minchin was not a clever woman, and in her excitement she was silly enough to make one desperate effort to regain what she could not help seeing she had lost through her worldly folly.
“He found her under my care,” she protested. “I have done everything for her. But for me she should have starved in the streets.”
Here the Indian gentleman lost his temper.
“As to starving in the streets,” he said, “she might have starved more comfortably there than in your attic.”
“Captain Crewe left her in my charge,” Miss Minchin argued. “She must return to it until she is of age. She can be a parlor boarder again. She must finish her education. The law will interfere in my behalf”
“Come, come, Miss Minchin,” Mr. Carmichael interposed, “the law will do nothing of the sort. If Sara herself wishes to return to you, I dare say Mr. Carrisford might not refuse to allow it. But that rests with Sara.”
“Then,” said Miss Minchin, “I appeal to Sara.  And—ahem—I have always been fond of you.”
Sara’s green-gray eyes fixed themselves on her with the quiet, clear look Miss Minchin particularly disliked.
“Have you, Miss Minchin?” she said. “I did not know that.”
Miss Minchin reddened and drew herself up.
“You ought to have known it,” said she; “but children, unfortunately, never know what is best for them. Amelia and I always said you were the cleverest child in the school. Will you not do your duty to your poor papa and come home with me?”
Sara took a step toward her and stood still. She was thinking of the day when she had been told that she belonged to nobody, and was in danger of being turned into the street; she was thinking of the cold, hungry hours she had spent alone with Emily and Melchisedec in the attic. She looked Miss Minchin steadily in the face.
“You know why I will not go home with you, Miss Minchin,” she said; “you know quite well.”

“You will never see your companions again,” she began. “I will see that Ermengarde and Lottie are kept away—”
Mr. Carmichael stopped her with polite firmness.
“Excuse me,” he said; “she will see anyone she wishes to see. The parents of Miss Crewe’s fellow-pupils are not likely to refuse her invitations to visit her at her guardian’s house. Mr. Carrisford will attend to that.”
It must be confessed that even Miss Minchin flinched. This was worse than the eccentric bachelor uncle who might have a peppery temper and be easily offended at the treatment of his niece. A woman of sordid mind could easily believe that most people would not refuse to allow their children to remain friends with a little heiress of diamond mines. And if Mr. Carrisford chose to tell certain of her patrons how unhappy Sara Crewe had been made, many unpleasant things might happen.
“You have not undertaken an easy charge,” she said to the Indian gentleman, as she turned to leave the room; “you will discover that very soon. The child is neither truthful nor grateful.
Sara looked down and flushed a little, because she thought her pet fancy might not be easy for strangers—even nice ones—to understand at first.
“I—tried not to be anything else,” she answered in a low voice— “even when I was coldest and hungriest—I tried not to be.”
“Now it will not be necessary to try,” said Miss Minchin, acidly, as Ram Dass salaamed her out of the room.
She returned home and, going to her sitting room, sent at once for Miss Amelia. She sat closeted with her all the rest of the afternoon, and it must be admitted that poor Miss Amelia passed through more than one bad quarter of an hour. She shed a good many tears, and mopped her eyes a good deal. One of her unfortunate remarks almost caused her sister to snap her head entirely off, but it resulted in an unusual manner.
“I’m not as clever as you, sister,” she said, “and I am always afraid to say things to you for fear of making you angry. Perhaps if I were not so timid it would be better for the school and for both of us. I must say I’ve often thought it would have been better if you had been less severe on Sara Crewe, and had seen that she was decently dressed and more comfortable. I know she was worked too hard for a child of her age, and I know she was only half fed—”
“How dare you say such a thing!” exclaimed Miss Minchin.
“I don’t know how I dare,” Miss Amelia answered, with a kind of reckless courage; “but now I’ve begun I may as well finish, whatever happens to me. The child was a clever child and a good child—and she would have paid you for any kindness you had shown her. But you didn’t show her any. The fact was, she was too clever for you, and you always disliked her for that reason. She used to see through us both—”
“Amelia!” gasped her infuriated elder, looking as if she would box her ears and knock her cap off, as she had often done to Becky.

“She did! She did!” she cried. “She saw through us both. She saw that you were a hard-hearted, worldly woman, and that I was a weak fool, and that we were both of us vulgar and mean enough to grovel on our knees for her money, and behave ill to her because it was taken from her—though she behaved herself like a little princess even when she was a beggar. She did—she did—like a little princess!” And her hysterics got the better of the poor woman, and she began to laugh and cry both at once, and rock herself backward and forward.
“And now you’ve lost her,” she cried wildly; “and some other school will get her and her money; and if she were like any other child she’d tell how she’s been treated, and all our pupils would be taken away and we should be ruined.
And she was in danger of making so much noise with her hysterical chokes and gurgles that her sister was obliged to go to her and apply salts and sal volatile to quiet her, instead of pouring forth her indignation at her audacity.
And from that time forward, it may be mentioned, the elder Miss Minchin actually began to stand a little in awe of a sister who, while she looked so foolish, was evidently not quite so foolish as she looked, and might, consequently, break out and speak truths people did not want to hear.
 It was queer because, while it was an expression of delighted excitement, it was combined with such amazement as seemed to belong to a kind of shock just received.
“What is the matter?” cried two or three voices at once.
“Is it anything to do with the row that has been going on?” said Lavinia, eagerly. “There has been such a row in Miss Minchin’s room, Miss Amelia has had something like hysterics and has had to go to bed.”
Ermengarde answered them slowly as if she were half stunned.
“I have just had this letter from Sara,” she said, holding it out to let them see what a long letter it was.
“From Sara!” Every voice joined in that exclamation.
“Where is she?” almost shrieked Jessie.
“Next door,” said Ermengarde, “with the Indian gentleman.”
“Where? Where? Has she been sent away? Does Miss Minchin know? Was the row about that? Why did she write? Tell us! Tell us!”
There was a perfect babel, and Lottie began to cry plaintively.
Ermengarde answered them slowly as if she were half plunged out into what, at the moment, seemed the most important and self- explaining thing.
“There were diamond mines,” she said stoutly; “there were!” Open mouths and open eyes confronted her.
“They were real,” she hurried on. “It was all a mistake about them. Something happened for a time, and Mr. Carrisford thought they were ruined—”
“Who is Mr. Carrisford?” shouted Jessie.
“The Indian gentleman. And Captain Crewe thought so, too—and he died; and Mr. Carrisford had brain fever and ran away, and he almost died. And he did not know where Sara was. And it turned out that there were millions and millions of diamonds in the mines; and half of them belong to Sara; and they belonged to her when she was living in the attic with no one but Melchisedec for a friend, and the cook ordering her about. And Mr. Carrisford found her this afternoon, and he has got her in his home—and she will never come back—and she will be more a princess than she ever was—a hundred and fifty thousand times more. And I am going to see her tomorrow afternoon. There!”
Even Miss Minchin herself could scarcely have controlled the uproar after this; and though she heard the noise, she did not try. She was not in the mood to face anything more than she was facing in her room, while Miss Amelia was weeping in bed. She knew that the news had penetrated the walls in some mysterious manner, and that every servant and every child would go to bed talking about it.
So until almost midnight the entire seminary, realizing somehow that all rules were laid aside, crowded round Ermengarde in the schoolroom and heard read and re-read the letter containing a story which was quite as wonderful as any Sara herself had ever invented, and which had the amazing charm of having happened to Sara herself and the mystic Indian gentleman in the very next house.
Becky, who had heard it also, managed to creep up stairs earlier than usual. She wanted to get away from people and go and look at the little magic room once more. She did not know what would happen to it. It was not likely that it would be left to Miss Minchin. It would be taken away, and the attic would be bare and empty again. Glad as she was for Sara’s sake, she went up the last flight of stairs with a lump in her throat and tears blurring her sight. There would be no fire tonight, and no rosy lamp; no supper, and no princess sitting in the glow reading or telling stories—no princess!
She choked down a sob as she pushed the attic door open, and then she broke into a low cry.
The lamp was flushing the room, the fire was blazing, the supper was waiting; and Ram Dass was standing smiling into her startled face.
“Missee sahib remembered,” he said. “She told the sahib all. She wished you to know the good fortune which has befallen her. Behold a letter on the tray. She has written. She did not wish that you should go to sleep unhappy. The sahib commands you to come to him tomorrow. You are to be the attendant of missee sahib. Tonight I take these things back over the roof.”
And having said this with a beaming face, he made a little salaam and slipped through the skylight with an agile silentness of movement which showed Becky how easily he had done it before.


Score: 0
High Score: 0
Snake is a popular game in which the user controls a snake-like line and moves it across the game board in order to eat food and grow longer. The object of the game is to become as long as possible, or equivalently, to earn the highest score. To that end, the user must take care to maneuver the snake in a way that avoids collision with itself or with the outer walls. Unfortunately, your browser does not support canvas, which is needed in order for this game to run.


This is my main program to run the code using MPI on our Superdome cluster. The code is well documented - please examine it for a discussion of how it works.
last modified 25 December, 2005


About
I am a rising Senior at the University of North Carolina - Chapel Hill; and my exepcted graduation is May 2016. After my undergrad I plan to pursue a MSIS graduate degree; which hopefully will better allow me to pursue a professional career in Information and Library Science. I am originally from Atlanta, Georgia, and attended high school at the Gwinnett School of Math, Science and Technology. My time at Carolina has been spent in a number of ways. My first few years at Univrsity, I was a part of the Carolina Millennial Scholars Program - an orginization dedicated to creating an open community for incoming male minority students. As a member I participated in peer mentoriship and community service in the Chapel Hill area. Outside of the program I also worked with Habitat for Humanity to help build homes in an attempt to lower the global housing crisis. For a more detailed look at my experience and qualifications, please refer to my resume below.
Resume and Cover Letter
Resume - is published and viewable through google docs.


padharo sa!
welcome to rajasthan tourism
Menu
Home
About
Places to visit
Jaipur
Jodhpur
Udaipur
Jaisalmer
Contact
Login


class: center, middle # 2017/04/04 - Bigdata Use Case --- # Problem: Design a Big Data architecture that can be used to process the clickstream data to extract insights for Business Analytics, Text Analytics, Recommendation Engines, Data Services, etc # Proposed Solution: After digging into the current technologies for Bigdata, the solution I chose to try was send the logs clickstrem from multiple web server through [Logstash](https://www.elastic.co/products/logstash) into [Kafka](http://kafka.apache.org/). From there we are going to use [Spark Streaming](http://spark.apache.org/streaming/) to get the data into an [Hadoop Cluster](http://hadoop.apache.org/) managed using the [Cloudera](https://www.cloudera.com/) tools.
--- # Devops Tools For the following slides, I'm going to use these tools: - [Invoke](http://www.pyinvoke.org) to create simple commands ([fabric](http://www.fabfile.org/) like) - [Ansible](https://www.ansible.com) for host config/setup automation Everything is under the `fdevops` directory. --- # Launch EC2 for Cloudera Director To build our use case, let's start to Install and Setup the Hadoop Cluster. I'm going to use Cloudera Director on Amazon EC2 following the instructions [here](https://www.cloudera.com/documentation/director/latest/topics/director_deployment_start_launcher.html#concept_jbc_zhk_wr). I chose to use Ubuntu 16.04 because it's the Linux distribution that I most use. ```bash $ invoke prd.ec2_create c4.large cdh PLAY [Create EC2] ************************************************************** TASK [aws-ec2-instance : Create an EC2 instance] ******************************* changed: [localhost -> localhost] PLAY RECAP ********************************************************************* localhost : ok=1 changed=1 unreachable=0 failed=0 ``` And on AWS EC2:
--- # Configure EC2 Get the public IP ```bash $ invoke prd.ec2_refresh_cache $ invoke prd.ec2_list cdh hosts (1): <IP_ADDRESS> ``` Update the file `inventory/hosts` and run ```bash $ invoke prd.cdh_update cdh [...] TASK [srv-cdh-apt : Setup cloudera director repo key] ************************** TASK [srv-cdh-apt : Setup cloudera director repo] ****************************** TASK [srv-cdh-apt : Apt Update] ************************************************ TASK [srv-cdh-apt : Apt install required packages] ***************************** TASK [srv-cdh-apt : Apt install cloudera] ************************************** TASK [srv-cdh-setup : Restart Cloudera Director Server] ************************ ``` --- # Access to Cloudera Director Cloudera Director is not accessible from the public, so I used the [Step 1: Set Up a SOCKS Proxy Server with SSH](https://www.cloudera.com/documentation/director/latest/topics/director_security_socks.html#concept_ish_wmh_4x) suggested by Cloudera. Open 2 terminals and run the following commands on each of them: ```bash $ invoke prd.cdh_start_proxy ``` ```bash $ invoke prd.cdh_start_chrome ``` The last command launches a Chrome browser able to connect to Cloudera Director, for this you need to go to the EC2 Console, and search for the private IP of the machine.
--- # Cloudera Director
--- # Cloudera Manager Following the documentation on [Deploying Cloudera Manager and CDH on AWS](https://www.cloudera.com/documentation/director/latest/topics/director_get_started_aws_install_cm_cdh.html) 1. We need to create an environment with our AWS credentials 2. Configure an Instance Template 3. Choose a license, in my case the trial license --- # Setup the Cluster 1/4 Time to setup and run the Cluster 1. Configured 'cdh-cluster' as the cluster name 2. Chose to install all services 3. For the instance groups "workers" I chose only 5 instances 4. Configure the instance templates for the instance groups --- # Setup the Cluster 2/4
--- # Setup the Cluster 3/4
--- # Setup the Cluster 4/4
--- # Cluster is on AWS All instances are up and running
--- # Logstash To start, let's create an instance with Logstash installed. After that we can send logs into Logstash and then connect it with Kafka. ```bash $ invoke prd.ec2_create t2.medium logstash_1 PLAY [Create EC2] ************************************************************** TASK [aws-ec2-instance : Create an EC2 instance] ******************************* changed: [localhost -> localhost] PLAY RECAP ********************************************************************* localhost : ok=1 changed=1 unreachable=0 failed=0 ``` Get the public IP ```bash $ invoke prd.ec2_refresh_cache $ invoke prd.ec2_list logstash_0 hosts (1): <IP_ADDRESS> ``` And then Update the file `inventory/hosts` --- # Setup Logstash - generate logs Before we run the `invoke` command to setup Logstash, let's just take a moment to think about it. We don't have a fully working web server to feed logs to logstash Using a sample log file let's make a python script to generate logs forever ```python def print_file(sleep=5, limit=10): with open('/home/ubuntu/ctlogs-.1438663216674') as fh: count = 0 for line in fh: sys.stdout.write(line) count += 1 if count >= limit: count = 0 time.sleep(sleep) def main(): while True: print_file(5, 10) ``` --- # Setup Logstash - clickstream.conf For the `input` we use the `pipe` plugin to run our python script Because we already have log sample shaped to our needs, we don't need to configure filters, and we just send the log lines directly to kafka. ```json input { pipe { command => "/home/ubuntu/gen_logs.py" } } ``` And then configure the `output` to send to kafka, and for that we need to find the private IP in **Cloudera manager > KAFKA-1 > instances** ```json output { kafka { bootstrap_servers => "<IP_ADDRESS>:9092" topic_id => "clickstream" codec => plain { format => "%{message}" } } stdout { } } ``` --- # Setup Logstash - nuisances The Logstash output plugin is not compatible with the Kafka version instaled on the Cloudera Cluster. To solve this I needed to downgrade `logstash-output-kafka` plugin to version 4.0.4 --- # Setup Logstash - Invoke command ```bash $ invoke prd.log_update logstash_1 PLAY [Logstash Setup] ********************************************************** TASK [setup] ******************************************************************* TASK [srv-log-apt : Setup logstash repo key] *********************************** TASK [srv-log-apt : Setup logstash repo] *************************************** TASK [srv-log-apt : Apt Update] ************************************************ TASK [srv-log-apt : Apt install required packages] ***************************** TASK [srv-log-apt : Apt install logstash] ************************************** TASK [srv-pyenv : Install pyenv] *********************************************** TASK [srv-pyenv : Set bash_aliases] ******************************************** TASK [srv-pyenv : Set .profile] ************************************************ TASK [srv-pyenv : Install python] ********************************************** TASK [srv-log-setup : Copy ctlogs] ********************************************* TASK [srv-log-setup : Copy gen_logs.py] **************************************** TASK [srv-log-setup : Copy clickstream.conf] *********************************** TASK [srv-log-setup : Stop logstash to remove plugin] ************************** TASK [srv-log-setup : Remove logstash-output-kafka plugin] ********************* TASK [srv-log-setup : Install logstash-output-kafka plugin version 4.0.4] ****** TASK [srv-log-setup : Start logstash] ****************************************** ``` --- # Kafka To check if the logs are be sent to Kafka we can start a consumer in the shell with the command: ```bash kafka-console-consumer --zookeeper <IP_ADDRESS>:2181 --topic clickstream ``` And the logs being fed to logstash should now being showed on the screen. --- # Kafka - Status Cloudera Kafka status page
--- # This is a Work In Progress! Next steps: 1. Configure a schema in HBase 2. Configure Spark Streaming to consume kafka clickstream into HBase 3. Work on the Exploration by Data Scientist and Data Analysts 4. Create real-time use case 5. Think about use cases and to do queries to fetch relevant data from HBase 7. Test the scalability of the architecture, and think about automation and strategies --- # References * https://www.elastic.co/webinars/getting-started-logstash?baymax=rtp&elektra=products&iesrc=ctr * https://kafka.apache.org/documentation/ * https://www.elastic.co/guide/en/logstash/current/plugins-outputs-kafka.html * https://github.com/logstash-plugins/logstash-output-kafka * https://www.elastic.co/guide/en/logstash/current/plugins-inputs-pipe.html * http://eagle.apache.org/docs/cloudera-integration.html * https://github.com/dpkp/kafka-python * http://docs.ansible.com/ansible/intro.html * https://mapr.com/blog/guidelines-hbase-schema-design/


It will expire on {{ profile.membership_expiration_datetime }}.
{% endif %}


Your account has been successfully verified. You can sign in with your registered email and password.


1 // Copyright 2007, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 31 // Google Mock - a framework for writing C++ mock classes. 32 // 33 // This file implements the spec builder syntax (ON_CALL and 34 // EXPECT_CALL). 35 36 #include "gmock/gmock-spec-builders.h" 37 38 #include <stdlib.h> 39 #include <iostream> // NOLINT 40 #include <map> 41 #include <set> 42 #include <string> 43 #include <vector> 44 #include "gmock/gmock.h" 45 #include "gtest/gtest.h" 46 47 #if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC 48 # include <unistd.h> // NOLINT 49 #endif 50 51 // Silence C4800 (C4800: 'int *const ': forcing value 52 // to bool 'true' or 'false') for MSVC 14,15 53 #ifdef _MSC_VER 54 #if _MSC_VER <= 1900 55 # pragma warning(push) 56 # pragma warning(disable:4800) 57 #endif 58 #endif 59 60 namespace testing { 61 namespace internal { 62 63 // Protects the mock object registry (in class Mock), all function 64 // mockers, and all expectations. 65 GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); 66 67 // Logs a message including file and line number information. 68 GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, 69 const char* file, int line, 70 const std::string& message) { 71 ::std::ostringstream s; 72 s << file << ":" << line << ": " << message << ::std::endl; 73 Log(severity, s.str(), 0); 74 } 75 76 // Constructs an ExpectationBase object. 77 ExpectationBase::ExpectationBase(const char* a_file, int a_line, 78 const std::string& a_source_text) 79 : file_(a_file), 80 line_(a_line), 81 source_text_(a_source_text), 82 cardinality_specified_(false), 83 cardinality_(Exactly(1)), 84 call_count_(0), 85 retired_(false), 86 extra_matcher_specified_(false), 87 repeated_action_specified_(false), 88 retires_on_saturation_(false), 89 last_clause_(kNone), 90 action_count_checked_(false) {} 91 92 // Destructs an ExpectationBase object. 93 ExpectationBase::~ExpectationBase() {} 94 95 // Explicitly specifies the cardinality of this expectation. Used by 96 // the subclasses to implement the .Times() clause. 97 void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) { 98 cardinality_specified_ = true; 99 cardinality_ = a_cardinality; 100 } 101 102 // Retires all pre-requisites of this expectation. 103 void ExpectationBase::RetireAllPreRequisites() 104 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 105 if (is_retired()) { 106 // We can take this short-cut as we never retire an expectation 107 // until we have retired all its pre-requisites. 108 return; 109 } 110 111 ::std::vector<ExpectationBase*> expectations(1, this); 112 while (!expectations.empty()) { 113 ExpectationBase* exp = expectations.back(); 114 expectations.pop_back(); 115 116 for (ExpectationSet::const_iterator it = 117 exp->immediate_prerequisites_.begin(); 118 it != exp->immediate_prerequisites_.end(); ++it) { 119 ExpectationBase* next = it->expectation_base().get(); 120 if (!next->is_retired()) { 121 next->Retire(); 122 expectations.push_back(next); 123 } 124 } 125 } 126 } 127 128 // Returns true iff all pre-requisites of this expectation have been 129 // satisfied. 130 bool ExpectationBase::AllPrerequisitesAreSatisfied() const 131 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 132 g_gmock_mutex.AssertHeld(); 133 ::std::vector<const ExpectationBase*> expectations(1, this); 134 while (!expectations.empty()) { 135 const ExpectationBase* exp = expectations.back(); 136 expectations.pop_back(); 137 138 for (ExpectationSet::const_iterator it = 139 exp->immediate_prerequisites_.begin(); 140 it != exp->immediate_prerequisites_.end(); ++it) { 141 const ExpectationBase* next = it->expectation_base().get(); 142 if (!next->IsSatisfied()) return false; 143 expectations.push_back(next); 144 } 145 } 146 return true; 147 } 148 149 // Adds unsatisfied pre-requisites of this expectation to 'result'. 150 void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const 151 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 152 g_gmock_mutex.AssertHeld(); 153 ::std::vector<const ExpectationBase*> expectations(1, this); 154 while (!expectations.empty()) { 155 const ExpectationBase* exp = expectations.back(); 156 expectations.pop_back(); 157 158 for (ExpectationSet::const_iterator it = 159 exp->immediate_prerequisites_.begin(); 160 it != exp->immediate_prerequisites_.end(); ++it) { 161 const ExpectationBase* next = it->expectation_base().get(); 162 163 if (next->IsSatisfied()) { 164 // If *it is satisfied and has a call count of 0, some of its 165 // pre-requisites may not be satisfied yet. 166 if (next->call_count_ == 0) { 167 expectations.push_back(next); 168 } 169 } else { 170 // Now that we know next is unsatisfied, we are not so interested 171 // in whether its pre-requisites are satisfied. Therefore we 172 // don't iterate into it here. 173 *result += *it; 174 } 175 } 176 } 177 } 178 179 // Describes how many times a function call matching this 180 // expectation has occurred. 181 void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const 182 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 183 g_gmock_mutex.AssertHeld(); 184 185 // Describes how many times the function is expected to be called. 186 *os << " Expected: to be "; 187 cardinality().DescribeTo(os); 188 *os << "\n Actual: "; 189 Cardinality::DescribeActualCallCountTo(call_count(), os); 190 191 // Describes the state of the expectation (e.g. is it satisfied? 192 // is it active?). 193 *os << " - " << (IsOverSaturated() ? "over-saturated" : 194 IsSaturated() ? "saturated" : 195 IsSatisfied() ? "satisfied" : "unsatisfied") 196 << " and " 197 << (is_retired() ? "retired" : "active"); 198 } 199 200 // Checks the action count (i.e. the number of WillOnce() and 201 // WillRepeatedly() clauses) against the cardinality if this hasn't 202 // been done before. Prints a warning if there are too many or too 203 // few actions. 204 void ExpectationBase::CheckActionCountIfNotDone() const 205 GTEST_LOCK_EXCLUDED_(mutex_) { 206 bool should_check = false; 207 { 208 MutexLock l(&mutex_); 209 if (!action_count_checked_) { 210 action_count_checked_ = true; 211 should_check = true; 212 } 213 } 214 215 if (should_check) { 216 if (!cardinality_specified_) { 217 // The cardinality was inferred - no need to check the action 218 // count against it. 219 return; 220 } 221 222 // The cardinality was explicitly specified. 223 const int action_count = static_cast<int>(untyped_actions_.size()); 224 const int upper_bound = cardinality().ConservativeUpperBound(); 225 const int lower_bound = cardinality().ConservativeLowerBound(); 226 bool too_many; // True if there are too many actions, or false 227 // if there are too few. 228 if (action_count > upper_bound || 229 (action_count == upper_bound && repeated_action_specified_)) { 230 too_many = true; 231 } else if (0 < action_count && action_count < lower_bound && 232 !repeated_action_specified_) { 233 too_many = false; 234 } else { 235 return; 236 } 237 238 ::std::stringstream ss; 239 DescribeLocationTo(&ss); 240 ss << "Too " << (too_many ? "many" : "few") 241 << " actions specified in " << source_text() << "...\n" 242 << "Expected to be "; 243 cardinality().DescribeTo(&ss); 244 ss << ", but has " << (too_many ? "" : "only ") 245 << action_count << " WillOnce()" 246 << (action_count == 1 ? "" : "s"); 247 if (repeated_action_specified_) { 248 ss << " and a WillRepeatedly()"; 249 } 250 ss << "."; 251 Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace". 252 } 253 } 254 255 // Implements the .Times() clause. 256 void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { 257 if (last_clause_ == kTimes) { 258 ExpectSpecProperty(false, 259 ".Times() cannot appear " 260 "more than once in an EXPECT_CALL()."); 261 } else { 262 ExpectSpecProperty(last_clause_ < kTimes, 263 ".Times() cannot appear after " 264 ".InSequence(), .WillOnce(), .WillRepeatedly(), " 265 "or .RetiresOnSaturation()."); 266 } 267 last_clause_ = kTimes; 268 269 SpecifyCardinality(a_cardinality); 270 } 271 272 // Points to the implicit sequence introduced by a living InSequence 273 // object (if any) in the current thread or NULL. 274 GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence; 275 276 // Reports an uninteresting call (whose description is in msg) in the 277 // manner specified by 'reaction'. 278 void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { 279 // Include a stack trace only if --gmock_verbose=info is specified. 280 const int stack_frames_to_skip = 281 GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1; 282 switch (reaction) { 283 case kAllow: 284 Log(kInfo, msg, stack_frames_to_skip); 285 break; 286 case kWarn: 287 Log(kWarning, 288 msg + 289 "\nNOTE: You can safely ignore the above warning unless this " 290 "call should not happen. Do not suppress it by blindly adding " 291 "an EXPECT_CALL() if you don't mean to enforce the call. " 292 "See " 293 "https://github.com/google/googletest/blob/master/googlemock/" 294 "docs/CookBook.md#" 295 "knowing-when-to-expect for details.\n", 296 stack_frames_to_skip); 297 break; 298 default: // FAIL 299 Expect(false, NULL, -1, msg); 300 } 301 } 302 303 UntypedFunctionMockerBase::UntypedFunctionMockerBase() 304 : mock_obj_(NULL), name_("") {} 305 306 UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {} 307 308 // Sets the mock object this mock method belongs to, and registers 309 // this information in the global mock registry. Will be called 310 // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock 311 // method. 312 void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) 313 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 314 { 315 MutexLock l(&g_gmock_mutex); 316 mock_obj_ = mock_obj; 317 } 318 Mock::Register(mock_obj, this); 319 } 320 321 // Sets the mock object this mock method belongs to, and sets the name 322 // of the mock function. Will be called upon each invocation of this 323 // mock function. 324 void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj, 325 const char* name) 326 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 327 // We protect name_ under g_gmock_mutex in case this mock function 328 // is called from two threads concurrently. 329 MutexLock l(&g_gmock_mutex); 330 mock_obj_ = mock_obj; 331 name_ = name; 332 } 333 334 // Returns the name of the function being mocked. Must be called 335 // after RegisterOwner() or SetOwnerAndName() has been called. 336 const void* UntypedFunctionMockerBase::MockObject() const 337 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 338 const void* mock_obj; 339 { 340 // We protect mock_obj_ under g_gmock_mutex in case this mock 341 // function is called from two threads concurrently. 342 MutexLock l(&g_gmock_mutex); 343 Assert(mock_obj_ != NULL, __FILE__, __LINE__, 344 "MockObject() must not be called before RegisterOwner() or " 345 "SetOwnerAndName() has been called."); 346 mock_obj = mock_obj_; 347 } 348 return mock_obj; 349 } 350 351 // Returns the name of this mock method. Must be called after 352 // SetOwnerAndName() has been called. 353 const char* UntypedFunctionMockerBase::Name() const 354 GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 355 const char* name; 356 { 357 // We protect name_ under g_gmock_mutex in case this mock 358 // function is called from two threads concurrently. 359 MutexLock l(&g_gmock_mutex); 360 Assert(name_ != NULL, __FILE__, __LINE__, 361 "Name() must not be called before SetOwnerAndName() has " 362 "been called."); 363 name = name_; 364 } 365 return name; 366 } 367 368 // Calculates the result of invoking this mock function with the given 369 // arguments, prints it, and returns it. The caller is responsible 370 // for deleting the result. 371 UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith( 372 void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { 373 // See the definition of untyped_expectations_ for why access to it 374 // is unprotected here. 375 if (untyped_expectations_.size() == 0) { 376 // No expectation is set on this mock method - we have an 377 // uninteresting call. 378 379 // We must get Google Mock's reaction on uninteresting calls 380 // made on this mock object BEFORE performing the action, 381 // because the action may DELETE the mock object and make the 382 // following expression meaningless. 383 const CallReaction reaction = 384 Mock::GetReactionOnUninterestingCalls(MockObject()); 385 386 // True iff we need to print this call's arguments and return 387 // value. This definition must be kept in sync with 388 // the behavior of ReportUninterestingCall(). 389 const bool need_to_report_uninteresting_call = 390 // If the user allows this uninteresting call, we print it 391 // only when they want informational messages. 392 reaction == kAllow ? LogIsVisible(kInfo) : 393 // If the user wants this to be a warning, we print 394 // it only when they want to see warnings. 395 reaction == kWarn 396 ? LogIsVisible(kWarning) 397 : 398 // Otherwise, the user wants this to be an error, and we 399 // should always print detailed information in the error. 400 true; 401 402 if (!need_to_report_uninteresting_call) { 403 // Perform the action without printing the call information. 404 return this->UntypedPerformDefaultAction( 405 untyped_args, "Function call: " + std::string(Name())); 406 } 407 408 // Warns about the uninteresting call. 409 ::std::stringstream ss; 410 this->UntypedDescribeUninterestingCall(untyped_args, &ss); 411 412 // Calculates the function result. 413 UntypedActionResultHolderBase* const result = 414 this->UntypedPerformDefaultAction(untyped_args, ss.str()); 415 416 // Prints the function result. 417 if (result != NULL) 418 result->PrintAsActionResult(&ss); 419 420 ReportUninterestingCall(reaction, ss.str()); 421 return result; 422 } 423 424 bool is_excessive = false; 425 ::std::stringstream ss; 426 ::std::stringstream why; 427 ::std::stringstream loc; 428 const void* untyped_action = NULL; 429 430 // The UntypedFindMatchingExpectation() function acquires and 431 // releases g_gmock_mutex. 432 const ExpectationBase* const untyped_expectation = 433 this->UntypedFindMatchingExpectation( 434 untyped_args, &untyped_action, &is_excessive, 435 &ss, &why); 436 const bool found = untyped_expectation != NULL; 437 438 // True iff we need to print the call's arguments and return value. 439 // This definition must be kept in sync with the uses of Expect() 440 // and Log() in this function. 441 const bool need_to_report_call = 442 !found || is_excessive || LogIsVisible(kInfo); 443 if (!need_to_report_call) { 444 // Perform the action without printing the call information. 445 return 446 untyped_action == NULL ? 447 this->UntypedPerformDefaultAction(untyped_args, "") : 448 this->UntypedPerformAction(untyped_action, untyped_args); 449 } 450 451 ss << " Function call: " << Name(); 452 this->UntypedPrintArgs(untyped_args, &ss); 453 454 // In case the action deletes a piece of the expectation, we 455 // generate the message beforehand. 456 if (found && !is_excessive) { 457 untyped_expectation->DescribeLocationTo(&loc); 458 } 459 460 UntypedActionResultHolderBase* const result = 461 untyped_action == NULL ? 462 this->UntypedPerformDefaultAction(untyped_args, ss.str()) : 463 this->UntypedPerformAction(untyped_action, untyped_args); 464 if (result != NULL) 465 result->PrintAsActionResult(&ss); 466 ss << "\n" << why.str(); 467 468 if (!found) { 469 // No expectation matches this call - reports a failure. 470 Expect(false, NULL, -1, ss.str()); 471 } else if (is_excessive) { 472 // We had an upper-bound violation and the failure message is in ss. 473 Expect(false, untyped_expectation->file(), 474 untyped_expectation->line(), ss.str()); 475 } else { 476 // We had an expected call and the matching expectation is 477 // described in ss. 478 Log(kInfo, loc.str() + ss.str(), 2); 479 } 480 481 return result; 482 } 483 484 // Returns an Expectation object that references and co-owns exp, 485 // which must be an expectation on this mock function. 486 Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { 487 // See the definition of untyped_expectations_ for why access to it 488 // is unprotected here. 489 for (UntypedExpectations::const_iterator it = 490 untyped_expectations_.begin(); 491 it != untyped_expectations_.end(); ++it) { 492 if (it->get() == exp) { 493 return Expectation(*it); 494 } 495 } 496 497 Assert(false, __FILE__, __LINE__, "Cannot find expectation."); 498 return Expectation(); 499 // The above statement is just to make the code compile, and will 500 // never be executed. 501 } 502 503 // Verifies that all expectations on this mock function have been 504 // satisfied. Reports one or more Google Test non-fatal failures 505 // and returns false if not. 506 bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() 507 GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { 508 g_gmock_mutex.AssertHeld(); 509 bool expectations_met = true; 510 for (UntypedExpectations::const_iterator it = 511 untyped_expectations_.begin(); 512 it != untyped_expectations_.end(); ++it) { 513 ExpectationBase* const untyped_expectation = it->get(); 514 if (untyped_expectation->IsOverSaturated()) { 515 // There was an upper-bound violation. Since the error was 516 // already reported when it occurred, there is no need to do 517 // anything here. 518 expectations_met = false; 519 } else if (!untyped_expectation->IsSatisfied()) { 520 expectations_met = false; 521 ::std::stringstream ss; 522 ss << "Actual function call count doesn't match " 523 << untyped_expectation->source_text() << "...\n"; 524 // No need to show the source file location of the expectation 525 // in the description, as the Expect() call that follows already 526 // takes care of it. 527 untyped_expectation->MaybeDescribeExtraMatcherTo(&ss); 528 untyped_expectation->DescribeCallCountTo(&ss); 529 Expect(false, untyped_expectation->file(), 530 untyped_expectation->line(), ss.str()); 531 } 532 } 533 534 // Deleting our expectations may trigger other mock objects to be deleted, for 535 // example if an action contains a reference counted smart pointer to that 536 // mock object, and that is the last reference. So if we delete our 537 // expectations within the context of the global mutex we may deadlock when 538 // this method is called again. Instead, make a copy of the set of 539 // expectations to delete, clear our set within the mutex, and then clear the 540 // copied set outside of it. 541 UntypedExpectations expectations_to_delete; 542 untyped_expectations_.swap(expectations_to_delete); 543 544 g_gmock_mutex.Unlock(); 545 expectations_to_delete.clear(); 546 g_gmock_mutex.Lock(); 547 548 return expectations_met; 549 } 550 551 CallReaction intToCallReaction(int mock_behavior) { 552 if (mock_behavior >= kAllow && mock_behavior <= kFail) { 553 return static_cast<internal::CallReaction>(mock_behavior); 554 } 555 return kWarn; 556 } 557 558 } // namespace internal 559 560 // Class Mock. 561 562 namespace { 563 564 typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers; 565 566 // The current state of a mock object. Such information is needed for 567 // detecting leaked mock objects and explicitly verifying a mock's 568 // expectations. 569 struct MockObjectState { 570 MockObjectState() 571 : first_used_file(NULL), first_used_line(-1), leakable(false) {} 572 573 // Where in the source file an ON_CALL or EXPECT_CALL is first 574 // invoked on this mock object. 575 const char* first_used_file; 576 int first_used_line; 577 ::std::string first_used_test_case; 578 ::std::string first_used_test; 579 bool leakable; // true iff it's OK to leak the object. 580 FunctionMockers function_mockers; // All registered methods of the object. 581 }; 582 583 // A global registry holding the state of all mock objects that are 584 // alive. A mock object is added to this registry the first time 585 // Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It 586 // is removed from the registry in the mock object's destructor. 587 class MockObjectRegistry { 588 public: 589 // Maps a mock object (identified by its address) to its state. 590 typedef std::map<const void*, MockObjectState> StateMap; 591 592 // This destructor will be called when a program exits, after all 593 // tests in it have been run. By then, there should be no mock 594 // object alive. Therefore we report any living object as test 595 // failure, unless the user explicitly asked us to ignore it. 596 ~MockObjectRegistry() { 597 // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is 598 // a macro. 599 600 if (!GMOCK_FLAG(catch_leaked_mocks)) 601 return; 602 603 int leaked_count = 0; 604 for (StateMap::const_iterator it = states_.begin(); it != states_.end(); 605 ++it) { 606 if (it->second.leakable) // The user said it's fine to leak this object. 607 continue; 608 609 // FIXME: Print the type of the leaked object. 610 // This can help the user identify the leaked object. 611 std::cout << "\n"; 612 const MockObjectState& state = it->second; 613 std::cout << internal::FormatFileLocation(state.first_used_file, 614 state.first_used_line); 615 std::cout << " ERROR: this mock object"; 616 if (state.first_used_test != "") { 617 std::cout << " (used in test " << state.first_used_test_case << "." 618 << state.first_used_test << ")"; 619 } 620 std::cout << " should be deleted but never is. Its address is @" 621 << it->first << "."; 622 leaked_count++; 623 } 624 if (leaked_count > 0) { 625 std::cout << "\nERROR: " << leaked_count << " leaked mock " 626 << (leaked_count == 1 ? "object" : "objects") 627 << " found at program exit. Expectations on a mock object is " 628 "verified when the object is destructed. Leaking a mock " 629 "means that its expectations aren't verified, which is " 630 "usually a test bug. If you really intend to leak a mock, " 631 "you can suppress this error using " 632 "testing::Mock::AllowLeak(mock_object), or you may use a " 633 "fake or stub instead of a mock.\n"; 634 std::cout.flush(); 635 ::std::cerr.flush(); 636 // RUN_ALL_TESTS() has already returned when this destructor is 637 // called. Therefore we cannot use the normal Google Test 638 // failure reporting mechanism. 639 _exit(1); // We cannot call exit() as it is not reentrant and 640 // may already have been called. 641 } 642 } 643 644 StateMap& states() { return states_; } 645 646 private: 647 StateMap states_; 648 }; 649 650 // Protected by g_gmock_mutex. 651 MockObjectRegistry g_mock_object_registry; 652 653 // Maps a mock object to the reaction Google Mock should have when an 654 // uninteresting method is called. Protected by g_gmock_mutex. 655 std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction; 656 657 // Sets the reaction Google Mock should have when an uninteresting 658 // method of the given mock object is called. 659 void SetReactionOnUninterestingCalls(const void* mock_obj, 660 internal::CallReaction reaction) 661 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 662 internal::MutexLock l(&internal::g_gmock_mutex); 663 g_uninteresting_call_reaction[mock_obj] = reaction; 664 } 665 666 } // namespace 667 668 // Tells Google Mock to allow uninteresting calls on the given mock 669 // object. 670 void Mock::AllowUninterestingCalls(const void* mock_obj) 671 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 672 SetReactionOnUninterestingCalls(mock_obj, internal::kAllow); 673 } 674 675 // Tells Google Mock to warn the user about uninteresting calls on the 676 // given mock object. 677 void Mock::WarnUninterestingCalls(const void* mock_obj) 678 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 679 SetReactionOnUninterestingCalls(mock_obj, internal::kWarn); 680 } 681 682 // Tells Google Mock to fail uninteresting calls on the given mock 683 // object. 684 void Mock::FailUninterestingCalls(const void* mock_obj) 685 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 686 SetReactionOnUninterestingCalls(mock_obj, internal::kFail); 687 } 688 689 // Tells Google Mock the given mock object is being destroyed and its 690 // entry in the call-reaction table should be removed. 691 void Mock::UnregisterCallReaction(const void* mock_obj) 692 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 693 internal::MutexLock l(&internal::g_gmock_mutex); 694 g_uninteresting_call_reaction.erase(mock_obj); 695 } 696 697 // Returns the reaction Google Mock will have on uninteresting calls 698 // made on the given mock object. 699 internal::CallReaction Mock::GetReactionOnUninterestingCalls( 700 const void* mock_obj) 701 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 702 internal::MutexLock l(&internal::g_gmock_mutex); 703 return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? 704 internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) : 705 g_uninteresting_call_reaction[mock_obj]; 706 } 707 708 // Tells Google Mock to ignore mock_obj when checking for leaked mock 709 // objects. 710 void Mock::AllowLeak(const void* mock_obj) 711 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 712 internal::MutexLock l(&internal::g_gmock_mutex); 713 g_mock_object_registry.states()[mock_obj].leakable = true; 714 } 715 716 // Verifies and clears all expectations on the given mock object. If 717 // the expectations aren't satisfied, generates one or more Google 718 // Test non-fatal failures and returns false. 719 bool Mock::VerifyAndClearExpectations(void* mock_obj) 720 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 721 internal::MutexLock l(&internal::g_gmock_mutex); 722 return VerifyAndClearExpectationsLocked(mock_obj); 723 } 724 725 // Verifies all expectations on the given mock object and clears its 726 // default actions and expectations. Returns true iff the 727 // verification was successful. 728 bool Mock::VerifyAndClear(void* mock_obj) 729 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 730 internal::MutexLock l(&internal::g_gmock_mutex); 731 ClearDefaultActionsLocked(mock_obj); 732 return VerifyAndClearExpectationsLocked(mock_obj); 733 } 734 735 // Verifies and clears all expectations on the given mock object. If 736 // the expectations aren't satisfied, generates one or more Google 737 // Test non-fatal failures and returns false. 738 bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) 739 GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { 740 internal::g_gmock_mutex.AssertHeld(); 741 if (g_mock_object_registry.states().count(mock_obj) == 0) { 742 // No EXPECT_CALL() was set on the given mock object. 743 return true; 744 } 745 746 // Verifies and clears the expectations on each mock method in the 747 // given mock object. 748 bool expectations_met = true; 749 FunctionMockers& mockers = 750 g_mock_object_registry.states()[mock_obj].function_mockers; 751 for (FunctionMockers::const_iterator it = mockers.begin(); 752 it != mockers.end(); ++it) { 753 if (!(*it)->VerifyAndClearExpectationsLocked()) { 754 expectations_met = false; 755 } 756 } 757 758 // We don't clear the content of mockers, as they may still be 759 // needed by ClearDefaultActionsLocked(). 760 return expectations_met; 761 } 762 763 // Registers a mock object and a mock method it owns. 764 void Mock::Register(const void* mock_obj, 765 internal::UntypedFunctionMockerBase* mocker) 766 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 767 internal::MutexLock l(&internal::g_gmock_mutex); 768 g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker); 769 } 770 771 // Tells Google Mock where in the source code mock_obj is used in an 772 // ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this 773 // information helps the user identify which object it is. 774 void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, 775 const char* file, int line) 776 GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { 777 internal::MutexLock l(&internal::g_gmock_mutex); 778 MockObjectState& state = g_mock_object_registry.states()[mock_obj]; 779 if (state.first_used_file == NULL) { 780 state.first_used_file = file; 781 state.first_used_line = line; 782 const TestInfo* const test_info = 783 UnitTest::GetInstance()->current_test_info(); 784 if (test_info != NULL) { 785 // FIXME: record the test case name when the 786 // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or 787 // TearDownTestCase(). 788 state.first_used_test_case = test_info->test_case_name(); 789 state.first_used_test = test_info->name(); 790 } 791 } 792 } 793 794 // Unregisters a mock method; removes the owning mock object from the 795 // registry when the last mock method associated with it has been 796 // unregistered. This is called only in the destructor of 797 // FunctionMockerBase. 798 void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) 799 GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { 800 internal::g_gmock_mutex.AssertHeld(); 801 for (MockObjectRegistry::StateMap::iterator it = 802 g_mock_object_registry.states().begin(); 803 it != g_mock_object_registry.states().end(); ++it) { 804 FunctionMockers& mockers = it->second.function_mockers; 805 if (mockers.erase(mocker) > 0) { 806 // mocker was in mockers and has been just removed. 807 if (mockers.empty()) { 808 g_mock_object_registry.states().erase(it); 809 } 810 return; 811 } 812 } 813 } 814 815 // Clears all ON_CALL()s set on the given mock object. 816 void Mock::ClearDefaultActionsLocked(void* mock_obj) 817 GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { 818 internal::g_gmock_mutex.AssertHeld(); 819 820 if (g_mock_object_registry.states().count(mock_obj) == 0) { 821 // No ON_CALL() was set on the given mock object. 822 return; 823 } 824 825 // Clears the default actions for each mock method in the given mock 826 // object. 827 FunctionMockers& mockers = 828 g_mock_object_registry.states()[mock_obj].function_mockers; 829 for (FunctionMockers::const_iterator it = mockers.begin(); 830 it != mockers.end(); ++it) { 831 (*it)->ClearDefaultActionsLocked(); 832 } 833 834 // We don't clear the content of mockers, as they may still be 835 // needed by VerifyAndClearExpectationsLocked(). 836 } 837 838 Expectation::Expectation() {} 839 840 Expectation::Expectation( 841 const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base) 842 : expectation_base_(an_expectation_base) {} 843 844 Expectation::~Expectation() {} 845 846 // Adds an expectation to a sequence. 847 void Sequence::AddExpectation(const Expectation& expectation) const { 848 if (*last_expectation_ != expectation) { 849 if (last_expectation_->expectation_base() != NULL) { 850 expectation.expectation_base()->immediate_prerequisites_ 851 += *last_expectation_; 852 } 853 *last_expectation_ = expectation; 854 } 855 } 856 857 // Creates the implicit sequence if there isn't one. 858 InSequence::InSequence() { 859 if (internal::g_gmock_implicit_sequence.get() == NULL) { 860 internal::g_gmock_implicit_sequence.set(new Sequence); 861 sequence_created_ = true; 862 } else { 863 sequence_created_ = false; 864 } 865 } 866 867 // Deletes the implicit sequence if it was created by the constructor 868 // of this object. 869 InSequence::~InSequence() { 870 if (sequence_created_) { 871 delete internal::g_gmock_implicit_sequence.get(); 872 internal::g_gmock_implicit_sequence.set(NULL); 873 } 874 } 875 876 } // namespace testing 877 878 #ifdef _MSC_VER 879 #if _MSC_VER <= 1900 880 # pragma warning(pop) 881 #endif 882 #endif