text:
Home Sport 'A betrayal': Malmo fury as Ibrahimovic invests in Hammarby
'A betrayal': Malmo fury as Ibrahimovic invests in Hammarby
A statue of Zlatan Ibrahimovic was vandalized and apparently set on fire outside the stadium of his boyhood club, Malmo, as fans reacted with fury at the Swedish soccer star buying a stake in one of its biggest rivals on Wednesday.
Ibrahimovic outlined his desire to make Hammarby the "best in Scandinavia" after acquiring nearly 25% of the Stockholm-based club in his first move into soccer ownership.
"There are no limits to how big Hammarby can be," Ibrahimovic told Swedish tabloid Aftonbladet in its Wednesday edition after the deal was announced.
His decision to invest in Hammarby went down badly in Malmo — where Ibrahimovic grew up and started his illustrious and globetrotting career — just a month after a golden statue of the 38-year-old striker was unveiled at his former club's stadium.
A toilet seat was placed around one of Ibrahimovic's arms on the statue early Wednesday, a plastic bag put over his face, and his name was covered up, leading to the monument requiring police protection during the afternoon.
Social media videos appeared to show fans lighting fires at the base of the statue in the evening, while a racist message had reportedly been spray-painted next to it.
Malmo fans are angry not just that he wants to make another club better than his boyhood team, but that he also said he didn't think Malmo supporters would be disappointed at his choice.
"A betrayal became a betrayal and a provocation," Kaveh Hosseinpour, vice-chairman of Malmo's official supporters' group, told The Associated Press. "So he basically stuck a knife in our backs, and then he came along with a sword and chopped off our heads."
Hosseinpour blasted Ibrahimovic for thinking he was "above criticism, that he is above Malmo FF and our feelings just because he is Zlatan."
"The statue is completely worthless now, just a piece of junk," Hosseinpour said. "The best way to solve that was if it was removed and put somewhere in Stockholm or something.
"Every game we go to, we are going to pass Zlatan knowing that there is a statue of an investor in Hammarby, not the statue of the football player Zlatan Ibrahimovic anymore."
Ibrahimovic has acquired half of the 47% stake in Hammarby owned by Anschutz Entertainment Group, the U.S.-based company whose portfolio of sports teams it owns or has investments in includes the Los Angeles Galaxy — the Major League Soccer team where Ibrahimovic played for the past 18 months.
By buying 50% of AEG Sweden, Ibrahimovic owns nearly a quarter of Hammarby.
Hammarby finished third in Sweden's top league this season — behind champion Djurgarden and Malmo — and will play in the Europa League next year.
"Spontaneously, the timing feels good," Hammarby chairman Richard von Yxkull said. "We have had a strong development in recent years and next year we play in Europe.
"To then get a person like Zlatan Ibrahimovic into the club, with the passion and winning mentality he stands for, feels right."
Ibrahimovic, who retired from international duty in 2016 and is regarded as one of Sweden's greatest ever players, had in recent days posted a photo of Hammarby's green-and-white jersey on his social media accounts, sparking speculation in his native country that he may join the club as a player having recently left LA Galaxy.
However, he says he will not play in Sweden again — he started his career at Malmo, where he was born, in 1999 — and is still weighing up where to play next. Ibrahimovic, whose ponytail and moustache makes him one of the most recognizable players in the world, has also played for Ajax, Barcelona, AC Milan, Inter Milan, Paris Saint-Germain and Manchester United in a trophy-laden career.
At the Galaxy, he scored 56 goals in 52 games in MLS — and he is still not done yet.
Except maybe in Malmo.
"What I have done for Malmo will be there forever," Ibrahimovic said, when asked if he was concerned about the reaction of Malmo fans. "This is a completely different situation. It has nothing to do with where my career began."
For Hosseinpour, that is an "absurd, completely mad" point of view.
"Of course we would be offended and angry," he said. "I don't know which dimension he lives in where we wouldn't be hurt by this."
Associated Press writer Jan M. Olsen in Copenhagen, Denmark, contributed to this story
More AP soccer https://apnews.com/Soccer and https://twitter.com/AP—Sports
Steve Douglas is at www.twitter.com/sdouglas80
invests
Previous articlePro-life groups clash with Georgia's Kemp over potential Senate pick
Next articleFired Apprentice star blasts show for editing out 'screaming' Ryan-Mark in explosive row
Boise St. rallies from 19 down, beats Utah State 88-83 in OT
AP-Scorecard
Buggs, Hawaii beat UC Santa Barbara 70-63
Fred VanVleet scores 24 points, Raptors beat Magic 113-97
SoftBank adds to financial burden with $10 billion WeWork deal
Steve Bruce reacts to Newcastle United being jeered off in dire draw with Brighton
Portis rallies Knicks past Bulls 105-98 for first win
N.Y. insurance regulator notifies opioid makers, distributors of enforcement action: sources
Galaxy S10 eclipsed? Galaxy S20 revealed in a leak Samsung won't want you to...
No doubt the Korean firm was hoping to keep that news under wraps until later next month but a new leak may give...
Justinian Jessup scored with 1.9 seconds left in regulation to force overtime as Boise State rallied from 19-points down to beat Utah State 88-83January...
WhatsApp shock – Millions face a huge bill to continuing using popular chat app
Millions of WhatsApp users are facing a very expensive start to 2020. From the beginning of next month, a number of devices will...
Here are the scores from yesterday's sports events: ——— NATIONAL BASKETBALL ASSOCIATION ...
Galaxy Watch update: Is Samsung about to release ANOTHER new wearable?
Samsung is working on the next-generation of its Galaxy Watch wearable series. That's according to Dutch outlet Galaxy Club that has a solid...
APNewsBreak: Union files grievance on behalf of Ellsbury
Trade war rejuvenates 'Silicon Valley' firms in Malaysia
Moss scores 20 points, No. 6 Kansas beats Oklahoma 66-52


1. Marina Bay - Marvel by the Waters For buying a wrist-watch the choice criterion depends on the cost aspect the objective of wearing it, which will be more advised by the price component. A straightforward and small layout ultimately fits a formal event. You can also afford to purchase reduced manufacturer for sporting on special occasions. Don't think that because you're investing less, that you can't-get a good quality view with great layout. Some of the luxury manufacturers that are mid present great models of watches that are at an affordable cost range. You look for designs which are classic and elegant and should consider these watches. Avoid acquiring over embellished watches while they have a tendency to walk out vogue rapidly and you also don't obtain a resale price that is excellent, in the event you ever need to market it. Once you cannot afford to buy a watch from a high-end luxury-brand, subsequently buying a view from the mid level watch brand is the best choice. Persons do not have to scratch on their brains before buying a time piece in the Swiss watches, or do not need any investigation. Such will be the trust that swiss-made the years have been developed over by watch models. Actually, the phenomena went to such an extent that today running a swiss- watch is actually an issue of design and course. Needless to say, being the most effective view brands in the market swiss-watch models have a major value, together with the greatest action technology too I begin by the characteristic that the majority visitors have on their brains - price The watch is cheaper compared to one that is physical . The previous prides itself by featuring prices as inexpensive as 4$ youngsters' watches or even free giveaways to as pricey like a 25,000$ Chopard for ladies. Another win for the quartz is its accuracy. Today, a great technical view can give an accuracy of at most 2-3 seconds per day. Quartz watches in sale begin with a wait of 0.5 seconds each day or greater at a portion of the price that high-precision physical versions are not worthlessness. Watch, the fact that is unhappy is that they be expensive. Nevertheless you do require a view and you also do not want to settle for cheap imitations. Why not obtain a view that's of the quality that is greatest but still will not burn an opening inside your pocket. A watch that is good needs to have impeccable design, outstanding quality and start to become of the newest style. Additional characteristics that tells you the date and morning will also be should have in a wristwatch that is good. If you desire an elegant and sophisticated timewear, you then need to find out which are for less the top watches as possible acquire,. Here we are going to take a peek at several of the finest watches that exist under 0.
Mial problemy z prawem i ze soba. Kim byl 29-latek zastrzelony w komendzie?


CoolerMaster today launches its MasterBox MB500 & TD500L, two cases that have been shown and demoed at CES earlier this year. With a Semi-Mesh Front and the ventilation holes on the top of the MasterBox MB500 offer many possibilities in terms of airflow.
The Semi-Mesh Front and the ventilation holes on the top of the MasterBox MB500 offer many possibilities in terms of airflow. The three pre-assembled RGB LED fans upgrade the system and the unique design gives the case a futuristic flair. A generous interior and the power supply chamber ensure a clean cable management.
A semi-meshed front panel and ventilation holes on top will allow more airflow from the two pre-installed 120mm RGB fans in the front and one 120mm RGB fan in the rear. The excellent thermal performance and aggressive outlook of the MasterBox MB500 make it a perfect choice for Gamers and PC enthusiasts. The spacious interior and two chamber design allows you to assemble the case faster and cleaner. It can support up to a 360mm radiator, 400mm in length for graphic card, 160mm in height for CPU cooler and 180mm in length for PSU.
Show off your unique build through the 4mm thick edge-to-edge tempered glass side panel.Two models are available, have a peek at the thumbnails below.
The Semi-Mesh Front and the ventilation holes on the top of the MasterBox MB500 offer many possibilities in terms of airflow. The three pre-assembled RGB LED fans upgrade the system and the unique design gives the case a futuristic flair. The generous interior and the power supply chamber ensure a clean cable management.
The MasterBox TD500L is characterized by a three-dimensional, diamond-cut design of the front panel and the side panel. This uniquely shaped sidewall, with LEDs, can produce special lighting effects from different angles and also leaves a clear view into your system. The TD500L supports six 120mm fans and the installation of a radiator on the front, top and back. The support of up to 407mm long graphics cards allows you to equip yourself with the latest hardware.
Edge-to-edge acrylic side panel: show what's in your PC. With the unique side window you can enjoy your lighting effects from every angle.
It's been a while we haven't seen a cooling product for laptops. Thanks to Coolermaster, we are glad to see a shroud that cools down our portable computers nice and easy.
Doesn't it look sispiciously alot like the new cases from Fractal?
I mean, look at that front face!


text:
Oxford University Computing Services (OUCS) until 2012 provided the central Information Technology services for the University of Oxford. The service was based at 7-19 Banbury Road in central north Oxford, England, near the junction with Keble Road. OUCS became part of IT Services, when the new department was created at the University of Oxford on 1 August 2012 through a merger of the three previous central IT departments: Oxford University Computing Services (OUCS), Business Services and Projects (BSP) and ICT Support Team (ICTST).

At the time when Oxford University Computing Services ceased to operate as an independent department, it offered facilities, training and advice to members of the university in all aspects of academic computing. OUCS was responsible for the core networks reaching all departments and colleges of Oxford University. OUCS was made up of 5 technical and one administration group. Each group had responsibility for different aspects of OUCS services supplied to the university. At the time of the merger, the 5 technical groups were: Learning Technologies, Information and Support, Network Systems Management Services, Infrastructure Systems and Services Group, and Network and Telecommunications.

History

A lease on a house was obtained in 1957 and operation started in 1958, initially as the Computing Laboratory at 9 South Parks Road, a Victorian building, now demolished to make way for the Experimental Psychology and Zoology departments. In 1963, due to space problems, the staff and computers moved to 19 Parks Road, the old Engineering Building. In 1970, the Computing Service occupied 17 and 19 Banbury Road, having split from the Computing Laboratory, which became the university's Department of Computer Science. By 1975, the Computing Service had taken over all of 7 to 19 Banbury Road, as IT Services still does today. An outpost at 59 George Street in central Oxford closed in the mid 1990s.

See also
 Oxford University Computing Laboratory
 University of Cambridge Computing Service
Oxford University Computing Services was an affiliated member of the Sakai Project
 Oxford University Computing Services was a member of the Opencast Community
 Oxford University Computing Services hosted several national and international services including OSS Watch  and the Oxford Text Archive

References

External links
 Oxford University Computing Services website
 OUCS user pages

Organizations established in 1957
Computing Services
Information technology organisations based in the United Kingdom

redpajama_set_name: RedPajamaWikipedia


text:
Underwater - Submarine Volcanoes
Currently there are over five thousand active volcanoes underwater varying from ones larger than any on the surface to cones no larger than an automobile. The net reslut of this action is thermal heating of the oceans, at key positions, which in turn reaches the surfaceto be carried aloft into the atmosphere to become part of our surface weather pattern system. As the oceans are heated winds of a high velocity are created and driven over the land areas due to temperature differential.
In the Pacific Ocean there are ocean basins - volcanoes, of which there are estimated to be about 20,000 on the ocean bottoms of the world. Some of these form single mountains, and others join with other volcanoes to form ridges. The highest ones rise above the surface of the water as islands, which in many cases linear groups such as the Hawaiian Islands.
Island groups are simply the highest summits of ridges. The submerged part of the Hawaiian Islands is among the largest and longest of these volcanic ridges--more than 1,500 miles (2,400 kilometers) long.
Many island groups of the Pacific are linear in form, with the largest and highest island of the group at one end and the lowest and smallest at the other. This feature is true of the Hawaiian Islands, explained as the result of intermittent movement of the tectonic plate over what is called a hot spot.
Molten volcanic material is ejected from it and results in the formation of a large mass of material if the plate pauses for a sufficient length of time at the spot. In this way a volcanic island, or ridge, is built. The plate moves, and another part of it lies over the hot spot, receiving fresh volcanic material. Meanwhile the older material, if it has become an island, is subject to erosion and thus is worn down.
Submarine Volcanoes
Mount Marsili
Europe's largest underwater volcano is active according to the scientists who have been monitoring it for years, but until recently believed it to be dormant. There has never been an eruption of the volcano in recorded history. The Tyrrhenian Project, the national research group studying the volcano, reported its findings last November 27, 1999.
Mt. Marsili, which rises 9,800 feet (3,000 meters) from the seabed in the Tyrrhenian Sea southwest of Naples, is capable of producing huge tidal waves along southern Italy if its activity ever does build to an eruption. According to the researchers, "Il Marsili'" is about 40 miles (65 km) long and 25 miles (40 km) wide. The experts said its tip was only 1,640 feet (500 metres) below the surface of the water.
Michael Marani, the scientist heading up the study of the volcano, said, "Because the Tyrrhenian Sea is the youngest sea in the Mediterranean, it is still unstable and carries elevated risks that must be monitored and understood." He reported that evidence of enormous masses which had probably broken away from the main crater a long time ago were found on the volcanic edge.
Underwater Volcano Erupts on Video National Geographic - May 25, 2006
A volcano is seen erupting 1,800 feet beneath the surface of the Pacific Ocean near Guam.
Unraveling the Mysteries of Underwater Volcanoes NOAA - August 21, 2001
New underwater volcano found in Aleutians
Alaska - August 12, 2001 - MSNBC
The North Pacific's Ring of Fire can claim a new member - a previously unknown underwater volcano in Alaska's Aleutian Islands that researchers in Alaska revealed Monday. Scientists this summer mapped the cone-shaped volcano, which rises beneath the waters near Amchitka Pass, a gap in the chain of largely uninhabited islands that separate the Pacific Ocean from the Bering Sea.
The volcano rises 1,903 feet above the sea floor and tops out less than 377 feet from the water's surface, said researchers with the University of Alaska Fairbanks and the National Marine Fisheries Service. The volcano is considered active but dormant, although it could erupt at any time, officials warned.
If it did erupt, it could produce a new island in the Aleutian chain, which arcs from southwestern Alaska to Siberia. An eruption could also bring some dangers to local mariners, either from lava or ash breaking the sea surface or from gaseous waters creating conditions that cause vessels to sink.
The Alaska Volcano Observatory, operated jointly by federal and state agencies, plans to place a seismic monitor on nearby Semisopochnoi Island by 2005, Reynolds said. The volcano is similar to a few others that have been found in places like the waters off Iceland. The discovery of the volcano, which remains unnamed, was a byproduct of a coral reef survey conducted in the Bering Sea and North Pacific.
South Pacific - Vailulu'u - Submarine Volcano
May 20, 2000 - Reuters
Marine geologists have reported that a newly discovered undersea volcano east of Samoa is erupting, sending out a five-mile cloud of "smoggy" water from its summit.
Local students recently named the volcano, located 28 miles east of Taiu Island, 'Vailulu'u'. The volcano rises up more than 16,400 feet from the seabed to within 2,000 feet of the ocean's surface.
Scientists from Scripps Institution of Oceanography and the Woods Hole Oceanographic Institution first mapped the volcano during a research cruise in 1999. They returned this spring to find the volcano erupting. Anthony Koppers, a scientist at Scripps who studies undersea volcanoes, said the find was exciting because so few of the world's undersea volcanoes are accessible to study. He said, "We have access to the buildup of a volcano that will eventually become an island."
The group left underwater microphones positioned near Vailulu'u and on the crater floor to record the rumblings that would indicate the movement of magma within.
Students in American Samoa held a contest to name the new volcano. Vailulu'u is the name for the sacred rain that always fell as a blessing before a gathering of the famed King Tuimanuia. ollapse would result in massive earthquakes in the region.
VOLCANO INDEX
ALPHABETICAL INDEX OF ALL FILES
CRYSTALINKS MAIN PAGE
Search crystalinks.com Search web

redpajama_set_name: RedPajamaCommonCrawl


text:
Christianizing the Social Network
Tim Challies looks at emerging technology through a theological lens.
Interview by Matthew Lee Anderson| May 17, 2011
The Next Story: Life and Faith after the Digital Explosion
by Tim Challies
Zondervan, April 2011
208 pp., $12.99
Blogger Tim Challies understands both technology's potential and its potential seduction. He uses emerging tools to keep his 15,000 visitors updated daily at Challies.com. His new book, The Next Story: Life and Faith after the Digital Explosion (Zondervan), considers our reliance on technology and how it impacts our faith. Matthew Lee Anderson spoke with Challies about how Christians might think theologically about technology.
You write that we are "molded and formed into the image of what shapes us." What risks do technologies like Facebook and YouTube pose to the Christian life?
When technologies give us an ability, they also give us a desire. Before Twitter or Facebook, none of us cared about moment-by-moment updates from friends. But with the new tools, we've grown to desire—and sometimes even demand—that sort of information. YouTube heightens and preys upon our desire to see and be seen. It makes us exhibitionists, telling us that any part of the human experience can be someone's entertainment.
You point out that the "new Calvinists" gained influence by adopting technology. How do you see those tools shaping the movement?
You can't really understand new Calvinism apart from the Internet. It allowed us to hear from these people in an unprecedented way.
We seem to have short attention spans, and much of what we're learning and hearing comes through social media. Far more people are getting John Piper in 140-character chunks than are listening to his 45-minute sermons, which means we're not learning in more holistic ways.
Is a specifically Reformed understanding of technology possible?
If it is, I don't know that I want to major in it. But certainly, I am Reformed in my understanding of God's sovereignty over all creation and my heightened sense of human depravity. A Reformed understanding would take into account God's sovereignty even over technology as the starting point and ending point. God saw fit to allow us technology, and God cares how we use it. Our job is to ensure that we're using technology in a way that's subject to his authority.
Does the emphasis on depravity lead to a stronger sense of caution or skepticism toward new technologies?
I think Reformed theology causes us to expend more effort understanding our sinfulness. That might give us a different starting point when we look at technology. We might have more reasons to doubt ourselves, but we also need a heightened sense of God's sovereignty.
You seem ambivalent about the "rise of the images," which some Christians have praised for creating a more holistic, less rationalistic faith than the print culture brought about. How should Christians relate to images?
The Christian faith is carried by words. Jesus Christ is not the picture—he's the Word. And we have to acknowledge that God saw fit to record Scripture for us in words. We don't have to fear images, but we should be wary of them.
The promise of the Internet was universality. You emphasize the role geography plays in the formation of our communities. What role should distance and proximity play in choosing a church?
The problem actually goes back to the automobile, which gave people the opportunity to attend commuter churches rather than community churches. The ability to attend church a long ways away forced people to rethink church.
But in a world shaped by the Internet, people find their hearts drawn to churches a thousand miles away rather than a short drive away. As a result, they relate to people through chats and forums rather than face to face. It leads to a very mediated form of church community.
You defend the role of authority in culture against the "radical egalitarianism" that the Internet promises. Do you think this egalitarian ethos undermines biblical authority?
The Internet has certainly flattened authority. We don't care about book reviews from experts anymore as much as we care about the quality of reviews. If we see authority flattened online and everywhere else, we expect to see authority flattened in the home and the church. The ideology of digital technology is this disruption of hierarchy, so we import that into other areas.
It seems clear from Scripture that authority is built into human experience, that God intends for there to be hierarchy. We should celebrate authority and use caution toward anything that might disrupt it. At the same time, there is not necessarily anything wrong with particular authority structures being dismantled. The idea that we make decisions based on more amateur book reviews isn't necessarily wrong, but it is noteworthy.
In the final section, you mention using tools to help you focus more. What's the problem with that?
We tend to think that when technology causes a problem, the best way to solve it is with more technology. It's fine to get rid of technology or become less dependent on technology. But we shouldn't assume that there is another technology that can bring peace where we're finding conflict.
Previous articles on technology and faith from Christianity Today and sister publications include:
Church ... Virtually | Why internet campuses are making us reconsider our assumptions about ministry. (Leadership Journal January 4, 2010)
From the Printing Press to the iPhone | Shane Hipps urges Christians to discern the technology spirits. (May 6, 2009)
People of the Nook | What Bible smartphone apps tell us about the Book. (May 16, 2011)
Have something to add about this? See something we missed? Share your feedback here.
Doctrine | Facebook | Internet | Social Networking | Technology | Virtues and Vices
May 2011, Vol. 55, No. 5, Pg 76
More From: Interview by Matthew Lee Anderson
This article is from the May 2011 issue.
Jan/Feb
Jul/Aug
More from this Issue
In Christian Publishing, 'Platform' Is Being Weighed and Found Wanting
Favoring big-name authors and "influencers" might be good for the bottom line, but not always for the books—and readers—themselves.
Collin Huber
Put Not Your Trust in ChatGPT, for Now
Q&A with a veteran AI engineer and entrepreneur, Tom Kehler, about the limits of the popular chatbot and the wonders of the human brain.
Interview by Emily Belz


When you think of a glass block exterior wall, think of all of the benefits of a glass block window, but on a larger scale. Natural light will fill your rooms while maintaining privacy without the need for window treatments.
With the hundreds of different block styles, shapes and colors, you can have a true one-of-a-kind glass block wall in your home.Our design team is happy to help you design your application. Stop in our showroom or call and schedule a consultation.
This kitchen wall uses satin finish Pegasus block to provide a soft glow to the room.
The Wave pattern Giallo and Neutro Pegasus provide natural light and privacy in this dining room.
The natural light provided by this Pegasus Satin wall elminates the need for any other lighting in the room during the day.
This clear block provides immense natural light to this kitchen.


"Not I, nor anyone else can travel that road for you.
Perhaps it is everywhere – on water and land."
Poignant and inspirational, this quote from the beloved author is laser engraved onto our custom insert then placed inside the lid for an awesome presentation. The box itself is quite roomy too! It is approximately 7" x 6" and is constructed from wood with a beautiful cherry finish. Perfect for home or office. Makes a wonderful retirement, birthday, anniversary or nautical gift. We like this for a person that travels a lot as well.
Free name plate engraving too!


text:
require File.join(File.dirname(__FILE__), '../spec_helper')

describe Astute::Provisioner do
  include SpecHelpers

  before(:each) do
    @provisioner = Astute::Provisioner.new
    @provisioner.stubs(:sleep)
    @reporter = mock('reporter')
    @reporter.stub_everything
  end

  describe '#node_type' do
    it "must be able to return node type" do
      nodes = [{'uid' => '1'}]
      res = {:data => {:node_type => 'target'},
             :sender=>"1"}

      mc_res = mock_mc_result(res)
      mc_timeout = 5

      rpcclient = mock_rpcclient(nodes, mc_timeout)
      rpcclient.expects(:get_type).once.returns([mc_res])

      types = @provisioner.node_type(@reporter, 'task_uuid', nodes.map { |n| n['uid'] }, mc_timeout)
      types.should eql([{"node_type"=>"target", "uid"=>"1"}])
    end
  end

  describe '#remove_nodes' do

    let(:nodes) { [{'uid' => '1', 'slave_name' => ''}] }
    let(:engine_attrs) do
      {
        "url"=>"http://localhost/cobbler_api",
        "username"=>"cobbler",
        "password"=>"cobbler",
        "master_ip"=>"127.0.0.1",
      }
    end

    before(:each) do
      remote = mock() do
        stubs(:call)
        stubs(:call).with('login', 'cobbler', 'cobbler').returns('remotetoken')
      end
      XMLRPC::Client = mock() do
        stubs(:new).returns(remote)
      end
      Astute::CobblerManager.any_instance.stubs(:remove_nodes)
    end

    it 'should use NodeRemover to remove nodes' do
      Astute::NodesRemover.any_instance.expects(:remove).once.returns({})
      Astute::Rsyslogd.expects(:send_sighup).once
      @provisioner.remove_nodes(
        @reporter,
        task_id="task_id",
        engine_attrs,
        nodes,
        {:reboot => true}
      )
    end

    it 'should return list of nodes which removed' do
      Astute::NodesRemover.any_instance.expects(:remove).once.returns({"nodes"=>[{"uid"=>"1"}]})
      Astute::Rsyslogd.stubs(:send_sighup).once
      expect(@provisioner.remove_nodes(
        @reporter,
        task_id="task_id",
        engine_attrs,
        nodes,
        {:reboot => true}
      )).to eql({"nodes"=>[{"uid"=>"1"}]})
    end

    context 'if exception in case of error enable' do
      it 'should raise error if nodes removing operation via mcollective failed(error)' do
        Astute::NodesRemover.any_instance.expects(:remove).once.returns({
          'status' => 'error',
          'error_nodes' => [{"uid"=>"1"}]
        })
        Astute::Rsyslogd.stubs(:send_sighup).never
        expect {@provisioner.remove_nodes(
          @reporter,
          task_id="task_id",
          engine_attrs,
          nodes,
          {
            :reboot => true,
            :raise_if_error => true
          }
        )}.to raise_error(/Mcollective problem with nodes/)
      end

      it 'should raise error if nodes removing operation via mcollective failed(inaccessible)' do
        Astute::NodesRemover.any_instance.expects(:remove).once.returns({
          'inaccessible_nodes' => [{"uid"=>"1"}]
        })
        Astute::Rsyslogd.stubs(:send_sighup).never
        expect {@provisioner.remove_nodes(
          @reporter,
          task_id="task_id",
          engine_attrs,
          nodes,
          {
            :reboot => true,
            :raise_if_error => true
          }
        )}.to raise_error(/Mcollective problem with nodes/)
      end
    end  #exception
  end #remove_nodes

  let(:data) do
    {
      "engine"=>{
        "url"=>"http://localhost/cobbler_api",
        "username"=>"cobbler",
        "password"=>"cobbler",
        "master_ip"=>"127.0.0.1",
      },
      "task_uuid"=>"a5c44b9a-285a-4a0c-ae65-2ed6b3d250f4",
      "nodes" => [
        {
          'uid' => '1',
          'profile' => 'centos-x86_64',
          "slave_name"=>"controller-1",
          "admin_ip" =>'1.2.3.5',
          'power_type' => 'ssh',
          'power_user' => 'root',
          'power_pass' => '/root/.ssh/bootstrap.rsa',
          'power-address' => '1.2.3.5',
          'hostname' => 'name.domain.tld',
          'name_servers' => '1.2.3.4 1.2.3.100',
          'name_servers_search' => 'some.domain.tld domain.tld',
          'netboot_enabled' => '1',
          'ks_meta' => {
            'gw' => '10.20.0.2',
            'mco_enable' => 1,
            'mco_vhost' => 'mcollective'
          },
          'interfaces' => {
            'eth0' => {
              'mac_address' => '00:00:00:00:00:00',
              'static' => '1',
              'netmask' => '255.255.255.0',
              'ip_address' => '1.2.3.5',
              'dns_name' => 'node.mirantis.net',
            },
            'eth1' => {
              'mac_address' => '00:00:00:00:00:01',
              'static' => '0',
              'netmask' => '255.255.255.0',
              'ip_address' => '1.2.3.6',
            }
          },
          'interfaces_extra' => {
            'eth0' => {
              'peerdns' => 'no',
              'onboot' => 'yes',
            },
            'eth1' => {
              'peerdns' => 'no',
              'onboot' => 'yes',
            }
          }
        }
      ]
    }
  end

  describe '#provision' do

    context 'cobler cases' do
      it "raise error if cobler settings empty" do
        @provisioner.stubs(:provision_and_watch_progress).returns([[],[]])
        data['engine'] = {}
        Astute::Rsyslogd.stubs(:send_sighup).once
        expect {@provisioner.provision(@reporter, data['task_uuid'], data, 'image')}.
                              to raise_error(/Settings for Cobbler must be set/)
      end

      it "raise error and send sighup for Rsyslogd" do
        @provisioner.stubs(:provision_and_watch_progress).returns([[],[]])
        data['engine'] = {}
        Astute::Rsyslogd.expects(:send_sighup).once
        expect {@provisioner.provision(@reporter, data['task_uuid'], data, 'image')}.
                              to raise_error(/Settings for Cobbler must be set/)
      end
    end

    context 'node state cases' do
      before(:each) do
        remote = mock() do
          stubs(:call)
          stubs(:call).with('login', 'cobbler', 'cobbler').returns('remotetoken')
        end
        XMLRPC::Client = mock() do
          stubs(:new).returns(remote)
        end
        Astute::CobblerManager.any_instance.stubs(:sleep)
      end

      before(:each) do
        @provisioner.stubs(:remove_nodes).returns([])
        @provisioner.stubs(:provision_and_watch_progress).returns([])
        @provisioner.stubs(:control_reboot_using_ssh).returns(nil)
      end

      it "raises error if nodes list is empty" do
        Astute::Rsyslogd.stubs(:send_sighup).once
        data['nodes'] = []
        expect {@provisioner.provision(@reporter, data['task_uuid'], data, 'image')}.
                              to raise_error(/Nodes to provision are not provided!/)
      end

      it "raises error if nodes list is empty and send sighup for Rsyslogd" do
        Astute::Rsyslogd.expects(:send_sighup).once
        data['nodes'] = []
        expect {@provisioner.provision(@reporter, data['task_uuid'], data, 'image')}.
                              to raise_error(/Nodes to provision are not provided!/)
      end

      it "try to reboot nodes from list" do
        Astute::Provision::Cobbler.any_instance do
          expects(:power_reboot).with('controller-1')
        end
        Astute::CobblerManager.any_instance.stubs(:check_reboot_nodes).returns([])
        Astute::CobblerManager.any_instance.stubs(:netboot_nodes)
        Astute::CobblerManager.any_instance.stubs(:edit_nodes)
        @provisioner.stubs(:change_nodes_type)
        @provisioner.stubs(:image_provision).returns([])

        @provisioner.provision_piece(@reporter, data['task_uuid'], data['engine'], data['nodes'], 'image')
      end

      it "does not reboot nodes which failed during provisioning" do
        Astute::Provision::Cobbler.any_instance do
          expects(:power_reboot).never
        end
        Astute::CobblerManager.any_instance.stubs(:check_reboot_nodes).returns([])
        Astute::CobblerManager.any_instance.stubs(:netboot_nodes)
        Astute::CobblerManager.any_instance.stubs(:edit_nodes)
        @provisioner.stubs(:change_nodes_type)
        @provisioner.stubs(:image_provision).returns(['1'])

        expect(@provisioner.provision_piece(@reporter, data['task_uuid'], data['engine'], data['nodes'], 'image')).to eql(['1'])
      end

      it "changes profile into bootstrap for all nodes in case of IBP" do
        Astute::CobblerManager.any_instance do
          expects(:edit_nodes).with(
            data['nodes'],
            {'profile' => Astute.config.bootstrap_profile}
          )
        end
        Astute::CobblerManager.any_instance.stubs(:check_reboot_nodes).returns([])
        Astute::CobblerManager.any_instance.stubs(:netboot_nodes)
        Astute::CobblerManager.any_instance.stubs(:edit_nodes)
        @provisioner.stubs(:change_nodes_type)
        @provisioner.stubs(:image_provision).returns([])

        @provisioner.provision_piece(@reporter, data['task_uuid'], data['engine'], data['nodes'], 'image')
      end

      it "does not change netboot setting for failed nodes in case of IBP" do
        Astute::CobblerManager.any_instance do
          expects(:netboot_nodes).with([], false)
        end
        Astute::CobblerManager.any_instance.stubs(:check_reboot_nodes).returns([])
        Astute::CobblerManager.any_instance.stubs(:edit_nodes)
        Astute::CobblerManager.any_instance.stubs(:netboot_nodes)
        @provisioner.stubs(:change_nodes_type)
        @provisioner.stubs(:image_provision).returns([1])

        @provisioner.provision_piece(@reporter, data['task_uuid'], data['engine'], data['nodes'], 'image')

      end

      before(:each) { Astute::Provision::Cobbler.any_instance.stubs(:power_reboot).returns(333) }

      context 'node reboot success' do

        it "does not find failed nodes" do
          Astute::Provision::Cobbler.any_instance.stubs(:event_status)
            .returns([Time.now.to_f, 'controller-1', 'complete'])
          Astute::CobblerManager.any_instance.stubs(:netboot_nodes)
          @provisioner.stubs(:change_nodes_type)
          @provisioner.stubs(:image_provision).returns([])

          @provisioner.provision_piece(@reporter, data['task_uuid'], data['engine'], data['nodes'], 'image')
        end

        it "should erase mbr for nodes" do
          Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
          Astute::CobblerManager.any_instance.stubs(:remove_nodes).returns([])
          @provisioner.stubs(:provision_and_watch_progress).returns([[], []])

          Astute::CobblerManager.any_instance.stubs(:get_existent_nodes).returns([])
          Astute::CobblerManager.any_instance.stubs(:get_mac_duplicate_names).returns([])
          @provisioner.stubs(:change_node_type).never
          Astute::NailgunHooks.any_instance.stubs(:process).never

          @provisioner.expects(:remove_nodes).with(
            @reporter,
            data['task_uuid'],
            data['engine'],
            data['nodes'],
            {
              :reboot => false,
              :raise_if_error => true,
              :reset => true
            }
          ).returns([])

          @provisioner.provision(@reporter, data['task_uuid'], data, 'image')
        end

        it 'should not try to unlock node discovery' do
          @provisioner.stubs(:prepare_nodes)
          @provisioner.stubs(:provision_and_watch_progress).returns([[], []])
          @provisioner.expects(:unlock_nodes_discovery).never
          @provisioner.provision(@reporter, data['task_uuid'], data, 'image')
        end

        it 'should try to reboot nodes using ssh(insurance for cobbler)' do
          Astute::Provision::Cobbler.any_instance.stubs(:event_status)
            .returns([Time.now.to_f, 'controller-1', 'complete'])
          @provisioner.expects(:control_reboot_using_ssh)
            .with(@reporter, data['task_uuid'], data['nodes']).once
          @provisioner.provision_piece(
            @reporter,
            data['task_uuid'],
            data['engine'],
            data['nodes'],
            'native'
          )
        end
      end

      context 'node reboot fail' do
        before(:each) do
          Astute::Provision::Cobbler.any_instance
                                    .stubs(:event_status)
                                    .returns([Time.now.to_f, 'controller-1', 'failed'])
          @provisioner.stubs(:unlock_nodes_discovery)
        end

        it 'should not try to reboot nodes using ssh(insurance for cobbler)' do
          @provisioner.expects(:control_reboot_using_ssh).never
          begin
            @provisioner.provision_piece(@reporter, data['task_uuid'], data['engine'], data['nodes'])
          rescue
          end
        end
      end

      it 'success report if all nodes were provisioned' do
        Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
        @provisioner.stubs(:prepare_nodes)
        @provisioner.stubs(:provision_and_watch_progress).returns([[], []])
        success_msg = {
          'status' => 'ready',
          'progress' => 100,
          'nodes' => [{
            'uid' => '1',
            'status' => 'provisioned',
            'progress' => 100}]}

        @reporter.expects(:report).with(success_msg).once
        @provisioner.provision(@reporter, data['task_uuid'], data, 'image')
      end

      it "fail if timeout of provisioning is exceeded" do
        @provisioner.stubs(:prepare_nodes)
        @provisioner.stubs(:provision_and_watch_progress).returns([[],['1']])

        msg = 'Too many nodes failed to provision'

        error_msg = {
          'nodes' => [{
            'uid' => '1',
            'status' => 'error',
            'error_msg' => 'Timeout of provisioning is exceeded',
            'progress' => 100,
            'error_type' => 'provision'}],
          'status' => 'error',
          'error' => msg,
          'progress' => 100}

        provision_info = data.clone
        provision_info["fault_tolerance"] = [{'uids'=>['1'], 'percentage' => 0}]

        @reporter.expects(:report).with(error_msg).once
        @provisioner.provision(@reporter, data['task_uuid'], provision_info, 'image')
      end

      it 'success report if all nodes report about success at least once' do
        @provisioner.stubs(:prepare_nodes)
        @provisioner.stubs(:provision_and_watch_progress).returns([[],[]])

        success_msg = {
          'nodes' => [{
              'uid' => '1',
              'progress' => 100,
              'status' => 'provisioned'}],
          'status' => 'ready',
          'progress' => 100
        }
        @reporter.expects(:report).with(success_msg).once
        @provisioner.provision(@reporter, data['task_uuid'], data, 'image')
      end
    end

    context 're-provisioned nodes' do

      it 'should reboot and bootstrap re-provisioned nodes' do
        Astute::CobblerManager.any_instance.expects(:get_existent_nodes)
          .with(data['nodes'])
          .returns(data['nodes'])
        Astute::CobblerManager.any_instance.expects(:get_mac_duplicate_names)
          .with(data['nodes'])
          .returns([])
        Astute::CobblerManager.any_instance.expects(:add_nodes)
          .with(data['nodes'])
        Astute::CobblerManager.any_instance.expects(:remove_nodes)
          .with(data['nodes'])
        @provisioner.stubs(:remove_nodes)

        Astute::NailgunHooks.any_instance.expects(:process)
        @provisioner.expects(:change_nodes_type).with(
          @reporter,
          data['task_uuid'],
          data['nodes'],
          'reprovisioned'
        )
        @provisioner.stubs(:provision_and_watch_progress).returns([[], []])

        @provisioner.provision(@reporter, data['task_uuid'], data, 'image')
      end

      it 'should not reboot and boostrap new nodes' do
        @provisioner.stubs(:remove_nodes)
        @provisioner.stubs(:provision_and_watch_progress).returns([[], []])

        Astute::CobblerManager.any_instance.expects(:get_existent_nodes)
          .with(data['nodes'])
          .returns([])
        Astute::CobblerManager.any_instance.expects(:get_mac_duplicate_names)
          .with(data['nodes'])
          .returns([])
        Astute::CobblerManager.any_instance.expects(:remove_nodes)
          .with(data['nodes'])
        Astute::CobblerManager.any_instance.expects(:add_nodes)
          .with(data['nodes'])

        @provisioner.expects(:change_nodes_type).never
        Astute::NailgunHooks.any_instance.expects(:process).never

        @provisioner.provision(@reporter, data['task_uuid'], data, 'image')
      end

    end
  end

  describe '#provision_and_watch_progress' do

    before(:each) do
      # Disable sleeping in test env (doubles the test speed)
      def @provisioner.sleep_not_greater_than(time, &block)
        block.call
      end
    end

    it "raises error if nodes list is empty" do
      expect {@provisioner.provision_and_watch_progress(@reporter, data['task_uuid'], {}, data['engine'], 'image', [])}.
                            to raise_error(/Nodes to provision are not provided!/)
    end

    it "raise error if failed node find" do
      expect do
        @provisioner.stubs(:node_type).returns([])
        @provisioner.stubs(:provision_piece).raises(Astute::AstuteError)
        error_msg = {
          'status' => 'error',
          'error' => '',
          'progress' => 100,
        }
        @provisioner.provision_and_watch_progress(@reporter, data['task_uuid'], data['nodes'], data['engine'], 'image', [])
        @reporter.expects(:report).with(error_msg).once
      end.to raise_error(Astute::AstuteError)
    end

    it "should try to unlock nodes discovery" do
      @provisioner.expects(:unlock_nodes_discovery)
      begin
        @provisioner.stubs(:remove_nodes).returns([])
        @provisioner.stubs(:prepare_nodes).returns([])
        Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
        @provisioner.stubs(:node_type).returns([])
        @provisioner.stubs(:provision_piece).returns([{'uid' => '1'}])
        @provisioner.provision(@reporter, data['task_uuid'], data, 'image')
      rescue
      end
    end

    it "prepare provision log for parsing" do
      Astute::LogParser::ParseProvisionLogs.any_instance do
        expects(:prepare).with(data['nodes']).once
      end
      @provisioner.stubs(:provision_piece).returns([])
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:node_type).returns([{'uid' => '1', 'node_type' => 'target' }])

      @provisioner.provision_and_watch_progress(@reporter, data['task_uuid'], data['nodes'], data['engine'], 'image', [])
    end

    it "ignore problem with parsing provision log" do
      Astute::LogParser::ParseProvisionLogs.any_instance do
        stubs(:prepare).with(data['nodes']).raises
      end

      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:provision_piece).returns([])
      @provisioner.stubs(:node_type).returns([{'uid' => '1', 'node_type' => 'target' }])

      @provisioner.provision_and_watch_progress(@reporter, data['task_uuid'], data['nodes'], data['engine'], 'image', [])
    end

    it 'provision nodes using mclient' do
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:provision_piece).returns([])
      @provisioner.expects(:node_type).returns([{'uid' => '1', 'node_type' => 'target' }])

      @provisioner.provision_and_watch_progress(@reporter, data['task_uuid'], data['nodes'], data['engine'], 'image', [])
    end

    it "unexpecting bootstrap nodes should be ereased and rebooted" do
      Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
      @provisioner.stubs(:prepare_nodes).returns([])
      @provisioner.stubs(:remove_nodes).returns([])
      Astute.config.provisioning_timeout = 5
      nodes = [
        { 'uid' => '1'},
        { 'uid' => '2'}
      ]
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:provision_piece).returns([])
      @provisioner.stubs(:node_type)
        .returns([{'uid' => '1', 'node_type' => 'target' }])
        .then.returns([{'uid' => '2', 'node_type' => 'bootstrap' }])
        .then.returns([{'uid' => '2', 'node_type' => 'bootstrap' }])
        .then.returns([{'uid' => '2', 'node_type' => 'target' }])

      Astute::NodesRemover.any_instance.expects(:remove)
                          .twice.returns({"nodes"=>[{"uid"=>"2", }]})

      success_msg = {
        'status' => 'ready',
        'progress' => 100,
        'nodes' => [{
            'uid' => '1',
            'status' => 'provisioned',
            'progress' => 100},
          {
            'uid' => '2',
            'status' => 'provisioned',
            'progress' => 100}
        ]}

      provision_info = {'nodes' => nodes,
                        'engine' => data['engine'],
                        'fault_tolerance' => []}

      @reporter.expects(:report).with(success_msg).once
      @provisioner.provision(@reporter, data['task_uuid'], provision_info,  'image')
    end

    it 'should provision nodes in chunks' do
      Astute.config.provisioning_timeout = 5
      Astute.config.max_nodes_to_provision = 2
      nodes = [
        { 'uid' => '1'},
        { 'uid' => '2'},
        { 'uid' => '3'}
      ]
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:node_type)
        .returns([{'uid' => '1', 'node_type' => 'target' }, {'uid' => '2', 'node_type' => 'target' }])
        .then.returns([{'uid' => '3', 'node_type' => 'target' }])

      @provisioner.expects(:provision_piece).returns([]).twice
      @provisioner.provision_and_watch_progress(@reporter, data['task_uuid'], nodes, data['engine'], 'image', [])
    end

    it 'should success if only one node fails' do
      Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
      @provisioner.stubs(:remove_nodes).returns([])
      @provisioner.stubs(:prepare_nodes).returns([])
      @provisioner.stubs(:unlock_nodes_discovery)
      Astute.config.provisioning_timeout = 5
      Astute.config.max_nodes_to_provision = 2
      nodes = [
        { 'uid' => '1'},
        { 'uid' => '2'},
        { 'uid' => '3'}
      ]
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:node_type)
        .returns([{'uid' => '1', 'node_type' => 'target' }, {'uid' => '2', 'node_type' => 'target' }])
        .then.returns([])

      success_msg = {
        'status' => 'ready',
        'progress' => 100,
        'nodes' => [
          {
            'uid' => '3',
            'status' => 'error',
            "error_msg"=>"Failed to provision",
            'progress' => 100,
            "error_type"=>"provision"},
          {
            'uid' => '1',
            'status' => 'provisioned',
            'progress' => 100},
          {
            'uid' => '2',
            'status' => 'provisioned',
            'progress' => 100}
        ]}

      @provisioner.stubs(:provision_piece).returns([]).then.returns(['3'])
      provision_info = {'nodes' => nodes,
                        'engine' => data['engine'],
                        'fault_tolerance' => [{'uids'=> ['2', '3'], 'percentage' => 50}]}

      @reporter.expects(:report).with(success_msg).once
      @provisioner.provision(@reporter, data['task_uuid'], provision_info,  'image')
    end

    it 'should fail if node without fault tolerance rule fails' do
      Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
      @provisioner.stubs(:remove_nodes).returns([])
      @provisioner.stubs(:prepare_nodes).returns([])
      @provisioner.stubs(:unlock_nodes_discovery)
      Astute.config.provisioning_timeout = 5
      Astute.config.max_nodes_to_provision = 2
      nodes = [
        { 'uid' => '1'},
        { 'uid' => '2'},
        { 'uid' => '3'}
      ]
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:node_type)
        .returns([{'uid' => '1', 'node_type' => 'target' }, {'uid' => '2', 'node_type' => 'target' }])
        .then.returns([])

      success_msg = {
        'status' => 'error',
        "error"=>"Too many nodes failed to provision",
        'progress' => 100,
        'nodes' => [
          {
            'uid' => '3',
            'status' => 'error',
            "error_msg"=>"Failed to provision",
            'progress' => 100,
            "error_type"=>"provision"},
          {
            'uid' => '1',
            'status' => 'provisioned',
            'progress' => 100},
          {
            'uid' => '2',
            'status' => 'provisioned',
            'progress' => 100}
        ]}

      @provisioner.stubs(:provision_piece).returns([]).then.returns(['3'])
      provision_info = {'nodes' => nodes,
                        'engine' => data['engine'],
                        'fault_tolerance' => [{'uids'=> ['1', '2'], 'percentage' => 50}]}

      @reporter.expects(:report).with(success_msg).once
      @provisioner.provision(@reporter, data['task_uuid'], provision_info,  'image')
    end

    it 'should fail if node has two roles and fails for one' do
      Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
      @provisioner.stubs(:remove_nodes).returns([])
      @provisioner.stubs(:prepare_nodes).returns([])
      @provisioner.stubs(:unlock_nodes_discovery)
      Astute.config.provisioning_timeout = 5
      Astute.config.max_nodes_to_provision = 2
      nodes = [
        { 'uid' => '1'},
        { 'uid' => '2'},
        { 'uid' => '3'}
      ]
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:node_type)
        .returns([{'uid' => '1', 'node_type' => 'target' }, {'uid' => '2', 'node_type' => 'target' }])
        .then.returns([])

      success_msg = {
        'status' => 'error',
        "error"=>"Too many nodes failed to provision",
        'progress' => 100,
        'nodes' => [
          {
            'uid' => '3',
            'status' => 'error',
            "error_msg"=>"Failed to provision",
            'progress' => 100,
            "error_type"=>"provision"},
          {
            'uid' => '1',
            'status' => 'provisioned',
            'progress' => 100},
          {
            'uid' => '2',
            'status' => 'provisioned',
            'progress' => 100}
        ]}

      @provisioner.stubs(:provision_piece).returns([]).then.returns(['3'])
      provision_info = {'nodes' => nodes,
                        'engine' => data['engine'],
                        'fault_tolerance' => [{'uids'=> ['3'], 'percentage' => 100},
                                              {'uids'=> ['3'], 'percentage' => 0}]}

      @reporter.expects(:report).with(success_msg).once
      @provisioner.provision(@reporter, data['task_uuid'], provision_info,  'image')
    end

    it 'should fail if one node fails' do
      Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
      @provisioner.stubs(:remove_nodes).returns([])
      @provisioner.stubs(:prepare_nodes).returns([])
      Astute.config.provisioning_timeout = 1
      Astute.config.max_nodes_to_provision = 2
      nodes = [
        { 'uid' => '1'},
        { 'uid' => '2'},
        { 'uid' => '3'}
      ]
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:unlock_nodes_discovery)
      @provisioner.stubs(:node_type)
        .returns([{'uid' => '1', 'node_type' => 'target' }, {'uid' => '2', 'node_type' => 'target' }])
        .then.returns([])

      success_msg = {
        'status' => 'error',
        "error"=>"Too many nodes failed to provision",
        'progress' => 100,
        'nodes' => [
          {
            'uid' => '3',
            'status' => 'error',
            "error_msg"=>"Failed to provision",
            'progress' => 100,
            "error_type"=>"provision"},
          {
            'uid' => '1',
            'status' => 'provisioned',
            'progress' => 100},
          {
            'uid' => '2',
            'status' => 'provisioned',
            'progress' => 100}
        ]}

      @provisioner.stubs(:provision_piece).returns([]).then.returns(['3'])
      provision_info = {'nodes' => nodes,
                        'engine' => data['engine'],
                        'fault_tolerance' => [{'uids'=> ['2', '3'], 'percentage' => 0}]}

      @reporter.expects(:report).with(success_msg).once
      @provisioner.provision(@reporter, data['task_uuid'], provision_info,  'image')
    end

    it 'fail on any node if no faul_tolerance rules are provided' do
      Astute::CobblerManager.any_instance.stubs(:add_nodes).returns([])
      @provisioner.stubs(:remove_nodes).returns([])
      @provisioner.stubs(:prepare_nodes).returns([])
      Astute.config.provisioning_timeout = 5
      Astute.config.max_nodes_to_provision = 2
      nodes = [
        { 'uid' => '1'},
        { 'uid' => '2'},
        { 'uid' => '3'}
      ]
      @provisioner.stubs(:report_about_progress).returns()
      @provisioner.stubs(:unlock_nodes_discovery)
      @provisioner.stubs(:node_type)
        .returns([{'uid' => '1', 'node_type' => 'target' }, {'uid' => '2', 'node_type' => 'target' }])
        .then.returns([])

      success_msg = {
        'status' => 'error',
        "error"=>"Too many nodes failed to provision",
        'progress' => 100,
        'nodes' => [
          {
            'uid' => '3',
            'status' => 'error',
            "error_msg"=>"Failed to provision",
            'progress' => 100,
            "error_type"=>"provision"},
          {
            'uid' => '1',
            'status' => 'provisioned',
            'progress' => 100},
          {
            'uid' => '2',
            'status' => 'provisioned',
            'progress' => 100}
        ]}

      @provisioner.stubs(:provision_piece).returns([]).then.returns(['3'])
      provision_info = {'nodes' => nodes,
                        'engine' => data['engine'],
                        'fault_tolerance' => []}

      @reporter.expects(:report).with(success_msg).once
      @provisioner.provision(@reporter, data['task_uuid'], provision_info,  'image')

    end
  end

  describe '#stop_provision' do
    around(:each) do |example|
      old_ssh_retries = Astute.config.ssh_retries
      old_mc_retries = Astute.config.mc_retries
      old_nodes_rm_interal = Astute.config.nodes_remove_interval
      example.run
      Astute.config.ssh_retries = old_ssh_retries
      Astute.config.mc_retries = old_mc_retries
      Astute.config.nodes_remove_interval = old_nodes_rm_interal
    end

    before(:each) do
      Astute.config.ssh_retries = 1
      Astute.config.mc_retries = 1
      Astute.config.nodes_remove_interval = 0
    end

    it 'erase nodes using ssh' do
      Astute::CobblerManager.any_instance.stubs(:remove_nodes).returns([])
      Astute::Rsyslogd.stubs(:send_sighup).once
      @provisioner.stubs(:stop_provision_via_mcollective).returns([[], {}])
      Astute::Ssh.stubs(:execute).returns({'inaccessible_nodes' => [{'uid' => '1'}]}).once

      Astute::Ssh.expects(:execute).with(instance_of(Astute::Context),
                                        data['nodes'],
                                        Astute::SshEraseNodes.command)
                                   .returns({'nodes' => [{'uid' => '1'}]})

      expect(@provisioner.stop_provision(@reporter,
                                   data['task_uuid'],
                                   data['engine'],
                                   data['nodes']))
            .to eql({
                     "error_nodes" => [],
                     "inaccessible_nodes" => [],
                     "nodes" => [{"uid"=>'1'}]
                    })
    end

    it 'always remove nodes from Cobbler' do
      Astute::Rsyslogd.stubs(:send_sighup).once
      Astute::Ssh.stubs(:execute).twice.returns({'inaccessible_nodes' => [{'uid' => '1'}]})
      @provisioner.stubs(:stop_provision_via_mcollective).returns([[], {}])

      Astute::CobblerManager.any_instance.expects(:remove_nodes)
                                         .with(data['nodes'])
                                         .returns([])

      @provisioner.stop_provision(@reporter,
                                   data['task_uuid'],
                                   data['engine'],
                                   data['nodes'])
    end

    it 'reboot nodes using using ssh' do
      Astute::CobblerManager.any_instance.stubs(:remove_nodes).returns([])
      Astute::Rsyslogd.stubs(:send_sighup).once
      @provisioner.stubs(:stop_provision_via_mcollective).returns([[], {}])
      Astute::Ssh.stubs(:execute).returns({'nodes' => [{'uid' => '1'}]}).once

      Astute::Ssh.expects(:execute).with(instance_of(Astute::Context),
                                       data['nodes'],
                                       Astute::SshHardReboot.command,
                                       timeout=5,
                                       retries=1)
                                 .returns({'inaccessible_nodes' => [{'uid' => '1'}]})

      expect(@provisioner.stop_provision(@reporter,
                                   data['task_uuid'],
                                   data['engine'],
                                   data['nodes']))
            .to eql({
                     "error_nodes" => [],
                     "inaccessible_nodes" => [],
                     "nodes" => [{"uid"=>'1'}]
                    })
    end

    it 'stop provision if provision operation stop immediately' do
      Astute::Rsyslogd.stubs(:send_sighup).once
      @provisioner.stubs(:stop_provision_via_ssh)
                   .returns({'inaccessible_nodes' => [{'uid' => '1'}]})
      @provisioner.stubs(:node_type).returns([{'uid' => '1', 'node_type' => 'bootstrap'}])

      Astute::NodesRemover.any_instance.expects(:remove)
                          .once.returns({"nodes"=>[{"uid"=>"1", }]})

      expect(@provisioner.stop_provision(@reporter,
                                   data['task_uuid'],
                                   data['engine'],
                                   data['nodes']))
            .to eql({
                     "error_nodes" => [],
                     "inaccessible_nodes" => [],
                     "nodes" => [{"uid"=>"1"}]
                    })
    end

    it 'stop provision if provision operation stop in the end' do
      Astute::Rsyslogd.stubs(:send_sighup).once
      @provisioner.stubs(:stop_provision_via_ssh)
             .returns({'nodes' => [{'uid' => "1"}]})
      @provisioner.stubs(:node_type).returns([{'uid' => "1", 'node_type' => 'target'}])

      Astute::NodesRemover.any_instance.expects(:remove)
                          .once.returns({"nodes"=>[{"uid"=>"1", }]})

      expect(@provisioner.stop_provision(@reporter,
                                   data['task_uuid'],
                                   data['engine'],
                                   data['nodes']))
            .to eql({
                     "error_nodes" => [],
                     "inaccessible_nodes" => [],
                     "nodes" => [{"uid"=>"1"}]
                    })
    end

    it 'inform about inaccessible nodes' do
      Astute::Rsyslogd.stubs(:send_sighup).once
      Astute::Ssh.stubs(:execute).returns({'inaccessible_nodes' => [{'uid' => '1'}]}).twice
      Astute::CobblerManager.any_instance.stubs(:remove_nodes).returns([])
      @provisioner.stubs(:node_type).returns([])

      Astute::NodesRemover.any_instance.expects(:remove).never

      expect(@provisioner.stop_provision(@reporter,
                             data['task_uuid'],
                             data['engine'],
                             data['nodes']))
            .to eql({
                     "error_nodes" => [],
                     "inaccessible_nodes" => [{"uid"=>'1'}],
                     "nodes" => []
                    })
    end

    it 'sleep between attempts to find and erase nodes using mcollective' do
      Astute::Rsyslogd.stubs(:send_sighup).once
      @provisioner.stubs(:stop_provision_via_ssh)
                   .returns({'inaccessible_nodes' => [{'uid' => '1'}]})
      @provisioner.stubs(:node_type).returns([{'uid' => '1', 'node_type' => 'bootstrap'}])
      Astute::NodesRemover.any_instance.stubs(:remove)
                          .once.returns({"nodes"=>[{"uid"=>"1", }]})

      @provisioner.expects(:sleep).with(Astute.config.nodes_remove_interval)

      @provisioner.stop_provision(@reporter,
                             data['task_uuid'],
                             data['engine'],
                             data['nodes'])
    end

    it 'perform several attempts to find and erase nodes using mcollective' do
      Astute::Rsyslogd.stubs(:send_sighup).once
      Astute.config.mc_retries = 2
      Astute.config.nodes_remove_interval = 0

      @provisioner.stubs(:stop_provision_via_ssh)
                   .returns({'nodes' => [{'uid' => "1"}],
                             'inaccessible_nodes' => [{'uid' => '2'}]})

      @provisioner.stubs(:node_type).twice
                   .returns([{'uid' => '1', 'node_type' => 'bootstrap'}])
                   .then.returns([{'uid' => '2', 'node_type' => 'target'}])

      Astute::NodesRemover.any_instance.stubs(:remove).twice
                          .returns({"nodes"=>[{"uid"=>"1"}]}).then
                          .returns({"error_nodes"=>[{"uid"=>"2"}]})

      data['nodes'] << {
        "uid" => '2',
        'profile' => 'centos-x86_64',
        "slave_name"=>"controller-2",
        "admin_ip" =>'1.2.3.6'
      }

      expect(@provisioner.stop_provision(@reporter,
                             data['task_uuid'],
                             data['engine'],
                             data['nodes']))
            .to eql({
                     "error_nodes" => [{"uid"=>'2'}],
                     "inaccessible_nodes" => [],
                     "nodes" => [{"uid"=>"1"}],
                     "status" => "error"
                    })
    end

    it 'should send sighup for Rsyslogd' do
      Astute::Rsyslogd.expects(:send_sighup).once

      Astute::Ssh.stubs(:execute).twice.returns({'inaccessible_nodes' => [{'uid' => '1'}]})
      @provisioner.stubs(:stop_provision_via_mcollective).returns([[], {}])

      Astute::CobblerManager.any_instance.stubs(:remove_nodes)
                                         .with(data['nodes'])
                                         .returns([])

      @provisioner.stop_provision(@reporter,
                                   data['task_uuid'],
                                   data['engine'],
                                   data['nodes'])
    end

  end # stop_provision

  describe 'provision_piece' do
    let(:nodes) { [{'uid' => '1', 'slave_name' => 'node1', 'profile' => 'centos-x86_64'}] }
    let(:engine_attrs) do
      {
        "url"=>"http://localhost/cobbler_api",
        "username"=>"cobbler",
        "password"=>"cobbler",
        "master_ip"=>"127.0.0.1",
      }
    end

    it 'return failed nodes if image provision return failed uid' do
      Astute::CobblerManager.any_instance.stubs(:netboot_nodes)
      Astute::CobblerManager.any_instance.stubs(:reboot_nodes)
      Astute::CobblerManager.any_instance.stubs(:check_reboot_nodes).returns(['node1'])
      @provisioner.stubs(:change_nodes_type)
      Astute::ImageProvision.stubs(:provision).returns(['1'])
      result = @provisioner.provision_piece(@reporter, 'task_uuid', engine_attrs, nodes, 'image')
      result.should eql(['1'])
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
Car drives through homeless encampment
A vehicle left an Interstate Highway 80 off-ramp in San Francisco this morning and went through a homeless encampment, injuring several people.
less than a minute reading
Bay City News April 5, 2015
A vehicle left an Interstate Highway 80 off-ramp in San Francisco this morning and went through a homeless encampment injuring several people, according to the California Highway Patrol.
The first report of the incident was at 1:08 a.m. The vehicle hit a parked vehicle near Fifth and Harrison streets after traveling through the homeless encampment, according to the CHP. The San Francisco Fire Department responded to the encampment and a fire department official said the injuries at this time to the parties are probably minor.
California Highway Patrol CHP fast5 homeless encampment I-80
Bay City News is a 24/7 news service covering the greater Bay Area. © 2022 Bay City News, Inc. All rights reserved. Republication, rebroadcast or redistribution without the express written consent of Bay City News, Inc. is prohibited.
A's new faces: Brett Lawrie
In Brett Lawrie, fans should expect an average hitter and average defender with room to grow.
Jason Leskiw
Woman allegedly shot in lover's quarrel
A verbal dispute between a boyfriend and girlfriend early this morning in Vallejo sent one to a hospital with...
Man shot, killed in Oakley streetfight
A 27-year-old man was fatally shot in a fight in Oakley late Saturday night.
Golden Gate Shark
The progressives that love the homeless and hate cars are going to have a field day with this story
Fatz Treeboy
a while back the same thing happened and a man was killed sleeping in his tent. it's tough to be on the street. be kind to the homeless no matter how funky they r :)


text:
Vicente de Carvalho és un barri de la Zona Nord del municipi de Rio de Janeiro. Limita amb els barris d'Irajá, Vaz Lobo, Cavalcanti, Tomás Coelho, Vila Kosmos i Vila da Penha.

El barri de Vicente de Carvalho forma part de la regió administrativa d'Irajá i compta amb una població de 24.310 persones (segons informacions de l'Institut Brasiler de Geografia i Estadística - IBGE - Cens Demogràfic 2000) distribuïdes en una àrea de 183,57 ha. El nom del barri és en homenatge la Vicente de Carvalho, antic fazendeiro local, encara que sovint confós amb el jutge i poeta paulista Vicente de Carvalho.

En el creuament de l'avinguda Vicente de Carvalho amb l'Avinguda Pastor Martin Luther King Júnior es troba un bust del principal líder del Moviment afroamericà pels drets civils als Estats Units. A prop de l'estació de metro es troba la 'Torre Da Paz' pintada amb els colors de l'Argentina, i que és una rèplica petita de la Torre Eiffel.

Història
La regió pertanyia a la parròquia d'Irajá, que comprenia les terres d'Engenho do Mato, propietat de Dona Maria d'Abreu Rangel, que el 1741 la donà als seus nets, avantpassats del mariscal Rangel. Aquest molí es va estendre als barris actuals de Tomás Coelho i Engenho da Rainha.

L'estació de tren de Vicente de Carvalho, inaugurada el 15 de gener de 1883 pel Ferrocarril Rio d'Ouro, estava situada aproximadament on avui hi ha l'estació del Metro amb el mateix nom, en la Línia 2 — verda. La línia del metro talla el barri per la meitat, entre les estacions Tomas Coelho i Irajá. Però des de la idea de creació del metro, Vicente de Carvalho era una estació dels trens que anaven directe fins a Irajá. No obstant això, en la reinauguració del tram desactivat des de la dècada de 1980 (setembre 1996) fins a la inauguració de l'estació de Pavuna, Vicente de Carvalho va quedar amb status d'estació terminal de la Línia 2 a Rio. Avui encara és una de les estacions de major trànsit de persones per dia.

La favela de Morro do Juramento, un referent del barri, es va començar a ocupar el 1945 amb la delimitació dels parcel·laments fets a la nit, per evitar la presència de la policia. Les primeres barraques de fusta es van començar a construir a la dècada de 1950 i, amb la construcció d'una església catòlica, es va començar a anomenar "petita església".

Vicente de Carvalho mai ha desenvolupat una ànima comercial o industrial. Té grans barris als voltants que sempre han ofert articles i feines. Per això Vicente de Carvalho té ànima residencial.

Referències

Bibliografia

Barris de la zona nord de Rio de Janeiro


text:
Email Addressinfo@ihic.org.au
Contact Us(02) 95581114
Sydney 17 July, 2019 - 02:24 PM 13 Dhul-Qi'da 1440
Fajr05:29
Thohr12:01
Maghreb17:28
Imam Husain Islamic Centre
What is Islam ?
Join Mailling List
Monthly Calendar and Events
Annual Islamic Calendar 1441 A.H. (2020)
Annual Salat Times
Ramadhan Calendar 1440
E-Hawza
Imam Husain School
Youth Program Details
Upcoming Events (10-14 Boys)
Upcoming Events (15-25+ Boys)
Hadith Competition
Islamic Courses & Classes
Islamic Syllabus
Ask The Sheikh
Ahlul Bayt (as)
Fiqh & Usool
Interfaith & Unity
Al-Fajr Online Magazine
Ask the Sheikh (ATS) is a Question and Answer website on Islam, designed for both Muslims and non-Muslims around the world, with particular emphasis on people living in the West.
About the Aim:
To educate, inform and hence enlighten all people about the True Islam, according to the teachings of the Holy Quran, and the traditions (Sunnah) of the Holy Prophet (s) and his purified progeny, the Ahlul-Bayt (a.s).
About the Objectives:
– to provide Muslims and non-Muslims with a deeper insight into the various aspects of Islam
– to provide solutions to the personal/social problems of people, within an Islamic context
– to counter the false information and propaganda being spread on Islam
– to promote an accurate understanding of Islam
About the Questions:
We warmly invite and encourage you to send in your questions on all matters related to Islam. Before sending in your questions, please do a quick search using the search engine on our home page (or manually by briefly exploring our Question Categories) lest your question has already been answered.
Also, please keep in mind that your questions will pass an administrator before reaching one of the Sheikhs. The administrators mainly check for spam mail, but also whether an answer already exists on the ATS database for the question sent. The privacy of all questioners' personal details (and questions that won't be published) is taken very seriously. However, we kindly suggest that you try to refrain from including any specific details (e.g. names, places), if you wish to further protect your confidentiality.
About the Answers:
In short, all answers provided on ATS are provided by highly-qualified and prominent religious scholars who come from various communities from around the world. The questions that are answered by more junior scholars, will definitely be reviewed and edited by a senior scholar before the answer is sent back to the questioner and/or published onto the website. The name of the more junior scholar aswell as the senior scholar who undertook the review will both appear below the answer during publication.
We will endeavour to provide you with the biographies, and the intellectual qualifications and background of every scholar who partakes in answering questions on the website (please refer to 'Meet the Sheikh' page).
Jurisprudential (Fiqh) Answers:
Please note that only the opinions of the currently living, most famous Maraaje' will be provided by the scholars at this point in time. That is, the opinions of:
– Grand Ayatollah Sayyed Ali Khamenei (h.a.)
– Grand Ayatollah Sayyed Ali Sistani (h.a.)
– Grand Ayatollah Makaarem Shirazi (h.a.)
However, please also note that we will only publish the opinions of Ayatollah Khamenei (h.a.) and Ayatollah Sistani (h.a.) on our website, because of technical limitations and the overwhelming numbers of Muslims who do Taqleed (religious emulation) to them. As for Ayatollah Makaarem Shirazi's opinions, they will be provided to questioners privately, but the Q&As will not be published on our website.
Finally, it must be said that while ATS endeavours to provide the best answers to your questioners, it is not responsible that all the answers will be 100% correct. Ultimately, every scholar is responsible for his own answers.
WWW.ASKTHESHEIKH.COM
General Contacts :
6 Lang Road, Earlwood, NSW, Australia
info@ihic.org.au
Birth of Imam Redha (as)
Friday 07:30 PM
Salat Jumu'ah
Tafsir of Dua Kumayl & Dua Kumayl
Thursday 07:30 PM
For Latest Updates & For Majalis
Copyright@2018 Imam Husain Islamic Centre


サクラホテルで韓国料理の卵パンをご紹介します。I will introduce the egg bread of Korean cuisine at Sakura Hotel.
I will introduce the egg bread of Korean cuisine at Sakura Hotel.
In Korea, we have sold wherever you go the pan of eggs.
You can eat to make easily at home.
You can make fun with their children.
Method of making a stir and put one egg and milk towards the cake.
And I put about paper cup half.
Please Bake about 15 minutes in the oven.
And, cheese stick that can be made easy with bread!
You can eat to make cheese stick with the remaining bread to eat.
Completed and fry to put the cheese in the center of the bread!
Please try to eat to make! ~!
I'm sakura hotel jimbocho's staff Ayumi.
We got guest from South Africa!
He have stayed sakura hotel jimbocho twice.
He ate breakfast everyday with this scrambled egg.
This is his favorite scrambled egg!!
We are serving this scrambled egg everyday at 500yen with toast, tea, coffee and soup.
Why don't you have breakfast at sakura cafe jimbocho??
Sakura cafe Jimbocho's Terrace is crowded today as well.
They met and get new friends at Sakura Hotel Jimbocho each other.
Everyone said 'kanpai' which means Cheers in Japanese.
They have Japanese beer which is Asahi Beer.
Of course we have Japanese beer wide variety.
This is way to get them 500 Yen each.
I went to Shin-Okubo where is Korean Town in Tokyo on my day off.
We drank matkori and chamisul and ate samgyeopsal.
This is korean healthy grilled pork style.
Today's last drink is Chamisul.
We also have world beers in Sakura Cafe Jimbocho.
Guess you can't choose just one beer.
I found awesome spring stuffs near Sakura Hotel Jimbocho!
I would like to know the name of this!
I like this color .like this blight one!
Many people in the world have come to visit the Sakura Hotel.
Customers in each country of about 25 countries have come to visit Sakura Hotel Many from 20 countries in a day.
The - I do not know at all whether the people anywhere in the country to see only the face!
There is also a Japanese case is the person who looks like a foreigner surprisingly.
In the cafe, there is also a chance for you to meet people in many countries around the world.
There is a chance that may become friends with many people in the world.
Simple is best, If you have a genuine ingredients.
Please try our pudding at Sakura Cafe Jimbocho!!
Spring has come in Tokyo!!
Why don't you try our breakfast?? You can eat every thing!!
You can get your breakfast just 500 Yen.
You can get Toast,coffer tea soup and scrambled eggs.
scrambled eggs are made by our staff.
We catch on among the staff who are or well make the most recently.
Please have a look my How to mix eggs.
I can make good scrambled eggs.
Rico also do well this.
Do you want to eat Rico's made one???
There are some people who are studying at Sakura Cafe Jimbocho.
Today I will write about Guest from Sakura Hotel Jimbocho!
He gave us a great photo for us!
This is his favorite one !
He said he feels real beautiful Japan from this picture.
This photo you can see at Sakura Hotel entrance called Guests Photo Collection!
Please come to see the photos here at Sakura Hotel Jimbocho!
こんにちは!サクラホテル神保町で研修中パクです。It is park training at the Sakura Hotel.
It is park training at the Sakura Hotel.
From today I will be training at Sakura Hotel Jimbocho.
I am very glad I learned from Sakura Hotel staff friendly! !
Keep it up, so thank you!
Here was a heavy snow for the first time in a long time is Nagasaki Peninsula golf courses say.
I was not able to play with everyone from golf.
Please talk about the Korean question at any time, so be accepted at any time!


text:
Did humans almost become extinct about 70,000 years ago?
I received this screenshot which is actually a post on Facebook by 8facts. It claims that humans nearly became extinct 70,000 years ago when the population sunk to 2,000.
Is there any evidence that this claim is correct?
history extinction-event
pacoverflow
agha rehan abbasagha rehan abbas
Possibly, but maybe not as severe as suggested. Basically the eruption of the Toba supervolcano caused a volcanic winter that decimated the human population at the time. There is evidence of this in the human genome. DNA mutates at a reasonably steady rate, so by looking at the genetic diversity of humans we can see that the population must have been very homogenous (i.e. small) at some point around 60K years ago.
differentiation of modern humans ☆
Stanley H. Ambrose
DOI: 10.1006/jhev.1998.0219
The "Weak Garden of Eden" model for the origin and dispersal of modern humans (Harpendinget al., 1993) posits that modern humans spread into separate regions from a restricted source, around 100 ka (thousand years ago), then passed through population bottlenecks. Around 50 ka, dramatic growth occurred within dispersed populations that were genetically isolated from each other. Population growth began earliest in Africa and later in Eurasia and is hypothesized to have been caused by the invention and spread of a more efficient Later Stone Age/Upper Paleolithic technology, which developed in equatorial Africa.
Climatic and geological evidence suggest an alternative hypothesis for Late Pleistocene population bottlenecks and releases. The last glacial period was preceded by one thousand years of the coldest temperatures of the Later Pleistocene (∼71–70 ka), apparently caused by the eruption of Toba, Sumatra. Toba was the largest known explosive eruption of the Quaternary. Toba's volcanic winter could have decimated most modern human populations, especially outside of isolated tropical refugia. Release from the bottleneck could have occurred either at the end of this hypercold phase, or 10,000 years later, at the transition from cold oxygen isotope stage 4 to warmer stage 3. The largest populations surviving through the bottleneck should have been found in the largest tropical refugia, and thus in equatorial Africa. High genetic diversity in modern Africans may thus reflect a less severe bottleneck rather than earlier population growth.
Volcanic winter may have reduced populations to levels low enough for founder effects, genetic drift and local adaptations to produce rapid population differentiation. If Toba caused the bottlenecks, then modern human races may have differentiated abruptly, only 70 thousand years ago.
Alternatively, Wikipedia's article titled Toba catastrophe theory links to a BBC News article, When humans faced extinction. This BBC News article gives the 70,000 and 2,000 figures, so that may well be the source of the claim:
Humans may have come close to extinction about 70,000 years ago, according to the latest genetic research.
Researchers from Stanford University, US, and the Russian Academy of Sciences compared 377 microsatellite markers in DNA collected from 52 regions around the world.
The small genetic diversity of modern humans indicates that at some stage during the last 100,000 years, the human population dwindled to a very low level.
It was out of this small population, with its consequent limited genetic diversity, that today's humans descended.
Estimates of how small the human population became vary but 2,000 is the figure suggested in the latest research.
If this is the case, humanity came very close to extinction.
Dikran MarsupialDikran Marsupial
This may answer the question, but if so, I can't see it. Could you either highlight the relevant portions of the abstract or provide your own summary? – Bobson Nov 7 '14 at 18:44
The source of the claim might be the "Researchers from Stanford University and the Russian Academy of Sciences". The article is from 2003. – ChrisW Nov 7 '14 at 19:55
Any idea on how dispersed they think those 2K - 70K were? If they were all on Gilligan's island, that would be less a threat of going out (unless some local event struck, I suppose) than if they were spread out over a couple of continents with less ability to interact or cooperate (less ability to war on each other too, I suppose). I know that the Black Plague was considered a significant carnage and threat, but wow, nothing like this. – PoloHoleSet Oct 26 '17 at 18:39
I've found a few sources on the subject that discuss the hypothesis.
The first is by Hawks et. al.. On the second page,
A 2-Myr Bottleneck There are many reasons to believe that there may have been a number of severe population size bottlenecks on the lineage leading to living humans, principally because of the many speciation events that must have occurred. The diversity of the Pliocene hominid fossil record, beginning with the large samples from Aramis and Kanapoi 4.0–4.4 MYA (White, Suwa, and Asfaw 1994; Leakey 1995; Leakey et al. 1998), indicates that ours is just the most recent of a wide array of hominid species that once existed. The demographic effects of such speciations can be expected to have been intense, probably involving significant founder effects due to small population sizes, and they eradicated evidence of earlier speciations, such as the chimpanzee-hominid divergence. In turn, we expect that any genetic evidence of these early hominid speciations would have been covered up by the most recent significant bottleneck. We believe this bottleneck could have been the speciation event at the beginning of the lineage leading to living human populations.
A paragraph in the conclusion puts it (in my opinion) a little better:
All the currently available genetic, paleontological, and archaeological data are consistent with a bottleneck in our lineage more or less at about 2 MYA. At the moment, genetic data cannot disprove a simple model of exponential population growth following such a bottleneck and extending through the Pleistocene. Archaeological and paleontological data indicate that this model is too oversimplified to be an accurate reflection of detailed population history, and therefore we conclude that genetic data lack the resolution to validly reflect many details of Pleistocene human population change.
However, the next sentence is a bit different:
However, there is one detail these data are sufficient to address. Both genetic and anthropological data are incompatible with the hypothesis of a recent population size bottleneck. Such an event would be expected to leave a significant mark across numerous genetic loci and observable anatomical traits.
In other words, the problem is that the genes of modern humans aren't quite what they should be if there was a bottleneck. Yes, they are very similar, as they should be if there was a bottleneck, but they aren't extremely similar, as they should be if there was such a recent bottleneck. In other words: Humans are genetically similar to each other, as are all species, but they aren't quite as "identical" as one would expect would be the case after a bottleneck.
This site efficiently summarizes a paper by Stanley Ambrose (which Dikran Marsupial was discussing). Here is the concluding paragraph:
Ambrose concludes that bottlenecks occurred among genetically isolated human populations because of a six-year long volcanic winter and subsequent hyper-cold millennium after the cataclysmic super-eruption of Toba. This volcanic winter played a role in recent human differentiation. The resultant combination of founder effects and genetic drift may account for low human genetic diversity as well as population differences associated with so-called races. The bottleneck hypothesis offers an explanation for why humans exhibit so little genetic variation, yet superficially appear diverse. It also affords an explanation for the apparent recent coalescence of mtDNA and African origins.
In summary: an eruption by the Toba volcano led to a volcanic winter, leading to bottlenecks in humans in many areas. The lack of genetic variation in humans today is evidence of such a bottleneck at some point in time.
NPR has a slightly less dull take on the issue. Here's a short excerpt:
Toba, The Supervolcano
Once upon a time, says Sam [Kean], around 70,000 B.C., a volcano called Toba, on Sumatra, in Indonesia went off, blowing roughly 650 miles of vaporized rock into the air. It is the largest volcanic eruption we know of, dwarfing everything else...
That eruption dropped roughly six centimeters of ash — the layer can still be seen on land — over all of South Asia, the Indian Ocean, the Arabian and South China Sea. According to the Volcanic Explosivity Index, the Toba eruption scored an "8", which translates to "mega-colossal" — that's two orders of magnitude greater than the largest volcanic eruption in historic times at Mount Tambora in Indonesia, which caused the 1816 "Year Without a Summer" in the northern hemisphere.
Why did this hurt humans? The ash and clouds hurt ecosystems around the world, making less food for humans:
With so much ash, dust and vapor in the air, Sam Kean says it's a safe guess that Toba "dimmed the sun for six years, disrupted seasonal rains, choked off streams and scattered whole cubic miles of hot ash (imagine wading through a giant ashtray) across acres and acres of plants." Berries, fruits, trees, African game became scarce; early humans, living in East Africa just across the Indian Ocean from Mount Toba, probably starved, or at least, he says, "It's not hard to imagine the population plummeting."
HDE 226868HDE 226868
Incidentally, "dwarfing everything else" is a bit extreme. It appears Toba pub up 2800 cubic kilometers of magma, which is huge, but it's only about 14% bit bigger than the Hucklebery Ridge eruption of Yellowstone (at 2450 ckm) For comparison, Mount St Helens put up a quarter of a cubic kilometer. – ReasonablySkeptical Oct 26 '17 at 15:56
Not the answer you're looking for? Browse other questions tagged history extinction-event .
Did the Ottoman sultans kill their own brothers?
Did removing one olive lead to an airline saving thousands of dollars?
Was Francis Crick high on LSD when he discovered the structure of DNA?
Are Adolf Hitler's DNA samples available?
Have leap days confused the calculated date for the "end of the Mayan calendar"?
Was Kursk sunk by USS Memphis?
Would humans starve if spiders disappeared?
Did Neanderthals keep Cro-Magnons as sex-slaves?
Are Ashkenazi Jews genetically more European than Semitic?
Has Syria received proportionally more refugees than other countries in recent history?